From 421476aeed56a8d19c890ae6729e3c43b740da7a Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 10 Jul 2013 12:03:21 -0700 Subject: i2c: mpc: Define unique I2C adapter names The I2C adapters on Freescale MPC107/824x/85xx/512x/52xx/83xx/86xx all have the same name "MPC adapter". Since I2C adapter numbers can change across reboots and even after loading/unloading an I2C bus master driver, adapter names have to be used to identify adapters and thus should be unique and well defined. Since this is not the case with this driver, it is difficult if not impossible to identify a specific adapter from user space on affected platforms. To remedy the problem, use the adapter memory address as part of the adapter name. With this patch, adapter names are: On P2020: MPC adapter at 0xfff703000 MPC adapter at 0xfff703100 On P5040: MPC adapter at 0xffe118000 MPC adapter at 0xffe118100 MPC adapter at 0xffe119000 MPC adapter at 0xffe119100 Signed-off-by: Guenter Roeck Acked-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mpc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/i2c/busses/i2c-mpc.c') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 7607dc061918..99acf636e496 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -609,7 +609,6 @@ static const struct i2c_algorithm mpc_algo = { static struct i2c_adapter mpc_ops = { .owner = THIS_MODULE, - .name = "MPC adapter", .algo = &mpc_algo, .timeout = HZ, }; @@ -623,6 +622,7 @@ static int fsl_i2c_probe(struct platform_device *op) u32 clock = MPC_I2C_CLOCK_LEGACY; int result = 0; int plen; + struct resource res; match = of_match_device(mpc_i2c_of_match, &op->dev); if (!match) @@ -682,6 +682,9 @@ static int fsl_i2c_probe(struct platform_device *op) platform_set_drvdata(op, i2c); i2c->adap = mpc_ops; + of_address_to_resource(op->dev.of_node, 0, &res); + scnprintf(i2c->adap.name, sizeof(i2c->adap.name), + "MPC adapter at 0x%llx", (unsigned long long)res.start); i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &op->dev; i2c->adap.dev.of_node = of_node_get(op->dev.of_node); -- cgit v1.2.3 From 0a488c49eac0ad851b1afbf12b345e2adaf3775c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 15 Jul 2013 11:28:23 +0900 Subject: i2c: i2c-mpc: add CONFIG_PM_SLEEP to suspend/resume functions Add CONFIG_PM_SLEEP to suspend/resume functions to fix the following build warning when CONFIG_PM_SLEEP is not selected. This is because sleep PM callbacks defined by SIMPLE_DEV_PM_OPS are only used when the CONFIG_PM_SLEEP is enabled. drivers/i2c/busses/i2c-mpc.c:724:12: warning: 'mpc_i2c_suspend' defined but not used [-Wunused-function] drivers/i2c/busses/i2c-mpc.c:734:12: warning: 'mpc_i2c_resume' defined but not used [-Wunused-function] Also, this patch makes mpc_i2c_pm_ops static, because mpc_i2c_pm_ops is not exported. Signed-off-by: Jingoo Han Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mpc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/i2c/busses/i2c-mpc.c') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 99acf636e496..ffac2145b94a 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -64,7 +64,7 @@ struct mpc_i2c { struct i2c_adapter adap; int irq; u32 real_clk; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP u8 fdr, dfsrr; #endif }; @@ -723,7 +723,7 @@ static int fsl_i2c_remove(struct platform_device *op) return 0; }; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int mpc_i2c_suspend(struct device *dev) { struct mpc_i2c *i2c = dev_get_drvdata(dev); @@ -744,7 +744,10 @@ static int mpc_i2c_resume(struct device *dev) return 0; } -SIMPLE_DEV_PM_OPS(mpc_i2c_pm_ops, mpc_i2c_suspend, mpc_i2c_resume); +static SIMPLE_DEV_PM_OPS(mpc_i2c_pm_ops, mpc_i2c_suspend, mpc_i2c_resume); +#define MPC_I2C_PM_OPS (&mpc_i2c_pm_ops) +#else +#define MPC_I2C_PM_OPS NULL #endif static const struct mpc_i2c_data mpc_i2c_data_512x = { @@ -791,9 +794,7 @@ static struct platform_driver mpc_i2c_driver = { .owner = THIS_MODULE, .name = DRV_NAME, .of_match_table = mpc_i2c_of_match, -#ifdef CONFIG_PM - .pm = &mpc_i2c_pm_ops, -#endif + .pm = MPC_I2C_PM_OPS, }, }; -- cgit v1.2.3 From 687b81d083c082bc1e853032e3a2a54f8c251d27 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 11 Jul 2013 12:56:15 +0100 Subject: i2c: move OF helpers into the core I2C of helpers used to live in of_i2c.c but experience (from SPI) shows that it is much cleaner to have this in the core. This also removes a circular dependency between the helpers and the core, and so we can finally register child nodes in the core instead of doing this manually in each driver. So, fix the drivers and documentation, too. Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mpc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/i2c/busses/i2c-mpc.c') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index ffac2145b94a..f4060939e959 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -694,7 +693,6 @@ static int fsl_i2c_probe(struct platform_device *op) dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } - of_i2c_register_devices(&i2c->adap); return result; -- cgit v1.2.3 From b3bfce2bc205ff4fdb4ec0b048513557cef459cf Mon Sep 17 00:00:00 2001 From: Gerhard Sittig Date: Fri, 23 Aug 2013 18:01:44 +0200 Subject: i2c: mpc: cleanup clock API use make the MPC I2C driver get, prepare and enable the gated clock item for register access during probe; disable and unprepare the clock upon remove(), put is done by the devm approach; hold a reference to the clock over the period of use clock lookup is non-fatal in this implementation as not all platforms may provide clock specs in their device tree, but failure to enable a clock when specified is considered fatal Signed-off-by: Gerhard Sittig Signed-off-by: Anatolij Gustschin Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mpc.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/i2c/busses/i2c-mpc.c') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f4060939e959..b80c76888cab 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -66,6 +67,7 @@ struct mpc_i2c { #ifdef CONFIG_PM_SLEEP u8 fdr, dfsrr; #endif + struct clk *clk_per; }; struct mpc_i2c_divider { @@ -622,6 +624,8 @@ static int fsl_i2c_probe(struct platform_device *op) int result = 0; int plen; struct resource res; + struct clk *clk; + int err; match = of_match_device(mpc_i2c_of_match, &op->dev); if (!match) @@ -652,6 +656,21 @@ static int fsl_i2c_probe(struct platform_device *op) } } + /* + * enable clock for the I2C peripheral (non fatal), + * keep a reference upon successful allocation + */ + clk = devm_clk_get(&op->dev, NULL); + if (!IS_ERR(clk)) { + err = clk_prepare_enable(clk); + if (err) { + dev_err(&op->dev, "failed to enable clock\n"); + goto fail_request; + } else { + i2c->clk_per = clk; + } + } + if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) { clock = MPC_I2C_CLOCK_PRESERVE; } else { @@ -697,6 +716,8 @@ static int fsl_i2c_probe(struct platform_device *op) return result; fail_add: + if (i2c->clk_per) + clk_disable_unprepare(i2c->clk_per); free_irq(i2c->irq, i2c); fail_request: irq_dispose_mapping(i2c->irq); @@ -712,6 +733,9 @@ static int fsl_i2c_remove(struct platform_device *op) i2c_del_adapter(&i2c->adap); + if (i2c->clk_per) + clk_disable_unprepare(i2c->clk_per); + if (i2c->irq) free_irq(i2c->irq, i2c); -- cgit v1.2.3