mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 02:50:43 +00:00
greybus: interface: reduce control-device lifetime
Make the control-device lifetime coincide with when the interface is enabled (enumerated). This is needed to be able register a new control device after a mode switch. Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
b6147e4fb1
commit
49605839bc
2 changed files with 23 additions and 12 deletions
|
@ -352,9 +352,6 @@ static void gb_interface_release(struct device *dev)
|
|||
{
|
||||
struct gb_interface *intf = to_gb_interface(dev);
|
||||
|
||||
if (intf->control)
|
||||
gb_control_put(intf->control);
|
||||
|
||||
kfree(intf);
|
||||
}
|
||||
|
||||
|
@ -381,7 +378,6 @@ struct device_type greybus_interface_type = {
|
|||
struct gb_interface *gb_interface_create(struct gb_host_device *hd,
|
||||
u8 interface_id)
|
||||
{
|
||||
struct gb_control *control;
|
||||
struct gb_interface *intf;
|
||||
|
||||
intf = kzalloc(sizeof(*intf), GFP_KERNEL);
|
||||
|
@ -404,13 +400,6 @@ struct gb_interface *gb_interface_create(struct gb_host_device *hd,
|
|||
device_initialize(&intf->dev);
|
||||
dev_set_name(&intf->dev, "%d-%d", hd->bus_id, interface_id);
|
||||
|
||||
control = gb_control_create(intf);
|
||||
if (IS_ERR(control)) {
|
||||
put_device(&intf->dev);
|
||||
return NULL;
|
||||
}
|
||||
intf->control = control;
|
||||
|
||||
list_add(&intf->links, &hd->interfaces);
|
||||
|
||||
return intf;
|
||||
|
@ -442,6 +431,7 @@ void gb_interface_deactivate(struct gb_interface *intf)
|
|||
*/
|
||||
int gb_interface_enable(struct gb_interface *intf)
|
||||
{
|
||||
struct gb_control *control;
|
||||
struct gb_bundle *bundle, *tmp;
|
||||
int ret, size;
|
||||
void *manifest;
|
||||
|
@ -453,9 +443,17 @@ int gb_interface_enable(struct gb_interface *intf)
|
|||
}
|
||||
|
||||
/* Establish control connection */
|
||||
control = gb_control_create(intf);
|
||||
if (IS_ERR(control)) {
|
||||
dev_err(&intf->dev, "failed to create control device: %lu\n",
|
||||
PTR_ERR(control));
|
||||
return PTR_ERR(control);
|
||||
}
|
||||
intf->control = control;
|
||||
|
||||
ret = gb_control_enable(intf->control);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_put_control;
|
||||
|
||||
/* Get manifest size using control protocol on CPort */
|
||||
size = gb_control_get_manifest_size_operation(intf);
|
||||
|
@ -503,6 +501,8 @@ int gb_interface_enable(struct gb_interface *intf)
|
|||
|
||||
kfree(manifest);
|
||||
|
||||
intf->enabled = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_bundles:
|
||||
|
@ -512,6 +512,9 @@ int gb_interface_enable(struct gb_interface *intf)
|
|||
kfree(manifest);
|
||||
err_disable_control:
|
||||
gb_control_disable(intf->control);
|
||||
err_put_control:
|
||||
gb_control_put(intf->control);
|
||||
intf->control = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -522,6 +525,9 @@ void gb_interface_disable(struct gb_interface *intf)
|
|||
struct gb_bundle *bundle;
|
||||
struct gb_bundle *next;
|
||||
|
||||
if (!intf->enabled)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Disable the control-connection early to avoid operation timeouts
|
||||
* when the interface is already gone.
|
||||
|
@ -534,6 +540,10 @@ void gb_interface_disable(struct gb_interface *intf)
|
|||
|
||||
gb_control_del(intf->control);
|
||||
gb_control_disable(intf->control);
|
||||
gb_control_put(intf->control);
|
||||
intf->control = NULL;
|
||||
|
||||
intf->enabled = false;
|
||||
}
|
||||
|
||||
/* Register an interface and its bundles. */
|
||||
|
|
|
@ -39,6 +39,7 @@ struct gb_interface {
|
|||
unsigned long quirks;
|
||||
|
||||
bool disconnected;
|
||||
bool enabled;
|
||||
};
|
||||
#define to_gb_interface(d) container_of(d, struct gb_interface, dev)
|
||||
|
||||
|
|
Loading…
Reference in a new issue