summaryrefslogtreecommitdiff
path: root/drivers/mfd/mcp-core.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-01-20 22:51:07 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-02-03 17:37:48 +0000
commit30816ac0495cb4f33fc8d748f64ac3cc880cb3c1 (patch)
tree689f82c11f0a1097bbd0e715178f94aa345fcebf /drivers/mfd/mcp-core.c
parent0af5e4c36e70cfd4ae96d3704a425c414f530f2a (diff)
MFD: mcp-core: sanitize host creation/removal
host_unregister() gives us no chance between removing the device and the mcp data structure being freed to access the data inbetween, which drivers may need to do if they need to iounmap() pointers in their private data structures. Therefore, re-jig the interfaces, which are now, on creation: mcp = mcp_host_alloc() if (mcp) { ret = mcp_host_add(mcp, data); if (!ret) mcp_host_free(mcp); } and on removal: mcp_host_del(mcp); ... access mcp ... mcp_host_free(mcp); The free does the final put_device() on the struct device as one would expect. Acked-by: Jochen Friedrich <jochen@scram.de> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mfd/mcp-core.c')
-rw-r--r--drivers/mfd/mcp-core.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 86cc3f7841cd..cc7643177841 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -208,6 +208,7 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
if (mcp) {
spin_lock_init(&mcp->lock);
+ device_initialize(&mcp->attached_device);
mcp->attached_device.parent = parent;
mcp->attached_device.bus = &mcp_bus_type;
mcp->attached_device.dma_mask = parent->dma_mask;
@@ -217,18 +218,24 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
}
EXPORT_SYMBOL(mcp_host_alloc);
-int mcp_host_register(struct mcp *mcp)
+int mcp_host_add(struct mcp *mcp)
{
dev_set_name(&mcp->attached_device, "mcp0");
- return device_register(&mcp->attached_device);
+ return device_add(&mcp->attached_device);
}
-EXPORT_SYMBOL(mcp_host_register);
+EXPORT_SYMBOL(mcp_host_add);
-void mcp_host_unregister(struct mcp *mcp)
+void mcp_host_del(struct mcp *mcp)
{
- device_unregister(&mcp->attached_device);
+ device_del(&mcp->attached_device);
}
-EXPORT_SYMBOL(mcp_host_unregister);
+EXPORT_SYMBOL(mcp_host_del);
+
+void mcp_host_free(struct mcp *mcp)
+{
+ put_device(&mcp->attached_device);
+}
+EXPORT_SYMBOL(mcp_host_free);
int mcp_driver_register(struct mcp_driver *mcpdrv)
{