mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-15 15:15:47 +00:00
63cc932b02
Update the definitions in "greybus_manifest.h" to reflect the changes to the Greybus specification made on October 1. They are: - renaming "device" to be "interface" - renumbering greybus descriptor type - eliminating the notion of a "function" - defining a CPort's protocol in the CPort descriptor - having a "class" take on the types previously used for "function" - renaming "serial number" to be "unique id" (for now) - relying on an interface's maximum cport id to determine how much device+cport address space the interface consumes - adding a simple class descriptor - renaming gb_interface->interface_id to be gb_interface->id This also reorders some things to match ordering in the document, and adds some commentary for the various structures. Since greybus_function_type is gone, we eliminate the "type" field from a function structure. (Functions are going away, next.) Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
93 lines
2 KiB
C
93 lines
2 KiB
C
/*
|
|
* Greybus modules
|
|
*
|
|
* Copyright 2014 Google Inc.
|
|
*
|
|
* Released under the GPLv2 only.
|
|
*/
|
|
|
|
#include "greybus.h"
|
|
|
|
/* XXX This could be per-host device */
|
|
static DEFINE_SPINLOCK(gb_modules_lock);
|
|
|
|
static int gb_module_match_one_id(struct gb_module *gmod,
|
|
const struct greybus_module_id *id)
|
|
{
|
|
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_VENDOR) &&
|
|
(id->vendor != gmod->vendor))
|
|
return 0;
|
|
|
|
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_PRODUCT) &&
|
|
(id->product != gmod->product))
|
|
return 0;
|
|
|
|
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_SERIAL) &&
|
|
(id->unique_id != gmod->unique_id))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
const struct greybus_module_id *gb_module_match_id(struct gb_module *gmod,
|
|
const struct greybus_module_id *id)
|
|
{
|
|
if (id == NULL)
|
|
return NULL;
|
|
|
|
for (; id->vendor || id->product || id->unique_id ||
|
|
id->driver_info; id++) {
|
|
if (gb_module_match_one_id(gmod, id))
|
|
return id;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* A Greybus module represents a user-replacable component on an Ara
|
|
* phone.
|
|
*
|
|
* Create a gb_module structure to represent a discovered module.
|
|
* The position within the Endo is encoded in the "module_id" argument.
|
|
* Returns a pointer to the new module or a null pointer if a
|
|
* failure occurs due to memory exhaustion.
|
|
*/
|
|
struct gb_module *gb_module_create(struct greybus_host_device *hd, u8 module_id)
|
|
{
|
|
struct gb_module *module;
|
|
|
|
module = kzalloc(sizeof(*module), GFP_KERNEL);
|
|
if (!module)
|
|
return NULL;
|
|
|
|
module->hd = hd; /* XXX refcount? */
|
|
module->module_id = module_id;
|
|
INIT_LIST_HEAD(&module->interfaces);
|
|
|
|
spin_lock_irq(&gb_modules_lock);
|
|
list_add_tail(&module->links, &hd->modules);
|
|
spin_unlock_irq(&gb_modules_lock);
|
|
|
|
return module;
|
|
}
|
|
|
|
/*
|
|
* Tear down a previously set up module.
|
|
*/
|
|
void gb_module_destroy(struct gb_module *module)
|
|
{
|
|
if (WARN_ON(!module))
|
|
return;
|
|
|
|
kfree(module->product_string);
|
|
kfree(module->vendor_string);
|
|
|
|
spin_lock_irq(&gb_modules_lock);
|
|
list_del(&module->links);
|
|
spin_unlock_irq(&gb_modules_lock);
|
|
|
|
/* kref_put(module->hd); */
|
|
|
|
kfree(module);
|
|
}
|