mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 23:34:05 +08:00
greybus: svc: create svc along with host device
Create svc device along with host-device and move the svc-connection to the svc structure. The svc connection is enabled when registering the host device, but as the SVC protocol is currently driven by the SVC, we need to defer registration of the svc device to the connection request handler. 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
2c848944c1
commit
7adeaae713
@ -21,8 +21,8 @@ static void gb_hd_release(struct device *dev)
|
||||
{
|
||||
struct gb_host_device *hd = to_gb_host_device(dev);
|
||||
|
||||
if (hd->svc_connection)
|
||||
gb_connection_destroy(hd->svc_connection);
|
||||
if (hd->svc)
|
||||
gb_svc_put(hd->svc);
|
||||
ida_simple_remove(&gb_hd_bus_id_map, hd->bus_id);
|
||||
ida_destroy(&hd->cport_id_map);
|
||||
kfree(hd);
|
||||
@ -95,10 +95,9 @@ struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
|
||||
device_initialize(&hd->dev);
|
||||
dev_set_name(&hd->dev, "greybus%d", hd->bus_id);
|
||||
|
||||
hd->svc_connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID,
|
||||
GREYBUS_PROTOCOL_SVC);
|
||||
if (!hd->svc_connection) {
|
||||
dev_err(&hd->dev, "failed to create svc connection\n");
|
||||
hd->svc = gb_svc_create(hd);
|
||||
if (!hd->svc) {
|
||||
dev_err(&hd->dev, "failed to create svc\n");
|
||||
put_device(&hd->dev);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
@ -115,7 +114,7 @@ int gb_hd_add(struct gb_host_device *hd)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = gb_connection_init(hd->svc_connection);
|
||||
ret = gb_svc_add(hd->svc);
|
||||
if (ret) {
|
||||
device_del(&hd->dev);
|
||||
return ret;
|
||||
@ -129,7 +128,7 @@ void gb_hd_del(struct gb_host_device *hd)
|
||||
{
|
||||
gb_interfaces_remove(hd);
|
||||
|
||||
gb_connection_exit(hd->svc_connection);
|
||||
gb_svc_del(hd->svc);
|
||||
|
||||
device_del(&hd->dev);
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ struct gb_host_device {
|
||||
size_t buffer_size_max;
|
||||
|
||||
struct gb_svc *svc;
|
||||
struct gb_connection *svc_connection;
|
||||
|
||||
/* Private data for the host driver */
|
||||
unsigned long hd_priv[0] __aligned(sizeof(s64));
|
||||
};
|
||||
|
@ -661,6 +661,8 @@ static void gb_svc_release(struct device *dev)
|
||||
{
|
||||
struct gb_svc *svc = to_gb_svc(dev);
|
||||
|
||||
if (svc->connection)
|
||||
gb_connection_destroy(svc->connection);
|
||||
ida_destroy(&svc->device_id_map);
|
||||
destroy_workqueue(svc->wq);
|
||||
kfree(svc);
|
||||
@ -671,19 +673,18 @@ struct device_type greybus_svc_type = {
|
||||
.release = gb_svc_release,
|
||||
};
|
||||
|
||||
static int gb_svc_connection_init(struct gb_connection *connection)
|
||||
struct gb_svc *gb_svc_create(struct gb_host_device *hd)
|
||||
{
|
||||
struct gb_host_device *hd = connection->hd;
|
||||
struct gb_svc *svc;
|
||||
|
||||
svc = kzalloc(sizeof(*svc), GFP_KERNEL);
|
||||
if (!svc)
|
||||
return -ENOMEM;
|
||||
return NULL;
|
||||
|
||||
svc->wq = alloc_workqueue("%s:svc", WQ_UNBOUND, 1, dev_name(&hd->dev));
|
||||
if (!svc->wq) {
|
||||
kfree(svc);
|
||||
return -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
svc->dev.parent = &hd->dev;
|
||||
@ -697,11 +698,60 @@ static int gb_svc_connection_init(struct gb_connection *connection)
|
||||
|
||||
ida_init(&svc->device_id_map);
|
||||
svc->state = GB_SVC_STATE_RESET;
|
||||
svc->connection = connection;
|
||||
svc->hd = hd;
|
||||
connection->private = svc;
|
||||
|
||||
hd->svc = svc;
|
||||
svc->connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID,
|
||||
GREYBUS_PROTOCOL_SVC);
|
||||
if (!svc->connection) {
|
||||
dev_err(&svc->dev, "failed to create connection\n");
|
||||
put_device(&svc->dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
svc->connection->private = svc;
|
||||
|
||||
return svc;
|
||||
}
|
||||
|
||||
int gb_svc_add(struct gb_svc *svc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The SVC protocol is currently driven by the SVC, so the SVC device
|
||||
* is added from the connection request handler when enough
|
||||
* information has been received.
|
||||
*/
|
||||
ret = gb_connection_init(svc->connection);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gb_svc_del(struct gb_svc *svc)
|
||||
{
|
||||
/*
|
||||
* The SVC device may have been registered from the request handler.
|
||||
*/
|
||||
if (device_is_registered(&svc->dev))
|
||||
device_del(&svc->dev);
|
||||
|
||||
gb_connection_exit(svc->connection);
|
||||
|
||||
flush_workqueue(svc->wq);
|
||||
}
|
||||
|
||||
void gb_svc_put(struct gb_svc *svc)
|
||||
{
|
||||
put_device(&svc->dev);
|
||||
}
|
||||
|
||||
static int gb_svc_connection_init(struct gb_connection *connection)
|
||||
{
|
||||
struct gb_svc *svc = connection->private;
|
||||
|
||||
dev_dbg(&svc->dev, "%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -710,15 +760,7 @@ static void gb_svc_connection_exit(struct gb_connection *connection)
|
||||
{
|
||||
struct gb_svc *svc = connection->private;
|
||||
|
||||
if (device_is_registered(&svc->dev))
|
||||
device_del(&svc->dev);
|
||||
|
||||
flush_workqueue(svc->wq);
|
||||
|
||||
connection->hd->svc = NULL;
|
||||
connection->private = NULL;
|
||||
|
||||
put_device(&svc->dev);
|
||||
dev_dbg(&svc->dev, "%s\n", __func__);
|
||||
}
|
||||
|
||||
static struct gb_protocol svc_protocol = {
|
||||
|
@ -30,6 +30,11 @@ struct gb_svc {
|
||||
};
|
||||
#define to_gb_svc(d) container_of(d, struct gb_svc, d)
|
||||
|
||||
struct gb_svc *gb_svc_create(struct gb_host_device *hd);
|
||||
int gb_svc_add(struct gb_svc *svc);
|
||||
void gb_svc_del(struct gb_svc *svc);
|
||||
void gb_svc_put(struct gb_svc *svc);
|
||||
|
||||
int gb_svc_intf_reset(struct gb_svc *svc, u8 intf_id);
|
||||
int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
|
||||
u8 intf2_id, u16 cport2_id, bool boot_over_unipro);
|
||||
|
Loading…
Reference in New Issue
Block a user