aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPankaj Dubey <pankaj.dubey@samsung.com>2014-11-24 03:33:38 -0500
committerWolfram Sang <wsa@the-dreams.de>2014-11-24 04:37:14 -0500
commita7750c3ef0122383901ae48396188aa4b861d32b (patch)
tree9a268b9c44a39e3f61c7e7e5adadf1063eb142e6
parent80f1774f967a16b1909628cd1ca3d5c30a32aac1 (diff)
i2c: s3c2410: Handle i2c sys_cfg register in i2c driver
Let's handle i2c interrupt re-configuration in i2c driver. This will help us in removing some soc specific checks from machine files and will help in removing static iomapping of SYS register in exynos.c Also handle saving and restoring of SYS_I2C_CFG register during suspend and resume of i2c driver. Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 65244774bfa3..09a6bace457e 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -35,6 +35,8 @@
35#include <linux/of.h> 35#include <linux/of.h>
36#include <linux/of_gpio.h> 36#include <linux/of_gpio.h>
37#include <linux/pinctrl/consumer.h> 37#include <linux/pinctrl/consumer.h>
38#include <linux/mfd/syscon.h>
39#include <linux/regmap.h>
38 40
39#include <asm/irq.h> 41#include <asm/irq.h>
40 42
@@ -87,6 +89,9 @@
87/* Max time to wait for bus to become idle after a xfer (in us) */ 89/* Max time to wait for bus to become idle after a xfer (in us) */
88#define S3C2410_IDLE_TIMEOUT 5000 90#define S3C2410_IDLE_TIMEOUT 5000
89 91
92/* Exynos5 Sysreg offset */
93#define EXYNOS5_SYS_I2C_CFG 0x0234
94
90/* i2c controller state */ 95/* i2c controller state */
91enum s3c24xx_i2c_state { 96enum s3c24xx_i2c_state {
92 STATE_IDLE, 97 STATE_IDLE,
@@ -123,6 +128,8 @@ struct s3c24xx_i2c {
123#if defined(CONFIG_ARM_S3C24XX_CPUFREQ) 128#if defined(CONFIG_ARM_S3C24XX_CPUFREQ)
124 struct notifier_block freq_transition; 129 struct notifier_block freq_transition;
125#endif 130#endif
131 struct regmap *sysreg;
132 unsigned int sys_i2c_cfg;
126}; 133};
127 134
128static struct platform_device_id s3c24xx_driver_ids[] = { 135static struct platform_device_id s3c24xx_driver_ids[] = {
@@ -1071,6 +1078,7 @@ static void
1071s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c) 1078s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c)
1072{ 1079{
1073 struct s3c2410_platform_i2c *pdata = i2c->pdata; 1080 struct s3c2410_platform_i2c *pdata = i2c->pdata;
1081 int id;
1074 1082
1075 if (!np) 1083 if (!np)
1076 return; 1084 return;
@@ -1080,6 +1088,21 @@ s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c)
1080 of_property_read_u32(np, "samsung,i2c-slave-addr", &pdata->slave_addr); 1088 of_property_read_u32(np, "samsung,i2c-slave-addr", &pdata->slave_addr);
1081 of_property_read_u32(np, "samsung,i2c-max-bus-freq", 1089 of_property_read_u32(np, "samsung,i2c-max-bus-freq",
1082 (u32 *)&pdata->frequency); 1090 (u32 *)&pdata->frequency);
1091 /*
1092 * Exynos5's legacy i2c controller and new high speed i2c
1093 * controller have muxed interrupt sources. By default the
1094 * interrupts for 4-channel HS-I2C controller are enabled.
1095 * If nodes for first four channels of legacy i2c controller
1096 * are available then re-configure the interrupts via the
1097 * system register.
1098 */
1099 id = of_alias_get_id(np, "i2c");
1100 i2c->sysreg = syscon_regmap_lookup_by_phandle(np,
1101 "samsung,sysreg-phandle");
1102 if (IS_ERR(i2c->sysreg))
1103 return;
1104
1105 regmap_update_bits(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, BIT(id), 0);
1083} 1106}
1084#else 1107#else
1085static void 1108static void
@@ -1260,6 +1283,9 @@ static int s3c24xx_i2c_suspend_noirq(struct device *dev)
1260 1283
1261 i2c->suspended = 1; 1284 i2c->suspended = 1;
1262 1285
1286 if (!IS_ERR(i2c->sysreg))
1287 regmap_read(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, &i2c->sys_i2c_cfg);
1288
1263 return 0; 1289 return 0;
1264} 1290}
1265 1291
@@ -1268,6 +1294,9 @@ static int s3c24xx_i2c_resume_noirq(struct device *dev)
1268 struct platform_device *pdev = to_platform_device(dev); 1294 struct platform_device *pdev = to_platform_device(dev);
1269 struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); 1295 struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
1270 1296
1297 if (!IS_ERR(i2c->sysreg))
1298 regmap_write(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, i2c->sys_i2c_cfg);
1299
1271 clk_prepare_enable(i2c->clk); 1300 clk_prepare_enable(i2c->clk);
1272 s3c24xx_i2c_init(i2c); 1301 s3c24xx_i2c_init(i2c);
1273 clk_disable_unprepare(i2c->clk); 1302 clk_disable_unprepare(i2c->clk);