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

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

Pull pwm updates from Thierry Reding:
"This set of changes contains a new driver for OMAP (using the
dual-mode timers) as well as an assortment of fixes all across the
board"

* tag 'pwm/for-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
pwm: Mark all devices as "might sleep"
pwm: omap-dmtimer: Potential NULL dereference on error
pwm: add HAS_IOMEM dependency to PWM_FSL_FTM
pwm: Add PWM driver for OMAP using dual-mode timers
pwm: rcar: Improve accuracy of frequency division setting
pwm: lpc32xx: return ERANGE, if requested period is not supported
pwm: lpc32xx: fix and simplify duty cycle and period calculations
pwm: lpc32xx: make device usable with common clock framework
pwm: lpc32xx: correct number of PWM channels from 2 to 1
dt: lpc32xx: pwm: update documentation of LPC32xx PWM device
dt: lpc32xx: pwm: correct LPC32xx PWM device node example
pwm: fsl-ftm: Fix clock enable/disable when using PM
pwm: lpss: Rework the sequence of programming PWM_SW_UPDATE
pwm: lpss: Select core part automatically
pwm: lpss: Update PWM setting for Broxton
pwm: bcm2835: Fix email address specification
pwm: bcm2835: Prevent division by zero
pwm: bcm2835: Calculate scaler in ->config()
pwm: lpss: Remove ->free() callback

