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

Merge tag 'pwm/for-5.2-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
"Nothing out of the ordinary this cycle.

The bulk of this is a collection of fixes for existing drivers and
some cleanups. There's one new driver for i.MX SoCs and addition of
support for some new variants to existing drivers"

* tag 'pwm/for-5.2-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
pwm: meson: Add clock source configuration for Meson G12A
dt-bindings: pwm: Update bindings for the Meson G12A Family
pwm: samsung: Don't uses devm_*() functions in ->request()
pwm: Clear chip_data in pwm_put()
pwm: Add i.MX TPM PWM driver support
dt-bindings: pwm: Add i.MX TPM PWM binding
pwm: imx27: Use devm_platform_ioremap_resource() to simplify code
pwm: meson: Use the spin-lock only to protect register modifications
pwm: meson: Don't disable PWM when setting duty repeatedly
pwm: meson: Consider 128 a valid pre-divider
pwm: sysfs: fix typo "its" -> "it's"
pwm: tiehrpwm: Enable compilation for ARCH_K3
dt-bindings: pwm: tiehrpwm: Add TI AM654 SoC specific compatible
pwm: tiehrpwm: Update shadow register for disabling PWMs
pwm: img: Turn final 'else if' into 'else' in img_pwm_config
pwm: Fix deadlock warning when removing PWM device

