summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/hd.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@hovoldconsulting.com>2015-11-25 15:59:02 +0100
committerGreg Kroah-Hartman <gregkh@google.com>2015-11-25 15:27:06 -0800
commit2adaefb1458f67b3f71111fcf6a15670ab64101d (patch)
treebe7543e200dffec38c62dfebdb87b5aedfc96acd /drivers/staging/greybus/hd.c
parenta97015c9e99d8421b80cdf9652a456f4cd93fc1e (diff)
downloadop-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.c59
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);
+}
OpenPOWER on IntegriCloud