* [PATCH 0/3] i2c: davinci: Add power management features
@ 2009-12-07 9:28 Chaithrika U S
[not found] ` <1260178136-26416-1-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
0 siblings, 1 reply; 8+ messages in thread
From: Chaithrika U S @ 2009-12-07 9:28 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR, Chaithrika U S
Add suspend/resume and cpufreq features to DaVinci I2C driver
All patches apply to Linus' kernel tree.
Testing of these features was done on DA850/OMAP-L138 EVM.
Chaithrika U S (3):
i2c: davinci: Add helper functions
i2c: davinci: Add suspend/resume support
i2c: davinci: Add cpufreq support
drivers/i2c/busses/i2c-davinci.c | 147 ++++++++++++++++++++++++++++++++-----
1 files changed, 127 insertions(+), 20 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/3] i2c: davinci: Add helper functions
[not found] ` <1260178136-26416-1-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
@ 2009-12-07 9:28 ` Chaithrika U S
[not found] ` <1260178136-26416-2-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
0 siblings, 1 reply; 8+ messages in thread
From: Chaithrika U S @ 2009-12-07 9:28 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR, Chaithrika U S
Add i2c reset control and clock divider calculation functions
which will be useful for power management features.
Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-davinci.c | 56 +++++++++++++++++++++++++-------------
1 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index c89687a..5f3838c 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -133,12 +133,21 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
return __raw_readw(i2c_dev->base + reg);
}
-/*
- * This functions configures I2C and brings I2C out of reset.
- * This function is called during I2C init function. This function
- * also gets called if I2C encounters any errors.
- */
-static int i2c_davinci_init(struct davinci_i2c_dev *dev)
+static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
+ int val)
+{
+ u16 w;
+
+ w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
+ if (!val) /* put I2C into reset */
+ MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
+ else /* take I2C out of reset */
+ MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
+
+ davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
+}
+
+static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
{
struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
u16 psc;
@@ -147,15 +156,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
u32 clkh;
u32 clkl;
u32 input_clock = clk_get_rate(dev->clk);
- u16 w;
-
- if (!pdata)
- pdata = &davinci_i2c_platform_data_default;
-
- /* put I2C into reset */
- w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
- MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
/* NOTE: I2C Clock divider programming info
* As per I2C specs the following formulas provide prescaler
@@ -187,12 +187,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
+ dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
+}
+
+/*
+ * This functions configures I2C and brings I2C out of reset.
+ * This function is called during I2C init function. This function
+ * also gets called if I2C encounters any errors.
+ */
+static int i2c_davinci_init(struct davinci_i2c_dev *dev)
+{
+ struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+
+ if (!pdata)
+ pdata = &davinci_i2c_platform_data_default;
+
+ /* put I2C into reset */
+ davinci_i2c_reset_ctrl(dev, 0);
+
+ /* compute clock dividers */
+ i2c_davinci_calc_clk_dividers(dev);
+
/* Respond at reserved "SMBus Host" slave address" (and zero);
* we seem to have no option to not respond...
*/
davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
- dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
dev_dbg(dev->dev, "PSC = %d\n",
davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
dev_dbg(dev->dev, "CLKL = %d\n",
@@ -203,9 +223,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
pdata->bus_freq, pdata->bus_delay);
/* Take the I2C module out of reset: */
- w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
- MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
+ davinci_i2c_reset_ctrl(dev, 1);
/* Enable interrupts */
davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);
--
1.5.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] i2c: davinci: Add suspend/resume support
[not found] ` <1260178136-26416-2-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
@ 2009-12-07 9:28 ` Chaithrika U S
[not found] ` <1260178136-26416-3-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
2009-12-07 18:24 ` [PATCH 1/3] i2c: davinci: Add helper functions Troy Kisky
1 sibling, 1 reply; 8+ messages in thread
From: Chaithrika U S @ 2009-12-07 9:28 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR, Chaithrika U S
Add suspend and resume callbacks to DaVinci I2C driver.
This has been tested on DA850/OMAP-L138 EVM. The SoC specific
suspend-to-RAM support patch series [1] is needed to test this feature.
[1] http://linux.davincidsp.com/pipermail/davinci-linux-open-source/
2009-November/016958.html
Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-davinci.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 5f3838c..5f0888d 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -623,6 +623,36 @@ static int davinci_i2c_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int davinci_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
+
+ /* put I2C into reset */
+ davinci_i2c_reset_ctrl(dev, 0);
+
+ clk_disable(dev->clk);
+
+ return 0;
+}
+
+static int davinci_i2c_resume(struct platform_device *pdev)
+{
+ struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
+
+ clk_enable(dev->clk);
+
+ /* take I2C out of reset */
+ davinci_i2c_reset_ctrl(dev, 1);
+
+ return 0;
+}
+
+#else
+#define davinci_i2c_suspend NULL
+#define davinci_i2c_resume NULL
+#endif
+
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:i2c_davinci");
@@ -633,6 +663,8 @@ static struct platform_driver davinci_i2c_driver = {
.name = "i2c_davinci",
.owner = THIS_MODULE,
},
+ .suspend = davinci_i2c_suspend,
+ .resume = davinci_i2c_resume,
};
/* I2C may be needed to bring up other drivers */
--
1.5.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] i2c: davinci: Add cpufreq support
[not found] ` <1260178136-26416-3-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
@ 2009-12-07 9:28 ` Chaithrika U S
[not found] ` <1260178136-26416-4-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
0 siblings, 1 reply; 8+ messages in thread
From: Chaithrika U S @ 2009-12-07 9:28 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA
Cc: davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
khilman-1D3HCaltpLuhEniVeURVKkEOCMrvLtNR, Chaithrika U S
Add cpufreq support for DaVinci I2C driver.
Tested on DA850/OMAP-L138 EVM. For the purpose of testing, the patches
which add cpufreq support [1] for this SoC are needed.
[1]http://linux.davincidsp.com/pipermail/davinci-linux-open-source/
2009-September/016118.html
Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-davinci.c | 59 +++++++++++++++++++++++++++++++++++++-
1 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 5f0888d..0f41da4 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -35,9 +35,9 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/cpufreq.h>
#include <mach/hardware.h>
-
#include <mach/i2c.h>
/* ----- global defines ----------------------------------------------- */
@@ -114,6 +114,10 @@ struct davinci_i2c_dev {
int irq;
u8 terminate;
struct i2c_adapter adapter;
+#ifdef CONFIG_CPU_FREQ
+ struct completion xfr_complete;
+ struct notifier_block freq_transition;
+#endif
};
/* default platform data to use if not supplied in the platform_device */
@@ -384,6 +388,11 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (ret < 0)
return ret;
}
+
+#ifdef CONFIG_CPU_FREQ
+ complete(&dev->xfr_complete);
+#endif
+
return num;
}
@@ -508,6 +517,39 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
return count ? IRQ_HANDLED : IRQ_NONE;
}
+#ifdef CONFIG_CPU_FREQ
+static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct davinci_i2c_dev *dev;
+
+ dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
+ if (val == CPUFREQ_PRECHANGE) {
+ wait_for_completion(&dev->xfr_complete);
+ davinci_i2c_reset_ctrl(dev, 0);
+ } else if (val == CPUFREQ_POSTCHANGE) {
+ i2c_davinci_calc_clk_dividers(dev);
+ davinci_i2c_reset_ctrl(dev, 1);
+ }
+
+ return 0;
+}
+
+static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
+{
+ dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition;
+
+ return cpufreq_register_notifier(&dev->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
+{
+ cpufreq_unregister_notifier(&dev->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+#endif
+
static struct i2c_algorithm i2c_davinci_algo = {
.master_xfer = i2c_davinci_xfer,
.functionality = i2c_davinci_func,
@@ -547,6 +589,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
}
init_completion(&dev->cmd_complete);
+#ifdef CONFIG_CPU_FREQ
+ init_completion(&dev->xfr_complete);
+#endif
dev->dev = get_device(&pdev->dev);
dev->irq = irq->start;
platform_set_drvdata(pdev, dev);
@@ -567,6 +612,14 @@ static int davinci_i2c_probe(struct platform_device *pdev)
goto err_unuse_clocks;
}
+#ifdef CONFIG_CPU_FREQ
+ r = i2c_davinci_cpufreq_register(dev);
+ if (r) {
+ dev_err(&pdev->dev, "failed to register cpufreq\n");
+ goto err_free_irq;
+ }
+#endif
+
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
@@ -606,6 +659,10 @@ static int davinci_i2c_remove(struct platform_device *pdev)
struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
+#ifdef CONFIG_CPU_FREQ
+ i2c_davinci_cpufreq_deregister(dev);
+#endif
+
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&dev->adapter);
put_device(&pdev->dev);
--
1.5.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 3/3] i2c: davinci: Add cpufreq support
[not found] ` <1260178136-26416-4-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
@ 2009-12-07 11:00 ` Sergei Shtylyov
[not found] ` <4B1CE03E.7040608-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
0 siblings, 1 reply; 8+ messages in thread
From: Sergei Shtylyov @ 2009-12-07 11:00 UTC (permalink / raw)
To: Chaithrika U S
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Hello.
Chaithrika U S wrote:
> Add cpufreq support for DaVinci I2C driver.
> Tested on DA850/OMAP-L138 EVM. For the purpose of testing, the patches
> which add cpufreq support [1] for this SoC are needed.
>
> [1]http://linux.davincidsp.com/pipermail/davinci-linux-open-source/
> 2009-September/016118.html
>
> Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
> ---
> drivers/i2c/busses/i2c-davinci.c | 59 +++++++++++++++++++++++++++++++++++++-
> 1 files changed, 58 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> index 5f0888d..0f41da4 100644
> --- a/drivers/i2c/busses/i2c-davinci.c
> +++ b/drivers/i2c/busses/i2c-davinci.c
[...]
> @@ -508,6 +517,39 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
> return count ? IRQ_HANDLED : IRQ_NONE;
> }
>
> +#ifdef CONFIG_CPU_FREQ
> +static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
> + unsigned long val, void *data)
> +{
> + struct davinci_i2c_dev *dev;
> +
> + dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
> + if (val == CPUFREQ_PRECHANGE) {
> + wait_for_completion(&dev->xfr_complete);
> + davinci_i2c_reset_ctrl(dev, 0);
> + } else if (val == CPUFREQ_POSTCHANGE) {
> + i2c_davinci_calc_clk_dividers(dev);
> + davinci_i2c_reset_ctrl(dev, 1);
> + }
> +
> + return 0;
> +}
> +
> +static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
> +{
> + dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition;
> +
> + return cpufreq_register_notifier(&dev->freq_transition,
> + CPUFREQ_TRANSITION_NOTIFIER);
> +}
> +
> +static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
> +{
> + cpufreq_unregister_notifier(&dev->freq_transition,
> + CPUFREQ_TRANSITION_NOTIFIER);
> +}
> +#endif
> +
> static struct i2c_algorithm i2c_davinci_algo = {
> .master_xfer = i2c_davinci_xfer,
> .functionality = i2c_davinci_func,
> @@ -547,6 +589,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
> }
>
> init_completion(&dev->cmd_complete);
> +#ifdef CONFIG_CPU_FREQ
> + init_completion(&dev->xfr_complete);
> +#endif
> dev->dev = get_device(&pdev->dev);
> dev->irq = irq->start;
> platform_set_drvdata(pdev, dev);
> @@ -567,6 +612,14 @@ static int davinci_i2c_probe(struct platform_device *pdev)
> goto err_unuse_clocks;
> }
>
> +#ifdef CONFIG_CPU_FREQ
> + r = i2c_davinci_cpufreq_register(dev);
> + if (r) {
> + dev_err(&pdev->dev, "failed to register cpufreq\n");
> + goto err_free_irq;
> + }
> +#endif
>
You should instead define this function as just returning 0 in the
#else branch above, so that #ifdef here can be avoided...
> +
> adap = &dev->adapter;
> i2c_set_adapdata(adap, dev);
> adap->owner = THIS_MODULE;
> @@ -606,6 +659,10 @@ static int davinci_i2c_remove(struct platform_device *pdev)
> struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
> struct resource *mem;
>
> +#ifdef CONFIG_CPU_FREQ
> + i2c_davinci_cpufreq_deregister(dev);
> +#endif
> +
>
Same comment here. #ifdef's in the function code are frowned upon....
WBR, Sergei
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3] i2c: davinci: Add helper functions
[not found] ` <1260178136-26416-2-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
2009-12-07 9:28 ` [PATCH 2/3] i2c: davinci: Add suspend/resume support Chaithrika U S
@ 2009-12-07 18:24 ` Troy Kisky
[not found] ` <4B1D4850.7010108-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
1 sibling, 1 reply; 8+ messages in thread
From: Troy Kisky @ 2009-12-07 18:24 UTC (permalink / raw)
To: Chaithrika U S
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
Chaithrika U S wrote:
> Add i2c reset control and clock divider calculation functions
> which will be useful for power management features.
>
> Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
> ---
> drivers/i2c/busses/i2c-davinci.c | 56 +++++++++++++++++++++++++-------------
> 1 files changed, 37 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> index c89687a..5f3838c 100644
> --- a/drivers/i2c/busses/i2c-davinci.c
> +++ b/drivers/i2c/busses/i2c-davinci.c
> @@ -133,12 +133,21 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
> return __raw_readw(i2c_dev->base + reg);
> }
>
> -/*
> - * This functions configures I2C and brings I2C out of reset.
> - * This function is called during I2C init function. This function
> - * also gets called if I2C encounters any errors.
> - */
> -static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> +static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
> + int val)
> +{
> + u16 w;
> +
> + w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
> + if (!val) /* put I2C into reset */
> + MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
> + else /* take I2C out of reset */
> + MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
> +
I dislike the MOD_REG_BIT macro. Maybe if you wrote
MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, val);
it would be slightly better, but I still wouldn't like it.
Please use w &= ~DAVINCI_I2C_MDR_IRS and
w |= DAVINCI_I2C_MDR_IRS directly.
I know the code you're replacing uses this obfuscating macro
but this is a good time to remove it.
> + davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
> +}
> +
> +static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
> {
> struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
> u16 psc;
> @@ -147,15 +156,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> u32 clkh;
> u32 clkl;
> u32 input_clock = clk_get_rate(dev->clk);
> - u16 w;
> -
> - if (!pdata)
> - pdata = &davinci_i2c_platform_data_default;
> -
> - /* put I2C into reset */
> - w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
> - MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
> - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
>
> /* NOTE: I2C Clock divider programming info
> * As per I2C specs the following formulas provide prescaler
> @@ -187,12 +187,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
> davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
>
> + dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
> +}
> +
> +/*
> + * This functions configures I2C and brings I2C out of reset.
> + * This function is called during I2C init function. This function
> + * also gets called if I2C encounters any errors.
> + */
> +static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> +{
> + struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
> +
> + if (!pdata)
> + pdata = &davinci_i2c_platform_data_default;
> +
> + /* put I2C into reset */
> + davinci_i2c_reset_ctrl(dev, 0);
> +
> + /* compute clock dividers */
> + i2c_davinci_calc_clk_dividers(dev);
> +
> /* Respond at reserved "SMBus Host" slave address" (and zero);
> * we seem to have no option to not respond...
> */
> davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
>
> - dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
> dev_dbg(dev->dev, "PSC = %d\n",
> davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
> dev_dbg(dev->dev, "CLKL = %d\n",
> @@ -203,9 +223,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> pdata->bus_freq, pdata->bus_delay);
>
> /* Take the I2C module out of reset: */
> - w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
> - MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
> - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
> + davinci_i2c_reset_ctrl(dev, 1);
>
> /* Enable interrupts */
> davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH 3/3] i2c: davinci: Add cpufreq support
[not found] ` <4B1CE03E.7040608-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
@ 2009-12-08 4:38 ` Chaithrika U S
0 siblings, 0 replies; 8+ messages in thread
From: Chaithrika U S @ 2009-12-08 4:38 UTC (permalink / raw)
To: 'Sergei Shtylyov'
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
On Mon, Dec 07, 2009 at 16:30:14, Sergei Shtylyov wrote:
> Hello.
>
> Chaithrika U S wrote:
>
> > Add cpufreq support for DaVinci I2C driver.
> > Tested on DA850/OMAP-L138 EVM. For the purpose of testing, the patches
> > which add cpufreq support [1] for this SoC are needed.
> >
> > [1]http://linux.davincidsp.com/pipermail/davinci-linux-open-source/
> > 2009-September/016118.html
> >
> > Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
> > ---
> > drivers/i2c/busses/i2c-davinci.c | 59 +++++++++++++++++++++++++++++++++++++-
> > 1 files changed, 58 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> > index 5f0888d..0f41da4 100644
> > --- a/drivers/i2c/busses/i2c-davinci.c
> > +++ b/drivers/i2c/busses/i2c-davinci.c
>
> [...]
>
> > @@ -508,6 +517,39 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
> > return count ? IRQ_HANDLED : IRQ_NONE;
> > }
> >
> > +#ifdef CONFIG_CPU_FREQ
> > +static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
> > + unsigned long val, void *data)
> > +{
> > + struct davinci_i2c_dev *dev;
> > +
> > + dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
> > + if (val == CPUFREQ_PRECHANGE) {
> > + wait_for_completion(&dev->xfr_complete);
> > + davinci_i2c_reset_ctrl(dev, 0);
> > + } else if (val == CPUFREQ_POSTCHANGE) {
> > + i2c_davinci_calc_clk_dividers(dev);
> > + davinci_i2c_reset_ctrl(dev, 1);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
> > +{
> > + dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition;
> > +
> > + return cpufreq_register_notifier(&dev->freq_transition,
> > + CPUFREQ_TRANSITION_NOTIFIER);
> > +}
> > +
> > +static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
> > +{
> > + cpufreq_unregister_notifier(&dev->freq_transition,
> > + CPUFREQ_TRANSITION_NOTIFIER);
> > +}
> > +#endif
> > +
> > static struct i2c_algorithm i2c_davinci_algo = {
> > .master_xfer = i2c_davinci_xfer,
> > .functionality = i2c_davinci_func,
> > @@ -547,6 +589,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
> > }
> >
> > init_completion(&dev->cmd_complete);
> > +#ifdef CONFIG_CPU_FREQ
> > + init_completion(&dev->xfr_complete);
> > +#endif
> > dev->dev = get_device(&pdev->dev);
> > dev->irq = irq->start;
> > platform_set_drvdata(pdev, dev);
> > @@ -567,6 +612,14 @@ static int davinci_i2c_probe(struct platform_device *pdev)
> > goto err_unuse_clocks;
> > }
> >
> > +#ifdef CONFIG_CPU_FREQ
> > + r = i2c_davinci_cpufreq_register(dev);
> > + if (r) {
> > + dev_err(&pdev->dev, "failed to register cpufreq\n");
> > + goto err_free_irq;
> > + }
> > +#endif
> >
>
> You should instead define this function as just returning 0 in the
> #else branch above, so that #ifdef here can be avoided...
>
> > +
> > adap = &dev->adapter;
> > i2c_set_adapdata(adap, dev);
> > adap->owner = THIS_MODULE;
> > @@ -606,6 +659,10 @@ static int davinci_i2c_remove(struct platform_device *pdev)
> > struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
> > struct resource *mem;
> >
> > +#ifdef CONFIG_CPU_FREQ
> > + i2c_davinci_cpufreq_deregister(dev);
> > +#endif
> > +
> >
>
> Same comment here. #ifdef's in the function code are frowned upon....
>
OK.I will post an updated version of this patch series soon.
Thanks and Regards,
Chaithrika
> WBR, Sergei
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH 1/3] i2c: davinci: Add helper functions
[not found] ` <4B1D4850.7010108-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
@ 2009-12-08 4:46 ` Chaithrika U S
0 siblings, 0 replies; 8+ messages in thread
From: Chaithrika U S @ 2009-12-08 4:46 UTC (permalink / raw)
To: 'Troy Kisky'
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/
On Mon, Dec 07, 2009 at 23:54:16, Troy Kisky wrote:
> Chaithrika U S wrote:
> > Add i2c reset control and clock divider calculation functions
> > which will be useful for power management features.
> >
> > Signed-off-by: Chaithrika U S <chaithrika-l0cyMroinI0@public.gmane.org>
> > ---
> > drivers/i2c/busses/i2c-davinci.c | 56 +++++++++++++++++++++++++-------------
> > 1 files changed, 37 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> > index c89687a..5f3838c 100644
> > --- a/drivers/i2c/busses/i2c-davinci.c
> > +++ b/drivers/i2c/busses/i2c-davinci.c
> > @@ -133,12 +133,21 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
> > return __raw_readw(i2c_dev->base + reg);
> > }
> >
> > -/*
> > - * This functions configures I2C and brings I2C out of reset.
> > - * This function is called during I2C init function. This function
> > - * also gets called if I2C encounters any errors.
> > - */
> > -static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> > +static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
> > + int val)
> > +{
> > + u16 w;
> > +
> > + w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
> > + if (!val) /* put I2C into reset */
> > + MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
> > + else /* take I2C out of reset */
> > + MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
> > +
>
>
> I dislike the MOD_REG_BIT macro. Maybe if you wrote
> MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, val);
>
> it would be slightly better, but I still wouldn't like it.
> Please use w &= ~DAVINCI_I2C_MDR_IRS and
> w |= DAVINCI_I2C_MDR_IRS directly.
>
>
> I know the code you're replacing uses this obfuscating macro
> but this is a good time to remove it.
>
>
Agree. Will include a patch to remove this macro in the next version of this
patch set.
Regards,
Chaithrika
> > + davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
> > +}
> > +
> > +static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
> > {
> > struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
> > u16 psc;
> > @@ -147,15 +156,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> > u32 clkh;
> > u32 clkl;
> > u32 input_clock = clk_get_rate(dev->clk);
> > - u16 w;
> > -
> > - if (!pdata)
> > - pdata = &davinci_i2c_platform_data_default;
> > -
> > - /* put I2C into reset */
> > - w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
> > - MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
> > - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
> >
> > /* NOTE: I2C Clock divider programming info
> > * As per I2C specs the following formulas provide prescaler
> > @@ -187,12 +187,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> > davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
> > davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
> >
> > + dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
> > +}
> > +
> > +/*
> > + * This functions configures I2C and brings I2C out of reset.
> > + * This function is called during I2C init function. This function
> > + * also gets called if I2C encounters any errors.
> > + */
> > +static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> > +{
> > + struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
> > +
> > + if (!pdata)
> > + pdata = &davinci_i2c_platform_data_default;
> > +
> > + /* put I2C into reset */
> > + davinci_i2c_reset_ctrl(dev, 0);
> > +
> > + /* compute clock dividers */
> > + i2c_davinci_calc_clk_dividers(dev);
> > +
> > /* Respond at reserved "SMBus Host" slave address" (and zero);
> > * we seem to have no option to not respond...
> > */
> > davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
> >
> > - dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
> > dev_dbg(dev->dev, "PSC = %d\n",
> > davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
> > dev_dbg(dev->dev, "CLKL = %d\n",
> > @@ -203,9 +223,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> > pdata->bus_freq, pdata->bus_delay);
> >
> > /* Take the I2C module out of reset: */
> > - w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
> > - MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
> > - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
> > + davinci_i2c_reset_ctrl(dev, 1);
> >
> > /* Enable interrupts */
> > davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-12-08 4:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-07 9:28 [PATCH 0/3] i2c: davinci: Add power management features Chaithrika U S
[not found] ` <1260178136-26416-1-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
2009-12-07 9:28 ` [PATCH 1/3] i2c: davinci: Add helper functions Chaithrika U S
[not found] ` <1260178136-26416-2-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
2009-12-07 9:28 ` [PATCH 2/3] i2c: davinci: Add suspend/resume support Chaithrika U S
[not found] ` <1260178136-26416-3-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
2009-12-07 9:28 ` [PATCH 3/3] i2c: davinci: Add cpufreq support Chaithrika U S
[not found] ` <1260178136-26416-4-git-send-email-chaithrika-l0cyMroinI0@public.gmane.org>
2009-12-07 11:00 ` Sergei Shtylyov
[not found] ` <4B1CE03E.7040608-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
2009-12-08 4:38 ` Chaithrika U S
2009-12-07 18:24 ` [PATCH 1/3] i2c: davinci: Add helper functions Troy Kisky
[not found] ` <4B1D4850.7010108-Q5RJGjKts06CY9SHAMCTRUEOCMrvLtNR@public.gmane.org>
2009-12-08 4:46 ` Chaithrika U S
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).