summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohan Hovold <johan@hovoldconsulting.com>2016-04-13 19:19:02 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2016-04-21 10:06:00 +0900
commita6e5b014b8fe0bd4cb1e1ca0380320a200605742 (patch)
tree963b67c08d45090c768eff28ce8b1b27b3382604 /drivers
parent1ed8cdef405806c246b62a1ba926e0251fdaa531 (diff)
downloadop-kernel-dev-a6e5b014b8fe0bd4cb1e1ca0380320a200605742.zip
op-kernel-dev-a6e5b014b8fe0bd4cb1e1ca0380320a200605742.tar.gz
greybus: core: make the control object be a device
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/greybus/control.c28
-rw-r--r--drivers/staging/greybus/control.h8
-rw-r--r--drivers/staging/greybus/core.c5
-rw-r--r--drivers/staging/greybus/greybus.h6
-rw-r--r--drivers/staging/greybus/interface.c2
5 files changed, 43 insertions, 6 deletions
diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c
index 3c1f664..c303bb2 100644
--- a/drivers/staging/greybus/control.c
+++ b/drivers/staging/greybus/control.c
@@ -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);
}
diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h
index 949f1a3..697f901 100644
--- a/drivers/staging/greybus/control.h
+++ b/drivers/staging/greybus/control.h
@@ -11,18 +11,22 @@
#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);
diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c
index d868066..9f143e5 100644
--- a/drivers/staging/greybus/core.c
+++ b/drivers/staging/greybus/core.c
@@ -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;
diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h
index 2fc79fa..4ab5f60 100644
--- a/drivers/staging/greybus/greybus.h
+++ b/drivers/staging/greybus/greybus.h
@@ -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;
diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
index a4bee41f..56a3207 100644
--- a/drivers/staging/greybus/interface.c
+++ b/drivers/staging/greybus/interface.c
@@ -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);
}
OpenPOWER on IntegriCloud