diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-22 19:02:25 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-02-18 23:15:32 +0000 |
commit | 2f7510c6070932371e0b842a5470ce7190dcf162 (patch) | |
tree | 956bcfceae25b3dac9936910ec2afae2bfbead36 | |
parent | c364ff473a8d31c93da5e21ac5d2789a935c8faf (diff) | |
download | linux-2f7510c6070932371e0b842a5470ce7190dcf162.tar.gz linux-2f7510c6070932371e0b842a5470ce7190dcf162.tar.bz2 linux-2f7510c6070932371e0b842a5470ce7190dcf162.zip |
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>
-rw-r--r-- | drivers/mfd/ucb1x00-core.c | 17 | ||||
-rw-r--r-- | include/linux/mfd/ucb1x00.h | 7 |
2 files changed, 20 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) diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index 731b23a656c0..fd088cc6a4ca 100644 --- a/include/linux/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h @@ -104,7 +104,14 @@ #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) #define UCB_MODE_AUD_OFF_CAN (1 << 13) +enum ucb1x00_reset { + UCB_RST_PROBE, + UCB_RST_REMOVE, + UCB_RST_PROBE_FAIL, +}; + struct ucb1x00_plat_data { + void (*reset)(enum ucb1x00_reset); int gpio_base; }; |