diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-22 14:02:25 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-02-18 18:15:32 -0500 |
commit | 2f7510c6070932371e0b842a5470ce7190dcf162 (patch) | |
tree | 956bcfceae25b3dac9936910ec2afae2bfbead36 | |
parent | c364ff473a8d31c93da5e21ac5d2789a935c8faf (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>
-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 = { | |||
530 | 530 | ||
531 | static int ucb1x00_probe(struct mcp *mcp) | 531 | static int ucb1x00_probe(struct mcp *mcp) |
532 | { | 532 | { |
533 | struct ucb1x00 *ucb; | 533 | struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; |
534 | struct ucb1x00_driver *drv; | 534 | struct ucb1x00_driver *drv; |
535 | struct ucb1x00_plat_data *pdata; | 535 | struct ucb1x00 *ucb; |
536 | unsigned int id; | 536 | unsigned int id; |
537 | int ret = -ENODEV; | 537 | int ret = -ENODEV; |
538 | int temp; | 538 | int temp; |
539 | 539 | ||
540 | /* Tell the platform to deassert the UCB1x00 reset */ | ||
541 | if (pdata && pdata->reset) | ||
542 | pdata->reset(UCB_RST_PROBE); | ||
543 | |||
540 | mcp_enable(mcp); | 544 | mcp_enable(mcp); |
541 | id = mcp_reg_read(mcp, UCB_ID); | 545 | id = mcp_reg_read(mcp, UCB_ID); |
542 | 546 | ||
@@ -550,7 +554,6 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
550 | if (!ucb) | 554 | if (!ucb) |
551 | goto err_disable; | 555 | goto err_disable; |
552 | 556 | ||
553 | pdata = mcp->attached_device.platform_data; | ||
554 | ucb->dev.class = &ucb1x00_class; | 557 | ucb->dev.class = &ucb1x00_class; |
555 | ucb->dev.parent = &mcp->attached_device; | 558 | ucb->dev.parent = &mcp->attached_device; |
556 | dev_set_name(&ucb->dev, "ucb1x00"); | 559 | dev_set_name(&ucb->dev, "ucb1x00"); |
@@ -606,7 +609,7 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
606 | } | 609 | } |
607 | mutex_unlock(&ucb1x00_mutex); | 610 | mutex_unlock(&ucb1x00_mutex); |
608 | 611 | ||
609 | goto out; | 612 | return ret; |
610 | 613 | ||
611 | err_irq: | 614 | err_irq: |
612 | free_irq(ucb->irq, ucb); | 615 | free_irq(ucb->irq, ucb); |
@@ -618,11 +621,14 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
618 | err_disable: | 621 | err_disable: |
619 | mcp_disable(mcp); | 622 | mcp_disable(mcp); |
620 | out: | 623 | out: |
624 | if (pdata && pdata->reset) | ||
625 | pdata->reset(UCB_RST_PROBE_FAIL); | ||
621 | return ret; | 626 | return ret; |
622 | } | 627 | } |
623 | 628 | ||
624 | static void ucb1x00_remove(struct mcp *mcp) | 629 | static void ucb1x00_remove(struct mcp *mcp) |
625 | { | 630 | { |
631 | struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; | ||
626 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); | 632 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); |
627 | struct list_head *l, *n; | 633 | struct list_head *l, *n; |
628 | int ret; | 634 | int ret; |
@@ -643,6 +649,9 @@ static void ucb1x00_remove(struct mcp *mcp) | |||
643 | 649 | ||
644 | free_irq(ucb->irq, ucb); | 650 | free_irq(ucb->irq, ucb); |
645 | device_unregister(&ucb->dev); | 651 | device_unregister(&ucb->dev); |
652 | |||
653 | if (pdata && pdata->reset) | ||
654 | pdata->reset(UCB_RST_REMOVE); | ||
646 | } | 655 | } |
647 | 656 | ||
648 | int ucb1x00_register_driver(struct ucb1x00_driver *drv) | 657 | 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 @@ | |||
104 | #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) | 104 | #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) |
105 | #define UCB_MODE_AUD_OFF_CAN (1 << 13) | 105 | #define UCB_MODE_AUD_OFF_CAN (1 << 13) |
106 | 106 | ||
107 | enum ucb1x00_reset { | ||
108 | UCB_RST_PROBE, | ||
109 | UCB_RST_REMOVE, | ||
110 | UCB_RST_PROBE_FAIL, | ||
111 | }; | ||
112 | |||
107 | struct ucb1x00_plat_data { | 113 | struct ucb1x00_plat_data { |
114 | void (*reset)(enum ucb1x00_reset); | ||
108 | int gpio_base; | 115 | int gpio_base; |
109 | }; | 116 | }; |
110 | 117 | ||