Commit e1e9dbdd authored by Alex Elder's avatar Alex Elder Committed by Greg Kroah-Hartman

greybus: isolate greybus module code

Define new source files "module.h" and "module.c" to separate the
definitions of the Greybus module abstraction from other code.

Rename "greybus_module" to be "gb_module", for brevity.  Do the same
for a few other symbols with "greybus_module" in their names.  A few
(like greybus_module_id) are more visible outside this kernel module
so we'll keep their names more descriptive.

Add a definition for U8_MAX in "kernel_ver.h" (it appeared in 3.14).
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent ecf7d579
...@@ -3,6 +3,7 @@ greybus-y := core.o \ ...@@ -3,6 +3,7 @@ greybus-y := core.o \
sysfs.o \ sysfs.o \
debugfs.o \ debugfs.o \
ap.o \ ap.o \
module.o \
i2c-gb.o \ i2c-gb.o \
gpio-gb.o \ gpio-gb.o \
sdio-gb.o \ sdio-gb.o \
......
...@@ -18,7 +18,7 @@ struct gb_battery { ...@@ -18,7 +18,7 @@ struct gb_battery {
// we will want to keep the battery stats in here as we will be getting // we will want to keep the battery stats in here as we will be getting
// updates from the SVC "on the fly" so we don't have to always go ask // updates from the SVC "on the fly" so we don't have to always go ask
// the battery for some information. Hopefully... // the battery for some information. Hopefully...
struct greybus_module *gmod; struct gb_module *gmod;
}; };
#define to_gb_battery(x) container_of(x, struct gb_battery, bat) #define to_gb_battery(x) container_of(x, struct gb_battery, bat)
...@@ -100,7 +100,7 @@ static enum power_supply_property battery_props[] = { ...@@ -100,7 +100,7 @@ static enum power_supply_property battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_NOW,
}; };
int gb_battery_probe(struct greybus_module *gmod, int gb_battery_probe(struct gb_module *gmod,
const struct greybus_module_id *id) const struct greybus_module_id *id)
{ {
struct gb_battery *gb; struct gb_battery *gb;
...@@ -130,7 +130,7 @@ int gb_battery_probe(struct greybus_module *gmod, ...@@ -130,7 +130,7 @@ int gb_battery_probe(struct greybus_module *gmod,
return 0; return 0;
} }
void gb_battery_disconnect(struct greybus_module *gmod) void gb_battery_disconnect(struct gb_module *gmod)
{ {
struct gb_battery *gb; struct gb_battery *gb;
......
...@@ -30,51 +30,13 @@ int greybus_disabled(void) ...@@ -30,51 +30,13 @@ int greybus_disabled(void)
} }
EXPORT_SYMBOL_GPL(greybus_disabled); EXPORT_SYMBOL_GPL(greybus_disabled);
static int greybus_match_one_id(struct greybus_module *gmod,
const struct greybus_module_id *id)
{
struct greybus_descriptor_module *module;
module = &gmod->module;
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_VENDOR) &&
(id->vendor != le16_to_cpu(module->vendor)))
return 0;
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_PRODUCT) &&
(id->product != le16_to_cpu(module->product)))
return 0;
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_SERIAL) &&
(id->serial_number != le64_to_cpu(module->serial_number)))
return 0;
return 1;
}
static const struct greybus_module_id *greybus_match_id(
struct greybus_module *gmod,
const struct greybus_module_id *id)
{
if (id == NULL)
return NULL;
for (; id->vendor || id->product || id->serial_number ||
id->driver_info ; id++) {
if (greybus_match_one_id(gmod, id))
return id;
}
return NULL;
}
static int greybus_module_match(struct device *dev, struct device_driver *drv) static int greybus_module_match(struct device *dev, struct device_driver *drv)
{ {
struct greybus_driver *driver = to_greybus_driver(dev->driver); struct greybus_driver *driver = to_greybus_driver(dev->driver);
struct greybus_module *gmod = to_greybus_module(dev); struct gb_module *gmod = to_gb_module(dev);
const struct greybus_module_id *id; const struct greybus_module_id *id;
id = greybus_match_id(gmod, driver->id_table); id = gb_module_match_id(gmod, driver->id_table);
if (id) if (id)
return 1; return 1;
/* FIXME - Dyanmic ids? */ /* FIXME - Dyanmic ids? */
...@@ -83,7 +45,7 @@ static int greybus_module_match(struct device *dev, struct device_driver *drv) ...@@ -83,7 +45,7 @@ static int greybus_module_match(struct device *dev, struct device_driver *drv)
static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env) static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
/* struct greybus_module *gmod = to_greybus_module(dev); */ /* struct gb_module *gmod = to_gb_module(dev); */
/* FIXME - add some uevents here... */ /* FIXME - add some uevents here... */
return 0; return 0;
...@@ -98,12 +60,12 @@ static struct bus_type greybus_bus_type = { ...@@ -98,12 +60,12 @@ static struct bus_type greybus_bus_type = {
static int greybus_probe(struct device *dev) static int greybus_probe(struct device *dev)
{ {
struct greybus_driver *driver = to_greybus_driver(dev->driver); struct greybus_driver *driver = to_greybus_driver(dev->driver);
struct greybus_module *gmod = to_greybus_module(dev); struct gb_module *gmod = to_gb_module(dev);
const struct greybus_module_id *id; const struct greybus_module_id *id;
int retval; int retval;
/* match id */ /* match id */
id = greybus_match_id(gmod, driver->id_table); id = gb_module_match_id(gmod, driver->id_table);
if (!id) if (!id)
return -ENODEV; return -ENODEV;
...@@ -117,7 +79,7 @@ static int greybus_probe(struct device *dev) ...@@ -117,7 +79,7 @@ static int greybus_probe(struct device *dev)
static int greybus_remove(struct device *dev) static int greybus_remove(struct device *dev)
{ {
struct greybus_driver *driver = to_greybus_driver(dev->driver); struct greybus_driver *driver = to_greybus_driver(dev->driver);
struct greybus_module *gmod = to_greybus_module(dev); struct gb_module *gmod = to_gb_module(dev);
driver->disconnect(gmod); driver->disconnect(gmod);
return 0; return 0;
...@@ -155,7 +117,7 @@ EXPORT_SYMBOL_GPL(greybus_deregister); ...@@ -155,7 +117,7 @@ EXPORT_SYMBOL_GPL(greybus_deregister);
static void greybus_module_release(struct device *dev) static void greybus_module_release(struct device *dev)
{ {
struct greybus_module *gmod = to_greybus_module(dev); struct gb_module *gmod = to_gb_module(dev);
int i; int i;
for (i = 0; i < gmod->num_strings; ++i) for (i = 0; i < gmod->num_strings; ++i)
...@@ -164,7 +126,7 @@ static void greybus_module_release(struct device *dev) ...@@ -164,7 +126,7 @@ static void greybus_module_release(struct device *dev)
} }
const u8 *greybus_string(struct greybus_module *gmod, int id) const u8 *greybus_string(struct gb_module *gmod, int id)
{ {
int i; int i;
struct gmod_string *string; struct gmod_string *string;
...@@ -185,7 +147,7 @@ static struct device_type greybus_module_type = { ...@@ -185,7 +147,7 @@ static struct device_type greybus_module_type = {
.release = greybus_module_release, .release = greybus_module_release,
}; };
static int gb_init_subdevs(struct greybus_module *gmod, static int gb_init_subdevs(struct gb_module *gmod,
const struct greybus_module_id *id) const struct greybus_module_id *id)
{ {
int retval; int retval;
...@@ -228,11 +190,11 @@ static int gb_init_subdevs(struct greybus_module *gmod, ...@@ -228,11 +190,11 @@ static int gb_init_subdevs(struct greybus_module *gmod,
return retval; return retval;
} }
static const struct greybus_module_id fake_gb_id = { static const struct greybus_module_id fake_greybus_module_id = {
GREYBUS_DEVICE(0x42, 0x42) GREYBUS_DEVICE(0x42, 0x42)
}; };
static int create_module(struct greybus_module *gmod, static int create_module(struct gb_module *gmod,
struct greybus_descriptor_module *module, struct greybus_descriptor_module *module,
size_t desc_size) size_t desc_size)
{ {
...@@ -245,7 +207,7 @@ static int create_module(struct greybus_module *gmod, ...@@ -245,7 +207,7 @@ static int create_module(struct greybus_module *gmod,
return 0; return 0;
} }
static int create_string(struct greybus_module *gmod, static int create_string(struct gb_module *gmod,
struct greybus_descriptor_string *string, struct greybus_descriptor_string *string,
size_t desc_size) size_t desc_size)
{ {
...@@ -279,7 +241,7 @@ static int create_string(struct greybus_module *gmod, ...@@ -279,7 +241,7 @@ static int create_string(struct greybus_module *gmod,
return 0; return 0;
} }
static int create_cport(struct greybus_module *gmod, static int create_cport(struct gb_module *gmod,
struct greybus_descriptor_cport *cport, struct greybus_descriptor_cport *cport,
size_t desc_size) size_t desc_size)
{ {
...@@ -309,7 +271,7 @@ static int create_cport(struct greybus_module *gmod, ...@@ -309,7 +271,7 @@ static int create_cport(struct greybus_module *gmod,
void gb_add_module(struct greybus_host_device *hd, u8 module_id, void gb_add_module(struct greybus_host_device *hd, u8 module_id,
u8 *data, int size) u8 *data, int size)
{ {
struct greybus_module *gmod; struct gb_module *gmod;
struct greybus_manifest *manifest; struct greybus_manifest *manifest;
int retval; int retval;
int overall_size; int overall_size;
...@@ -318,11 +280,10 @@ void gb_add_module(struct greybus_host_device *hd, u8 module_id, ...@@ -318,11 +280,10 @@ void gb_add_module(struct greybus_host_device *hd, u8 module_id,
if (size <= sizeof(manifest->header)) if (size <= sizeof(manifest->header))
return; return;
gmod = kzalloc(sizeof(*gmod), GFP_KERNEL); gmod = gb_module_create(hd, module_id);
if (!gmod) if (!gmod)
return; return;
gmod->module_number = module_id;
gmod->dev.parent = hd->parent; gmod->dev.parent = hd->parent;
gmod->dev.driver = NULL; gmod->dev.driver = NULL;
gmod->dev.bus = &greybus_bus_type; gmod->dev.bus = &greybus_bus_type;
...@@ -400,7 +361,7 @@ void gb_add_module(struct greybus_host_device *hd, u8 module_id, ...@@ -400,7 +361,7 @@ void gb_add_module(struct greybus_host_device *hd, u8 module_id,
data += desc_size; data += desc_size;
} }
retval = gb_init_subdevs(gmod, &fake_gb_id); retval = gb_init_subdevs(gmod, &fake_greybus_module_id);
if (retval) if (retval)
goto error; goto error;
...@@ -418,7 +379,7 @@ void gb_remove_module(struct greybus_host_device *hd, u8 module_id) ...@@ -418,7 +379,7 @@ void gb_remove_module(struct greybus_host_device *hd, u8 module_id)
// FIXME should be the remove_device call... // FIXME should be the remove_device call...
} }
void greybus_remove_device(struct greybus_module *gmod) void greybus_remove_device(struct gb_module *gmod)
{ {
/* tear down all of the "sub device types" for this device */ /* tear down all of the "sub device types" for this device */
gb_i2c_disconnect(gmod); gb_i2c_disconnect(gmod);
...@@ -453,6 +414,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver ...@@ -453,6 +414,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver
kref_init(&hd->kref); kref_init(&hd->kref);
hd->parent = parent; hd->parent = parent;
hd->driver = driver; hd->driver = driver;
INIT_LIST_HEAD(&hd->modules);
return hd; return hd;
} }
......
...@@ -26,7 +26,7 @@ static struct kmem_cache *gbuf_head_cache; ...@@ -26,7 +26,7 @@ static struct kmem_cache *gbuf_head_cache;
/* Workqueue to handle Greybus buffer completions. */ /* Workqueue to handle Greybus buffer completions. */
static struct workqueue_struct *gbuf_workqueue; static struct workqueue_struct *gbuf_workqueue;
static struct gbuf *__alloc_gbuf(struct greybus_module *gmod, static struct gbuf *__alloc_gbuf(struct gb_module *gmod,
u16 cport_id, u16 cport_id,
gbuf_complete_t complete, gbuf_complete_t complete,
gfp_t gfp_mask, gfp_t gfp_mask,
...@@ -63,7 +63,7 @@ static struct gbuf *__alloc_gbuf(struct greybus_module *gmod, ...@@ -63,7 +63,7 @@ static struct gbuf *__alloc_gbuf(struct greybus_module *gmod,
* that the driver can then fill up with the data to be sent out. Curse * that the driver can then fill up with the data to be sent out. Curse
* hardware designers for this issue... * hardware designers for this issue...
*/ */
struct gbuf *greybus_alloc_gbuf(struct greybus_module *gmod, struct gbuf *greybus_alloc_gbuf(struct gb_module *gmod,
u16 cport_id, u16 cport_id,
gbuf_complete_t complete, gbuf_complete_t complete,
unsigned int size, unsigned int size,
...@@ -80,7 +80,7 @@ struct gbuf *greybus_alloc_gbuf(struct greybus_module *gmod, ...@@ -80,7 +80,7 @@ struct gbuf *greybus_alloc_gbuf(struct greybus_module *gmod,
gbuf->direction = GBUF_DIRECTION_OUT; gbuf->direction = GBUF_DIRECTION_OUT;
/* Host controller specific allocation for the actual buffer */ /* Host controller specific allocation for the actual buffer */
retval = gbuf->gmod->hd->driver->alloc_gbuf_data(gbuf, size, gfp_mask); retval = gmod->hd->driver->alloc_gbuf_data(gbuf, size, gfp_mask);
if (retval) { if (retval) {
greybus_free_gbuf(gbuf); greybus_free_gbuf(gbuf);
return NULL; return NULL;
...@@ -147,7 +147,7 @@ static void cport_process_event(struct work_struct *work) ...@@ -147,7 +147,7 @@ static void cport_process_event(struct work_struct *work)
struct gb_cport_handler { struct gb_cport_handler {
gbuf_complete_t handler; gbuf_complete_t handler;
u16 cport_id; u16 cport_id;
struct greybus_module *gmod; struct gb_module *gmod;
void *context; void *context;
}; };
...@@ -155,8 +155,9 @@ static struct gb_cport_handler cport_handler[MAX_CPORTS]; ...@@ -155,8 +155,9 @@ static struct gb_cport_handler cport_handler[MAX_CPORTS];
// FIXME - use a lock for this list of handlers, but really, for now we don't // FIXME - use a lock for this list of handlers, but really, for now we don't
// need it, we don't have a dynamic system... // need it, we don't have a dynamic system...
int gb_register_cport_complete(struct greybus_module *gmod, int gb_register_cport_complete(struct gb_module *gmod,
gbuf_complete_t handler, u16 cport_id, gbuf_complete_t handler,
u16 cport_id,
void *context) void *context)
{ {
if (cport_handler[cport_id].handler) if (cport_handler[cport_id].handler)
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
struct gb_gpio_device { struct gb_gpio_device {
struct gpio_chip chip; struct gpio_chip chip;
struct greybus_module *gmod; struct gb_module *gmod;
struct gpio_chip *gpio; struct gpio_chip *gpio;
// FIXME - some lock? // FIXME - some lock?
}; };
...@@ -49,7 +49,7 @@ static void gpio_set(struct gpio_chip *gpio, unsigned nr, int val) ...@@ -49,7 +49,7 @@ static void gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
// FIXME - do something there // FIXME - do something there
} }
int gb_gpio_probe(struct greybus_module *gmod, int gb_gpio_probe(struct gb_module *gmod,
const struct greybus_module_id *id) const struct greybus_module_id *id)
{ {
struct gb_gpio_device *gb_gpio; struct gb_gpio_device *gb_gpio;
...@@ -86,7 +86,7 @@ int gb_gpio_probe(struct greybus_module *gmod, ...@@ -86,7 +86,7 @@ int gb_gpio_probe(struct greybus_module *gmod,
return 0; return 0;
} }
void gb_gpio_disconnect(struct greybus_module *gmod) void gb_gpio_disconnect(struct gb_module *gmod)
{ {
struct gb_gpio_device *gb_gpio_dev; struct gb_gpio_device *gb_gpio_dev;
int retval; int retval;
......
...@@ -11,12 +11,16 @@ ...@@ -11,12 +11,16 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/slab.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include "greybus_id.h" #include "greybus_id.h"
#include "greybus_manifest.h" #include "greybus_manifest.h"
#include "module.h"
/* Matches up with the Greybus Protocol specification document */ /* Matches up with the Greybus Protocol specification document */
...@@ -113,7 +117,7 @@ struct gbuf { ...@@ -113,7 +117,7 @@ struct gbuf {
struct kref kref; struct kref kref;
void *hdpriv; void *hdpriv;
struct greybus_module *gmod; struct gb_module *gmod;
u16 cport_id; u16 cport_id;
int status; int status;
void *transfer_buffer; void *transfer_buffer;
...@@ -142,7 +146,7 @@ struct gbuf { ...@@ -142,7 +146,7 @@ struct gbuf {
* same module as the gpio pins, etc.) * same module as the gpio pins, etc.)
* *
* So, put the "private" data structures here in greybus.h and link to them off * So, put the "private" data structures here in greybus.h and link to them off
* of the "main" greybus_module structure. * of the "main" gb_module structure.
*/ */
struct gb_i2c_device; struct gb_i2c_device;
...@@ -173,6 +177,8 @@ struct greybus_host_device { ...@@ -173,6 +177,8 @@ struct greybus_host_device {
struct device *parent; struct device *parent;
const struct greybus_host_driver *driver; const struct greybus_host_driver *driver;
struct list_head modules;
/* Private data for the host driver */ /* Private data for the host driver */
unsigned long hd_priv[0] __attribute__ ((aligned(sizeof(s64)))); unsigned long hd_priv[0] __attribute__ ((aligned(sizeof(s64))));
}; };
...@@ -184,32 +190,7 @@ void greybus_cport_in(struct greybus_host_device *hd, u16 cport_id, ...@@ -184,32 +190,7 @@ void greybus_cport_in(struct greybus_host_device *hd, u16 cport_id,
u8 *data, size_t length); u8 *data, size_t length);
void greybus_gbuf_finished(struct gbuf *gbuf); void greybus_gbuf_finished(struct gbuf *gbuf);
struct gbuf *greybus_alloc_gbuf(struct gb_module *gmod, u16 cport_id,
/* Increase these values if needed */
#define MAX_CPORTS_PER_MODULE 10
#define MAX_STRINGS_PER_MODULE 10
struct greybus_module {
struct device dev;
u16 module_number;
struct greybus_descriptor_module module;
int num_cports;
int num_strings;
u16 cport_ids[MAX_CPORTS_PER_MODULE];
struct gmod_string *string[MAX_STRINGS_PER_MODULE];
struct greybus_host_device *hd;
struct gb_i2c_device *gb_i2c_dev;
struct gb_gpio_device *gb_gpio_dev;
struct gb_sdio_host *gb_sdio_host;
struct gb_tty *gb_tty;
struct gb_usb_device *gb_usb_dev;
struct gb_battery *gb_battery;
};
#define to_greybus_module(d) container_of(d, struct greybus_module, dev)
struct gbuf *greybus_alloc_gbuf(struct greybus_module *gmod, u16 cport_id,
gbuf_complete_t complete, unsigned int size, gbuf_complete_t complete, unsigned int size,
gfp_t gfp_mask, void *context); gfp_t gfp_mask, void *context);
void greybus_free_gbuf(struct gbuf *gbuf); void greybus_free_gbuf(struct gbuf *gbuf);
...@@ -223,12 +204,12 @@ int greybus_kill_gbuf(struct gbuf *gbuf); ...@@ -223,12 +204,12 @@ int greybus_kill_gbuf(struct gbuf *gbuf);
struct greybus_driver { struct greybus_driver {
const char *name; const char *name;
int (*probe)(struct greybus_module *gmod, int (*probe)(struct gb_module *gmod,
const struct greybus_module_id *id); const struct greybus_module_id *id);
void (*disconnect)(struct greybus_module *gmod); void (*disconnect)(struct gb_module *gmod);
int (*suspend)(struct greybus_module *gmod, pm_message_t message); int (*suspend)(struct gb_module *gmod, pm_message_t message);
int (*resume)(struct greybus_module *gmod); int (*resume)(struct gb_module *gmod);
const struct greybus_module_id *id_table; const struct greybus_module_id *id_table;
...@@ -236,16 +217,6 @@ struct greybus_driver { ...@@ -236,16 +217,6 @@ struct greybus_driver {
}; };
#define to_greybus_driver(d) container_of(d, struct greybus_driver, driver) #define to_greybus_driver(d) container_of(d, struct greybus_driver, driver)
static inline void greybus_set_drvdata(struct greybus_module *gmod, void *data)
{
dev_set_drvdata(&gmod->dev, data);
}
static inline void *greybus_get_drvdata(struct greybus_module *gmod)
{
return dev_get_drvdata(&gmod->dev);
}
/* Don't call these directly, use the module_greybus_driver() macro instead */ /* Don't call these directly, use the module_greybus_driver() macro instead */
int greybus_register_driver(struct greybus_driver *driver, int greybus_register_driver(struct greybus_driver *driver,
struct module *module, const char *mod_name); struct module *module, const char *mod_name);
...@@ -268,9 +239,9 @@ void greybus_deregister(struct greybus_driver *driver); ...@@ -268,9 +239,9 @@ void greybus_deregister(struct greybus_driver *driver);
int greybus_disabled(void); int greybus_disabled(void);
void greybus_remove_device(struct greybus_module *gmod); void greybus_remove_device(struct gb_module *gmod);
const u8 *greybus_string(struct greybus_module *gmod, int id); const u8 *greybus_string(struct gb_module *gmod, int id);
/* Internal functions to gb module, move to internal .h file eventually. */ /* Internal functions to gb module, move to internal .h file eventually. */
...@@ -286,7 +257,7 @@ void gb_debugfs_cleanup(void); ...@@ -286,7 +257,7 @@ void gb_debugfs_cleanup(void);
int gb_gbuf_init(void); int gb_gbuf_init(void);
void gb_gbuf_exit(void); void gb_gbuf_exit(void);
int gb_register_cport_complete(struct greybus_module *gmod, int gb_register_cport_complete(struct gb_module *gmod,
gbuf_complete_t handler, u16 cport_id, gbuf_complete_t handler, u16 cport_id,
void *context); void *context);
void gb_deregister_cport_complete(u16 cport_id); void gb_deregister_cport_complete(u16 cport_id);
...@@ -298,16 +269,17 @@ extern const struct attribute_group *greybus_module_groups[]; ...@@ -298,16 +269,17 @@ extern const struct attribute_group *greybus_module_groups[];
* we have static functions for this, not "dynamic" drivers like we really * we have static functions for this, not "dynamic" drivers like we really
* should in the end. * should in the end.
*/ */
int gb_i2c_probe(struct greybus_module *gmod, const struct greybus_module_id *id); int gb_i2c_probe(struct gb_module *gmod, const struct greybus_module_id *id);
void gb_i2c_disconnect(struct greybus_module *gmod); void gb_i2c_disconnect(struct gb_module *gmod);
int gb_gpio_probe(struct greybus_module *gmod, const struct greybus_module_id *id); int gb_gpio_probe(struct gb_module *gmod, const struct greybus_module_id *id);
void gb_gpio_disconnect(struct greybus_module *gmod); void gb_gpio_disconnect(struct gb_module *gmod);
int gb_sdio_probe(struct greybus_module *gmod, const struct greybus_module_id *id); int gb_sdio_probe(struct gb_module *gmod, const struct greybus_module_id *id);
void gb_sdio_disconnect(struct greybus_module *gmod); void gb_sdio_disconnect(struct gb_module *gmod);
int gb_tty_probe(struct greybus_module *gmod, const struct greybus_module_id *id); int gb_tty_probe(struct gb_module *gmod, const struct greybus_module_id *id);
void gb_tty_disconnect(struct greybus_module *gmod); void gb_tty_disconnect(struct gb_module *gmod);
int gb_battery_probe(struct greybus_module *gmod, const struct greybus_module_id *id); int gb_battery_probe(struct gb_module *gmod,
void gb_battery_disconnect(struct greybus_module *gmod); const struct greybus_module_id *id);
void gb_battery_disconnect(struct gb_module *gmod);
int gb_tty_init(void); int gb_tty_init(void);
void gb_tty_exit(void); void gb_tty_exit(void);
......
...@@ -10,11 +10,12 @@ ...@@ -10,11 +10,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include "greybus.h" #include "greybus.h"
struct gb_i2c_device { struct gb_i2c_device {
struct i2c_adapter *adapter; struct i2c_adapter *adapter;
struct greybus_module *gmod; struct gb_module *gmod;
}; };
static const struct greybus_module_id id_table[] = { static const struct greybus_module_id id_table[] = {
...@@ -33,7 +34,7 @@ static s32 i2c_gb_access(struct i2c_adapter *adap, u16 addr, ...@@ -33,7 +34,7 @@ static s32 i2c_gb_access(struct i2c_adapter *adap, u16 addr,
int size, union i2c_smbus_data *data) int size, union i2c_smbus_data *data)
{ {
struct gb_i2c_device *gb_i2c_dev; struct gb_i2c_device *gb_i2c_dev;
struct greybus_module *gmod; struct gb_module *gmod;
gb_i2c_dev = i2c_get_adapdata(adap); gb_i2c_dev = i2c_get_adapdata(adap);
gmod = gb_i2c_dev->gmod; gmod = gb_i2c_dev->gmod;
...@@ -75,7 +76,7 @@ static const struct i2c_algorithm smbus_algorithm = { ...@@ -75,7 +76,7 @@ static const struct i2c_algorithm smbus_algorithm = {
.functionality = i2c_gb_func, .functionality = i2c_gb_func,
}; };
int gb_i2c_probe(struct greybus_module *gmod, int gb_i2c_probe(struct gb_module *gmod,
const struct greybus_module_id *id) const struct greybus_module_id *id)
{ {
struct gb_i2c_device *gb_i2c_dev; struct gb_i2c_device *gb_i2c_dev;
...@@ -115,7 +116,7 @@ int gb_i2c_probe(struct greybus_module *gmod, ...@@ -115,7 +116,7 @@ int gb_i2c_probe(struct greybus_module *gmod,
return retval; return retval;
} }
void gb_i2c_disconnect(struct greybus_module *gmod) void gb_i2c_disconnect(struct gb_module *gmod)
{ {
struct gb_i2c_device *gb_i2c_dev; struct gb_i2c_device *gb_i2c_dev;
......
/*
* 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)
{
struct greybus_descriptor_module *module;
module = &gmod->module;
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_VENDOR) &&
(id->vendor != le16_to_cpu(module->vendor)))
return 0;
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_PRODUCT) &&
(id->product != le16_to_cpu(module->product)))
return 0;
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_SERIAL) &&
(id->serial_number != le64_to_cpu(module->serial_number)))
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->serial_number ||
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;
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;
spin_lock_irq(&gb_modules_lock);
list_del(&module->links);
spin_unlock_irq(&gb_modules_lock);
/* kref_put(module->hd); */
kfree(module);
}
/*
* Greybus modules
*
* Copyright 2014 Google Inc.
*
* Released under the GPLv2 only.
*/
#ifndef __MODULE_H
#define __MODULE_H
/* Increase these values if needed */
#define MAX_CPORTS_PER_MODULE 10
#define MAX_STRINGS_PER_MODULE 10
struct gb_module {
struct device dev;
struct list_head links; /* greybus_host_device->modules */
u8 module_id; /* Physical location within the Endo */
struct greybus_descriptor_module module;
int num_cports;
int num_strings;
u16 cport_ids[MAX_CPORTS_PER_MODULE];
struct gmod_string *string[MAX_STRINGS_PER_MODULE];
struct greybus_host_device *hd;
struct gb_i2c_device *gb_i2c_dev;
struct gb_gpio_device *gb_gpio_dev;
struct gb_sdio_host *gb_sdio_host;
struct gb_tty *gb_tty;
struct gb_usb_device *gb_usb_dev;
struct gb_battery *gb_battery;
};
#define to_gb_module(d) container_of(d, struct gb_module, dev)
static inline void
gb_module_set_drvdata(struct gb_module *gmod, void *data)
{
dev_set_drvdata(&gmod->dev, data);
}
static inline void *gb_module_get_drvdata(struct gb_module *gmod)
{
return dev_get_drvdata(&gmod->dev);
}
const struct greybus_module_id *gb_module_match_id(struct gb_module *gmod,
const struct greybus_module_id *id);
struct gb_module *gb_module_create(struct greybus_host_device *hd,
u8 module_id);
void gb_module_destroy(struct gb_module *module);
#endif /* __MODULE_H */
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include "greybus.h" #include "greybus.h"
struct gb_sdio_host { struct gb_sdio_host {
...@@ -45,7 +45,7 @@ static const struct mmc_host_ops gb_sd_ops = { ...@@ -45,7 +45,7 @@ static const struct mmc_host_ops gb_sd_ops = {
.get_ro = gb_sd_get_ro, .get_ro = gb_sd_get_ro,
}; };
int gb_sdio_probe(struct greybus_module *gmod, int gb_sdio_probe(struct gb_module *gmod,
const struct greybus_module_id *id) const struct greybus_module_id *id)
{ {
struct mmc_host *mmc; struct mmc_host *mmc;
...@@ -65,7 +65,7 @@ int gb_sdio_probe(struct greybus_module *gmod, ...@@ -65,7 +65,7 @@ int gb_sdio_probe(struct greybus_module *gmod,
return 0; return 0;
} }
void gb_sdio_disconnect(struct greybus_module *gmod) void gb_sdio_disconnect(struct gb_module *gmod)
{ {
struct mmc_host *mmc; struct mmc_host *mmc;
struct gb_sdio_host *host; struct gb_sdio_host *host;
......
...@@ -17,29 +17,28 @@ ...@@ -17,29 +17,28 @@
#include <linux/device.h> #include <linux/device.h>
#include "greybus.h" #include "greybus.h"
#include "kernel_ver.h" #include "kernel_ver.h"
/* Module fields */ /* Module fields */
#define greybus_module_attr(field) \ #define gb_module_attr(field) \
static ssize_t module_##field##_show(struct device *dev, \ static ssize_t module_##field##_show(struct device *dev, \
struct device_attribute *attr, \ struct device_attribute *attr, \
char *buf) \ char *buf) \
{ \ { \
struct greybus_module *gmod = to_greybus_module(dev); \ struct gb_module *gmod = to_gb_module(dev); \
return sprintf(buf, "%x\n", gmod->module.field); \ return sprintf(buf, "%x\n", gmod->module.field); \
} \ } \
static DEVICE_ATTR_RO(module_##field) static DEVICE_ATTR_RO(module_##field)
greybus_module_attr(vendor); gb_module_attr(vendor);
greybus_module_attr(product); gb_module_attr(product);
greybus_module_attr(version); gb_module_attr(version);
static ssize_t module_serial_number_show(struct device *dev, static ssize_t module_serial_number_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct greybus_module *gmod = to_greybus_module(dev); struct gb_module *gmod = to_gb_module(dev);
return sprintf(buf, "%llX\n", return sprintf(buf, "%llX\n",
(unsigned long long)le64_to_cpu(gmod->module.serial_number)); (unsigned long long)le64_to_cpu(gmod->module.serial_number));
...@@ -50,7 +49,7 @@ static ssize_t module_vendor_string_show(struct device *dev, ...@@ -50,7 +49,7 @@ static ssize_t module_vendor_string_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct greybus_module *gmod = to_greybus_module(dev); struct gb_module *gmod = to_gb_module(dev);
return sprintf(buf, "%s", return sprintf(buf, "%s",
greybus_string(gmod, gmod->module.vendor_stringid)); greybus_string(gmod, gmod->module.vendor_stringid));
...@@ -61,7 +60,7 @@ static ssize_t module_product_string_show(struct device *dev, ...@@ -61,7 +60,7 @@ static ssize_t module_product_string_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct greybus_module *gmod = to_greybus_module(dev); struct gb_module *gmod = to_gb_module(dev);
return sprintf(buf, "%s", return sprintf(buf, "%s",
greybus_string(gmod, gmod->module.product_stringid)); greybus_string(gmod, gmod->module.product_stringid));
...@@ -81,7 +80,7 @@ static struct attribute *module_attrs[] = { ...@@ -81,7 +80,7 @@ static struct attribute *module_attrs[] = {
static umode_t module_attrs_are_visible(struct kobject *kobj, static umode_t module_attrs_are_visible(struct kobject *kobj,
struct attribute *a, int n) struct attribute *a, int n)
{ {
struct greybus_module *gmod = to_greybus_module(kobj_to_dev(kobj)); struct gb_module *gmod = to_gb_module(kobj_to_dev(kobj));
if ((a == &dev_attr_module_vendor_string.attr) && if ((a == &dev_attr_module_vendor_string.attr) &&
(gmod->module.vendor_stringid)) (gmod->module.vendor_stringid))
......
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
#include "greybus.h" #include "greybus.h"
struct test_device { struct test_device {
struct greybus_module *gmod; struct gb_module *gmod;
}; };
int gb_register_cport_complete(struct greybus_module *gmod, int gb_register_cport_complete(struct gb_module *gmod,
gbuf_complete_t handler, u16 cport_id, gbuf_complete_t handler, u16 cport_id,
void *context); void *context);
void gb_deregister_cport_complete(u16 cport_id); void gb_deregister_cport_complete(u16 cport_id);
......
...@@ -26,14 +26,16 @@ ...@@ -26,14 +26,16 @@
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include "greybus.h" #include "greybus.h"
#include "module.h"
#define GB_NUM_MINORS 255 /* 255 is enough for anyone... */ #define GB_NUM_MINORS 255 /* 255 is enough for anyone... */
#define GB_NAME "ttyGB" #define GB_NAME "ttyGB"
struct gb_tty { struct gb_tty {
struct tty_port port; struct tty_port port;
struct greybus_module *gmod; struct gb_module *gmod;
u16 cport_id; u16 cport_id;
unsigned int minor; unsigned int minor;
unsigned char clocal; unsigned char clocal;
...@@ -384,7 +386,7 @@ static const struct tty_operations gb_ops = { ...@@ -384,7 +386,7 @@ static const struct tty_operations gb_ops = {
}; };
int gb_tty_probe(struct greybus_module *gmod, int gb_tty_probe(struct gb_module *gmod,
const struct greybus_module_id *id) const struct greybus_module_id *id)
{ {
struct gb_tty *gb_tty; struct gb_tty *gb_tty;
...@@ -430,7 +432,7 @@ int gb_tty_probe(struct greybus_module *gmod, ...@@ -430,7 +432,7 @@ int gb_tty_probe(struct greybus_module *gmod,
return retval; return retval;
} }
void gb_tty_disconnect(struct greybus_module *gmod) void gb_tty_disconnect(struct gb_module *gmod)
{ {
struct gb_tty *gb_tty = gmod->gb_tty; struct gb_tty *gb_tty = gmod->gb_tty;
struct tty_struct *tty; struct tty_struct *tty;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment