Message ID | 1542365396-9959-1-git-send-email-pierre-yves.mordret@st.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v1] i2c: i2c-stm32f7: add PM Runtime support | expand |
Hi Pierre-Yves, I love your patch! Yet something to improve: [auto build test ERROR on wsa/i2c/for-next] [also build test ERROR on v4.20-rc2 next-20181116] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Pierre-Yves-MORDRET/i2c-i2c-stm32f7-add-PM-Runtime-support/20181118-230534 base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next config: xtensa-allyesconfig (attached as .config) compiler: xtensa-linux-gcc (GCC) 8.1.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=8.1.0 make.cross ARCH=xtensa All errors (new ones prefixed by >>): drivers/i2c/busses/i2c-stm32f7.c: In function 'stm32f7_i2c_probe': >> drivers/i2c/busses/i2c-stm32f7.c:1913:7: error: 'STM32F7_AUTOSUSPEND_DELAY' undeclared (first use in this function); did you mean 'RPM_REQ_AUTOSUSPEND'? STM32F7_AUTOSUSPEND_DELAY); ^~~~~~~~~~~~~~~~~~~~~~~~~ RPM_REQ_AUTOSUSPEND drivers/i2c/busses/i2c-stm32f7.c:1913:7: note: each undeclared identifier is reported only once for each function it appears in vim +1913 drivers/i2c/busses/i2c-stm32f7.c 1782 1783 static int stm32f7_i2c_probe(struct platform_device *pdev) 1784 { 1785 struct device_node *np = pdev->dev.of_node; 1786 struct stm32f7_i2c_dev *i2c_dev; 1787 const struct stm32f7_i2c_setup *setup; 1788 struct resource *res; 1789 u32 irq_error, irq_event, clk_rate, rise_time, fall_time; 1790 struct i2c_adapter *adap; 1791 struct reset_control *rst; 1792 dma_addr_t phy_addr; 1793 int ret; 1794 1795 i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); 1796 if (!i2c_dev) 1797 return -ENOMEM; 1798 1799 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1800 i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); 1801 if (IS_ERR(i2c_dev->base)) 1802 return PTR_ERR(i2c_dev->base); 1803 phy_addr = (dma_addr_t)res->start; 1804 1805 irq_event = irq_of_parse_and_map(np, 0); 1806 if (!irq_event) { 1807 dev_err(&pdev->dev, "IRQ event missing or invalid\n"); 1808 return -EINVAL; 1809 } 1810 1811 irq_error = irq_of_parse_and_map(np, 1); 1812 if (!irq_error) { 1813 dev_err(&pdev->dev, "IRQ error missing or invalid\n"); 1814 return -EINVAL; 1815 } 1816 1817 i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); 1818 if (IS_ERR(i2c_dev->clk)) { 1819 dev_err(&pdev->dev, "Error: Missing controller clock\n"); 1820 return PTR_ERR(i2c_dev->clk); 1821 } 1822 1823 ret = clk_prepare_enable(i2c_dev->clk); 1824 if (ret) { 1825 dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); 1826 return ret; 1827 } 1828 1829 i2c_dev->speed = STM32_I2C_SPEED_STANDARD; 1830 ret = device_property_read_u32(&pdev->dev, "clock-frequency", 1831 &clk_rate); 1832 if (!ret && clk_rate >= 1000000) 1833 i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS; 1834 else if (!ret && clk_rate >= 400000) 1835 i2c_dev->speed = STM32_I2C_SPEED_FAST; 1836 else if (!ret && clk_rate >= 100000) 1837 i2c_dev->speed = STM32_I2C_SPEED_STANDARD; 1838 1839 rst = devm_reset_control_get(&pdev->dev, NULL); 1840 if (IS_ERR(rst)) { 1841 dev_err(&pdev->dev, "Error: Missing controller reset\n"); 1842 ret = PTR_ERR(rst); 1843 goto clk_free; 1844 } 1845 reset_control_assert(rst); 1846 udelay(2); 1847 reset_control_deassert(rst); 1848 1849 i2c_dev->dev = &pdev->dev; 1850 1851 ret = devm_request_threaded_irq(&pdev->dev, irq_event, 1852 stm32f7_i2c_isr_event, 1853 stm32f7_i2c_isr_event_thread, 1854 IRQF_ONESHOT, 1855 pdev->name, i2c_dev); 1856 if (ret) { 1857 dev_err(&pdev->dev, "Failed to request irq event %i\n", 1858 irq_event); 1859 goto clk_free; 1860 } 1861 1862 ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0, 1863 pdev->name, i2c_dev); 1864 if (ret) { 1865 dev_err(&pdev->dev, "Failed to request irq error %i\n", 1866 irq_error); 1867 goto clk_free; 1868 } 1869 1870 setup = of_device_get_match_data(&pdev->dev); 1871 if (!setup) { 1872 dev_err(&pdev->dev, "Can't get device data\n"); 1873 ret = -ENODEV; 1874 goto clk_free; 1875 } 1876 i2c_dev->setup = *setup; 1877 1878 ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns", 1879 &rise_time); 1880 if (!ret) 1881 i2c_dev->setup.rise_time = rise_time; 1882 1883 ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-falling-time-ns", 1884 &fall_time); 1885 if (!ret) 1886 i2c_dev->setup.fall_time = fall_time; 1887 1888 ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup); 1889 if (ret) 1890 goto clk_free; 1891 1892 adap = &i2c_dev->adap; 1893 i2c_set_adapdata(adap, i2c_dev); 1894 snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", 1895 &res->start); 1896 adap->owner = THIS_MODULE; 1897 adap->timeout = 2 * HZ; 1898 adap->retries = 3; 1899 adap->algo = &stm32f7_i2c_algo; 1900 adap->dev.parent = &pdev->dev; 1901 adap->dev.of_node = pdev->dev.of_node; 1902 1903 init_completion(&i2c_dev->complete); 1904 1905 /* Init DMA config if supported */ 1906 i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr, 1907 STM32F7_I2C_TXDR, 1908 STM32F7_I2C_RXDR); 1909 1910 platform_set_drvdata(pdev, i2c_dev); 1911 1912 pm_runtime_set_autosuspend_delay(i2c_dev->dev, > 1913 STM32F7_AUTOSUSPEND_DELAY); 1914 pm_runtime_use_autosuspend(i2c_dev->dev); 1915 pm_runtime_set_active(i2c_dev->dev); 1916 pm_runtime_enable(i2c_dev->dev); 1917 1918 pm_runtime_get_noresume(&pdev->dev); 1919 1920 stm32f7_i2c_hw_config(i2c_dev); 1921 1922 ret = i2c_add_adapter(adap); 1923 if (ret) 1924 goto pm_disable; 1925 1926 dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); 1927 1928 pm_runtime_mark_last_busy(i2c_dev->dev); 1929 pm_runtime_put_autosuspend(i2c_dev->dev); 1930 1931 return 0; 1932 1933 pm_disable: 1934 pm_runtime_put_noidle(i2c_dev->dev); 1935 pm_runtime_disable(i2c_dev->dev); 1936 pm_runtime_set_suspended(i2c_dev->dev); 1937 pm_runtime_dont_use_autosuspend(i2c_dev->dev); 1938 1939 clk_free: 1940 clk_disable_unprepare(i2c_dev->clk); 1941 1942 return ret; 1943 } 1944 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Pierre-Yves, I love your patch! Yet something to improve: [auto build test ERROR on wsa/i2c/for-next] [also build test ERROR on v4.20-rc2 next-20181116] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Pierre-Yves-MORDRET/i2c-i2c-stm32f7-add-PM-Runtime-support/20181118-230534 base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next config: nds32-allmodconfig (attached as .config) compiler: nds32le-linux-gcc (GCC) 6.4.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=6.4.0 make.cross ARCH=nds32 All errors (new ones prefixed by >>): drivers/i2c/busses/i2c-stm32f7.c: In function 'stm32f7_i2c_probe': >> drivers/i2c/busses/i2c-stm32f7.c:1913:7: error: 'STM32F7_AUTOSUSPEND_DELAY' undeclared (first use in this function) STM32F7_AUTOSUSPEND_DELAY); ^~~~~~~~~~~~~~~~~~~~~~~~~ drivers/i2c/busses/i2c-stm32f7.c:1913:7: note: each undeclared identifier is reported only once for each function it appears in vim +/STM32F7_AUTOSUSPEND_DELAY +1913 drivers/i2c/busses/i2c-stm32f7.c 1782 1783 static int stm32f7_i2c_probe(struct platform_device *pdev) 1784 { 1785 struct device_node *np = pdev->dev.of_node; 1786 struct stm32f7_i2c_dev *i2c_dev; 1787 const struct stm32f7_i2c_setup *setup; 1788 struct resource *res; 1789 u32 irq_error, irq_event, clk_rate, rise_time, fall_time; 1790 struct i2c_adapter *adap; 1791 struct reset_control *rst; 1792 dma_addr_t phy_addr; 1793 int ret; 1794 1795 i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); 1796 if (!i2c_dev) 1797 return -ENOMEM; 1798 1799 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1800 i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); 1801 if (IS_ERR(i2c_dev->base)) 1802 return PTR_ERR(i2c_dev->base); 1803 phy_addr = (dma_addr_t)res->start; 1804 1805 irq_event = irq_of_parse_and_map(np, 0); 1806 if (!irq_event) { 1807 dev_err(&pdev->dev, "IRQ event missing or invalid\n"); 1808 return -EINVAL; 1809 } 1810 1811 irq_error = irq_of_parse_and_map(np, 1); 1812 if (!irq_error) { 1813 dev_err(&pdev->dev, "IRQ error missing or invalid\n"); 1814 return -EINVAL; 1815 } 1816 1817 i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); 1818 if (IS_ERR(i2c_dev->clk)) { 1819 dev_err(&pdev->dev, "Error: Missing controller clock\n"); 1820 return PTR_ERR(i2c_dev->clk); 1821 } 1822 1823 ret = clk_prepare_enable(i2c_dev->clk); 1824 if (ret) { 1825 dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); 1826 return ret; 1827 } 1828 1829 i2c_dev->speed = STM32_I2C_SPEED_STANDARD; 1830 ret = device_property_read_u32(&pdev->dev, "clock-frequency", 1831 &clk_rate); 1832 if (!ret && clk_rate >= 1000000) 1833 i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS; 1834 else if (!ret && clk_rate >= 400000) 1835 i2c_dev->speed = STM32_I2C_SPEED_FAST; 1836 else if (!ret && clk_rate >= 100000) 1837 i2c_dev->speed = STM32_I2C_SPEED_STANDARD; 1838 1839 rst = devm_reset_control_get(&pdev->dev, NULL); 1840 if (IS_ERR(rst)) { 1841 dev_err(&pdev->dev, "Error: Missing controller reset\n"); 1842 ret = PTR_ERR(rst); 1843 goto clk_free; 1844 } 1845 reset_control_assert(rst); 1846 udelay(2); 1847 reset_control_deassert(rst); 1848 1849 i2c_dev->dev = &pdev->dev; 1850 1851 ret = devm_request_threaded_irq(&pdev->dev, irq_event, 1852 stm32f7_i2c_isr_event, 1853 stm32f7_i2c_isr_event_thread, 1854 IRQF_ONESHOT, 1855 pdev->name, i2c_dev); 1856 if (ret) { 1857 dev_err(&pdev->dev, "Failed to request irq event %i\n", 1858 irq_event); 1859 goto clk_free; 1860 } 1861 1862 ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0, 1863 pdev->name, i2c_dev); 1864 if (ret) { 1865 dev_err(&pdev->dev, "Failed to request irq error %i\n", 1866 irq_error); 1867 goto clk_free; 1868 } 1869 1870 setup = of_device_get_match_data(&pdev->dev); 1871 if (!setup) { 1872 dev_err(&pdev->dev, "Can't get device data\n"); 1873 ret = -ENODEV; 1874 goto clk_free; 1875 } 1876 i2c_dev->setup = *setup; 1877 1878 ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns", 1879 &rise_time); 1880 if (!ret) 1881 i2c_dev->setup.rise_time = rise_time; 1882 1883 ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-falling-time-ns", 1884 &fall_time); 1885 if (!ret) 1886 i2c_dev->setup.fall_time = fall_time; 1887 1888 ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup); 1889 if (ret) 1890 goto clk_free; 1891 1892 adap = &i2c_dev->adap; 1893 i2c_set_adapdata(adap, i2c_dev); 1894 snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", 1895 &res->start); 1896 adap->owner = THIS_MODULE; 1897 adap->timeout = 2 * HZ; 1898 adap->retries = 3; 1899 adap->algo = &stm32f7_i2c_algo; 1900 adap->dev.parent = &pdev->dev; 1901 adap->dev.of_node = pdev->dev.of_node; 1902 1903 init_completion(&i2c_dev->complete); 1904 1905 /* Init DMA config if supported */ 1906 i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr, 1907 STM32F7_I2C_TXDR, 1908 STM32F7_I2C_RXDR); 1909 1910 platform_set_drvdata(pdev, i2c_dev); 1911 1912 pm_runtime_set_autosuspend_delay(i2c_dev->dev, > 1913 STM32F7_AUTOSUSPEND_DELAY); 1914 pm_runtime_use_autosuspend(i2c_dev->dev); 1915 pm_runtime_set_active(i2c_dev->dev); 1916 pm_runtime_enable(i2c_dev->dev); 1917 1918 pm_runtime_get_noresume(&pdev->dev); 1919 1920 stm32f7_i2c_hw_config(i2c_dev); 1921 1922 ret = i2c_add_adapter(adap); 1923 if (ret) 1924 goto pm_disable; 1925 1926 dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); 1927 1928 pm_runtime_mark_last_busy(i2c_dev->dev); 1929 pm_runtime_put_autosuspend(i2c_dev->dev); 1930 1931 return 0; 1932 1933 pm_disable: 1934 pm_runtime_put_noidle(i2c_dev->dev); 1935 pm_runtime_disable(i2c_dev->dev); 1936 pm_runtime_set_suspended(i2c_dev->dev); 1937 pm_runtime_dont_use_autosuspend(i2c_dev->dev); 1938 1939 clk_free: 1940 clk_disable_unprepare(i2c_dev->clk); 1941 1942 return ret; 1943 } 1944 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 62d023e..4623b82 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -27,6 +27,8 @@ #include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/platform_device.h> +#include <linux/pinctrl/consumer.h> +#include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/slab.h> @@ -1545,15 +1547,13 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, i2c_dev->msg_id = 0; f7_msg->smbus = false; - ret = clk_enable(i2c_dev->clk); - if (ret) { - dev_err(i2c_dev->dev, "Failed to enable clock\n"); + ret = pm_runtime_get_sync(i2c_dev->dev); + if (ret < 0) return ret; - } ret = stm32f7_i2c_wait_free_bus(i2c_dev); if (ret) - goto clk_free; + goto pm_free; stm32f7_i2c_xfer_msg(i2c_dev, msgs); @@ -1569,8 +1569,9 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, ret = -ETIMEDOUT; } -clk_free: - clk_disable(i2c_dev->clk); +pm_free: + pm_runtime_mark_last_busy(i2c_dev->dev); + pm_runtime_put_autosuspend(i2c_dev->dev); return (ret < 0) ? ret : num; } @@ -1592,39 +1593,37 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, f7_msg->read_write = read_write; f7_msg->smbus = true; - ret = clk_enable(i2c_dev->clk); - if (ret) { - dev_err(i2c_dev->dev, "Failed to enable clock\n"); + ret = pm_runtime_get_sync(dev); + if (ret < 0) return ret; - } ret = stm32f7_i2c_wait_free_bus(i2c_dev); if (ret) - goto clk_free; + goto pm_free; ret = stm32f7_i2c_smbus_xfer_msg(i2c_dev, flags, command, data); if (ret) - goto clk_free; + goto pm_free; timeout = wait_for_completion_timeout(&i2c_dev->complete, i2c_dev->adap.timeout); ret = f7_msg->result; if (ret) - goto clk_free; + goto pm_free; if (!timeout) { dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); if (i2c_dev->use_dma) dmaengine_terminate_all(dma->chan_using); ret = -ETIMEDOUT; - goto clk_free; + goto pm_free; } /* Check PEC */ if ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && read_write) { ret = stm32f7_i2c_smbus_check_pec(i2c_dev); if (ret) - goto clk_free; + goto pm_free; } if (read_write && size != I2C_SMBUS_QUICK) { @@ -1649,8 +1648,9 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, } } -clk_free: - clk_disable(i2c_dev->clk); +pm_free: + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return ret; } @@ -1676,13 +1676,9 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) if (ret) return ret; - if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) { - ret = clk_enable(i2c_dev->clk); - if (ret) { - dev_err(dev, "Failed to enable clock\n"); - return ret; - } - } + ret = pm_runtime_get_sync(dev); + if (ret < 0) + return ret; if (id == 0) { /* Configure Own Address 1 */ @@ -1703,7 +1699,7 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) oar2 &= ~STM32F7_I2C_OAR2_MASK; if (slave->flags & I2C_CLIENT_TEN) { ret = -EOPNOTSUPP; - goto exit; + goto pm_free; } oar2 |= STM32F7_I2C_OAR2_OA2_7(slave->addr); @@ -1712,7 +1708,7 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) writel_relaxed(oar2, i2c_dev->base + STM32F7_I2C_OAR2); } else { ret = -ENODEV; - goto exit; + goto pm_free; } /* Enable ACK */ @@ -1723,11 +1719,10 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) STM32F7_I2C_CR1_PE; stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask); - return 0; - -exit: - if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) - clk_disable(i2c_dev->clk); + ret = 0; +pm_free: + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return ret; } @@ -1745,6 +1740,10 @@ static int stm32f7_i2c_unreg_slave(struct i2c_client *slave) WARN_ON(!i2c_dev->slave[id]); + ret = pm_runtime_get_sync(i2c_dev->dev); + if (ret < 0) + return ret; + if (id == 0) { mask = STM32F7_I2C_OAR1_OA1EN; stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR1, mask); @@ -1755,10 +1754,11 @@ static int stm32f7_i2c_unreg_slave(struct i2c_client *slave) i2c_dev->slave[id] = NULL; - if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) { + if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); - clk_disable(i2c_dev->clk); - } + + pm_runtime_mark_last_busy(i2c_dev->dev); + pm_runtime_put_autosuspend(i2c_dev->dev); return 0; } @@ -1819,6 +1819,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Error: Missing controller clock\n"); return PTR_ERR(i2c_dev->clk); } + ret = clk_prepare_enable(i2c_dev->clk); if (ret) { dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); @@ -1888,8 +1889,6 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) if (ret) goto clk_free; - stm32f7_i2c_hw_config(i2c_dev); - adap = &i2c_dev->adap; i2c_set_adapdata(adap, i2c_dev); snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", @@ -1908,18 +1907,35 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) STM32F7_I2C_TXDR, STM32F7_I2C_RXDR); - ret = i2c_add_adapter(adap); - if (ret) - goto clk_free; - platform_set_drvdata(pdev, i2c_dev); - clk_disable(i2c_dev->clk); + pm_runtime_set_autosuspend_delay(i2c_dev->dev, + STM32F7_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(i2c_dev->dev); + pm_runtime_set_active(i2c_dev->dev); + pm_runtime_enable(i2c_dev->dev); + + pm_runtime_get_noresume(&pdev->dev); + + stm32f7_i2c_hw_config(i2c_dev); + + ret = i2c_add_adapter(adap); + if (ret) + goto pm_disable; dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); + pm_runtime_mark_last_busy(i2c_dev->dev); + pm_runtime_put_autosuspend(i2c_dev->dev); + return 0; +pm_disable: + pm_runtime_put_noidle(i2c_dev->dev); + pm_runtime_disable(i2c_dev->dev); + pm_runtime_set_suspended(i2c_dev->dev); + pm_runtime_dont_use_autosuspend(i2c_dev->dev); + clk_free: clk_disable_unprepare(i2c_dev->clk); @@ -1936,12 +1952,51 @@ static int stm32f7_i2c_remove(struct platform_device *pdev) } i2c_del_adapter(&i2c_dev->adap); + pm_runtime_get_sync(i2c_dev->dev); + + clk_disable_unprepare(i2c_dev->clk); - clk_unprepare(i2c_dev->clk); + pm_runtime_put_noidle(i2c_dev->dev); + pm_runtime_disable(i2c_dev->dev); + pm_runtime_set_suspended(i2c_dev->dev); + pm_runtime_dont_use_autosuspend(i2c_dev->dev); return 0; } +#ifdef CONFIG_PM +static int stm32f7_i2c_runtime_suspend(struct device *dev) +{ + struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); + + if (!stm32f7_i2c_is_slave_registered(i2c_dev)) + clk_disable_unprepare(i2c_dev->clk); + + return 0; +} + +static int stm32f7_i2c_runtime_resume(struct device *dev) +{ + struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); + int ret; + + if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { + ret = clk_prepare_enable(i2c_dev->clk); + if (ret) { + dev_err(dev, "failed to prepare_enable clock\n"); + return ret; + } + } + + return 0; +} +#endif + +static const struct dev_pm_ops stm32f7_i2c_pm_ops = { + SET_RUNTIME_PM_OPS(stm32f7_i2c_runtime_suspend, + stm32f7_i2c_runtime_resume, NULL) +}; + static const struct of_device_id stm32f7_i2c_match[] = { { .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup}, {}, @@ -1952,6 +2007,7 @@ static struct platform_driver stm32f7_i2c_driver = { .driver = { .name = "stm32f7-i2c", .of_match_table = stm32f7_i2c_match, + .pm = &stm32f7_i2c_pm_ops, }, .probe = stm32f7_i2c_probe, .remove = stm32f7_i2c_remove,
Use PM Runtime API to enable/disable clock Signed-off-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com> --- Version history: v1: * Initial --- --- drivers/i2c/busses/i2c-stm32f7.c | 142 +++++++++++++++++++++++++++------------ 1 file changed, 99 insertions(+), 43 deletions(-)