Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: stm32f7: disable/restore Fast Mode Plus bits in low power modes

Defer the initial enabling of the Fast Mode Plus bits after the
stm32f7_i2c_setup_timing call in probe function in order to avoid
enabling them if speed is downgraded.
Clear & restore the Fast Mode Plus bits in the suspend/resume
handlers of the driver.

Signed-off-by: Alain Volmat <alain.volmat@st.com>
Reviewed-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Alain Volmat and committed by
Wolfram Sang
3347ea9b d31f59ea

+39 -13
+39 -13
drivers/i2c/busses/i2c-stm32f7.c
··· 303 303 * @dma: dma data 304 304 * @use_dma: boolean to know if dma is used in the current transfer 305 305 * @regmap: holds SYSCFG phandle for Fast Mode Plus bits 306 + * @fmp_reg: register address for setting Fast Mode Plus bits 307 + * @fmp_mask: mask for Fast Mode Plus bits in set register 306 308 * @wakeup_src: boolean to know if the device is a wakeup source 307 309 */ 308 310 struct stm32f7_i2c_dev { ··· 328 326 struct stm32_i2c_dma *dma; 329 327 bool use_dma; 330 328 struct regmap *regmap; 329 + u32 fmp_reg; 330 + u32 fmp_mask; 331 331 bool wakeup_src; 332 332 }; 333 333 ··· 1834 1830 return 0; 1835 1831 } 1836 1832 1833 + static int stm32f7_i2c_write_fm_plus_bits(struct stm32f7_i2c_dev *i2c_dev, 1834 + bool enable) 1835 + { 1836 + if (i2c_dev->speed != STM32_I2C_SPEED_FAST_PLUS || 1837 + IS_ERR_OR_NULL(i2c_dev->regmap)) 1838 + /* Optional */ 1839 + return 0; 1840 + 1841 + return regmap_update_bits(i2c_dev->regmap, i2c_dev->fmp_reg, 1842 + i2c_dev->fmp_mask, 1843 + enable ? i2c_dev->fmp_mask : 0); 1844 + } 1845 + 1837 1846 static int stm32f7_i2c_setup_fm_plus_bits(struct platform_device *pdev, 1838 1847 struct stm32f7_i2c_dev *i2c_dev) 1839 1848 { 1840 1849 struct device_node *np = pdev->dev.of_node; 1841 1850 int ret; 1842 - u32 reg, mask; 1843 1851 1844 1852 i2c_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg-fmp"); 1845 - if (IS_ERR(i2c_dev->regmap)) { 1853 + if (IS_ERR(i2c_dev->regmap)) 1846 1854 /* Optional */ 1847 1855 return 0; 1848 - } 1849 1856 1850 - ret = of_property_read_u32_index(np, "st,syscfg-fmp", 1, &reg); 1857 + ret = of_property_read_u32_index(np, "st,syscfg-fmp", 1, 1858 + &i2c_dev->fmp_reg); 1851 1859 if (ret) 1852 1860 return ret; 1853 1861 1854 - ret = of_property_read_u32_index(np, "st,syscfg-fmp", 2, &mask); 1855 - if (ret) 1856 - return ret; 1857 - 1858 - return regmap_update_bits(i2c_dev->regmap, reg, mask, mask); 1862 + return of_property_read_u32_index(np, "st,syscfg-fmp", 2, 1863 + &i2c_dev->fmp_mask); 1859 1864 } 1860 1865 1861 1866 static u32 stm32f7_i2c_func(struct i2c_adapter *adap) ··· 1942 1929 &clk_rate); 1943 1930 if (!ret && clk_rate >= 1000000) { 1944 1931 i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS; 1945 - ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev); 1946 - if (ret) 1947 - goto clk_free; 1948 1932 } else if (!ret && clk_rate >= 400000) { 1949 1933 i2c_dev->speed = STM32_I2C_SPEED_FAST; 1950 1934 } else if (!ret && clk_rate >= 100000) { ··· 2001 1991 if (ret) 2002 1992 goto clk_free; 2003 1993 1994 + if (i2c_dev->speed == STM32_I2C_SPEED_FAST_PLUS) { 1995 + ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev); 1996 + if (ret) 1997 + goto clk_free; 1998 + ret = stm32f7_i2c_write_fm_plus_bits(i2c_dev, true); 1999 + if (ret) 2000 + goto clk_free; 2001 + } 2002 + 2004 2003 adap = &i2c_dev->adap; 2005 2004 i2c_set_adapdata(adap, i2c_dev); 2006 2005 snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", ··· 2034 2015 if (ret != -EPROBE_DEFER) 2035 2016 dev_err(&pdev->dev, 2036 2017 "Failed to request dma error %i\n", ret); 2037 - goto clk_free; 2018 + goto fmp_clear; 2038 2019 } 2039 2020 2040 2021 if (i2c_dev->wakeup_src) { ··· 2088 2069 i2c_dev->dma = NULL; 2089 2070 } 2090 2071 2072 + fmp_clear: 2073 + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); 2074 + 2091 2075 clk_free: 2092 2076 clk_disable_unprepare(i2c_dev->clk); 2093 2077 ··· 2122 2100 stm32_i2c_dma_free(i2c_dev->dma); 2123 2101 i2c_dev->dma = NULL; 2124 2102 } 2103 + 2104 + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); 2125 2105 2126 2106 clk_disable_unprepare(i2c_dev->clk); 2127 2107 ··· 2172 2148 backup_regs->oar2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR2); 2173 2149 backup_regs->pecr = readl_relaxed(i2c_dev->base + STM32F7_I2C_PECR); 2174 2150 backup_regs->tmgr = readl_relaxed(i2c_dev->base + STM32F7_I2C_TIMINGR); 2151 + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); 2175 2152 2176 2153 pm_runtime_put_sync(i2c_dev->dev); 2177 2154 ··· 2204 2179 writel_relaxed(backup_regs->oar1, i2c_dev->base + STM32F7_I2C_OAR1); 2205 2180 writel_relaxed(backup_regs->oar2, i2c_dev->base + STM32F7_I2C_OAR2); 2206 2181 writel_relaxed(backup_regs->pecr, i2c_dev->base + STM32F7_I2C_PECR); 2182 + stm32f7_i2c_write_fm_plus_bits(i2c_dev, true); 2207 2183 2208 2184 pm_runtime_put_sync(i2c_dev->dev); 2209 2185