summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-01-22 19:02:25 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-02-18 23:15:32 +0000
commit2f7510c6070932371e0b842a5470ce7190dcf162 (patch)
tree956bcfceae25b3dac9936910ec2afae2bfbead36 /drivers
parentc364ff473a8d31c93da5e21ac5d2789a935c8faf (diff)
MFD: ucb1x00-core: add handling for ucb1x00 reset
Provide a way to handle the software controlled ucb1x00 reset signal from the ucb1x00-core driver without having to code platform specifics into these drivers. Acked-by: Jochen Friedrich <jochen@scram.de> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/ucb1x00-core.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index cc1c0dce7bd9..42eee633b864 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -530,13 +530,17 @@ static struct class ucb1x00_class = {
static int ucb1x00_probe(struct mcp *mcp)
{
- struct ucb1x00 *ucb;
+ struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
struct ucb1x00_driver *drv;
- struct ucb1x00_plat_data *pdata;
+ struct ucb1x00 *ucb;
unsigned int id;
int ret = -ENODEV;
int temp;
+ /* Tell the platform to deassert the UCB1x00 reset */
+ if (pdata && pdata->reset)
+ pdata->reset(UCB_RST_PROBE);
+
mcp_enable(mcp);
id = mcp_reg_read(mcp, UCB_ID);
@@ -550,7 +554,6 @@ static int ucb1x00_probe(struct mcp *mcp)
if (!ucb)
goto err_disable;
- pdata = mcp->attached_device.platform_data;
ucb->dev.class = &ucb1x00_class;
ucb->dev.parent = &mcp->attached_device;
dev_set_name(&ucb->dev, "ucb1x00");
@@ -606,7 +609,7 @@ static int ucb1x00_probe(struct mcp *mcp)
}
mutex_unlock(&ucb1x00_mutex);
- goto out;
+ return ret;
err_irq:
free_irq(ucb->irq, ucb);
@@ -618,11 +621,14 @@ static int ucb1x00_probe(struct mcp *mcp)
err_disable:
mcp_disable(mcp);
out:
+ if (pdata && pdata->reset)
+ pdata->reset(UCB_RST_PROBE_FAIL);
return ret;
}
static void ucb1x00_remove(struct mcp *mcp)
{
+ struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct list_head *l, *n;
int ret;
@@ -643,6 +649,9 @@ static void ucb1x00_remove(struct mcp *mcp)
free_irq(ucb->irq, ucb);
device_unregister(&ucb->dev);
+
+ if (pdata && pdata->reset)
+ pdata->reset(UCB_RST_REMOVE);
}
int ucb1x00_register_driver(struct ucb1x00_driver *drv)