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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull pwm updates from Thierry Reding:
"This series contains a number of improvements to existing drivers,
such as LPSS. Some drivers, such as renesas-tpu and rcar get support
for more SoC generations. To round things off this fixes an issue with
the sysfs interface"

* tag 'pwm/for-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
pwm: lpss: Only set update bit if we are actually changing the settings
pwm: lpss: Force runtime-resume on suspend on Cherry Trail
pwm: Enable TI ECAP driver for ARCH_K3
dt-bindings: pwm: tiecap: Add TI AM654 SoC specific compatible
dt-bindings: pwm: rcar: Add r8a774a1 support
pwm: Send a uevent on the pwmchip device upon channel sysfs (un)export
Revert "pwm: Set class for exported channels in sysfs"
dt-bindings: pwm: renesas-tpu: Document r8a7744 support
dt-bindings: pwm: rcar: Add r8a7744 support
dt-bindings: pwm: renesas: tpu: Document R8A779{7|8}0 bindings
dt-bindings: pwm: renesas: pwm-rcar: Document R8A779{7|8}0 bindings
dt-bindings: pwm: renesas: tpu: Fix "compatible" prop description
pwm: Use SPDX identifier for Renesas drivers
pwm: lpss: Add get_state callback
pwm: lpss: Release runtime-pm reference from the driver's remove callback
pwm: lpss: Check PWM powerstate after resume on Cherry Trail devices
pwm: lpss: Move struct pwm_lpss_chip definition to the header file
pwm: lpss: Add ACPI HID for second PWM controller on Cherry Trail devices
ACPI / PM: Export acpi_device_get_power() for use by modular build drivers
pwm: tegra: Remove gratuituous blank line

