Commit a6e5b014 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

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: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 1ed8cdef
...@@ -213,6 +213,20 @@ int gb_control_timesync_authoritative(struct gb_control *control, ...@@ -213,6 +213,20 @@ int gb_control_timesync_authoritative(struct gb_control *control,
NULL, 0); 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 *gb_control_create(struct gb_interface *intf)
{ {
struct gb_control *control; struct gb_control *control;
...@@ -221,6 +235,8 @@ struct gb_control *gb_control_create(struct gb_interface *intf) ...@@ -221,6 +235,8 @@ struct gb_control *gb_control_create(struct gb_interface *intf)
if (!control) if (!control)
return NULL; return NULL;
control->intf = intf;
control->connection = gb_connection_create_control(intf); control->connection = gb_connection_create_control(intf);
if (IS_ERR(control->connection)) { if (IS_ERR(control->connection)) {
dev_err(&intf->dev, dev_err(&intf->dev,
...@@ -230,6 +246,13 @@ struct gb_control *gb_control_create(struct gb_interface *intf) ...@@ -230,6 +246,13 @@ struct gb_control *gb_control_create(struct gb_interface *intf)
return NULL; 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); gb_connection_set_data(control->connection, control);
return control; return control;
...@@ -271,8 +294,7 @@ void gb_control_disable(struct gb_control *control) ...@@ -271,8 +294,7 @@ void gb_control_disable(struct gb_control *control)
gb_connection_disable(control->connection); 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); put_device(&control->dev);
kfree(control);
} }
...@@ -11,18 +11,22 @@ ...@@ -11,18 +11,22 @@
#define __CONTROL_H #define __CONTROL_H
struct gb_control { struct gb_control {
struct gb_connection *connection; struct device dev;
struct gb_interface *intf;
struct gb_connection *connection;
u8 protocol_major; u8 protocol_major;
u8 protocol_minor; u8 protocol_minor;
bool has_bundle_version; 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); struct gb_control *gb_control_create(struct gb_interface *intf);
int gb_control_enable(struct gb_control *control); int gb_control_enable(struct gb_control *control);
void gb_control_disable(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_get_bundle_versions(struct gb_control *control);
int gb_control_connected_operation(struct gb_control *control, u16 cport_id); int gb_control_connected_operation(struct gb_control *control, u16 cport_id);
......
...@@ -86,6 +86,7 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -86,6 +86,7 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
struct gb_host_device *hd; struct gb_host_device *hd;
struct gb_interface *intf = NULL; struct gb_interface *intf = NULL;
struct gb_control *control = NULL;
struct gb_bundle *bundle = NULL; struct gb_bundle *bundle = NULL;
struct gb_svc *svc = NULL; struct gb_svc *svc = NULL;
...@@ -94,6 +95,10 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -94,6 +95,10 @@ static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
} else if (is_gb_interface(dev)) { } else if (is_gb_interface(dev)) {
intf = to_gb_interface(dev); intf = to_gb_interface(dev);
hd = intf->hd; 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)) { } else if (is_gb_bundle(dev)) {
bundle = to_gb_bundle(dev); bundle = to_gb_bundle(dev);
intf = bundle->intf; intf = bundle->intf;
......
...@@ -113,6 +113,7 @@ extern struct bus_type greybus_bus_type; ...@@ -113,6 +113,7 @@ extern struct bus_type greybus_bus_type;
extern struct device_type greybus_hd_type; extern struct device_type greybus_hd_type;
extern struct device_type greybus_interface_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_bundle_type;
extern struct device_type greybus_svc_type; extern struct device_type greybus_svc_type;
...@@ -126,6 +127,11 @@ static inline int is_gb_interface(const struct device *dev) ...@@ -126,6 +127,11 @@ static inline int is_gb_interface(const struct device *dev)
return dev->type == &greybus_interface_type; 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) static inline int is_gb_bundle(const struct device *dev)
{ {
return dev->type == &greybus_bundle_type; return dev->type == &greybus_bundle_type;
......
...@@ -360,7 +360,7 @@ static void gb_interface_release(struct device *dev) ...@@ -360,7 +360,7 @@ static void gb_interface_release(struct device *dev)
kfree(intf->vendor_string); kfree(intf->vendor_string);
if (intf->control) if (intf->control)
gb_control_destroy(intf->control); gb_control_put(intf->control);
kfree(intf); kfree(intf);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment