diff options
author | Johan Hovold <johan@hovoldconsulting.com> | 2015-11-25 15:59:02 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2015-11-25 15:27:06 -0800 |
commit | 2adaefb1458f67b3f71111fcf6a15670ab64101d (patch) | |
tree | be7543e200dffec38c62dfebdb87b5aedfc96acd /drivers/staging/greybus/hd.c | |
parent | a97015c9e99d8421b80cdf9652a456f4cd93fc1e (diff) | |
download | op-kernel-dev-2adaefb1458f67b3f71111fcf6a15670ab64101d.zip op-kernel-dev-2adaefb1458f67b3f71111fcf6a15670ab64101d.tar.gz |
greybus: hd: make host device a device
Make the host device a proper device in the kernel device model.
Host devices will be our new greybus-bus root devices.
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/hd.c')
-rw-r--r-- | drivers/staging/greybus/hd.c | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/drivers/staging/greybus/hd.c b/drivers/staging/greybus/hd.c index 3446fec..88d2f01 100644 --- a/drivers/staging/greybus/hd.c +++ b/drivers/staging/greybus/hd.c @@ -14,26 +14,30 @@ #include "greybus.h" -static DEFINE_MUTEX(hd_mutex); +static struct ida gb_hd_bus_id_map; -static void free_hd(struct kref *kref) +static void gb_hd_release(struct device *dev) { - struct gb_host_device *hd; - - hd = container_of(kref, struct gb_host_device, kref); + struct gb_host_device *hd = to_gb_host_device(dev); + ida_simple_remove(&gb_hd_bus_id_map, hd->bus_id); ida_destroy(&hd->cport_id_map); kfree(hd); - mutex_unlock(&hd_mutex); } +struct device_type greybus_hd_type = { + .name = "greybus_host_device", + .release = gb_hd_release, +}; + struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver, struct device *parent, size_t buffer_size_max, size_t num_cports) { struct gb_host_device *hd; + int ret; /* * Validate that the driver implements all of the callbacks @@ -68,8 +72,21 @@ struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver, if (!hd) return ERR_PTR(-ENOMEM); - kref_init(&hd->kref); - hd->parent = parent; + hd->dev.parent = parent; + hd->dev.bus = &greybus_bus_type; + hd->dev.type = &greybus_hd_type; + hd->dev.dma_mask = hd->dev.parent->dma_mask; + device_initialize(&hd->dev); + + ret = ida_simple_get(&gb_hd_bus_id_map, 1, 0, GFP_KERNEL); + if (ret < 0) { + kfree(hd); + return ERR_PTR(ret); + } + + hd->bus_id = ret; + dev_set_name(&hd->dev, "greybus%d", hd->bus_id); + hd->driver = driver; INIT_LIST_HEAD(&hd->interfaces); INIT_LIST_HEAD(&hd->connections); @@ -83,6 +100,12 @@ EXPORT_SYMBOL_GPL(gb_hd_create); int gb_hd_add(struct gb_host_device *hd) { + int ret; + + ret = device_add(&hd->dev); + if (ret) + return ret; + /* * Initialize AP's SVC protocol connection: * @@ -93,8 +116,10 @@ int gb_hd_add(struct gb_host_device *hd) * time we will create a fully initialized svc-connection, as we need * endo-id and AP's interface id for that. */ - if (!gb_ap_svc_connection_create(hd)) + if (!gb_ap_svc_connection_create(hd)) { + device_del(&hd->dev); return -ENOMEM; + } return 0; } @@ -113,11 +138,25 @@ void gb_hd_del(struct gb_host_device *hd) /* Is the SVC still using the partially uninitialized connection ? */ if (hd->initial_svc_connection) gb_connection_destroy(hd->initial_svc_connection); + + device_del(&hd->dev); } EXPORT_SYMBOL_GPL(gb_hd_del); void gb_hd_put(struct gb_host_device *hd) { - kref_put_mutex(&hd->kref, free_hd, &hd_mutex); + put_device(&hd->dev); } EXPORT_SYMBOL_GPL(gb_hd_put); + +int __init gb_hd_init(void) +{ + ida_init(&gb_hd_bus_id_map); + + return 0; +} + +void gb_hd_exit(void) +{ + ida_destroy(&gb_hd_bus_id_map); +} |