greybus: core: make the control object be a device
authorJohan Hovold <johan@hovoldconsulting.com>
Wed, 13 Apr 2016 17:19:02 +0000 (19:19 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 21 Apr 2016 01:06:00 +0000 (10:06 +0900)
Make the control object be a greybus device.

The control device will be used to expose attributes specific to
greybus-type interfaces.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/control.c
drivers/staging/greybus/control.h
drivers/staging/greybus/core.c
drivers/staging/greybus/greybus.h
drivers/staging/greybus/interface.c

index 3c1f66400a79347c643763bbde582a3349a12238..c303bb2937bce94e5c8b4e8c2b4cad9fe3465c61 100644 (file)
@@ -213,6 +213,20 @@ int gb_control_timesync_authoritative(struct gb_control *control,
                                 NULL, 0);
 }
 
+static void gb_control_release(struct device *dev)
+{
+       struct gb_control *control = to_gb_control(dev);
+
+       gb_connection_destroy(control->connection);
+
+       kfree(control);
+}
+
+struct device_type greybus_control_type = {
+       .name =         "greybus_control",
+       .release =      gb_control_release,
+};
+
 struct gb_control *gb_control_create(struct gb_interface *intf)
 {
        struct gb_control *control;
@@ -221,6 +235,8 @@ struct gb_control *gb_control_create(struct gb_interface *intf)
        if (!control)
                return NULL;
 
+       control->intf = intf;
+
        control->connection = gb_connection_create_control(intf);
        if (IS_ERR(control->connection)) {
                dev_err(&intf->dev,
@@ -230,6 +246,13 @@ struct gb_control *gb_control_create(struct gb_interface *intf)
                return NULL;
        }
 
+       control->dev.parent = &intf->dev;
+       control->dev.bus = &greybus_bus_type;
+       control->dev.type = &greybus_control_type;
+       control->dev.dma_mask = intf->dev.dma_mask;
+       device_initialize(&control->dev);
+       dev_set_name(&control->dev, "%s.ctrl", dev_name(&intf->dev));
+
        gb_connection_set_data(control->connection, control);
 
        return control;
@@ -271,8 +294,7 @@ void gb_control_disable(struct gb_control *control)
        gb_connection_disable(control->connection);
 }
 
-void gb_control_destroy(struct gb_control *control)
+void gb_control_put(struct gb_control *control)
 {
-       gb_connection_destroy(control->connection);
-       kfree(control);
+       put_device(&control->dev);
 }
index 949f1a3c433b04ef00b8f24f9b72eda842c33c53..697f901b34a797026842dccaf7b231f60fabdc16 100644 (file)
 #define __CONTROL_H
 
 struct gb_control {
-       struct gb_connection    *connection;
+       struct device dev;
+       struct gb_interface *intf;
+
+       struct gb_connection *connection;
 
        u8 protocol_major;
        u8 protocol_minor;
 
        bool has_bundle_version;
 };
+#define to_gb_control(d) container_of(d, struct gb_control, dev)
 
 struct gb_control *gb_control_create(struct gb_interface *intf);
 int gb_control_enable(struct gb_control *control);
 void gb_control_disable(struct gb_control *control);
-void gb_control_destroy(struct gb_control *control);
+void gb_control_put(struct gb_control *control);
 
 int gb_control_get_bundle_versions(struct gb_control *control);
 int gb_control_connected_operation(struct gb_control *control, u16 cport_id);
index d8680667ca32598009202b16fcb50e9cf0972ace..9f143e5a7c9c8471e4f2042ce79588146bf11bab 100644 (file)
@@ -86,6 +86,7 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
        struct gb_host_device *hd;
        struct gb_interface *intf = NULL;
+       struct gb_control *control = NULL;
        struct gb_bundle *bundle = NULL;
        struct gb_svc *svc = NULL;
 
@@ -94,6 +95,10 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
        } else if (is_gb_interface(dev)) {
                intf = to_gb_interface(dev);
                hd = intf->hd;
+       } else if (is_gb_control(dev)) {
+               control = to_gb_control(dev);
+               intf = control->intf;
+               hd = intf->hd;
        } else if (is_gb_bundle(dev)) {
                bundle = to_gb_bundle(dev);
                intf = bundle->intf;
index 2fc79faad28ec5b0b643fd67014d3a0145f9bb0a..4ab5f608b8cd4359720b087572619b90d069a2f6 100644 (file)
@@ -113,6 +113,7 @@ extern struct bus_type greybus_bus_type;
 
 extern struct device_type greybus_hd_type;
 extern struct device_type greybus_interface_type;
+extern struct device_type greybus_control_type;
 extern struct device_type greybus_bundle_type;
 extern struct device_type greybus_svc_type;
 
@@ -126,6 +127,11 @@ static inline int is_gb_interface(const struct device *dev)
        return dev->type == &greybus_interface_type;
 }
 
+static inline int is_gb_control(const struct device *dev)
+{
+       return dev->type == &greybus_control_type;
+}
+
 static inline int is_gb_bundle(const struct device *dev)
 {
        return dev->type == &greybus_bundle_type;
index a4bee41feec4518777fcc3c19b970969f711f617..56a320732ef9ca7ce5e78cfa0b4585ccb7029c2c 100644 (file)
@@ -360,7 +360,7 @@ static void gb_interface_release(struct device *dev)
        kfree(intf->vendor_string);
 
        if (intf->control)
-               gb_control_destroy(intf->control);
+               gb_control_put(intf->control);
 
        kfree(intf);
 }