+537 -105
+7 -2
Documentation/devicetree/bindings/pwm/lpc32xx-pwm.txt
··· 6 6 7 7 Examples: 8 8 9 - pwm@0x4005C000 { 9 + pwm@4005c000 { 10 10 compatible = "nxp,lpc3220-pwm"; 11 - reg = <0x4005C000 0x8>; 11 + reg = <0x4005c000 0x4>; 12 + }; 13 + 14 + pwm@4005c004 { 15 + compatible = "nxp,lpc3220-pwm"; 16 + reg = <0x4005c004 0x4>; 12 17 };
+18
Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt
··· 1 + * OMAP PWM for dual-mode timers 2 + 3 + Required properties: 4 + - compatible: Shall contain "ti,omap-dmtimer-pwm". 5 + - ti,timers: phandle to PWM capable OMAP timer. See arm/omap/timer.txt for info 6 + about these timers. 7 + - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of 8 + the cells format. 9 + 10 + Optional properties: 11 + - ti,prescaler: Should be a value between 0 and 7, see the timers datasheet 12 + 13 + Example: 14 + pwm9: dmtimer-pwm@9 { 15 + compatible = "ti,omap-dmtimer-pwm"; 16 + ti,timers = <&timer9>; 17 + #pwm-cells = <3>; 18 + };
+15 -10
drivers/pwm/Kconfig
··· 148 148 149 149 config PWM_FSL_FTM 150 150 tristate "Freescale FlexTimer Module (FTM) PWM support" 151 + depends on HAS_IOMEM 151 152 depends on OF 152 153 select REGMAP_MMIO 153 154 help ··· 223 222 will be called pwm-lpc32xx. 224 223 225 224 config PWM_LPSS 226 - tristate "Intel LPSS PWM support" 227 - depends on X86 228 - help 229 - Generic PWM framework driver for Intel Low Power Subsystem PWM 230 - controller. 231 - 232 - To compile this driver as a module, choose M here: the module 233 - will be called pwm-lpss. 225 + tristate 234 226 235 227 config PWM_LPSS_PCI 236 228 tristate "Intel LPSS PWM PCI driver" 237 - depends on PWM_LPSS && PCI 229 + depends on X86 && PCI 230 + select PWM_LPSS 238 231 help 239 232 The PCI driver for Intel Low Power Subsystem PWM controller. 240 233 ··· 237 242 238 243 config PWM_LPSS_PLATFORM 239 244 tristate "Intel LPSS PWM platform driver" 240 - depends on PWM_LPSS && ACPI 245 + depends on X86 && ACPI 246 + select PWM_LPSS 241 247 help 242 248 The platform driver for Intel Low Power Subsystem PWM controller. 243 249 ··· 265 269 266 270 To compile this driver as a module, choose M here: the module 267 271 will be called pwm-mxs. 272 + 273 + config PWM_OMAP_DMTIMER 274 + tristate "OMAP Dual-Mode Timer PWM support" 275 + depends on OF && ARCH_OMAP && OMAP_DM_TIMER 276 + help 277 + Generic PWM framework driver for OMAP Dual-Mode Timer PWM output 278 + 279 + To compile this driver as a module, choose M here: the module 280 + will be called pwm-omap-dmtimer 268 281 269 282 config PWM_PCA9685 270 283 tristate "NXP PCA9685 PWM driver"
+1
drivers/pwm/Makefile
··· 24 24 obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o 25 25 obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o 26 26 obj-$(CONFIG_PWM_MXS) += pwm-mxs.o 27 + obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o 27 28 obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o 28 29 obj-$(CONFIG_PWM_PUV3) += pwm-puv3.o 29 30 obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
+1 -1
drivers/pwm/core.c
··· 889 889 */ 890 890 bool pwm_can_sleep(struct pwm_device *pwm) 891 891 { 892 - return pwm->chip->can_sleep; 892 + return true; 893 893 } 894 894 EXPORT_SYMBOL_GPL(pwm_can_sleep); 895 895
+12 -6
drivers/pwm/pwm-bcm2835.c
··· 29 29 struct bcm2835_pwm { 30 30 struct pwm_chip chip; 31 31 struct device *dev; 32 - unsigned long scaler; 33 32 void __iomem *base; 34 33 struct clk *clk; 35 34 }; ··· 65 66 int duty_ns, int period_ns) 66 67 { 67 68 struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); 69 + unsigned long rate = clk_get_rate(pc->clk); 70 + unsigned long scaler; 71 + 72 + if (!rate) { 73 + dev_err(pc->dev, "failed to get clock rate\n"); 74 + return -EINVAL; 75 + } 76 + 77 + scaler = NSEC_PER_SEC / rate; 68 78 69 79 if (period_ns <= MIN_PERIOD) { 70 80 dev_err(pc->dev, "period %d not supported, minimum %d\n", ··· 81 73 return -EINVAL; 82 74 } 83 75 84 - writel(duty_ns / pc->scaler, pc->base + DUTY(pwm->hwpwm)); 85 - writel(period_ns / pc->scaler, pc->base + PERIOD(pwm->hwpwm)); 76 + writel(duty_ns / scaler, pc->base + DUTY(pwm->hwpwm)); 77 + writel(period_ns / scaler, pc->base + PERIOD(pwm->hwpwm)); 86 78 87 79 return 0; 88 80 } ··· 164 156 if (ret) 165 157 return ret; 166 158 167 - pc->scaler = NSEC_PER_SEC / clk_get_rate(pc->clk); 168 - 169 159 pc->chip.dev = &pdev->dev; 170 160 pc->chip.ops = &bcm2835_pwm_ops; 171 161 pc->chip.npwm = 2; ··· 206 200 }; 207 201 module_platform_driver(bcm2835_pwm_driver); 208 202 209 - MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be"); 203 + MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be>"); 210 204 MODULE_DESCRIPTION("Broadcom BCM2835 PWM driver"); 211 205 MODULE_LICENSE("GPL v2");
+25 -33
drivers/pwm/pwm-fsl-ftm.c
··· 80 80 81 81 struct mutex lock; 82 82 83 - unsigned int use_count; 84 83 unsigned int cnt_select; 85 84 unsigned int clk_ps; 86 85 ··· 299 300 { 300 301 int ret; 301 302 302 - if (fpc->use_count++ != 0) 303 - return 0; 304 - 305 303 /* select counter clock source */ 306 304 regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK, 307 305 FTM_SC_CLK(fpc->cnt_select)); ··· 330 334 return ret; 331 335 } 332 336 333 - static void fsl_counter_clock_disable(struct fsl_pwm_chip *fpc) 334 - { 335 - /* 336 - * already disabled, do nothing 337 - */ 338 - if (fpc->use_count == 0) 339 - return; 340 - 341 - /* there are still users, so can't disable yet */ 342 - if (--fpc->use_count > 0) 343 - return; 344 - 345 - /* no users left, disable PWM counter clock */ 346 - regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK, 0); 347 - 348 - clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]); 349 - clk_disable_unprepare(fpc->clk[fpc->cnt_select]); 350 - } 351 - 352 337 static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 353 338 { 354 339 struct fsl_pwm_chip *fpc = to_fsl_chip(chip); ··· 339 362 regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm), 340 363 BIT(pwm->hwpwm)); 341 364 342 - fsl_counter_clock_disable(fpc); 365 + clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]); 366 + clk_disable_unprepare(fpc->clk[fpc->cnt_select]); 343 367 344 368 regmap_read(fpc->regmap, FTM_OUTMASK, &val); 345 369 if ((val & 0xFF) == 0xFF) ··· 470 492 static int fsl_pwm_suspend(struct device *dev) 471 493 { 472 494 struct fsl_pwm_chip *fpc = dev_get_drvdata(dev); 473 - u32 val; 495 + int i; 474 496 475 497 regcache_cache_only(fpc->regmap, true); 476 498 regcache_mark_dirty(fpc->regmap); 477 499 478 - /* read from cache */ 479 - regmap_read(fpc->regmap, FTM_OUTMASK, &val); 480 - if ((val & 0xFF) != 0xFF) { 500 + for (i = 0; i < fpc->chip.npwm; i++) { 501 + struct pwm_device *pwm = &fpc->chip.pwms[i]; 502 + 503 + if (!test_bit(PWMF_REQUESTED, &pwm->flags)) 504 + continue; 505 + 506 + clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]); 507 + 508 + if (!pwm_is_enabled(pwm)) 509 + continue; 510 + 481 511 clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]); 482 512 clk_disable_unprepare(fpc->clk[fpc->cnt_select]); 483 - clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]); 484 513 } 485 514 486 515 return 0; ··· 496 511 static int fsl_pwm_resume(struct device *dev) 497 512 { 498 513 struct fsl_pwm_chip *fpc = dev_get_drvdata(dev); 499 - u32 val; 514 + int i; 500 515 501 - /* read from cache */ 502 - regmap_read(fpc->regmap, FTM_OUTMASK, &val); 503 - if ((val & 0xFF) != 0xFF) { 516 + for (i = 0; i < fpc->chip.npwm; i++) { 517 + struct pwm_device *pwm = &fpc->chip.pwms[i]; 518 + 519 + if (!test_bit(PWMF_REQUESTED, &pwm->flags)) 520 + continue; 521 + 504 522 clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]); 523 + 524 + if (!pwm_is_enabled(pwm)) 525 + continue; 526 + 505 527 clk_prepare_enable(fpc->clk[fpc->cnt_select]); 506 528 clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]); 507 529 }
+20 -35
drivers/pwm/pwm-lpc32xx.c
··· 24 24 void __iomem *base; 25 25 }; 26 26 27 - #define PWM_ENABLE (1 << 31) 28 - #define PWM_RELOADV(x) (((x) & 0xFF) << 8) 29 - #define PWM_DUTY(x) ((x) & 0xFF) 27 + #define PWM_ENABLE BIT(31) 30 28 31 29 #define to_lpc32xx_pwm_chip(_chip) \ 32 30 container_of(_chip, struct lpc32xx_pwm_chip, chip) ··· 36 38 unsigned long long c; 37 39 int period_cycles, duty_cycles; 38 40 u32 val; 41 + c = clk_get_rate(lpc32xx->clk); 39 42 40 - c = clk_get_rate(lpc32xx->clk) / 256; 41 - c = c * period_ns; 42 - do_div(c, NSEC_PER_SEC); 43 + /* The highest acceptable divisor is 256, which is represented by 0 */ 44 + period_cycles = div64_u64(c * period_ns, 45 + (unsigned long long)NSEC_PER_SEC * 256); 46 + if (!period_cycles || period_cycles > 256) 47 + return -ERANGE; 48 + if (period_cycles == 256) 49 + period_cycles = 0; 43 50 44 - /* Handle high and low extremes */ 45 - if (c == 0) 46 - c = 1; 47 - if (c > 255) 48 - c = 0; /* 0 set division by 256 */ 49 - period_cycles = c; 50 - 51 - /* The duty-cycle value is as follows: 52 - * 53 - * DUTY-CYCLE HIGH LEVEL 54 - * 1 99.9% 55 - * 25 90.0% 56 - * 128 50.0% 57 - * 220 10.0% 58 - * 255 0.1% 59 - * 0 0.0% 60 - * 61 - * In other words, the register value is duty-cycle % 256 with 62 - * duty-cycle in the range 1-256. 63 - */ 64 - c = 256 * duty_ns; 65 - do_div(c, period_ns); 66 - if (c > 255) 67 - c = 255; 68 - duty_cycles = 256 - c; 51 + /* Compute 256 x #duty/period value and care for corner cases */ 52 + duty_cycles = div64_u64((unsigned long long)(period_ns - duty_ns) * 256, 53 + period_ns); 54 + if (!duty_cycles) 55 + duty_cycles = 1; 56 + if (duty_cycles > 255) 57 + duty_cycles = 255; 69 58 70 59 val = readl(lpc32xx->base + (pwm->hwpwm << 2)); 71 60 val &= ~0xFFFF; 72 - val |= PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles); 61 + val |= (period_cycles << 8) | duty_cycles; 73 62 writel(val, lpc32xx->base + (pwm->hwpwm << 2)); 74 63 75 64 return 0; ··· 68 83 u32 val; 69 84 int ret; 70 85 71 - ret = clk_enable(lpc32xx->clk); 86 + ret = clk_prepare_enable(lpc32xx->clk); 72 87 if (ret) 73 88 return ret; 74 89 ··· 88 103 val &= ~PWM_ENABLE; 89 104 writel(val, lpc32xx->base + (pwm->hwpwm << 2)); 90 105 91 - clk_disable(lpc32xx->clk); 106 + clk_disable_unprepare(lpc32xx->clk); 92 107 } 93 108 94 109 static const struct pwm_ops lpc32xx_pwm_ops = { ··· 119 134 120 135 lpc32xx->chip.dev = &pdev->dev; 121 136 lpc32xx->chip.ops = &lpc32xx_pwm_ops; 122 - lpc32xx->chip.npwm = 2; 137 + lpc32xx->chip.npwm = 1; 123 138 lpc32xx->chip.base = -1; 124 139 125 140 ret = pwmchip_add(&lpc32xx->chip);
+40 -17
drivers/pwm/pwm-lpss.c
··· 13 13 * published by the Free Software Foundation. 14 14 */ 15 15 16 + #include <linux/delay.h> 16 17 #include <linux/io.h> 17 18 #include <linux/kernel.h> 18 19 #include <linux/module.h> 19 20 #include <linux/pm_runtime.h> 21 + #include <linux/time.h> 20 22 21 23 #include "pwm-lpss.h" 22 24 ··· 26 24 #define PWM_ENABLE BIT(31) 27 25 #define PWM_SW_UPDATE BIT(30) 28 26 #define PWM_BASE_UNIT_SHIFT 8 29 - #define PWM_BASE_UNIT_MASK 0x00ffff00 30 27 #define PWM_ON_TIME_DIV_MASK 0x000000ff 31 28 #define PWM_DIVISION_CORRECTION 0x2 32 - #define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION) 33 - #define NSECS_PER_SEC 1000000000UL 34 29 35 30 /* Size of each PWM register space if multiple */ 36 31 #define PWM_SIZE 0x400 ··· 35 36 struct pwm_lpss_chip { 36 37 struct pwm_chip chip; 37 38 void __iomem *regs; 38 - unsigned long clk_rate; 39 + const struct pwm_lpss_boardinfo *info; 39 40 }; 40 41 41 42 /* BayTrail */ 42 43 const struct pwm_lpss_boardinfo pwm_lpss_byt_info = { 43 44 .clk_rate = 25000000, 44 45 .npwm = 1, 46 + .base_unit_bits = 16, 45 47 }; 46 48 EXPORT_SYMBOL_GPL(pwm_lpss_byt_info); 47 49 ··· 50 50 const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = { 51 51 .clk_rate = 19200000, 52 52 .npwm = 1, 53 + .base_unit_bits = 16, 53 54 }; 54 55 EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info); 55 56 ··· 58 57 const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = { 59 58 .clk_rate = 19200000, 60 59 .npwm = 4, 60 + .base_unit_bits = 22, 61 61 }; 62 62 EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info); 63 63 ··· 81 79 writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM); 82 80 } 83 81 82 + static void pwm_lpss_update(struct pwm_device *pwm) 83 + { 84 + pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE); 85 + /* Give it some time to propagate */ 86 + usleep_range(10, 50); 87 + } 88 + 84 89 static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm, 85 90 int duty_ns, int period_ns) 86 91 { 87 92 struct pwm_lpss_chip *lpwm = to_lpwm(chip); 88 93 u8 on_time_div; 89 - unsigned long c; 90 - unsigned long long base_unit, freq = NSECS_PER_SEC; 94 + unsigned long c, base_unit_range; 95 + unsigned long long base_unit, freq = NSEC_PER_SEC; 91 96 u32 ctrl; 92 97 93 98 do_div(freq, period_ns); 94 99 95 - /* The equation is: base_unit = ((freq / c) * 65536) + correction */ 96 - base_unit = freq * 65536; 100 + /* 101 + * The equation is: 102 + * base_unit = ((freq / c) * base_unit_range) + correction 103 + */ 104 + base_unit_range = BIT(lpwm->info->base_unit_bits); 105 + base_unit = freq * base_unit_range; 97 106 98 - c = lpwm->clk_rate; 107 + c = lpwm->info->clk_rate; 99 108 if (!c) 100 109 return -EINVAL; 101 110 102 111 do_div(base_unit, c); 103 112 base_unit += PWM_DIVISION_CORRECTION; 104 - if (base_unit > PWM_LIMIT) 105 - return -EINVAL; 106 113 107 114 if (duty_ns <= 0) 108 115 duty_ns = 1; ··· 120 109 pm_runtime_get_sync(chip->dev); 121 110 122 111 ctrl = pwm_lpss_read(pwm); 123 - ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK); 124 - ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT; 112 + ctrl &= ~PWM_ON_TIME_DIV_MASK; 113 + ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT); 114 + base_unit &= (base_unit_range - 1); 115 + ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT; 125 116 ctrl |= on_time_div; 126 - /* request PWM to update on next cycle */ 127 - ctrl |= PWM_SW_UPDATE; 128 117 pwm_lpss_write(pwm, ctrl); 118 + 119 + /* 120 + * If the PWM is already enabled we need to notify the hardware 121 + * about the change by setting PWM_SW_UPDATE. 122 + */ 123 + if (pwm_is_enabled(pwm)) 124 + pwm_lpss_update(pwm); 129 125 130 126 pm_runtime_put(chip->dev); 131 127 ··· 142 124 static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm) 143 125 { 144 126 pm_runtime_get_sync(chip->dev); 127 + 128 + /* 129 + * Hardware must first see PWM_SW_UPDATE before the PWM can be 130 + * enabled. 131 + */ 132 + pwm_lpss_update(pwm); 145 133 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE); 146 134 return 0; 147 135 } ··· 159 135 } 160 136 161 137 static const struct pwm_ops pwm_lpss_ops = { 162 - .free = pwm_lpss_disable, 163 138 .config = pwm_lpss_config, 164 139 .enable = pwm_lpss_enable, 165 140 .disable = pwm_lpss_disable, ··· 179 156 if (IS_ERR(lpwm->regs)) 180 157 return ERR_CAST(lpwm->regs); 181 158 182 - lpwm->clk_rate = info->clk_rate; 159 + lpwm->info = info; 183 160 lpwm->chip.dev = dev; 184 161 lpwm->chip.ops = &pwm_lpss_ops; 185 162 lpwm->chip.base = -1;
+1
drivers/pwm/pwm-lpss.h
··· 21 21 struct pwm_lpss_boardinfo { 22 22 unsigned long clk_rate; 23 23 unsigned int npwm; 24 + unsigned long base_unit_bits; 24 25 }; 25 26 26 27 extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
+327
drivers/pwm/pwm-omap-dmtimer.c
··· 1 + /* 2 + * Copyright (c) 2015 Neil Armstrong <narmstrong@baylibre.com> 3 + * Copyright (c) 2014 Joachim Eastwood <manabian@gmail.com> 4 + * Copyright (c) 2012 NeilBrown <neilb@suse.de> 5 + * Heavily based on earlier code which is: 6 + * Copyright (c) 2010 Grant Erickson <marathon96@gmail.com> 7 + * 8 + * Also based on pwm-samsung.c 9 + * 10 + * This program is free software; you can redistribute it and/or 11 + * modify it under the terms of the GNU General Public License 12 + * version 2 as published by the Free Software Foundation. 13 + * 14 + * Description: 15 + * This file is the core OMAP support for the generic, Linux 16 + * PWM driver / controller, using the OMAP's dual-mode timers. 17 + */ 18 + 19 + #include <linux/clk.h> 20 + #include <linux/err.h> 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 + #include <linux/mutex.h> 24 + #include <linux/of.h> 25 + #include <linux/of_platform.h> 26 + #include <linux/platform_data/pwm_omap_dmtimer.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/pm_runtime.h> 29 + #include <linux/pwm.h> 30 + #include <linux/slab.h> 31 + #include <linux/time.h> 32 + 33 + #define DM_TIMER_LOAD_MIN 0xfffffffe 34 + 35 + struct pwm_omap_dmtimer_chip { 36 + struct pwm_chip chip; 37 + struct mutex mutex; 38 + pwm_omap_dmtimer *dm_timer; 39 + struct pwm_omap_dmtimer_pdata *pdata; 40 + struct platform_device *dm_timer_pdev; 41 + }; 42 + 43 + static inline struct pwm_omap_dmtimer_chip * 44 + to_pwm_omap_dmtimer_chip(struct pwm_chip *chip) 45 + { 46 + return container_of(chip, struct pwm_omap_dmtimer_chip, chip); 47 + } 48 + 49 + static int pwm_omap_dmtimer_calc_value(unsigned long clk_rate, int ns) 50 + { 51 + u64 c = (u64)clk_rate * ns; 52 + 53 + do_div(c, NSEC_PER_SEC); 54 + 55 + return DM_TIMER_LOAD_MIN - c; 56 + } 57 + 58 + static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap) 59 + { 60 + /* 61 + * According to OMAP 4 TRM section 22.2.4.10 the counter should be 62 + * started at 0xFFFFFFFE when overflow and match is used to ensure 63 + * that the PWM line is toggled on the first event. 64 + * 65 + * Note that omap_dm_timer_enable/disable is for register access and 66 + * not the timer counter itself. 67 + */ 68 + omap->pdata->enable(omap->dm_timer); 69 + omap->pdata->write_counter(omap->dm_timer, DM_TIMER_LOAD_MIN); 70 + omap->pdata->disable(omap->dm_timer); 71 + 72 + omap->pdata->start(omap->dm_timer); 73 + } 74 + 75 + static int pwm_omap_dmtimer_enable(struct pwm_chip *chip, 76 + struct pwm_device *pwm) 77 + { 78 + struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 79 + 80 + mutex_lock(&omap->mutex); 81 + pwm_omap_dmtimer_start(omap); 82 + mutex_unlock(&omap->mutex); 83 + 84 + return 0; 85 + } 86 + 87 + static void pwm_omap_dmtimer_disable(struct pwm_chip *chip, 88 + struct pwm_device *pwm) 89 + { 90 + struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 91 + 92 + mutex_lock(&omap->mutex); 93 + omap->pdata->stop(omap->dm_timer); 94 + mutex_unlock(&omap->mutex); 95 + } 96 + 97 + static int pwm_omap_dmtimer_config(struct pwm_chip *chip, 98 + struct pwm_device *pwm, 99 + int duty_ns, int period_ns) 100 + { 101 + struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 102 + int load_value, match_value; 103 + struct clk *fclk; 104 + unsigned long clk_rate; 105 + bool timer_active; 106 + 107 + dev_dbg(chip->dev, "duty cycle: %d, period %d\n", duty_ns, period_ns); 108 + 109 + mutex_lock(&omap->mutex); 110 + if (duty_ns == pwm_get_duty_cycle(pwm) && 111 + period_ns == pwm_get_period(pwm)) { 112 + /* No change - don't cause any transients. */ 113 + mutex_unlock(&omap->mutex); 114 + return 0; 115 + } 116 + 117 + fclk = omap->pdata->get_fclk(omap->dm_timer); 118 + if (!fclk) { 119 + dev_err(chip->dev, "invalid pmtimer fclk\n"); 120 + mutex_unlock(&omap->mutex); 121 + return -EINVAL; 122 + } 123 + 124 + clk_rate = clk_get_rate(fclk); 125 + if (!clk_rate) { 126 + dev_err(chip->dev, "invalid pmtimer fclk rate\n"); 127 + mutex_unlock(&omap->mutex); 128 + return -EINVAL; 129 + } 130 + 131 + dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate); 132 + 133 + /* 134 + * Calculate the appropriate load and match values based on the 135 + * specified period and duty cycle. The load value determines the 136 + * cycle time and the match value determines the duty cycle. 137 + */ 138 + load_value = pwm_omap_dmtimer_calc_value(clk_rate, period_ns); 139 + match_value = pwm_omap_dmtimer_calc_value(clk_rate, 140 + period_ns - duty_ns); 141 + 142 + /* 143 + * We MUST stop the associated dual-mode timer before attempting to 144 + * write its registers, but calls to omap_dm_timer_start/stop must 145 + * be balanced so check if timer is active before calling timer_stop. 146 + */ 147 + timer_active = pm_runtime_active(&omap->dm_timer_pdev->dev); 148 + if (timer_active) 149 + omap->pdata->stop(omap->dm_timer); 150 + 151 + omap->pdata->set_load(omap->dm_timer, true, load_value); 152 + omap->pdata->set_match(omap->dm_timer, true, match_value); 153 + 154 + dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n", 155 + load_value, load_value, match_value, match_value); 156 + 157 + omap->pdata->set_pwm(omap->dm_timer, 158 + pwm->polarity == PWM_POLARITY_INVERSED, 159 + true, 160 + PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); 161 + 162 + /* If config was called while timer was running it must be reenabled. */ 163 + if (timer_active) 164 + pwm_omap_dmtimer_start(omap); 165 + 166 + mutex_unlock(&omap->mutex); 167 + 168 + return 0; 169 + } 170 + 171 + static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip, 172 + struct pwm_device *pwm, 173 + enum pwm_polarity polarity) 174 + { 175 + struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); 176 + 177 + /* 178 + * PWM core will not call set_polarity while PWM is enabled so it's 179 + * safe to reconfigure the timer here without stopping it first. 180 + */ 181 + mutex_lock(&omap->mutex); 182 + omap->pdata->set_pwm(omap->dm_timer, 183 + polarity == PWM_POLARITY_INVERSED, 184 + true, 185 + PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); 186 + mutex_unlock(&omap->mutex); 187 + 188 + return 0; 189 + } 190 + 191 + static const struct pwm_ops pwm_omap_dmtimer_ops = { 192 + .enable = pwm_omap_dmtimer_enable, 193 + .disable = pwm_omap_dmtimer_disable, 194 + .config = pwm_omap_dmtimer_config, 195 + .set_polarity = pwm_omap_dmtimer_set_polarity, 196 + .owner = THIS_MODULE, 197 + }; 198 + 199 + static int pwm_omap_dmtimer_probe(struct platform_device *pdev) 200 + { 201 + struct device_node *np = pdev->dev.of_node; 202 + struct device_node *timer; 203 + struct pwm_omap_dmtimer_chip *omap; 204 + struct pwm_omap_dmtimer_pdata *pdata; 205 + pwm_omap_dmtimer *dm_timer; 206 + u32 prescaler; 207 + int status; 208 + 209 + pdata = dev_get_platdata(&pdev->dev); 210 + if (!pdata) { 211 + dev_err(&pdev->dev, "Missing dmtimer platform data\n"); 212 + return -EINVAL; 213 + } 214 + 215 + if (!pdata->request_by_node || 216 + !pdata->free || 217 + !pdata->enable || 218 + !pdata->disable || 219 + !pdata->get_fclk || 220 + !pdata->start || 221 + !pdata->stop || 222 + !pdata->set_load || 223 + !pdata->set_match || 224 + !pdata->set_pwm || 225 + !pdata->set_prescaler || 226 + !pdata->write_counter) { 227 + dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); 228 + return -EINVAL; 229 + } 230 + 231 + timer = of_parse_phandle(np, "ti,timers", 0); 232 + if (!timer) 233 + return -ENODEV; 234 + 235 + if (!of_get_property(timer, "ti,timer-pwm", NULL)) { 236 + dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); 237 + return -ENODEV; 238 + } 239 + 240 + dm_timer = pdata->request_by_node(timer); 241 + if (!dm_timer) 242 + return -EPROBE_DEFER; 243 + 244 + omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); 245 + if (!omap) { 246 + pdata->free(dm_timer); 247 + return -ENOMEM; 248 + } 249 + 250 + omap->pdata = pdata; 251 + omap->dm_timer = dm_timer; 252 + 253 + omap->dm_timer_pdev = of_find_device_by_node(timer); 254 + if (!omap->dm_timer_pdev) { 255 + dev_err(&pdev->dev, "Unable to find timer pdev\n"); 256 + omap->pdata->free(dm_timer); 257 + return -EINVAL; 258 + } 259 + 260 + /* 261 + * Ensure that the timer is stopped before we allow PWM core to call 262 + * pwm_enable. 263 + */ 264 + if (pm_runtime_active(&omap->dm_timer_pdev->dev)) 265 + omap->pdata->stop(omap->dm_timer); 266 + 267 + /* setup dmtimer prescaler */ 268 + if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", 269 + &prescaler)) 270 + omap->pdata->set_prescaler(omap->dm_timer, prescaler); 271 + 272 + omap->chip.dev = &pdev->dev; 273 + omap->chip.ops = &pwm_omap_dmtimer_ops; 274 + omap->chip.base = -1; 275 + omap->chip.npwm = 1; 276 + omap->chip.of_xlate = of_pwm_xlate_with_flags; 277 + omap->chip.of_pwm_n_cells = 3; 278 + 279 + mutex_init(&omap->mutex); 280 + 281 + status = pwmchip_add(&omap->chip); 282 + if (status < 0) { 283 + dev_err(&pdev->dev, "failed to register PWM\n"); 284 + omap->pdata->free(omap->dm_timer); 285 + return status; 286 + } 287 + 288 + platform_set_drvdata(pdev, omap); 289 + 290 + return 0; 291 + } 292 + 293 + static int pwm_omap_dmtimer_remove(struct platform_device *pdev) 294 + { 295 + struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev); 296 + 297 + if (pm_runtime_active(&omap->dm_timer_pdev->dev)) 298 + omap->pdata->stop(omap->dm_timer); 299 + 300 + omap->pdata->free(omap->dm_timer); 301 + 302 + mutex_destroy(&omap->mutex); 303 + 304 + return pwmchip_remove(&omap->chip); 305 + } 306 + 307 + static const struct of_device_id pwm_omap_dmtimer_of_match[] = { 308 + {.compatible = "ti,omap-dmtimer-pwm"}, 309 + {} 310 + }; 311 + MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match); 312 + 313 + static struct platform_driver pwm_omap_dmtimer_driver = { 314 + .driver = { 315 + .name = "omap-dmtimer-pwm", 316 + .of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match), 317 + }, 318 + .probe = pwm_omap_dmtimer_probe, 319 + .remove = pwm_omap_dmtimer_remove, 320 + }; 321 + module_platform_driver(pwm_omap_dmtimer_driver); 322 + 323 + MODULE_AUTHOR("Grant Erickson <marathon96@gmail.com>"); 324 + MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); 325 + MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 326 + MODULE_LICENSE("GPL v2"); 327 + MODULE_DESCRIPTION("OMAP PWM Driver using Dual-mode Timers");
+1 -1
drivers/pwm/pwm-rcar.c
··· 81 81 max = (unsigned long long)NSEC_PER_SEC * RCAR_PWM_MAX_CYCLE * 82 82 (1 << div); 83 83 do_div(max, clk_rate); 84 - if (period_ns < max) 84 + if (period_ns <= max) 85 85 break; 86 86 } 87 87
+69
include/linux/platform_data/pwm_omap_dmtimer.h
··· 1 + /* 2 + * include/linux/platform_data/pwm_omap_dmtimer.h 3 + * 4 + * OMAP Dual-Mode Timer PWM platform data 5 + * 6 + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 7 + * Tarun Kanti DebBarma <tarun.kanti@ti.com> 8 + * Thara Gopinath <thara@ti.com> 9 + * 10 + * Platform device conversion and hwmod support. 11 + * 12 + * Copyright (C) 2005 Nokia Corporation 13 + * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com> 14 + * PWM and clock framework support by Timo Teras. 15 + * 16 + * This program is free software; you can redistribute it and/or modify it 17 + * under the terms of the GNU General Public License as published by the 18 + * Free Software Foundation; either version 2 of the License, or (at your 19 + * option) any later version. 20 + * 21 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 24 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 + * 30 + * You should have received a copy of the GNU General Public License along 31 + * with this program; if not, write to the Free Software Foundation, Inc., 32 + * 675 Mass Ave, Cambridge, MA 02139, USA. 33 + */ 34 + 35 + #ifndef __PWM_OMAP_DMTIMER_PDATA_H 36 + #define __PWM_OMAP_DMTIMER_PDATA_H 37 + 38 + /* trigger types */ 39 + #define PWM_OMAP_DMTIMER_TRIGGER_NONE 0x00 40 + #define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW 0x01 41 + #define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02 42 + 43 + struct omap_dm_timer; 44 + typedef struct omap_dm_timer pwm_omap_dmtimer; 45 + 46 + struct pwm_omap_dmtimer_pdata { 47 + pwm_omap_dmtimer *(*request_by_node)(struct device_node *np); 48 + int (*free)(pwm_omap_dmtimer *timer); 49 + 50 + void (*enable)(pwm_omap_dmtimer *timer); 51 + void (*disable)(pwm_omap_dmtimer *timer); 52 + 53 + struct clk *(*get_fclk)(pwm_omap_dmtimer *timer); 54 + 55 + int (*start)(pwm_omap_dmtimer *timer); 56 + int (*stop)(pwm_omap_dmtimer *timer); 57 + 58 + int (*set_load)(pwm_omap_dmtimer *timer, int autoreload, 59 + unsigned int value); 60 + int (*set_match)(pwm_omap_dmtimer *timer, int enable, 61 + unsigned int match); 62 + int (*set_pwm)(pwm_omap_dmtimer *timer, int def_on, 63 + int toggle, int trigger); 64 + int (*set_prescaler)(pwm_omap_dmtimer *timer, int prescaler); 65 + 66 + int (*write_counter)(pwm_omap_dmtimer *timer, unsigned int value); 67 + }; 68 + 69 + #endif /* __PWM_OMAP_DMTIMER_PDATA_H */