diff options
author | Jochen Friedrich <jochen@scram.de> | 2011-11-27 16:00:54 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-01-08 18:37:33 -0500 |
commit | 5dd7bf59e0e8563265b3e5b33276099ef628fcc7 (patch) | |
tree | 1372dd626865e4ed21cac103a706f06ef6ff700e /drivers/mfd/mcp-core.c | |
parent | c9531227b289947950cce29cfe881b768bf9d7d9 (diff) |
ARM: sa11x0: Implement autoloading of codec and codec pdata for mcp bus.
Signed-off-by: Jochen Friedrich <jochen@scram.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/mcp-core.c')
-rw-r--r-- | drivers/mfd/mcp-core.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 84815f9ef636..63be60bc3455 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c | |||
@@ -26,9 +26,35 @@ | |||
26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) | 26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) |
27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) | 27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) |
28 | 28 | ||
29 | static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id, | ||
30 | const char *codec) | ||
31 | { | ||
32 | while (id->name[0]) { | ||
33 | if (strcmp(codec, id->name) == 0) | ||
34 | return id; | ||
35 | id++; | ||
36 | } | ||
37 | return NULL; | ||
38 | } | ||
39 | |||
40 | const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp) | ||
41 | { | ||
42 | const struct mcp_driver *driver = | ||
43 | to_mcp_driver(mcp->attached_device.driver); | ||
44 | |||
45 | return mcp_match_id(driver->id_table, mcp->codec); | ||
46 | } | ||
47 | EXPORT_SYMBOL(mcp_get_device_id); | ||
48 | |||
29 | static int mcp_bus_match(struct device *dev, struct device_driver *drv) | 49 | static int mcp_bus_match(struct device *dev, struct device_driver *drv) |
30 | { | 50 | { |
31 | return 1; | 51 | const struct mcp *mcp = to_mcp(dev); |
52 | const struct mcp_driver *driver = to_mcp_driver(drv); | ||
53 | |||
54 | if (driver->id_table) | ||
55 | return !!mcp_match_id(driver->id_table, mcp->codec); | ||
56 | |||
57 | return 0; | ||
32 | } | 58 | } |
33 | 59 | ||
34 | static int mcp_bus_probe(struct device *dev) | 60 | static int mcp_bus_probe(struct device *dev) |
@@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev) | |||
74 | return ret; | 100 | return ret; |
75 | } | 101 | } |
76 | 102 | ||
103 | static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
104 | { | ||
105 | struct mcp *mcp = to_mcp(dev); | ||
106 | |||
107 | add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
77 | static struct bus_type mcp_bus_type = { | 111 | static struct bus_type mcp_bus_type = { |
78 | .name = "mcp", | 112 | .name = "mcp", |
79 | .match = mcp_bus_match, | 113 | .match = mcp_bus_match, |
114 | .uevent = mcp_bus_uevent, | ||
80 | .probe = mcp_bus_probe, | 115 | .probe = mcp_bus_probe, |
81 | .remove = mcp_bus_remove, | 116 | .remove = mcp_bus_remove, |
82 | .suspend = mcp_bus_suspend, | 117 | .suspend = mcp_bus_suspend, |
@@ -212,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) | |||
212 | } | 247 | } |
213 | EXPORT_SYMBOL(mcp_host_alloc); | 248 | EXPORT_SYMBOL(mcp_host_alloc); |
214 | 249 | ||
215 | int mcp_host_register(struct mcp *mcp) | 250 | int mcp_host_register(struct mcp *mcp, void *pdata) |
216 | { | 251 | { |
252 | if (!mcp->codec) | ||
253 | return -EINVAL; | ||
254 | |||
255 | mcp->attached_device.platform_data = pdata; | ||
217 | dev_set_name(&mcp->attached_device, "mcp0"); | 256 | dev_set_name(&mcp->attached_device, "mcp0"); |
257 | request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec); | ||
218 | return device_register(&mcp->attached_device); | 258 | return device_register(&mcp->attached_device); |
219 | } | 259 | } |
220 | EXPORT_SYMBOL(mcp_host_register); | 260 | EXPORT_SYMBOL(mcp_host_register); |