aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2014-03-04 11:28:37 -0500
committerWolfram Sang <wsa@the-dreams.de>2014-03-05 11:29:19 -0500
commit370136bc67c3f502ec96446e502ba80b94150f9d (patch)
tree496a317839161e9af290463fc8f4b61c35287c52 /drivers/i2c
parent96c4b6bb5ddb03881dfc1c91410548432138d4ba (diff)
i2c: mv64xxx: Add reset deassert call
The Allwinner A31 SoC using that IP has a reset controller maintaining it reset unless told otherwise. Add some optional reset support to the driver. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig1
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c21
2 files changed, 20 insertions, 2 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index f5ed03164d86..70bcad941657 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -528,6 +528,7 @@ config I2C_MPC
528config I2C_MV64XXX 528config I2C_MV64XXX
529 tristate "Marvell mv64xxx I2C Controller" 529 tristate "Marvell mv64xxx I2C Controller"
530 depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI) 530 depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI)
531 select RESET_CONTROLLER
531 help 532 help
532 If you say yes to this option, support will be included for the 533 If you say yes to this option, support will be included for the
533 built-in I2C interface on the Marvell 64xxx line of host bridges. 534 built-in I2C interface on the Marvell 64xxx line of host bridges.
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index d52d84937ad3..1bb69b6f746d 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -17,6 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/mv643xx_i2c.h> 18#include <linux/mv643xx_i2c.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/reset.h>
20#include <linux/io.h> 21#include <linux/io.h>
21#include <linux/of.h> 22#include <linux/of.h>
22#include <linux/of_device.h> 23#include <linux/of_device.h>
@@ -148,6 +149,7 @@ struct mv64xxx_i2c_data {
148 bool offload_enabled; 149 bool offload_enabled;
149/* 5us delay in order to avoid repeated start timing violation */ 150/* 5us delay in order to avoid repeated start timing violation */
150 bool errata_delay; 151 bool errata_delay;
152 struct reset_control *rstc;
151}; 153};
152 154
153static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { 155static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -759,6 +761,16 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
759 } 761 }
760 drv_data->irq = irq_of_parse_and_map(np, 0); 762 drv_data->irq = irq_of_parse_and_map(np, 0);
761 763
764 drv_data->rstc = devm_reset_control_get(dev, NULL);
765 if (IS_ERR(drv_data->rstc)) {
766 if (PTR_ERR(drv_data->rstc) == -EPROBE_DEFER) {
767 rc = -EPROBE_DEFER;
768 goto out;
769 }
770 } else {
771 reset_control_deassert(drv_data->rstc);
772 }
773
762 /* Its not yet defined how timeouts will be specified in device tree. 774 /* Its not yet defined how timeouts will be specified in device tree.
763 * So hard code the value to 1 second. 775 * So hard code the value to 1 second.
764 */ 776 */
@@ -845,7 +857,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
845 } 857 }
846 if (drv_data->irq < 0) { 858 if (drv_data->irq < 0) {
847 rc = -ENXIO; 859 rc = -ENXIO;
848 goto exit_clk; 860 goto exit_reset;
849 } 861 }
850 862
851 drv_data->adapter.dev.parent = &pd->dev; 863 drv_data->adapter.dev.parent = &pd->dev;
@@ -865,7 +877,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
865 dev_err(&drv_data->adapter.dev, 877 dev_err(&drv_data->adapter.dev,
866 "mv64xxx: Can't register intr handler irq%d: %d\n", 878 "mv64xxx: Can't register intr handler irq%d: %d\n",
867 drv_data->irq, rc); 879 drv_data->irq, rc);
868 goto exit_clk; 880 goto exit_reset;
869 } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) { 881 } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
870 dev_err(&drv_data->adapter.dev, 882 dev_err(&drv_data->adapter.dev,
871 "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); 883 "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
@@ -876,6 +888,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)
876 888
877exit_free_irq: 889exit_free_irq:
878 free_irq(drv_data->irq, drv_data); 890 free_irq(drv_data->irq, drv_data);
891exit_reset:
892 if (pd->dev.of_node && !IS_ERR(drv_data->rstc))
893 reset_control_assert(drv_data->rstc);
879exit_clk: 894exit_clk:
880#if defined(CONFIG_HAVE_CLK) 895#if defined(CONFIG_HAVE_CLK)
881 /* Not all platforms have a clk */ 896 /* Not all platforms have a clk */
@@ -894,6 +909,8 @@ mv64xxx_i2c_remove(struct platform_device *dev)
894 909
895 i2c_del_adapter(&drv_data->adapter); 910 i2c_del_adapter(&drv_data->adapter);
896 free_irq(drv_data->irq, drv_data); 911 free_irq(drv_data->irq, drv_data);
912 if (dev->dev.of_node && !IS_ERR(drv_data->rstc))
913 reset_control_assert(drv_data->rstc);
897#if defined(CONFIG_HAVE_CLK) 914#if defined(CONFIG_HAVE_CLK)
898 /* Not all platforms have a clk */ 915 /* Not all platforms have a clk */
899 if (!IS_ERR(drv_data->clk)) { 916 if (!IS_ERR(drv_data->clk)) {