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>
This commit is contained in:
parent
c364ff473a
commit
2f7510c607
2 changed files with 20 additions and 4 deletions
|
@ -530,13 +530,17 @@ static struct class ucb1x00_class = {
|
||||||
|
|
||||||
static int ucb1x00_probe(struct mcp *mcp)
|
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_driver *drv;
|
||||||
struct ucb1x00_plat_data *pdata;
|
struct ucb1x00 *ucb;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
int temp;
|
int temp;
|
||||||
|
|
||||||
|
/* Tell the platform to deassert the UCB1x00 reset */
|
||||||
|
if (pdata && pdata->reset)
|
||||||
|
pdata->reset(UCB_RST_PROBE);
|
||||||
|
|
||||||
mcp_enable(mcp);
|
mcp_enable(mcp);
|
||||||
id = mcp_reg_read(mcp, UCB_ID);
|
id = mcp_reg_read(mcp, UCB_ID);
|
||||||
|
|
||||||
|
@ -550,7 +554,6 @@ static int ucb1x00_probe(struct mcp *mcp)
|
||||||
if (!ucb)
|
if (!ucb)
|
||||||
goto err_disable;
|
goto err_disable;
|
||||||
|
|
||||||
pdata = mcp->attached_device.platform_data;
|
|
||||||
ucb->dev.class = &ucb1x00_class;
|
ucb->dev.class = &ucb1x00_class;
|
||||||
ucb->dev.parent = &mcp->attached_device;
|
ucb->dev.parent = &mcp->attached_device;
|
||||||
dev_set_name(&ucb->dev, "ucb1x00");
|
dev_set_name(&ucb->dev, "ucb1x00");
|
||||||
|
@ -606,7 +609,7 @@ static int ucb1x00_probe(struct mcp *mcp)
|
||||||
}
|
}
|
||||||
mutex_unlock(&ucb1x00_mutex);
|
mutex_unlock(&ucb1x00_mutex);
|
||||||
|
|
||||||
goto out;
|
return ret;
|
||||||
|
|
||||||
err_irq:
|
err_irq:
|
||||||
free_irq(ucb->irq, ucb);
|
free_irq(ucb->irq, ucb);
|
||||||
|
@ -618,11 +621,14 @@ static int ucb1x00_probe(struct mcp *mcp)
|
||||||
err_disable:
|
err_disable:
|
||||||
mcp_disable(mcp);
|
mcp_disable(mcp);
|
||||||
out:
|
out:
|
||||||
|
if (pdata && pdata->reset)
|
||||||
|
pdata->reset(UCB_RST_PROBE_FAIL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ucb1x00_remove(struct mcp *mcp)
|
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 ucb1x00 *ucb = mcp_get_drvdata(mcp);
|
||||||
struct list_head *l, *n;
|
struct list_head *l, *n;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -643,6 +649,9 @@ static void ucb1x00_remove(struct mcp *mcp)
|
||||||
|
|
||||||
free_irq(ucb->irq, ucb);
|
free_irq(ucb->irq, ucb);
|
||||||
device_unregister(&ucb->dev);
|
device_unregister(&ucb->dev);
|
||||||
|
|
||||||
|
if (pdata && pdata->reset)
|
||||||
|
pdata->reset(UCB_RST_REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ucb1x00_register_driver(struct ucb1x00_driver *drv)
|
int ucb1x00_register_driver(struct ucb1x00_driver *drv)
|
||||||
|
|
|
@ -104,7 +104,14 @@
|
||||||
#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
|
#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
|
||||||
#define UCB_MODE_AUD_OFF_CAN (1 << 13)
|
#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 {
|
struct ucb1x00_plat_data {
|
||||||
|
void (*reset)(enum ucb1x00_reset);
|
||||||
int gpio_base;
|
int gpio_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue