alistair23-linux/drivers/staging/greybus/module.c
Greg Kroah-Hartman e5646710c1 greybus: module: get rid of global list of modules
Use the list that the driver core keeps of our structure, no need to
duplicate it with a local list as well.  This gets rid of a static lock
too, always a nice thing to do.

Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Reviewed-by: Alex Elder <elder@linaro.org>
2015-01-02 13:05:42 -08:00

136 lines
2.8 KiB
C

/*
* Greybus module code
*
* Copyright 2014 Google Inc.
* Copyright 2014 Linaro Ltd.
*
* Released under the GPLv2 only.
*/
#include "greybus.h"
/* module sysfs attributes */
#define gb_module_attr(field, type) \
static ssize_t field##_show(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
struct gb_module *module = to_gb_module(dev); \
return sprintf(buf, "%"#type"\n", module->field); \
} \
static DEVICE_ATTR_RO(field)
// FIXME, do we really need this attribute?
gb_module_attr(module_id, x);
static ssize_t epm_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
// FIXME, implement something here
return sprintf(buf, "1\n");
}
static ssize_t epm_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
// FIXME, implement something here.
return 0;
}
static DEVICE_ATTR_RW(epm);
static struct attribute *module_attrs[] = {
&dev_attr_module_id.attr,
&dev_attr_epm.attr,
NULL,
};
ATTRIBUTE_GROUPS(module);
static void greybus_module_release(struct device *dev)
{
struct gb_module *module = to_gb_module(dev);
kfree(module);
}
struct device_type greybus_module_type = {
.name = "greybus_module",
.release = greybus_module_release,
};
static int module_find(struct device *dev, void *data)
{
struct gb_module *module;
u8 *module_id = data;
if (!is_gb_module(dev))
return 0;
module = to_gb_module(dev);
if (module->module_id == *module_id)
return 1;
return 0;
}
/*
* Search the list of modules in the system. If one is found, return it, with
* the reference count incremented.
*/
static struct gb_module *gb_module_find(u8 module_id)
{
struct device *dev;
struct gb_module *module = NULL;
dev = bus_find_device(&greybus_bus_type, NULL,
&module_id, module_find);
if (dev)
module = to_gb_module(dev);
return module;
}
static struct gb_module *gb_module_create(struct greybus_host_device *hd,
u8 module_id)
{
struct gb_module *module;
int retval;
module = kzalloc(sizeof(*module), GFP_KERNEL);
if (!module)
return NULL;
module->module_id = module_id;
module->dev.parent = hd->parent;
module->dev.bus = &greybus_bus_type;
module->dev.type = &greybus_module_type;
module->dev.groups = module_groups;
module->dev.dma_mask = hd->parent->dma_mask;
device_initialize(&module->dev);
dev_set_name(&module->dev, "%d", module_id);
retval = device_add(&module->dev);
if (retval) {
pr_err("failed to add module device for id 0x%02hhx\n",
module_id);
put_device(&module->dev);
kfree(module);
return NULL;
}
return module;
}
struct gb_module *gb_module_find_or_create(struct greybus_host_device *hd,
u8 module_id)
{
struct gb_module *module;
module = gb_module_find(module_id);
if (module)
return module;
return gb_module_create(hd, module_id);
}