+110 -38
+1
Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
··· 7 7 for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; 8 8 for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap"; 9 9 for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap"; 10 + for am654 - compatible = "ti,am654-ecap", "ti,am3352-ecap"; 10 11 - #pwm-cells: should be 3. See pwm.txt in this directory for a description of 11 12 the cells format. The PWM channel index ranges from 0 to 4. The only third 12 13 cell flag supported by this binding is PWM_POLARITY_INVERTED.
+4
Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt
··· 3 3 Required Properties: 4 4 - compatible: should be "renesas,pwm-rcar" and one of the following. 5 5 - "renesas,pwm-r8a7743": for RZ/G1M 6 + - "renesas,pwm-r8a7744": for RZ/G1N 6 7 - "renesas,pwm-r8a7745": for RZ/G1E 8 + - "renesas,pwm-r8a774a1": for RZ/G2M 7 9 - "renesas,pwm-r8a7778": for R-Car M1A 8 10 - "renesas,pwm-r8a7779": for R-Car H1 9 11 - "renesas,pwm-r8a7790": for R-Car H2 ··· 14 12 - "renesas,pwm-r8a7795": for R-Car H3 15 13 - "renesas,pwm-r8a7796": for R-Car M3-W 16 14 - "renesas,pwm-r8a77965": for R-Car M3-N 15 + - "renesas,pwm-r8a77970": for R-Car V3M 16 + - "renesas,pwm-r8a77980": for R-Car V3H 17 17 - "renesas,pwm-r8a77990": for R-Car E3 18 18 - "renesas,pwm-r8a77995": for R-Car D3 19 19 - reg: base address and length of the registers block for the PWM.
+8 -2
Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt
··· 2 2 3 3 Required Properties: 4 4 5 - - compatible: should be one of the following. 5 + - compatible: must contain one or more of the following: 6 6 - "renesas,tpu-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible PWM controller. 7 7 - "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller. 8 8 - "renesas,tpu-r8a7743": for R8A7743 (RZ/G1M) compatible PWM controller. 9 + - "renesas,tpu-r8a7744": for R8A7744 (RZ/G1N) compatible PWM controller. 9 10 - "renesas,tpu-r8a7745": for R8A7745 (RZ/G1E) compatible PWM controller. 10 11 - "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller. 11 - - "renesas,tpu": for generic R-Car and RZ/G1 TPU PWM controller. 12 + - "renesas,tpu-r8a77970": for R8A77970 (R-Car V3M) compatible PWM 13 + controller. 14 + - "renesas,tpu-r8a77980": for R8A77980 (R-Car V3H) compatible PWM 15 + controller. 16 + - "renesas,tpu": for the generic TPU PWM controller; this is a fallback for 17 + the entries listed above. 12 18 13 19 - reg: Base address and length of each memory resource used by the PWM 14 20 controller hardware module.
+1
drivers/acpi/device_pm.c
··· 126 126 127 127 return 0; 128 128 } 129 + EXPORT_SYMBOL(acpi_device_get_power); 129 130 130 131 static int acpi_dev_pm_explicit_set(struct acpi_device *adev, int state) 131 132 {
+2 -3
drivers/pwm/Kconfig
··· 447 447 448 448 config PWM_TIECAP 449 449 tristate "ECAP PWM support" 450 - depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE 450 + depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE || ARCH_K3 451 451 help 452 - PWM driver support for the ECAP APWM controller found on AM33XX 453 - TI SOC 452 + PWM driver support for the ECAP APWM controller found on TI SOCs 454 453 455 454 To compile this driver as a module, choose M here: the module 456 455 will be called pwm-tiecap.
+21 -3
drivers/pwm/pwm-lpss-platform.c
··· 30 30 .clk_rate = 19200000, 31 31 .npwm = 1, 32 32 .base_unit_bits = 16, 33 + .other_devices_aml_touches_pwm_regs = true, 33 34 }; 34 35 35 36 /* Broxton */ ··· 61 60 62 61 platform_set_drvdata(pdev, lpwm); 63 62 63 + dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_SMART_PREPARE); 64 64 pm_runtime_set_active(&pdev->dev); 65 65 pm_runtime_enable(&pdev->dev); 66 66 ··· 76 74 return pwm_lpss_remove(lpwm); 77 75 } 78 76 79 - static SIMPLE_DEV_PM_OPS(pwm_lpss_platform_pm_ops, 80 - pwm_lpss_suspend, 81 - pwm_lpss_resume); 77 + static int pwm_lpss_prepare(struct device *dev) 78 + { 79 + struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev); 80 + 81 + /* 82 + * If other device's AML code touches the PWM regs on suspend/resume 83 + * force runtime-resume the PWM controller to allow this. 84 + */ 85 + if (lpwm->info->other_devices_aml_touches_pwm_regs) 86 + return 0; /* Force runtime-resume */ 87 + 88 + return 1; /* If runtime-suspended leave as is */ 89 + } 90 + 91 + static const struct dev_pm_ops pwm_lpss_platform_pm_ops = { 92 + .prepare = pwm_lpss_prepare, 93 + SET_SYSTEM_SLEEP_PM_OPS(pwm_lpss_suspend, pwm_lpss_resume) 94 + }; 82 95 83 96 static const struct acpi_device_id pwm_lpss_acpi_match[] = { 84 97 { "80860F09", (unsigned long)&pwm_lpss_byt_info }, 85 98 { "80862288", (unsigned long)&pwm_lpss_bsw_info }, 99 + { "80862289", (unsigned long)&pwm_lpss_bsw_info }, 86 100 { "80865AC8", (unsigned long)&pwm_lpss_bxt_info }, 87 101 { }, 88 102 };
+47 -14
drivers/pwm/pwm-lpss.c
··· 32 32 /* Size of each PWM register space if multiple */ 33 33 #define PWM_SIZE 0x400 34 34 35 - #define MAX_PWMS 4 36 - 37 - struct pwm_lpss_chip { 38 - struct pwm_chip chip; 39 - void __iomem *regs; 40 - const struct pwm_lpss_boardinfo *info; 41 - u32 saved_ctrl[MAX_PWMS]; 42 - }; 43 - 44 35 static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) 45 36 { 46 37 return container_of(chip, struct pwm_lpss_chip, chip); ··· 88 97 unsigned long long on_time_div; 89 98 unsigned long c = lpwm->info->clk_rate, base_unit_range; 90 99 unsigned long long base_unit, freq = NSEC_PER_SEC; 91 - u32 ctrl; 100 + u32 orig_ctrl, ctrl; 92 101 93 102 do_div(freq, period_ns); 94 103 ··· 105 114 do_div(on_time_div, period_ns); 106 115 on_time_div = 255ULL - on_time_div; 107 116 108 - ctrl = pwm_lpss_read(pwm); 117 + orig_ctrl = ctrl = pwm_lpss_read(pwm); 109 118 ctrl &= ~PWM_ON_TIME_DIV_MASK; 110 119 ctrl &= ~(base_unit_range << PWM_BASE_UNIT_SHIFT); 111 120 base_unit &= base_unit_range; 112 121 ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT; 113 122 ctrl |= on_time_div; 114 - pwm_lpss_write(pwm, ctrl); 123 + 124 + if (orig_ctrl != ctrl) { 125 + pwm_lpss_write(pwm, ctrl); 126 + pwm_lpss_write(pwm, ctrl | PWM_SW_UPDATE); 127 + } 115 128 } 116 129 117 130 static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond) ··· 139 144 return ret; 140 145 } 141 146 pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); 142 - pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE); 143 147 pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false); 144 148 ret = pwm_lpss_wait_for_update(pwm); 145 149 if (ret) { ··· 151 157 if (ret) 152 158 return ret; 153 159 pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); 154 - pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE); 155 160 return pwm_lpss_wait_for_update(pwm); 156 161 } 157 162 } else if (pwm_is_enabled(pwm)) { ··· 161 168 return 0; 162 169 } 163 170 171 + /* This function gets called once from pwmchip_add to get the initial state */ 172 + static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm, 173 + struct pwm_state *state) 174 + { 175 + struct pwm_lpss_chip *lpwm = to_lpwm(chip); 176 + unsigned long base_unit_range; 177 + unsigned long long base_unit, freq, on_time_div; 178 + u32 ctrl; 179 + 180 + base_unit_range = BIT(lpwm->info->base_unit_bits); 181 + 182 + ctrl = pwm_lpss_read(pwm); 183 + on_time_div = 255 - (ctrl & PWM_ON_TIME_DIV_MASK); 184 + base_unit = (ctrl >> PWM_BASE_UNIT_SHIFT) & (base_unit_range - 1); 185 + 186 + freq = base_unit * lpwm->info->clk_rate; 187 + do_div(freq, base_unit_range); 188 + if (freq == 0) 189 + state->period = NSEC_PER_SEC; 190 + else 191 + state->period = NSEC_PER_SEC / (unsigned long)freq; 192 + 193 + on_time_div *= state->period; 194 + do_div(on_time_div, 255); 195 + state->duty_cycle = on_time_div; 196 + 197 + state->polarity = PWM_POLARITY_NORMAL; 198 + state->enabled = !!(ctrl & PWM_ENABLE); 199 + 200 + if (state->enabled) 201 + pm_runtime_get(chip->dev); 202 + } 203 + 164 204 static const struct pwm_ops pwm_lpss_ops = { 165 205 .apply = pwm_lpss_apply, 206 + .get_state = pwm_lpss_get_state, 166 207 .owner = THIS_MODULE, 167 208 }; 168 209 ··· 241 214 242 215 int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) 243 216 { 217 + int i; 218 + 219 + for (i = 0; i < lpwm->info->npwm; i++) { 220 + if (pwm_is_enabled(&lpwm->chip.pwms[i])) 221 + pm_runtime_put(lpwm->chip.dev); 222 + } 244 223 return pwmchip_remove(&lpwm->chip); 245 224 } 246 225 EXPORT_SYMBOL_GPL(pwm_lpss_remove);
+13 -1
drivers/pwm/pwm-lpss.h
··· 16 16 #include <linux/device.h> 17 17 #include <linux/pwm.h> 18 18 19 - struct pwm_lpss_chip; 19 + #define MAX_PWMS 4 20 + 21 + struct pwm_lpss_chip { 22 + struct pwm_chip chip; 23 + void __iomem *regs; 24 + const struct pwm_lpss_boardinfo *info; 25 + u32 saved_ctrl[MAX_PWMS]; 26 + }; 20 27 21 28 struct pwm_lpss_boardinfo { 22 29 unsigned long clk_rate; 23 30 unsigned int npwm; 24 31 unsigned long base_unit_bits; 25 32 bool bypass; 33 + /* 34 + * On some devices the _PS0/_PS3 AML code of the GPU (GFX0) device 35 + * messes with the PWM0 controllers state, 36 + */ 37 + bool other_devices_aml_touches_pwm_regs; 26 38 }; 27 39 28 40 struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
+1 -4
drivers/pwm/pwm-rcar.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * R-Car PWM Timer driver 3 4 * 4 5 * Copyright (C) 2015 Renesas Electronics Corporation 5 - * 6 - * This is free software; you can redistribute it and/or modify 7 - * it under the terms of version 2 of the GNU General Public License as 8 - * published by the Free Software Foundation. 9 6 */ 10 7 11 8 #include <linux/clk.h>
+1 -9
drivers/pwm/pwm-renesas-tpu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * R-Mobile TPU PWM driver 3 4 * 4 5 * Copyright (C) 2012 Renesas Solutions Corp. 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License 9 - * 10 - * This program is distributed in the hope that it will be useful, 11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - * GNU General Public License for more details. 14 6 */ 15 7 16 8 #include <linux/clk.h>
-1
drivers/pwm/pwm-tegra.c
··· 300 300 { .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc }, 301 301 { } 302 302 }; 303 - 304 303 MODULE_DEVICE_TABLE(of, tegra_pwm_of_match); 305 304 306 305 static const struct dev_pm_ops tegra_pwm_pm_ops = {
+11 -1
drivers/pwm/sysfs.c
··· 249 249 static int pwm_export_child(struct device *parent, struct pwm_device *pwm) 250 250 { 251 251 struct pwm_export *export; 252 + char *pwm_prop[2]; 252 253 int ret; 253 254 254 255 if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) ··· 264 263 export->pwm = pwm; 265 264 mutex_init(&export->lock); 266 265 267 - export->child.class = parent->class; 268 266 export->child.release = pwm_export_release; 269 267 export->child.parent = parent; 270 268 export->child.devt = MKDEV(0, 0); ··· 277 277 export = NULL; 278 278 return ret; 279 279 } 280 + pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm); 281 + pwm_prop[1] = NULL; 282 + kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop); 283 + kfree(pwm_prop[0]); 280 284 281 285 return 0; 282 286 } ··· 293 289 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm) 294 290 { 295 291 struct device *child; 292 + char *pwm_prop[2]; 296 293 297 294 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags)) 298 295 return -ENODEV; ··· 301 296 child = device_find_child(parent, pwm, pwm_unexport_match); 302 297 if (!child) 303 298 return -ENODEV; 299 + 300 + pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm); 301 + pwm_prop[1] = NULL; 302 + kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop); 303 + kfree(pwm_prop[0]); 304 304 305 305 /* for device_find_child() */ 306 306 put_device(child);