summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/manifest.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@hovoldconsulting.com>2016-01-21 17:34:09 +0100
committerGreg Kroah-Hartman <gregkh@google.com>2016-01-21 22:45:09 -0800
commit98fdf5a037f0789f1ea6e22431a4a4cc7c41829d (patch)
tree8d7cb053d2dfdce35334440311b53d5edf755d77 /drivers/staging/greybus/manifest.c
parent6ce4cc278deca9849bd54783294be7edbe24bac0 (diff)
greybus: core: defer connection creation to driver probe
Defer connection creation to bundle driver probe instead of creating them when initialising the interface and parsing the manifest. Store copies of the CPorts descriptors in the bundle for the drivers to use, and update the legacy driver. This is needed for drivers that need more control over host-device resource management, for example, when a protocol needs to use a dedicated host CPort for traffic offloading (e.g. camera data). This also avoids allocating host CPorts for bundles that are not bound to a driver or for remote CPorts that a driver does not need. Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/manifest.c')
-rw-r--r--drivers/staging/greybus/manifest.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/staging/greybus/manifest.c b/drivers/staging/greybus/manifest.c
index 357f9c64821b..64c60c2dfaf5 100644
--- a/drivers/staging/greybus/manifest.c
+++ b/drivers/staging/greybus/manifest.c
@@ -228,19 +228,18 @@ static char *gb_string_get(struct gb_interface *intf, u8 string_id)
*/
static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
{
- struct gb_connection *connection;
struct gb_interface *intf = bundle->intf;
+ struct greybus_descriptor_cport *desc_cport;
struct manifest_desc *desc;
struct manifest_desc *next;
+ LIST_HEAD(list);
u8 bundle_id = bundle->id;
- u8 protocol_id;
u16 cport_id;
u32 count = 0;
+ int i;
/* Set up all cport descriptors associated with this bundle */
list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
- struct greybus_descriptor_cport *desc_cport;
-
if (desc->type != GREYBUS_TYPE_CPORT)
continue;
@@ -252,16 +251,26 @@ static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
if (cport_id > CPORT_ID_MAX)
goto exit;
- /* Found one. Set up its function structure */
- protocol_id = desc_cport->protocol_id;
+ /* Found one, move it to our temporary list. */
+ list_move(&desc->links, &list);
+ count++;
+ }
- connection = gb_connection_create_dynamic(intf, bundle,
- cport_id,
- protocol_id);
- if (!connection)
- goto exit;
+ if (!count)
+ return 0;
- count++;
+ bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc),
+ GFP_KERNEL);
+ if (!bundle->cport_desc)
+ goto exit;
+
+ bundle->num_cports = count;
+
+ i = 0;
+ list_for_each_entry_safe(desc, next, &list, links) {
+ desc_cport = desc->data;
+ memcpy(&bundle->cport_desc[i++], desc_cport,
+ sizeof(*desc_cport));
/* Release the cport descriptor */
release_manifest_descriptor(desc);
@@ -269,7 +278,7 @@ static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
return count;
exit:
-
+ release_cport_descriptors(&list, bundle_id);
/*
* Free all cports for this bundle to avoid 'excess descriptors'
* warnings.