+552 -51
+22
Documentation/devicetree/bindings/pwm/imx-tpm-pwm.txt
··· 1 + Freescale i.MX TPM PWM controller 2 + 3 + Required properties: 4 + - compatible : Should be "fsl,imx7ulp-pwm". 5 + - reg: Physical base address and length of the controller's registers. 6 + - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of the cells format. 7 + - clocks : The clock provided by the SoC to drive the PWM. 8 + - interrupts: The interrupt for the PWM controller. 9 + 10 + Note: The TPM counter and period counter are shared between multiple channels, so all channels 11 + should use same period setting. 12 + 13 + Example: 14 + 15 + tpm4: pwm@40250000 { 16 + compatible = "fsl,imx7ulp-pwm"; 17 + reg = <0x40250000 0x1000>; 18 + assigned-clocks = <&pcc2 IMX7ULP_CLK_LPTPM4>; 19 + assigned-clock-parents = <&scg1 IMX7ULP_CLK_SOSC_BUS_CLK>; 20 + clocks = <&pcc2 IMX7ULP_CLK_LPTPM4>; 21 + #pwm-cells = <3>; 22 + };
+3
Documentation/devicetree/bindings/pwm/pwm-meson.txt
··· 7 7 or "amlogic,meson-gxbb-ao-pwm" 8 8 or "amlogic,meson-axg-ee-pwm" 9 9 or "amlogic,meson-axg-ao-pwm" 10 + or "amlogic,meson-g12a-ee-pwm" 11 + or "amlogic,meson-g12a-ao-pwm-ab" 12 + or "amlogic,meson-g12a-ao-pwm-cd" 10 13 - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of 11 14 the cells format. 12 15
+1
Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
··· 4 4 - compatible: Must be "ti,<soc>-ehrpwm". 5 5 for am33xx - compatible = "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; 6 6 for am4372 - compatible = "ti,am4372-ehrpwm", "ti-am3352-ehrpwm", "ti,am33xx-ehrpwm"; 7 + for am654 - compatible = "ti,am654-ehrpwm", "ti-am3352-ehrpwm"; 7 8 for da850 - compatible = "ti,da850-ehrpwm", "ti-am3352-ehrpwm", "ti,am33xx-ehrpwm"; 8 9 for dra746 - compatible = "ti,dra746-ehrpwm", "ti-am3352-ehrpwm"; 9 10 - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
+13 -3
drivers/pwm/Kconfig
··· 210 210 To compile this driver as a module, choose M here: the module 211 211 will be called pwm-imx27. 212 212 213 + config PWM_IMX_TPM 214 + tristate "i.MX TPM PWM support" 215 + depends on ARCH_MXC || COMPILE_TEST 216 + depends on HAVE_CLK && HAS_IOMEM 217 + help 218 + Generic PWM framework driver for i.MX7ULP TPM module, TPM's full 219 + name is Low Power Timer/Pulse Width Modulation Module. 220 + 221 + To compile this driver as a module, choose M here: the module 222 + will be called pwm-imx-tpm. 223 + 213 224 config PWM_JZ4740 214 225 tristate "Ingenic JZ47xx PWM support" 215 226 depends on MACH_INGENIC ··· 478 467 479 468 config PWM_TIEHRPWM 480 469 tristate "EHRPWM PWM support" 481 - depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX 470 + depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_K3 482 471 help 483 - PWM driver support for the EHRPWM controller found on AM33XX 484 - TI SOC 472 + PWM driver support for the EHRPWM controller found on TI SOCs 485 473 486 474 To compile this driver as a module, choose M here: the module 487 475 will be called pwm-tiehrpwm.
+1
drivers/pwm/Makefile
··· 19 19 obj-$(CONFIG_PWM_IMG) += pwm-img.o 20 20 obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o 21 21 obj-$(CONFIG_PWM_IMX27) += pwm-imx27.o 22 + obj-$(CONFIG_PWM_IMX_TPM) += pwm-imx-tpm.o 22 23 obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o 23 24 obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o 24 25 obj-$(CONFIG_PWM_LPC18XX_SCT) += pwm-lpc18xx-sct.o
+6 -5
drivers/pwm/core.c
··· 311 311 if (IS_ENABLED(CONFIG_OF)) 312 312 of_pwmchip_add(chip); 313 313 314 - pwmchip_sysfs_export(chip); 315 - 316 314 out: 317 315 mutex_unlock(&pwm_lock); 316 + 317 + if (!ret) 318 + pwmchip_sysfs_export(chip); 319 + 318 320 return ret; 319 321 } 320 322 EXPORT_SYMBOL_GPL(pwmchip_add_with_polarity); ··· 350 348 unsigned int i; 351 349 int ret = 0; 352 350 353 - pwmchip_sysfs_unexport_children(chip); 351 + pwmchip_sysfs_unexport(chip); 354 352 355 353 mutex_lock(&pwm_lock); 356 354 ··· 369 367 of_pwmchip_remove(chip); 370 368 371 369 free_pwms(chip); 372 - 373 - pwmchip_sysfs_unexport(chip); 374 370 375 371 out: 376 372 mutex_unlock(&pwm_lock); ··· 877 877 if (pwm->chip->ops->free) 878 878 pwm->chip->ops->free(pwm->chip, pwm); 879 879 880 + pwm_set_chip_data(pwm, NULL); 880 881 pwm->label = NULL; 881 882 882 883 module_put(pwm->chip->ops->owner);
-1
drivers/pwm/pwm-berlin.c
··· 84 84 { 85 85 struct berlin_pwm_channel *channel = pwm_get_chip_data(pwm); 86 86 87 - pwm_set_chip_data(pwm, NULL); 88 87 kfree(channel); 89 88 } 90 89
+1 -1
drivers/pwm/pwm-img.c
··· 123 123 } else if (mul <= max_timebase * 512) { 124 124 div = PWM_CTRL_CFG_SUB_DIV0_DIV1; 125 125 timebase = DIV_ROUND_UP(mul, 512); 126 - } else if (mul > max_timebase * 512) { 126 + } else { 127 127 dev_err(chip->dev, 128 128 "failed to configure timebase steps/divider value\n"); 129 129 return -EINVAL;
+449
drivers/pwm/pwm-imx-tpm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright 2018-2019 NXP. 4 + * 5 + * Limitations: 6 + * - The TPM counter and period counter are shared between 7 + * multiple channels, so all channels should use same period 8 + * settings. 9 + * - Changes to polarity cannot be latched at the time of the 10 + * next period start. 11 + * - Changing period and duty cycle together isn't atomic, 12 + * with the wrong timing it might happen that a period is 13 + * produced with old duty cycle but new period settings. 14 + */ 15 + 16 + #include <linux/bitfield.h> 17 + #include <linux/bitops.h> 18 + #include <linux/clk.h> 19 + #include <linux/err.h> 20 + #include <linux/io.h> 21 + #include <linux/log2.h> 22 + #include <linux/module.h> 23 + #include <linux/of.h> 24 + #include <linux/of_address.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/pwm.h> 27 + #include <linux/slab.h> 28 + 29 + #define PWM_IMX_TPM_PARAM 0x4 30 + #define PWM_IMX_TPM_GLOBAL 0x8 31 + #define PWM_IMX_TPM_SC 0x10 32 + #define PWM_IMX_TPM_CNT 0x14 33 + #define PWM_IMX_TPM_MOD 0x18 34 + #define PWM_IMX_TPM_CnSC(n) (0x20 + (n) * 0x8) 35 + #define PWM_IMX_TPM_CnV(n) (0x24 + (n) * 0x8) 36 + 37 + #define PWM_IMX_TPM_PARAM_CHAN GENMASK(7, 0) 38 + 39 + #define PWM_IMX_TPM_SC_PS GENMASK(2, 0) 40 + #define PWM_IMX_TPM_SC_CMOD GENMASK(4, 3) 41 + #define PWM_IMX_TPM_SC_CMOD_INC_EVERY_CLK FIELD_PREP(PWM_IMX_TPM_SC_CMOD, 1) 42 + #define PWM_IMX_TPM_SC_CPWMS BIT(5) 43 + 44 + #define PWM_IMX_TPM_CnSC_CHF BIT(7) 45 + #define PWM_IMX_TPM_CnSC_MSB BIT(5) 46 + #define PWM_IMX_TPM_CnSC_MSA BIT(4) 47 + 48 + /* 49 + * The reference manual describes this field as two separate bits. The 50 + * semantic of the two bits isn't orthogonal though, so they are treated 51 + * together as a 2-bit field here. 52 + */ 53 + #define PWM_IMX_TPM_CnSC_ELS GENMASK(3, 2) 54 + #define PWM_IMX_TPM_CnSC_ELS_INVERSED FIELD_PREP(PWM_IMX_TPM_CnSC_ELS, 1) 55 + #define PWM_IMX_TPM_CnSC_ELS_NORMAL FIELD_PREP(PWM_IMX_TPM_CnSC_ELS, 2) 56 + 57 + 58 + #define PWM_IMX_TPM_MOD_WIDTH 16 59 + #define PWM_IMX_TPM_MOD_MOD GENMASK(PWM_IMX_TPM_MOD_WIDTH - 1, 0) 60 + 61 + struct imx_tpm_pwm_chip { 62 + struct pwm_chip chip; 63 + struct clk *clk; 64 + void __iomem *base; 65 + struct mutex lock; 66 + u32 user_count; 67 + u32 enable_count; 68 + u32 real_period; 69 + }; 70 + 71 + struct imx_tpm_pwm_param { 72 + u8 prescale; 73 + u32 mod; 74 + u32 val; 75 + }; 76 + 77 + static inline struct imx_tpm_pwm_chip * 78 + to_imx_tpm_pwm_chip(struct pwm_chip *chip) 79 + { 80 + return container_of(chip, struct imx_tpm_pwm_chip, chip); 81 + } 82 + 83 + /* 84 + * This function determines for a given pwm_state *state that a consumer 85 + * might request the pwm_state *real_state that eventually is implemented 86 + * by the hardware and the necessary register values (in *p) to achieve 87 + * this. 88 + */ 89 + static int pwm_imx_tpm_round_state(struct pwm_chip *chip, 90 + struct imx_tpm_pwm_param *p, 91 + struct pwm_state *real_state, 92 + struct pwm_state *state) 93 + { 94 + struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 95 + u32 rate, prescale, period_count, clock_unit; 96 + u64 tmp; 97 + 98 + rate = clk_get_rate(tpm->clk); 99 + tmp = (u64)state->period * rate; 100 + clock_unit = DIV_ROUND_CLOSEST_ULL(tmp, NSEC_PER_SEC); 101 + if (clock_unit <= PWM_IMX_TPM_MOD_MOD) 102 + prescale = 0; 103 + else 104 + prescale = ilog2(clock_unit) + 1 - PWM_IMX_TPM_MOD_WIDTH; 105 + 106 + if ((!FIELD_FIT(PWM_IMX_TPM_SC_PS, prescale))) 107 + return -ERANGE; 108 + p->prescale = prescale; 109 + 110 + period_count = (clock_unit + ((1 << prescale) >> 1)) >> prescale; 111 + p->mod = period_count; 112 + 113 + /* calculate real period HW can support */ 114 + tmp = (u64)period_count << prescale; 115 + tmp *= NSEC_PER_SEC; 116 + real_state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate); 117 + 118 + /* 119 + * if eventually the PWM output is inactive, either 120 + * duty cycle is 0 or status is disabled, need to 121 + * make sure the output pin is inactive. 122 + */ 123 + if (!state->enabled) 124 + real_state->duty_cycle = 0; 125 + else 126 + real_state->duty_cycle = state->duty_cycle; 127 + 128 + tmp = (u64)p->mod * real_state->duty_cycle; 129 + p->val = DIV_ROUND_CLOSEST_ULL(tmp, real_state->period); 130 + 131 + real_state->polarity = state->polarity; 132 + real_state->enabled = state->enabled; 133 + 134 + return 0; 135 + } 136 + 137 + static void pwm_imx_tpm_get_state(struct pwm_chip *chip, 138 + struct pwm_device *pwm, 139 + struct pwm_state *state) 140 + { 141 + struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 142 + u32 rate, val, prescale; 143 + u64 tmp; 144 + 145 + /* get period */ 146 + state->period = tpm->real_period; 147 + 148 + /* get duty cycle */ 149 + rate = clk_get_rate(tpm->clk); 150 + val = readl(tpm->base + PWM_IMX_TPM_SC); 151 + prescale = FIELD_GET(PWM_IMX_TPM_SC_PS, val); 152 + tmp = readl(tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm)); 153 + tmp = (tmp << prescale) * NSEC_PER_SEC; 154 + state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate); 155 + 156 + /* get polarity */ 157 + val = readl(tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm)); 158 + if ((val & PWM_IMX_TPM_CnSC_ELS) == PWM_IMX_TPM_CnSC_ELS_INVERSED) 159 + state->polarity = PWM_POLARITY_INVERSED; 160 + else 161 + /* 162 + * Assume reserved values (2b00 and 2b11) to yield 163 + * normal polarity. 164 + */ 165 + state->polarity = PWM_POLARITY_NORMAL; 166 + 167 + /* get channel status */ 168 + state->enabled = FIELD_GET(PWM_IMX_TPM_CnSC_ELS, val) ? true : false; 169 + } 170 + 171 + /* this function is supposed to be called with mutex hold */ 172 + static int pwm_imx_tpm_apply_hw(struct pwm_chip *chip, 173 + struct imx_tpm_pwm_param *p, 174 + struct pwm_state *state, 175 + struct pwm_device *pwm) 176 + { 177 + struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 178 + bool period_update = false; 179 + bool duty_update = false; 180 + u32 val, cmod, cur_prescale; 181 + unsigned long timeout; 182 + struct pwm_state c; 183 + 184 + if (state->period != tpm->real_period) { 185 + /* 186 + * TPM counter is shared by multiple channels, so 187 + * prescale and period can NOT be modified when 188 + * there are multiple channels in use with different 189 + * period settings. 190 + */ 191 + if (tpm->user_count > 1) 192 + return -EBUSY; 193 + 194 + val = readl(tpm->base + PWM_IMX_TPM_SC); 195 + cmod = FIELD_GET(PWM_IMX_TPM_SC_CMOD, val); 196 + cur_prescale = FIELD_GET(PWM_IMX_TPM_SC_PS, val); 197 + if (cmod && cur_prescale != p->prescale) 198 + return -EBUSY; 199 + 200 + /* set TPM counter prescale */ 201 + val &= ~PWM_IMX_TPM_SC_PS; 202 + val |= FIELD_PREP(PWM_IMX_TPM_SC_PS, p->prescale); 203 + writel(val, tpm->base + PWM_IMX_TPM_SC); 204 + 205 + /* 206 + * set period count: 207 + * if the PWM is disabled (CMOD[1:0] = 2b00), then MOD register 208 + * is updated when MOD register is written. 209 + * 210 + * if the PWM is enabled (CMOD[1:0] ≠ 2b00), the period length 211 + * is latched into hardware when the next period starts. 212 + */ 213 + writel(p->mod, tpm->base + PWM_IMX_TPM_MOD); 214 + tpm->real_period = state->period; 215 + period_update = true; 216 + } 217 + 218 + pwm_imx_tpm_get_state(chip, pwm, &c); 219 + 220 + /* polarity is NOT allowed to be changed if PWM is active */ 221 + if (c.enabled && c.polarity != state->polarity) 222 + return -EBUSY; 223 + 224 + if (state->duty_cycle != c.duty_cycle) { 225 + /* 226 + * set channel value: 227 + * if the PWM is disabled (CMOD[1:0] = 2b00), then CnV register 228 + * is updated when CnV register is written. 229 + * 230 + * if the PWM is enabled (CMOD[1:0] ≠ 2b00), the duty length 231 + * is latched into hardware when the next period starts. 232 + */ 233 + writel(p->val, tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm)); 234 + duty_update = true; 235 + } 236 + 237 + /* make sure MOD & CnV registers are updated */ 238 + if (period_update || duty_update) { 239 + timeout = jiffies + msecs_to_jiffies(tpm->real_period / 240 + NSEC_PER_MSEC + 1); 241 + while (readl(tpm->base + PWM_IMX_TPM_MOD) != p->mod 242 + || readl(tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm)) 243 + != p->val) { 244 + if (time_after(jiffies, timeout)) 245 + return -ETIME; 246 + cpu_relax(); 247 + } 248 + } 249 + 250 + /* 251 + * polarity settings will enabled/disable output status 252 + * immediately, so if the channel is disabled, need to 253 + * make sure MSA/MSB/ELS are set to 0 which means channel 254 + * disabled. 255 + */ 256 + val = readl(tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm)); 257 + val &= ~(PWM_IMX_TPM_CnSC_ELS | PWM_IMX_TPM_CnSC_MSA | 258 + PWM_IMX_TPM_CnSC_MSB); 259 + if (state->enabled) { 260 + /* 261 + * set polarity (for edge-aligned PWM modes) 262 + * 263 + * ELS[1:0] = 2b10 yields normal polarity behaviour, 264 + * ELS[1:0] = 2b01 yields inversed polarity. 265 + * The other values are reserved. 266 + */ 267 + val |= PWM_IMX_TPM_CnSC_MSB; 268 + val |= (state->polarity == PWM_POLARITY_NORMAL) ? 269 + PWM_IMX_TPM_CnSC_ELS_NORMAL : 270 + PWM_IMX_TPM_CnSC_ELS_INVERSED; 271 + } 272 + writel(val, tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm)); 273 + 274 + /* control the counter status */ 275 + if (state->enabled != c.enabled) { 276 + val = readl(tpm->base + PWM_IMX_TPM_SC); 277 + if (state->enabled) { 278 + if (++tpm->enable_count == 1) 279 + val |= PWM_IMX_TPM_SC_CMOD_INC_EVERY_CLK; 280 + } else { 281 + if (--tpm->enable_count == 0) 282 + val &= ~PWM_IMX_TPM_SC_CMOD; 283 + } 284 + writel(val, tpm->base + PWM_IMX_TPM_SC); 285 + } 286 + 287 + return 0; 288 + } 289 + 290 + static int pwm_imx_tpm_apply(struct pwm_chip *chip, 291 + struct pwm_device *pwm, 292 + struct pwm_state *state) 293 + { 294 + struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 295 + struct imx_tpm_pwm_param param; 296 + struct pwm_state real_state; 297 + int ret; 298 + 299 + ret = pwm_imx_tpm_round_state(chip, &param, &real_state, state); 300 + if (ret) 301 + return ret; 302 + 303 + mutex_lock(&tpm->lock); 304 + ret = pwm_imx_tpm_apply_hw(chip, &param, &real_state, pwm); 305 + mutex_unlock(&tpm->lock); 306 + 307 + return ret; 308 + } 309 + 310 + static int pwm_imx_tpm_request(struct pwm_chip *chip, struct pwm_device *pwm) 311 + { 312 + struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 313 + 314 + mutex_lock(&tpm->lock); 315 + tpm->user_count++; 316 + mutex_unlock(&tpm->lock); 317 + 318 + return 0; 319 + } 320 + 321 + static void pwm_imx_tpm_free(struct pwm_chip *chip, struct pwm_device *pwm) 322 + { 323 + struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 324 + 325 + mutex_lock(&tpm->lock); 326 + tpm->user_count--; 327 + mutex_unlock(&tpm->lock); 328 + } 329 + 330 + static const struct pwm_ops imx_tpm_pwm_ops = { 331 + .request = pwm_imx_tpm_request, 332 + .free = pwm_imx_tpm_free, 333 + .get_state = pwm_imx_tpm_get_state, 334 + .apply = pwm_imx_tpm_apply, 335 + .owner = THIS_MODULE, 336 + }; 337 + 338 + static int pwm_imx_tpm_probe(struct platform_device *pdev) 339 + { 340 + struct imx_tpm_pwm_chip *tpm; 341 + int ret; 342 + u32 val; 343 + 344 + tpm = devm_kzalloc(&pdev->dev, sizeof(*tpm), GFP_KERNEL); 345 + if (!tpm) 346 + return -ENOMEM; 347 + 348 + platform_set_drvdata(pdev, tpm); 349 + 350 + tpm->base = devm_platform_ioremap_resource(pdev, 0); 351 + if (IS_ERR(tpm->base)) 352 + return PTR_ERR(tpm->base); 353 + 354 + tpm->clk = devm_clk_get(&pdev->dev, NULL); 355 + if (IS_ERR(tpm->clk)) { 356 + ret = PTR_ERR(tpm->clk); 357 + if (ret != -EPROBE_DEFER) 358 + dev_err(&pdev->dev, 359 + "failed to get PWM clock: %d\n", ret); 360 + return ret; 361 + } 362 + 363 + ret = clk_prepare_enable(tpm->clk); 364 + if (ret) { 365 + dev_err(&pdev->dev, 366 + "failed to prepare or enable clock: %d\n", ret); 367 + return ret; 368 + } 369 + 370 + tpm->chip.dev = &pdev->dev; 371 + tpm->chip.ops = &imx_tpm_pwm_ops; 372 + tpm->chip.base = -1; 373 + tpm->chip.of_xlate = of_pwm_xlate_with_flags; 374 + tpm->chip.of_pwm_n_cells = 3; 375 + 376 + /* get number of channels */ 377 + val = readl(tpm->base + PWM_IMX_TPM_PARAM); 378 + tpm->chip.npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val); 379 + 380 + mutex_init(&tpm->lock); 381 + 382 + ret = pwmchip_add(&tpm->chip); 383 + if (ret) { 384 + dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); 385 + clk_disable_unprepare(tpm->clk); 386 + } 387 + 388 + return ret; 389 + } 390 + 391 + static int pwm_imx_tpm_remove(struct platform_device *pdev) 392 + { 393 + struct imx_tpm_pwm_chip *tpm = platform_get_drvdata(pdev); 394 + int ret = pwmchip_remove(&tpm->chip); 395 + 396 + clk_disable_unprepare(tpm->clk); 397 + 398 + return ret; 399 + } 400 + 401 + static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev) 402 + { 403 + struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev); 404 + 405 + if (tpm->enable_count > 0) 406 + return -EBUSY; 407 + 408 + clk_disable_unprepare(tpm->clk); 409 + 410 + return 0; 411 + } 412 + 413 + static int __maybe_unused pwm_imx_tpm_resume(struct device *dev) 414 + { 415 + struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev); 416 + int ret = 0; 417 + 418 + ret = clk_prepare_enable(tpm->clk); 419 + if (ret) 420 + dev_err(dev, 421 + "failed to prepare or enable clock: %d\n", 422 + ret); 423 + 424 + return ret; 425 + } 426 + 427 + static SIMPLE_DEV_PM_OPS(imx_tpm_pwm_pm, 428 + pwm_imx_tpm_suspend, pwm_imx_tpm_resume); 429 + 430 + static const struct of_device_id imx_tpm_pwm_dt_ids[] = { 431 + { .compatible = "fsl,imx7ulp-pwm", }, 432 + { /* sentinel */ } 433 + }; 434 + MODULE_DEVICE_TABLE(of, imx_tpm_pwm_dt_ids); 435 + 436 + static struct platform_driver imx_tpm_pwm_driver = { 437 + .driver = { 438 + .name = "imx7ulp-tpm-pwm", 439 + .of_match_table = imx_tpm_pwm_dt_ids, 440 + .pm = &imx_tpm_pwm_pm, 441 + }, 442 + .probe = pwm_imx_tpm_probe, 443 + .remove = pwm_imx_tpm_remove, 444 + }; 445 + module_platform_driver(imx_tpm_pwm_driver); 446 + 447 + MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>"); 448 + MODULE_DESCRIPTION("i.MX TPM PWM Driver"); 449 + MODULE_LICENSE("GPL v2");
+1 -3
drivers/pwm/pwm-imx27.c
··· 291 291 static int pwm_imx27_probe(struct platform_device *pdev) 292 292 { 293 293 struct pwm_imx27_chip *imx; 294 - struct resource *r; 295 294 296 295 imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); 297 296 if (imx == NULL) ··· 325 326 imx->chip.of_xlate = of_pwm_xlate_with_flags; 326 327 imx->chip.of_pwm_n_cells = 3; 327 328 328 - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 329 - imx->mmio_base = devm_ioremap_resource(&pdev->dev, r); 329 + imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); 330 330 if (IS_ERR(imx->mmio_base)) 331 331 return PTR_ERR(imx->mmio_base); 332 332
+49 -15
drivers/pwm/pwm-meson.c
··· 111 111 const struct meson_pwm_data *data; 112 112 void __iomem *base; 113 113 u8 inverter_mask; 114 + /* 115 + * Protects register (write) access to the REG_MISC_AB register 116 + * that is shared between the two PWMs. 117 + */ 114 118 spinlock_t lock; 115 119 }; 116 120 ··· 188 184 do_div(fin_ps, fin_freq); 189 185 190 186 /* Calc pre_div with the period */ 191 - for (pre_div = 0; pre_div < MISC_CLK_DIV_MASK; pre_div++) { 187 + for (pre_div = 0; pre_div <= MISC_CLK_DIV_MASK; pre_div++) { 192 188 cnt = DIV_ROUND_CLOSEST_ULL((u64)period * 1000, 193 189 fin_ps * (pre_div + 1)); 194 190 dev_dbg(meson->chip.dev, "fin_ps=%llu pre_div=%u cnt=%u\n", ··· 197 193 break; 198 194 } 199 195 200 - if (pre_div == MISC_CLK_DIV_MASK) { 196 + if (pre_div > MISC_CLK_DIV_MASK) { 201 197 dev_err(meson->chip.dev, "unable to get period pre_div\n"); 202 198 return -EINVAL; 203 199 } ··· 239 235 { 240 236 u32 value, clk_shift, clk_enable, enable; 241 237 unsigned int offset; 238 + unsigned long flags; 242 239 243 240 switch (id) { 244 241 case 0: ··· 260 255 return; 261 256 } 262 257 258 + spin_lock_irqsave(&meson->lock, flags); 259 + 263 260 value = readl(meson->base + REG_MISC_AB); 264 261 value &= ~(MISC_CLK_DIV_MASK << clk_shift); 265 262 value |= channel->pre_div << clk_shift; ··· 274 267 value = readl(meson->base + REG_MISC_AB); 275 268 value |= enable; 276 269 writel(value, meson->base + REG_MISC_AB); 270 + 271 + spin_unlock_irqrestore(&meson->lock, flags); 277 272 } 278 273 279 274 static void meson_pwm_disable(struct meson_pwm *meson, unsigned int id) 280 275 { 281 276 u32 value, enable; 277 + unsigned long flags; 282 278 283 279 switch (id) { 284 280 case 0: ··· 296 286 return; 297 287 } 298 288 289 + spin_lock_irqsave(&meson->lock, flags); 290 + 299 291 value = readl(meson->base + REG_MISC_AB); 300 292 value &= ~enable; 301 293 writel(value, meson->base + REG_MISC_AB); 294 + 295 + spin_unlock_irqrestore(&meson->lock, flags); 302 296 } 303 297 304 298 static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ··· 310 296 { 311 297 struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); 312 298 struct meson_pwm *meson = to_meson_pwm(chip); 313 - unsigned long flags; 314 299 int err = 0; 315 300 316 301 if (!state) 317 302 return -EINVAL; 318 303 319 - spin_lock_irqsave(&meson->lock, flags); 320 - 321 304 if (!state->enabled) { 322 305 meson_pwm_disable(meson, pwm->hwpwm); 323 306 channel->state.enabled = false; 324 307 325 - goto unlock; 308 + return 0; 326 309 } 327 310 328 311 if (state->period != channel->state.period || 329 312 state->duty_cycle != channel->state.duty_cycle || 330 313 state->polarity != channel->state.polarity) { 331 - if (channel->state.enabled) { 332 - meson_pwm_disable(meson, pwm->hwpwm); 333 - channel->state.enabled = false; 334 - } 335 - 336 314 if (state->polarity != channel->state.polarity) { 337 315 if (state->polarity == PWM_POLARITY_NORMAL) 338 316 meson->inverter_mask |= BIT(pwm->hwpwm); ··· 335 329 err = meson_pwm_calc(meson, channel, pwm->hwpwm, 336 330 state->duty_cycle, state->period); 337 331 if (err < 0) 338 - goto unlock; 332 + return err; 339 333 340 334 channel->state.polarity = state->polarity; 341 335 channel->state.period = state->period; ··· 347 341 channel->state.enabled = true; 348 342 } 349 343 350 - unlock: 351 - spin_unlock_irqrestore(&meson->lock, flags); 352 - return err; 344 + return 0; 353 345 } 354 346 355 347 static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, ··· 433 429 .num_parents = ARRAY_SIZE(pwm_axg_ao_parent_names), 434 430 }; 435 431 432 + static const char * const pwm_g12a_ao_cd_parent_names[] = { 433 + "aoclk81", "xtal", 434 + }; 435 + 436 + static const struct meson_pwm_data pwm_g12a_ao_cd_data = { 437 + .parent_names = pwm_g12a_ao_cd_parent_names, 438 + .num_parents = ARRAY_SIZE(pwm_g12a_ao_cd_parent_names), 439 + }; 440 + 441 + static const char * const pwm_g12a_ee_parent_names[] = { 442 + "xtal", "hdmi_pll", "fclk_div4", "fclk_div3" 443 + }; 444 + 445 + static const struct meson_pwm_data pwm_g12a_ee_data = { 446 + .parent_names = pwm_g12a_ee_parent_names, 447 + .num_parents = ARRAY_SIZE(pwm_g12a_ee_parent_names), 448 + }; 449 + 436 450 static const struct of_device_id meson_pwm_matches[] = { 437 451 { 438 452 .compatible = "amlogic,meson8b-pwm", ··· 471 449 { 472 450 .compatible = "amlogic,meson-axg-ao-pwm", 473 451 .data = &pwm_axg_ao_data 452 + }, 453 + { 454 + .compatible = "amlogic,meson-g12a-ee-pwm", 455 + .data = &pwm_g12a_ee_data 456 + }, 457 + { 458 + .compatible = "amlogic,meson-g12a-ao-pwm-ab", 459 + .data = &pwm_axg_ao_data 460 + }, 461 + { 462 + .compatible = "amlogic,meson-g12a-ao-pwm-cd", 463 + .data = &pwm_g12a_ao_cd_data 474 464 }, 475 465 {}, 476 466 };
-1
drivers/pwm/pwm-pca9685.c
··· 176 176 pm_runtime_put(pca->chip.dev); 177 177 mutex_lock(&pca->lock); 178 178 pwm = &pca->chip.pwms[offset]; 179 - pwm_set_chip_data(pwm, NULL); 180 179 mutex_unlock(&pca->lock); 181 180 } 182 181
+2 -3
drivers/pwm/pwm-samsung.c
··· 226 226 return -EINVAL; 227 227 } 228 228 229 - our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL); 229 + our_chan = kzalloc(sizeof(*our_chan), GFP_KERNEL); 230 230 if (!our_chan) 231 231 return -ENOMEM; 232 232 ··· 237 237 238 238 static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm) 239 239 { 240 - devm_kfree(chip->dev, pwm_get_chip_data(pwm)); 241 - pwm_set_chip_data(pwm, NULL); 240 + kfree(pwm_get_chip_data(pwm)); 242 241 } 243 242 244 243 static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+2
drivers/pwm/pwm-tiehrpwm.c
··· 382 382 } 383 383 384 384 /* Update shadow register first before modifying active register */ 385 + ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK, 386 + AQSFRC_RLDCSF_ZRO); 385 387 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); 386 388 /* 387 389 * Changes to immediate action on Action Qualifier. This puts
+2 -14
drivers/pwm/sysfs.c
··· 398 398 399 399 /* 400 400 * If device_create() fails the pwm_chip is still usable by 401 - * the kernel its just not exported. 401 + * the kernel it's just not exported. 402 402 */ 403 403 parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip, 404 404 "pwmchip%d", chip->base); ··· 409 409 } 410 410 411 411 void pwmchip_sysfs_unexport(struct pwm_chip *chip) 412 - { 413 - struct device *parent; 414 - 415 - parent = class_find_device(&pwm_class, NULL, chip, 416 - pwmchip_sysfs_match); 417 - if (parent) { 418 - /* for class_find_device() */ 419 - put_device(parent); 420 - device_unregister(parent); 421 - } 422 - } 423 - 424 - void pwmchip_sysfs_unexport_children(struct pwm_chip *chip) 425 412 { 426 413 struct device *parent; 427 414 unsigned int i; ··· 426 439 } 427 440 428 441 put_device(parent); 442 + device_unregister(parent); 429 443 } 430 444 431 445 static int __init pwm_sysfs_init(void)
-5
include/linux/pwm.h
··· 596 596 #ifdef CONFIG_PWM_SYSFS 597 597 void pwmchip_sysfs_export(struct pwm_chip *chip); 598 598 void pwmchip_sysfs_unexport(struct pwm_chip *chip); 599 - void pwmchip_sysfs_unexport_children(struct pwm_chip *chip); 600 599 #else 601 600 static inline void pwmchip_sysfs_export(struct pwm_chip *chip) 602 601 { 603 602 } 604 603 605 604 static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) 606 - { 607 - } 608 - 609 - static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip) 610 605 { 611 606 } 612 607 #endif /* CONFIG_PWM_SYSFS */