* [PATCH 1/4] i2c: davinci: Preserve return value of devm_clk_get
2017-08-02 22:17 [PATCH 0/4] ARM: dts: keystone-k2g: Add I2C support for 66AK2G Franklin S Cooper Jr
@ 2017-08-02 22:17 ` Franklin S Cooper Jr
2017-08-11 22:00 ` Grygorii Strashko
2017-08-02 22:17 ` [PATCH 2/4] i2c: davinci: Add PM Runtime Support Franklin S Cooper Jr
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Franklin S Cooper Jr @ 2017-08-02 22:17 UTC (permalink / raw)
To: wsa, robh+dt, linux, nsekhar, linux-i2c, devicetree,
linux-kernel, linux-arm-kernel
Cc: Franklin S Cooper Jr
The i2c driver can run into driver dependency issues if its loaded
before a clock driver it depends on. Therefore, EPROBE_DEFER may be
returned by devm_clk_get and should be returned in probe to allow the
kernel to reprobe the driver at a later time. This patch allows the error
value returned by devm_clk_get to be passed through and not overwritten.
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
drivers/i2c/busses/i2c-davinci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 9e7ef5c..5749aac 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -801,7 +801,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
dev->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk))
- return -ENODEV;
+ return PTR_ERR(dev->clk);
clk_prepare_enable(dev->clk);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--
2.9.4.dirty
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 2/4] i2c: davinci: Add PM Runtime Support
2017-08-02 22:17 [PATCH 0/4] ARM: dts: keystone-k2g: Add I2C support for 66AK2G Franklin S Cooper Jr
2017-08-02 22:17 ` [PATCH 1/4] i2c: davinci: Preserve return value of devm_clk_get Franklin S Cooper Jr
@ 2017-08-02 22:17 ` Franklin S Cooper Jr
2017-08-11 22:11 ` Grygorii Strashko
2017-08-02 22:17 ` [PATCH 3/4] dt-bindings: i2c: i2c-davinci: Update binding for 66AK2Gx pwr dm property Franklin S Cooper Jr
2017-08-02 22:17 ` [PATCH 4/4] ARM: dts: keystone-k2g: Add I2C nodes Franklin S Cooper Jr
3 siblings, 1 reply; 9+ messages in thread
From: Franklin S Cooper Jr @ 2017-08-02 22:17 UTC (permalink / raw)
To: wsa, robh+dt, linux, nsekhar, linux-i2c, devicetree,
linux-kernel, linux-arm-kernel
Cc: Franklin S Cooper Jr
This patch adds PM runtime support to the I2C Davinci driver.
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
drivers/i2c/busses/i2c-davinci.c | 61 ++++++++++++++++++++++++++++++++++------
1 file changed, 53 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 5749aac..62ff869 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -36,6 +36,7 @@
#include <linux/gpio.h>
#include <linux/of_device.h>
#include <linux/platform_data/i2c-davinci.h>
+#include <linux/pm_runtime.h>
/* ----- global defines ----------------------------------------------- */
@@ -122,6 +123,9 @@
/* set the SDA GPIO low */
#define DAVINCI_I2C_DCLR_PDCLR1 BIT(1)
+/* timeout for pm runtime autosuspend */
+#define DAVINCI_I2C_PM_TIMEOUT 1000 /* ms */
+
struct davinci_i2c_dev {
struct device *dev;
void __iomem *base;
@@ -541,10 +545,17 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
+ ret = pm_runtime_get_sync(dev->dev);
+ if (ret < 0) {
+ dev_err(dev->dev, "Failed to runtime_get device: %d\n", ret);
+ pm_runtime_put_noidle(dev->dev);
+ return ret;
+ }
+
ret = i2c_davinci_wait_bus_not_busy(dev);
if (ret < 0) {
dev_warn(dev->dev, "timeout waiting for bus ready\n");
- return ret;
+ goto out;
}
for (i = 0; i < num; i++) {
@@ -552,14 +563,19 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
dev_dbg(dev->dev, "%s [%d/%d] ret: %d\n", __func__, i + 1, num,
ret);
if (ret < 0)
- return ret;
+ goto out;
}
+ ret = num;
#ifdef CONFIG_CPU_FREQ
complete(&dev->xfr_complete);
#endif
- return num;
+out:
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+
+ return ret;
}
static u32 i2c_davinci_func(struct i2c_adapter *adap)
@@ -599,6 +615,9 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
int count = 0;
u16 w;
+ if (pm_runtime_suspended(dev->dev))
+ return IRQ_NONE;
+
while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat);
if (count++ == 100) {
@@ -802,7 +821,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
dev->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk))
return PTR_ERR(dev->clk);
- clk_prepare_enable(dev->clk);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->base = devm_ioremap_resource(&pdev->dev, mem);
@@ -811,6 +829,17 @@ static int davinci_i2c_probe(struct platform_device *pdev)
goto err_unuse_clocks;
}
+ pm_runtime_enable(dev->dev);
+ pm_runtime_set_autosuspend_delay(dev->dev,
+ DAVINCI_I2C_PM_TIMEOUT);
+ pm_runtime_use_autosuspend(dev->dev);
+
+ r = pm_runtime_get_sync(dev->dev);
+ if (r < 0) {
+ dev_err(dev->dev, "failed to runtime_get device: %d\n", r);
+ goto err_unuse_clocks;
+ }
+
i2c_davinci_init(dev);
r = devm_request_irq(&pdev->dev, dev->irq, i2c_davinci_isr, 0,
@@ -849,10 +878,16 @@ static int davinci_i2c_probe(struct platform_device *pdev)
if (r)
goto err_unuse_clocks;
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+
return 0;
err_unuse_clocks:
- clk_disable_unprepare(dev->clk);
+ pm_runtime_dont_use_autosuspend(dev->dev);
+ pm_runtime_put_sync(dev->dev);
+ pm_runtime_disable(dev->dev);
+
dev->clk = NULL;
return r;
}
@@ -860,16 +895,26 @@ static int davinci_i2c_probe(struct platform_device *pdev)
static int davinci_i2c_remove(struct platform_device *pdev)
{
struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
+ int ret;
i2c_davinci_cpufreq_deregister(dev);
i2c_del_adapter(&dev->adapter);
- clk_disable_unprepare(dev->clk);
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(&pdev->dev);
+ return ret;
+ }
+
dev->clk = NULL;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0);
+ pm_runtime_dont_use_autosuspend(dev->dev);
+ pm_runtime_put_sync(dev->dev);
+ pm_runtime_disable(dev->dev);
+
return 0;
}
@@ -881,7 +926,6 @@ static int davinci_i2c_suspend(struct device *dev)
/* put I2C into reset */
davinci_i2c_reset_ctrl(i2c_dev, 0);
- clk_disable_unprepare(i2c_dev->clk);
return 0;
}
@@ -891,7 +935,6 @@ static int davinci_i2c_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
- clk_prepare_enable(i2c_dev->clk);
/* take I2C out of reset */
davinci_i2c_reset_ctrl(i2c_dev, 1);
@@ -901,6 +944,8 @@ static int davinci_i2c_resume(struct device *dev)
static const struct dev_pm_ops davinci_i2c_pm = {
.suspend = davinci_i2c_suspend,
.resume = davinci_i2c_resume,
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
};
#define davinci_i2c_pm_ops (&davinci_i2c_pm)
--
2.9.4.dirty
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 3/4] dt-bindings: i2c: i2c-davinci: Update binding for 66AK2Gx pwr dm property
2017-08-02 22:17 [PATCH 0/4] ARM: dts: keystone-k2g: Add I2C support for 66AK2G Franklin S Cooper Jr
2017-08-02 22:17 ` [PATCH 1/4] i2c: davinci: Preserve return value of devm_clk_get Franklin S Cooper Jr
2017-08-02 22:17 ` [PATCH 2/4] i2c: davinci: Add PM Runtime Support Franklin S Cooper Jr
@ 2017-08-02 22:17 ` Franklin S Cooper Jr
2017-08-10 16:36 ` Rob Herring
2017-08-02 22:17 ` [PATCH 4/4] ARM: dts: keystone-k2g: Add I2C nodes Franklin S Cooper Jr
3 siblings, 1 reply; 9+ messages in thread
From: Franklin S Cooper Jr @ 2017-08-02 22:17 UTC (permalink / raw)
To: wsa, robh+dt, linux, nsekhar, linux-i2c, devicetree,
linux-kernel, linux-arm-kernel
Cc: Franklin S Cooper Jr
Add pm-domains property which is required for 66AK2Gx. Also document 66AK2G
unique clocks property usage.
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
---
Documentation/devicetree/bindings/i2c/i2c-davinci.txt | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-davinci.txt b/Documentation/devicetree/bindings/i2c/i2c-davinci.txt
index 5b123e0..64e6e65 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-davinci.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-davinci.txt
@@ -6,6 +6,18 @@ davinci/keystone i2c interface contains.
Required properties:
- compatible: "ti,davinci-i2c" or "ti,keystone-i2c";
- reg : Offset and length of the register set for the device
+- clocks: I2C functional clock phandle.
+ For 66AK2G this property should be set per binding,
+ Documentation/devicetree/bindings/clock/ti,sci-clk.txt
+
+SoC-specific Required Properties:
+
+The following are mandatory properties for Keystone 2 66AK2G SoCs only:
+
+- power-domains: Should contain a phandle to a PM domain provider node
+ and an args specifier containing the I2C device id
+ value. This property is as per the binding,
+ Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
Recommended properties :
- interrupts : standard interrupt property.
--
2.9.4.dirty
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/4] ARM: dts: keystone-k2g: Add I2C nodes
2017-08-02 22:17 [PATCH 0/4] ARM: dts: keystone-k2g: Add I2C support for 66AK2G Franklin S Cooper Jr
` (2 preceding siblings ...)
2017-08-02 22:17 ` [PATCH 3/4] dt-bindings: i2c: i2c-davinci: Update binding for 66AK2Gx pwr dm property Franklin S Cooper Jr
@ 2017-08-02 22:17 ` Franklin S Cooper Jr
2017-08-11 22:18 ` Grygorii Strashko
3 siblings, 1 reply; 9+ messages in thread
From: Franklin S Cooper Jr @ 2017-08-02 22:17 UTC (permalink / raw)
To: wsa, robh+dt, linux, nsekhar, linux-i2c, devicetree,
linux-kernel, linux-arm-kernel
Cc: Vitaly Andrianov, Dave Gerlach, Franklin S Cooper Jr
From: Vitaly Andrianov <vitalya@ti.com>
Add nodes for the various I2C instances.
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
[d-gerlach@ti.com: Add power domain and clock properties]
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
[fcooper@ti.com: Update subject and commit message]
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
---
arch/arm/boot/dts/keystone-k2g.dtsi | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
index bf4d1fa..5c0acf37 100644
--- a/arch/arm/boot/dts/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/keystone-k2g.dtsi
@@ -27,6 +27,9 @@
aliases {
serial0 = &uart0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
};
cpus {
@@ -113,6 +116,39 @@
status = "disabled";
};
+ i2c0: i2c@2530000 {
+ compatible = "ti,keystone-i2c";
+ reg = <0x02530000 0x400>;
+ clocks = <&k2g_clks 0x003a 0>;
+ power-domains = <&k2g_pds 0x003a>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@2530400 {
+ compatible = "ti,keystone-i2c";
+ reg = <0x02530400 0x400>;
+ clocks = <&k2g_clks 0x003b 0>;
+ power-domains = <&k2g_pds 0x003b>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@2530800 {
+ compatible = "ti,keystone-i2c";
+ reg = <0x02530800 0x400>;
+ clocks = <&k2g_clks 0x003c 0>;
+ power-domains = <&k2g_pds 0x003c>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
kirq0: keystone_irq@026202a0 {
compatible = "ti,keystone-irq";
interrupts = <GIC_SPI 1 IRQ_TYPE_EDGE_RISING>;
--
2.9.4.dirty
^ permalink raw reply [flat|nested] 9+ messages in thread