.. | .. |
---|
11 | 11 | #include <linux/delay.h> |
---|
12 | 12 | #include <linux/module.h> |
---|
13 | 13 | #include <linux/of_platform.h> |
---|
| 14 | +#include <linux/pm_runtime.h> |
---|
14 | 15 | #include <linux/regulator/consumer.h> |
---|
15 | 16 | #include <linux/reset.h> |
---|
16 | 17 | |
---|
.. | .. |
---|
19 | 20 | /** |
---|
20 | 21 | * struct stm32_dac_priv - stm32 DAC core private data |
---|
21 | 22 | * @pclk: peripheral clock common for all DACs |
---|
22 | | - * @rst: peripheral reset control |
---|
23 | 23 | * @vref: regulator reference |
---|
24 | 24 | * @common: Common data for all DAC instances |
---|
25 | 25 | */ |
---|
26 | 26 | struct stm32_dac_priv { |
---|
27 | 27 | struct clk *pclk; |
---|
28 | | - struct reset_control *rst; |
---|
29 | 28 | struct regulator *vref; |
---|
30 | 29 | struct stm32_dac_common common; |
---|
31 | 30 | }; |
---|
.. | .. |
---|
50 | 49 | .max_register = 0x3fc, |
---|
51 | 50 | }; |
---|
52 | 51 | |
---|
| 52 | +static int stm32_dac_core_hw_start(struct device *dev) |
---|
| 53 | +{ |
---|
| 54 | + struct stm32_dac_common *common = dev_get_drvdata(dev); |
---|
| 55 | + struct stm32_dac_priv *priv = to_stm32_dac_priv(common); |
---|
| 56 | + int ret; |
---|
| 57 | + |
---|
| 58 | + ret = regulator_enable(priv->vref); |
---|
| 59 | + if (ret < 0) { |
---|
| 60 | + dev_err(dev, "vref enable failed: %d\n", ret); |
---|
| 61 | + return ret; |
---|
| 62 | + } |
---|
| 63 | + |
---|
| 64 | + ret = clk_prepare_enable(priv->pclk); |
---|
| 65 | + if (ret < 0) { |
---|
| 66 | + dev_err(dev, "pclk enable failed: %d\n", ret); |
---|
| 67 | + goto err_regulator_disable; |
---|
| 68 | + } |
---|
| 69 | + |
---|
| 70 | + return 0; |
---|
| 71 | + |
---|
| 72 | +err_regulator_disable: |
---|
| 73 | + regulator_disable(priv->vref); |
---|
| 74 | + |
---|
| 75 | + return ret; |
---|
| 76 | +} |
---|
| 77 | + |
---|
| 78 | +static void stm32_dac_core_hw_stop(struct device *dev) |
---|
| 79 | +{ |
---|
| 80 | + struct stm32_dac_common *common = dev_get_drvdata(dev); |
---|
| 81 | + struct stm32_dac_priv *priv = to_stm32_dac_priv(common); |
---|
| 82 | + |
---|
| 83 | + clk_disable_unprepare(priv->pclk); |
---|
| 84 | + regulator_disable(priv->vref); |
---|
| 85 | +} |
---|
| 86 | + |
---|
53 | 87 | static int stm32_dac_probe(struct platform_device *pdev) |
---|
54 | 88 | { |
---|
55 | 89 | struct device *dev = &pdev->dev; |
---|
.. | .. |
---|
58 | 92 | struct regmap *regmap; |
---|
59 | 93 | struct resource *res; |
---|
60 | 94 | void __iomem *mmio; |
---|
| 95 | + struct reset_control *rst; |
---|
61 | 96 | int ret; |
---|
62 | 97 | |
---|
63 | 98 | if (!dev->of_node) |
---|
.. | .. |
---|
66 | 101 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
---|
67 | 102 | if (!priv) |
---|
68 | 103 | return -ENOMEM; |
---|
| 104 | + platform_set_drvdata(pdev, &priv->common); |
---|
| 105 | + |
---|
69 | 106 | cfg = (const struct stm32_dac_cfg *) |
---|
70 | 107 | of_match_device(dev->driver->of_match_table, dev)->data; |
---|
71 | 108 | |
---|
.. | .. |
---|
74 | 111 | if (IS_ERR(mmio)) |
---|
75 | 112 | return PTR_ERR(mmio); |
---|
76 | 113 | |
---|
77 | | - regmap = devm_regmap_init_mmio(dev, mmio, &stm32_dac_regmap_cfg); |
---|
| 114 | + regmap = devm_regmap_init_mmio_clk(dev, "pclk", mmio, |
---|
| 115 | + &stm32_dac_regmap_cfg); |
---|
78 | 116 | if (IS_ERR(regmap)) |
---|
79 | 117 | return PTR_ERR(regmap); |
---|
80 | 118 | priv->common.regmap = regmap; |
---|
| 119 | + |
---|
| 120 | + priv->pclk = devm_clk_get(dev, "pclk"); |
---|
| 121 | + if (IS_ERR(priv->pclk)) { |
---|
| 122 | + ret = PTR_ERR(priv->pclk); |
---|
| 123 | + dev_err(dev, "pclk get failed\n"); |
---|
| 124 | + return ret; |
---|
| 125 | + } |
---|
81 | 126 | |
---|
82 | 127 | priv->vref = devm_regulator_get(dev, "vref"); |
---|
83 | 128 | if (IS_ERR(priv->vref)) { |
---|
.. | .. |
---|
86 | 131 | return ret; |
---|
87 | 132 | } |
---|
88 | 133 | |
---|
89 | | - ret = regulator_enable(priv->vref); |
---|
90 | | - if (ret < 0) { |
---|
91 | | - dev_err(dev, "vref enable failed\n"); |
---|
92 | | - return ret; |
---|
93 | | - } |
---|
| 134 | + pm_runtime_get_noresume(dev); |
---|
| 135 | + pm_runtime_set_active(dev); |
---|
| 136 | + pm_runtime_enable(dev); |
---|
| 137 | + |
---|
| 138 | + ret = stm32_dac_core_hw_start(dev); |
---|
| 139 | + if (ret) |
---|
| 140 | + goto err_pm_stop; |
---|
94 | 141 | |
---|
95 | 142 | ret = regulator_get_voltage(priv->vref); |
---|
96 | 143 | if (ret < 0) { |
---|
97 | 144 | dev_err(dev, "vref get voltage failed, %d\n", ret); |
---|
98 | | - goto err_vref; |
---|
| 145 | + goto err_hw_stop; |
---|
99 | 146 | } |
---|
100 | 147 | priv->common.vref_mv = ret / 1000; |
---|
101 | 148 | dev_dbg(dev, "vref+=%dmV\n", priv->common.vref_mv); |
---|
102 | 149 | |
---|
103 | | - priv->pclk = devm_clk_get(dev, "pclk"); |
---|
104 | | - if (IS_ERR(priv->pclk)) { |
---|
105 | | - ret = PTR_ERR(priv->pclk); |
---|
106 | | - dev_err(dev, "pclk get failed\n"); |
---|
107 | | - goto err_vref; |
---|
108 | | - } |
---|
| 150 | + rst = devm_reset_control_get_optional_exclusive(dev, NULL); |
---|
| 151 | + if (rst) { |
---|
| 152 | + if (IS_ERR(rst)) { |
---|
| 153 | + ret = dev_err_probe(dev, PTR_ERR(rst), "reset get failed\n"); |
---|
| 154 | + goto err_hw_stop; |
---|
| 155 | + } |
---|
109 | 156 | |
---|
110 | | - ret = clk_prepare_enable(priv->pclk); |
---|
111 | | - if (ret < 0) { |
---|
112 | | - dev_err(dev, "pclk enable failed\n"); |
---|
113 | | - goto err_vref; |
---|
114 | | - } |
---|
115 | | - |
---|
116 | | - priv->rst = devm_reset_control_get_exclusive(dev, NULL); |
---|
117 | | - if (!IS_ERR(priv->rst)) { |
---|
118 | | - reset_control_assert(priv->rst); |
---|
| 157 | + reset_control_assert(rst); |
---|
119 | 158 | udelay(2); |
---|
120 | | - reset_control_deassert(priv->rst); |
---|
| 159 | + reset_control_deassert(rst); |
---|
121 | 160 | } |
---|
122 | 161 | |
---|
123 | 162 | if (cfg && cfg->has_hfsel) { |
---|
.. | .. |
---|
128 | 167 | priv->common.hfsel ? |
---|
129 | 168 | STM32H7_DAC_CR_HFSEL : 0); |
---|
130 | 169 | if (ret) |
---|
131 | | - goto err_pclk; |
---|
| 170 | + goto err_hw_stop; |
---|
132 | 171 | } |
---|
133 | 172 | |
---|
134 | | - platform_set_drvdata(pdev, &priv->common); |
---|
135 | 173 | |
---|
136 | 174 | ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev); |
---|
137 | 175 | if (ret < 0) { |
---|
138 | 176 | dev_err(dev, "failed to populate DT children\n"); |
---|
139 | | - goto err_pclk; |
---|
| 177 | + goto err_hw_stop; |
---|
140 | 178 | } |
---|
| 179 | + |
---|
| 180 | + pm_runtime_put(dev); |
---|
141 | 181 | |
---|
142 | 182 | return 0; |
---|
143 | 183 | |
---|
144 | | -err_pclk: |
---|
145 | | - clk_disable_unprepare(priv->pclk); |
---|
146 | | -err_vref: |
---|
147 | | - regulator_disable(priv->vref); |
---|
| 184 | +err_hw_stop: |
---|
| 185 | + stm32_dac_core_hw_stop(dev); |
---|
| 186 | +err_pm_stop: |
---|
| 187 | + pm_runtime_disable(dev); |
---|
| 188 | + pm_runtime_set_suspended(dev); |
---|
| 189 | + pm_runtime_put_noidle(dev); |
---|
148 | 190 | |
---|
149 | 191 | return ret; |
---|
150 | 192 | } |
---|
151 | 193 | |
---|
152 | 194 | static int stm32_dac_remove(struct platform_device *pdev) |
---|
153 | 195 | { |
---|
154 | | - struct stm32_dac_common *common = platform_get_drvdata(pdev); |
---|
155 | | - struct stm32_dac_priv *priv = to_stm32_dac_priv(common); |
---|
156 | | - |
---|
| 196 | + pm_runtime_get_sync(&pdev->dev); |
---|
157 | 197 | of_platform_depopulate(&pdev->dev); |
---|
158 | | - clk_disable_unprepare(priv->pclk); |
---|
159 | | - regulator_disable(priv->vref); |
---|
| 198 | + stm32_dac_core_hw_stop(&pdev->dev); |
---|
| 199 | + pm_runtime_disable(&pdev->dev); |
---|
| 200 | + pm_runtime_set_suspended(&pdev->dev); |
---|
| 201 | + pm_runtime_put_noidle(&pdev->dev); |
---|
160 | 202 | |
---|
161 | 203 | return 0; |
---|
162 | 204 | } |
---|
| 205 | + |
---|
| 206 | +static int __maybe_unused stm32_dac_core_resume(struct device *dev) |
---|
| 207 | +{ |
---|
| 208 | + struct stm32_dac_common *common = dev_get_drvdata(dev); |
---|
| 209 | + struct stm32_dac_priv *priv = to_stm32_dac_priv(common); |
---|
| 210 | + int ret; |
---|
| 211 | + |
---|
| 212 | + if (priv->common.hfsel) { |
---|
| 213 | + /* restore hfsel (maybe lost under low power state) */ |
---|
| 214 | + ret = regmap_update_bits(priv->common.regmap, STM32_DAC_CR, |
---|
| 215 | + STM32H7_DAC_CR_HFSEL, |
---|
| 216 | + STM32H7_DAC_CR_HFSEL); |
---|
| 217 | + if (ret) |
---|
| 218 | + return ret; |
---|
| 219 | + } |
---|
| 220 | + |
---|
| 221 | + return pm_runtime_force_resume(dev); |
---|
| 222 | +} |
---|
| 223 | + |
---|
| 224 | +static int __maybe_unused stm32_dac_core_runtime_suspend(struct device *dev) |
---|
| 225 | +{ |
---|
| 226 | + stm32_dac_core_hw_stop(dev); |
---|
| 227 | + |
---|
| 228 | + return 0; |
---|
| 229 | +} |
---|
| 230 | + |
---|
| 231 | +static int __maybe_unused stm32_dac_core_runtime_resume(struct device *dev) |
---|
| 232 | +{ |
---|
| 233 | + return stm32_dac_core_hw_start(dev); |
---|
| 234 | +} |
---|
| 235 | + |
---|
| 236 | +static const struct dev_pm_ops stm32_dac_core_pm_ops = { |
---|
| 237 | + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, stm32_dac_core_resume) |
---|
| 238 | + SET_RUNTIME_PM_OPS(stm32_dac_core_runtime_suspend, |
---|
| 239 | + stm32_dac_core_runtime_resume, |
---|
| 240 | + NULL) |
---|
| 241 | +}; |
---|
163 | 242 | |
---|
164 | 243 | static const struct stm32_dac_cfg stm32h7_dac_cfg = { |
---|
165 | 244 | .has_hfsel = true, |
---|
.. | .. |
---|
182 | 261 | .driver = { |
---|
183 | 262 | .name = "stm32-dac-core", |
---|
184 | 263 | .of_match_table = stm32_dac_of_match, |
---|
| 264 | + .pm = &stm32_dac_core_pm_ops, |
---|
185 | 265 | }, |
---|
186 | 266 | }; |
---|
187 | 267 | module_platform_driver(stm32_dac_driver); |
---|