diff options
31 files changed, 578 insertions, 178 deletions
diff --git a/Documentation/devicetree/bindings/pwm/bcm-kona-pwm.txt b/Documentation/devicetree/bindings/pwm/bcm-kona-pwm.txt new file mode 100644 index 000000000000..8eae9fe7841c --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/bcm-kona-pwm.txt | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | Broadcom Kona PWM controller device tree bindings | ||
| 2 | |||
| 3 | This controller has 6 channels. | ||
| 4 | |||
| 5 | Required Properties : | ||
| 6 | - compatible: should contain "brcm,kona-pwm" | ||
| 7 | - reg: physical base address and length of the controller's registers | ||
| 8 | - clocks: phandle + clock specifier pair for the external clock | ||
| 9 | - #pwm-cells: Should be 3. See pwm.txt in this directory for a | ||
| 10 | description of the cells format. | ||
| 11 | |||
| 12 | Refer to clocks/clock-bindings.txt for generic clock consumer properties. | ||
| 13 | |||
| 14 | Example: | ||
| 15 | |||
| 16 | pwm: pwm@3e01a000 { | ||
| 17 | compatible = "brcm,bcm11351-pwm", "brcm,kona-pwm"; | ||
| 18 | reg = <0x3e01a000 0xc4>; | ||
| 19 | clocks = <&pwm_clk>; | ||
| 20 | #pwm-cells = <3>; | ||
| 21 | }; | ||
diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt index 93cb97974986..ca895fd211e4 100644 --- a/Documentation/pwm.txt +++ b/Documentation/pwm.txt | |||
| @@ -19,7 +19,8 @@ should instead register a static mapping that can be used to match PWM | |||
| 19 | consumers to providers, as given in the following example: | 19 | consumers to providers, as given in the following example: |
| 20 | 20 | ||
| 21 | static struct pwm_lookup board_pwm_lookup[] = { | 21 | static struct pwm_lookup board_pwm_lookup[] = { |
| 22 | PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight", NULL), | 22 | PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight", NULL, |
| 23 | 50000, PWM_POLARITY_NORMAL), | ||
| 23 | }; | 24 | }; |
| 24 | 25 | ||
| 25 | static void __init board_init(void) | 26 | static void __init board_init(void) |
| @@ -97,6 +98,13 @@ pwm_chip as argument which provides a description of the PWM chip, the | |||
| 97 | number of PWM devices provided by the chip and the chip-specific | 98 | number of PWM devices provided by the chip and the chip-specific |
| 98 | implementation of the supported PWM operations to the framework. | 99 | implementation of the supported PWM operations to the framework. |
| 99 | 100 | ||
| 101 | When implementing polarity support in a PWM driver, make sure to respect the | ||
| 102 | signal conventions in the PWM framework. By definition, normal polarity | ||
| 103 | characterizes a signal starts high for the duration of the duty cycle and | ||
| 104 | goes low for the remainder of the period. Conversely, a signal with inversed | ||
| 105 | polarity starts low for the duration of the duty cycle and goes high for the | ||
| 106 | remainder of the period. | ||
| 107 | |||
| 100 | Locking | 108 | Locking |
| 101 | ------- | 109 | ------- |
| 102 | 110 | ||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 660bfc5a70d7..e2e52031f056 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
| @@ -60,7 +60,8 @@ | |||
| 60 | 60 | ||
| 61 | static struct pwm_lookup pwm_lookup[] = { | 61 | static struct pwm_lookup pwm_lookup[] = { |
| 62 | /* LEDB -> PMU_STAT */ | 62 | /* LEDB -> PMU_STAT */ |
| 63 | PWM_LOOKUP("twl-pwmled", 1, "leds_pwm", "beagleboard::pmu_stat"), | 63 | PWM_LOOKUP("twl-pwmled", 1, "leds_pwm", "beagleboard::pmu_stat", |
| 64 | 7812500, PWM_POLARITY_NORMAL), | ||
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | static struct led_pwm pwm_leds[] = { | 67 | static struct led_pwm pwm_leds[] = { |
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index a7c30eb0c8db..c66ad4edc5e3 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c | |||
| @@ -574,7 +574,8 @@ static struct platform_device backlight = { | |||
| 574 | }; | 574 | }; |
| 575 | 575 | ||
| 576 | static struct pwm_lookup hx4700_pwm_lookup[] = { | 576 | static struct pwm_lookup hx4700_pwm_lookup[] = { |
| 577 | PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL), | 577 | PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL, |
| 578 | 30923, PWM_POLARITY_NORMAL), | ||
| 578 | }; | 579 | }; |
| 579 | 580 | ||
| 580 | /* | 581 | /* |
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 01f81100c330..30fcac73a540 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <linux/gpio_keys.h> | 31 | #include <linux/gpio_keys.h> |
| 32 | #include <linux/regulator/driver.h> | 32 | #include <linux/regulator/driver.h> |
| 33 | #include <linux/pinctrl/machine.h> | 33 | #include <linux/pinctrl/machine.h> |
| 34 | #include <linux/platform_data/pwm-renesas-tpu.h> | 34 | #include <linux/pwm.h> |
| 35 | #include <linux/pwm_backlight.h> | 35 | #include <linux/pwm_backlight.h> |
| 36 | #include <linux/regulator/fixed.h> | 36 | #include <linux/regulator/fixed.h> |
| 37 | #include <linux/regulator/gpio-regulator.h> | 37 | #include <linux/regulator/gpio-regulator.h> |
| @@ -399,24 +399,16 @@ static struct resource pwm_resources[] = { | |||
| 399 | }, | 399 | }, |
| 400 | }; | 400 | }; |
| 401 | 401 | ||
| 402 | static struct tpu_pwm_platform_data pwm_device_data = { | ||
| 403 | .channels[2] = { | ||
| 404 | .polarity = PWM_POLARITY_INVERSED, | ||
| 405 | } | ||
| 406 | }; | ||
| 407 | |||
| 408 | static struct platform_device pwm_device = { | 402 | static struct platform_device pwm_device = { |
| 409 | .name = "renesas-tpu-pwm", | 403 | .name = "renesas-tpu-pwm", |
| 410 | .id = -1, | 404 | .id = -1, |
| 411 | .dev = { | ||
| 412 | .platform_data = &pwm_device_data, | ||
| 413 | }, | ||
| 414 | .num_resources = ARRAY_SIZE(pwm_resources), | 405 | .num_resources = ARRAY_SIZE(pwm_resources), |
| 415 | .resource = pwm_resources, | 406 | .resource = pwm_resources, |
| 416 | }; | 407 | }; |
| 417 | 408 | ||
| 418 | static struct pwm_lookup pwm_lookup[] = { | 409 | static struct pwm_lookup pwm_lookup[] = { |
| 419 | PWM_LOOKUP("renesas-tpu-pwm", 2, "pwm-backlight.0", NULL), | 410 | PWM_LOOKUP("renesas-tpu-pwm", 2, "pwm-backlight.0", NULL, |
| 411 | 33333, PWM_POLARITY_INVERSED), | ||
| 420 | }; | 412 | }; |
| 421 | 413 | ||
| 422 | /* LCDC and backlight */ | 414 | /* LCDC and backlight */ |
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c index be4ad0b21c08..2157c5b539e6 100644 --- a/arch/arm/plat-samsung/dev-backlight.c +++ b/arch/arm/plat-samsung/dev-backlight.c | |||
| @@ -124,8 +124,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, | |||
| 124 | samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns; | 124 | samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns; |
| 125 | if (bl_data->enable_gpio >= 0) | 125 | if (bl_data->enable_gpio >= 0) |
| 126 | samsung_bl_data->enable_gpio = bl_data->enable_gpio; | 126 | samsung_bl_data->enable_gpio = bl_data->enable_gpio; |
| 127 | if (bl_data->enable_gpio_flags) | ||
| 128 | samsung_bl_data->enable_gpio_flags = bl_data->enable_gpio_flags; | ||
| 129 | if (bl_data->init) | 127 | if (bl_data->init) |
| 130 | samsung_bl_data->init = bl_data->init; | 128 | samsung_bl_data->init = bl_data->init; |
| 131 | if (bl_data->notify) | 129 | if (bl_data->notify) |
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 7d0aaed1e23a..aa770ec1e892 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c | |||
| @@ -181,7 +181,6 @@ static int led_pwm_probe(struct platform_device *pdev) | |||
| 181 | led_dat->cdev.name = cur_led->name; | 181 | led_dat->cdev.name = cur_led->name; |
| 182 | led_dat->cdev.default_trigger = cur_led->default_trigger; | 182 | led_dat->cdev.default_trigger = cur_led->default_trigger; |
| 183 | led_dat->active_low = cur_led->active_low; | 183 | led_dat->active_low = cur_led->active_low; |
| 184 | led_dat->period = cur_led->pwm_period_ns; | ||
| 185 | led_dat->cdev.brightness_set = led_pwm_set; | 184 | led_dat->cdev.brightness_set = led_pwm_set; |
| 186 | led_dat->cdev.brightness = LED_OFF; | 185 | led_dat->cdev.brightness = LED_OFF; |
| 187 | led_dat->cdev.max_brightness = cur_led->max_brightness; | 186 | led_dat->cdev.max_brightness = cur_led->max_brightness; |
| @@ -191,6 +190,10 @@ static int led_pwm_probe(struct platform_device *pdev) | |||
| 191 | if (led_dat->can_sleep) | 190 | if (led_dat->can_sleep) |
| 192 | INIT_WORK(&led_dat->work, led_pwm_work); | 191 | INIT_WORK(&led_dat->work, led_pwm_work); |
| 193 | 192 | ||
| 193 | led_dat->period = pwm_get_period(led_dat->pwm); | ||
| 194 | if (!led_dat->period && (cur_led->pwm_period_ns > 0)) | ||
| 195 | led_dat->period = cur_led->pwm_period_ns; | ||
| 196 | |||
| 194 | ret = led_classdev_register(&pdev->dev, &led_dat->cdev); | 197 | ret = led_classdev_register(&pdev->dev, &led_dat->cdev); |
| 195 | if (ret < 0) | 198 | if (ret < 0) |
| 196 | goto err; | 199 | goto err; |
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 5b34ff29ea38..4ad7b89a4cb4 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig | |||
| @@ -62,6 +62,15 @@ config PWM_ATMEL_TCB | |||
| 62 | To compile this driver as a module, choose M here: the module | 62 | To compile this driver as a module, choose M here: the module |
| 63 | will be called pwm-atmel-tcb. | 63 | will be called pwm-atmel-tcb. |
| 64 | 64 | ||
| 65 | config PWM_BCM_KONA | ||
| 66 | tristate "Kona PWM support" | ||
| 67 | depends on ARCH_BCM_MOBILE | ||
| 68 | help | ||
| 69 | Generic PWM framework driver for Broadcom Kona PWM block. | ||
| 70 | |||
| 71 | To compile this driver as a module, choose M here: the module | ||
| 72 | will be called pwm-bcm-kona. | ||
| 73 | |||
| 65 | config PWM_BFIN | 74 | config PWM_BFIN |
| 66 | tristate "Blackfin PWM support" | 75 | tristate "Blackfin PWM support" |
| 67 | depends on BFIN_GPTIMERS | 76 | depends on BFIN_GPTIMERS |
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index e57d2c38a794..5c86a19d5d39 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile | |||
| @@ -3,6 +3,7 @@ obj-$(CONFIG_PWM_SYSFS) += sysfs.o | |||
| 3 | obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o | 3 | obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o |
| 4 | obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o | 4 | obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o |
| 5 | obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o | 5 | obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o |
| 6 | obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-kona.o | ||
| 6 | obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o | 7 | obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o |
| 7 | obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o | 8 | obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o |
| 8 | obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o | 9 | obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o |
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index a80471399c20..4b66bf09ee55 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c | |||
| @@ -661,10 +661,16 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
| 661 | } | 661 | } |
| 662 | } | 662 | } |
| 663 | 663 | ||
| 664 | mutex_unlock(&pwm_lookup_lock); | ||
| 665 | |||
| 664 | if (chip) | 666 | if (chip) |
| 665 | pwm = pwm_request_from_chip(chip, index, con_id ?: dev_id); | 667 | pwm = pwm_request_from_chip(chip, index, con_id ?: dev_id); |
| 668 | if (IS_ERR(pwm)) | ||
| 669 | return pwm; | ||
| 670 | |||
| 671 | pwm_set_period(pwm, p->period); | ||
| 672 | pwm_set_polarity(pwm, p->polarity); | ||
| 666 | 673 | ||
| 667 | mutex_unlock(&pwm_lookup_lock); | ||
| 668 | 674 | ||
| 669 | return pwm; | 675 | return pwm; |
| 670 | } | 676 | } |
diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c index 1d07a6f99375..4c07a8420b37 100644 --- a/drivers/pwm/pwm-ab8500.c +++ b/drivers/pwm/pwm-ab8500.c | |||
| @@ -20,10 +20,6 @@ | |||
| 20 | #define AB8500_PWM_OUT_CTRL2_REG 0x61 | 20 | #define AB8500_PWM_OUT_CTRL2_REG 0x61 |
| 21 | #define AB8500_PWM_OUT_CTRL7_REG 0x66 | 21 | #define AB8500_PWM_OUT_CTRL7_REG 0x66 |
| 22 | 22 | ||
| 23 | /* backlight driver constants */ | ||
| 24 | #define ENABLE_PWM 1 | ||
| 25 | #define DISABLE_PWM 0 | ||
| 26 | |||
| 27 | struct ab8500_pwm_chip { | 23 | struct ab8500_pwm_chip { |
| 28 | struct pwm_chip chip; | 24 | struct pwm_chip chip; |
| 29 | }; | 25 | }; |
| @@ -64,7 +60,7 @@ static int ab8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
| 64 | 60 | ||
| 65 | ret = abx500_mask_and_set_register_interruptible(chip->dev, | 61 | ret = abx500_mask_and_set_register_interruptible(chip->dev, |
| 66 | AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, | 62 | AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, |
| 67 | 1 << (chip->base - 1), ENABLE_PWM); | 63 | 1 << (chip->base - 1), 1 << (chip->base - 1)); |
| 68 | if (ret < 0) | 64 | if (ret < 0) |
| 69 | dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", | 65 | dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", |
| 70 | pwm->label, ret); | 66 | pwm->label, ret); |
| @@ -77,11 +73,10 @@ static void ab8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
| 77 | 73 | ||
| 78 | ret = abx500_mask_and_set_register_interruptible(chip->dev, | 74 | ret = abx500_mask_and_set_register_interruptible(chip->dev, |
| 79 | AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, | 75 | AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, |
| 80 | 1 << (chip->base - 1), DISABLE_PWM); | 76 | 1 << (chip->base - 1), 0); |
| 81 | if (ret < 0) | 77 | if (ret < 0) |
| 82 | dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", | 78 | dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", |
| 83 | pwm->label, ret); | 79 | pwm->label, ret); |
| 84 | return; | ||
| 85 | } | 80 | } |
| 86 | 81 | ||
| 87 | static const struct pwm_ops ab8500_pwm_ops = { | 82 | static const struct pwm_ops ab8500_pwm_ops = { |
| @@ -101,10 +96,8 @@ static int ab8500_pwm_probe(struct platform_device *pdev) | |||
| 101 | * device which is required for ab8500 read and write | 96 | * device which is required for ab8500 read and write |
| 102 | */ | 97 | */ |
| 103 | ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); | 98 | ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); |
| 104 | if (ab8500 == NULL) { | 99 | if (ab8500 == NULL) |
| 105 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 106 | return -ENOMEM; | 100 | return -ENOMEM; |
| 107 | } | ||
| 108 | 101 | ||
| 109 | ab8500->chip.dev = &pdev->dev; | 102 | ab8500->chip.dev = &pdev->dev; |
| 110 | ab8500->chip.ops = &ab8500_pwm_ops; | 103 | ab8500->chip.ops = &ab8500_pwm_ops; |
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c index 0adc952cc4ef..6e700a541ca3 100644 --- a/drivers/pwm/pwm-atmel.c +++ b/drivers/pwm/pwm-atmel.c | |||
| @@ -357,6 +357,7 @@ static int atmel_pwm_probe(struct platform_device *pdev) | |||
| 357 | 357 | ||
| 358 | atmel_pwm->chip.base = -1; | 358 | atmel_pwm->chip.base = -1; |
| 359 | atmel_pwm->chip.npwm = 4; | 359 | atmel_pwm->chip.npwm = 4; |
| 360 | atmel_pwm->chip.can_sleep = true; | ||
| 360 | atmel_pwm->config = data->config; | 361 | atmel_pwm->config = data->config; |
| 361 | 362 | ||
| 362 | ret = pwmchip_add(&atmel_pwm->chip); | 363 | ret = pwmchip_add(&atmel_pwm->chip); |
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c new file mode 100644 index 000000000000..02bc048892a9 --- /dev/null +++ b/drivers/pwm/pwm-bcm-kona.c | |||
| @@ -0,0 +1,318 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License as | ||
| 6 | * published by the Free Software Foundation version 2. | ||
| 7 | * | ||
| 8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
| 9 | * kind, whether express or implied; without even the implied warranty | ||
| 10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/clk.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/math64.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/of.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/pwm.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/types.h> | ||
| 26 | |||
| 27 | /* | ||
| 28 | * The Kona PWM has some unusual characteristics. Here are the main points. | ||
| 29 | * | ||
| 30 | * 1) There is no disable bit and the hardware docs advise programming a zero | ||
| 31 | * duty to achieve output equivalent to that of a normal disable operation. | ||
| 32 | * | ||
| 33 | * 2) Changes to prescale, duty, period, and polarity do not take effect until | ||
| 34 | * a subsequent rising edge of the trigger bit. | ||
| 35 | * | ||
| 36 | * 3) If the smooth bit and trigger bit are both low, the output is a constant | ||
| 37 | * high signal. Otherwise, the earlier waveform continues to be output. | ||
| 38 | * | ||
| 39 | * 4) If the smooth bit is set on the rising edge of the trigger bit, output | ||
| 40 | * will transition to the new settings on a period boundary (which could be | ||
| 41 | * seconds away). If the smooth bit is clear, new settings will be applied | ||
| 42 | * as soon as possible (the hardware always has a 400ns delay). | ||
| 43 | * | ||
| 44 | * 5) When the external clock that feeds the PWM is disabled, output is pegged | ||
| 45 | * high or low depending on its state at that exact instant. | ||
| 46 | */ | ||
| 47 | |||
| 48 | #define PWM_CONTROL_OFFSET (0x00000000) | ||
| 49 | #define PWM_CONTROL_SMOOTH_SHIFT(chan) (24 + (chan)) | ||
| 50 | #define PWM_CONTROL_TYPE_SHIFT(chan) (16 + (chan)) | ||
| 51 | #define PWM_CONTROL_POLARITY_SHIFT(chan) (8 + (chan)) | ||
| 52 | #define PWM_CONTROL_TRIGGER_SHIFT(chan) (chan) | ||
| 53 | |||
| 54 | #define PRESCALE_OFFSET (0x00000004) | ||
| 55 | #define PRESCALE_SHIFT(chan) ((chan) << 2) | ||
| 56 | #define PRESCALE_MASK(chan) (0x7 << PRESCALE_SHIFT(chan)) | ||
| 57 | #define PRESCALE_MIN (0x00000000) | ||
| 58 | #define PRESCALE_MAX (0x00000007) | ||
| 59 | |||
| 60 | #define PERIOD_COUNT_OFFSET(chan) (0x00000008 + ((chan) << 3)) | ||
| 61 | #define PERIOD_COUNT_MIN (0x00000002) | ||
| 62 | #define PERIOD_COUNT_MAX (0x00ffffff) | ||
| 63 | |||
| 64 | #define DUTY_CYCLE_HIGH_OFFSET(chan) (0x0000000c + ((chan) << 3)) | ||
| 65 | #define DUTY_CYCLE_HIGH_MIN (0x00000000) | ||
| 66 | #define DUTY_CYCLE_HIGH_MAX (0x00ffffff) | ||
| 67 | |||
| 68 | struct kona_pwmc { | ||
| 69 | struct pwm_chip chip; | ||
| 70 | void __iomem *base; | ||
| 71 | struct clk *clk; | ||
| 72 | }; | ||
| 73 | |||
| 74 | static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *_chip) | ||
| 75 | { | ||
| 76 | return container_of(_chip, struct kona_pwmc, chip); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) | ||
| 80 | { | ||
| 81 | unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET); | ||
| 82 | |||
| 83 | /* Clear trigger bit but set smooth bit to maintain old output */ | ||
| 84 | value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan); | ||
| 85 | value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan)); | ||
| 86 | writel(value, kp->base + PWM_CONTROL_OFFSET); | ||
| 87 | |||
| 88 | /* Set trigger bit and clear smooth bit to apply new settings */ | ||
| 89 | value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan)); | ||
| 90 | value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan); | ||
| 91 | writel(value, kp->base + PWM_CONTROL_OFFSET); | ||
| 92 | } | ||
| 93 | |||
| 94 | static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm, | ||
| 95 | int duty_ns, int period_ns) | ||
| 96 | { | ||
| 97 | struct kona_pwmc *kp = to_kona_pwmc(chip); | ||
| 98 | u64 val, div, rate; | ||
| 99 | unsigned long prescale = PRESCALE_MIN, pc, dc; | ||
| 100 | unsigned int value, chan = pwm->hwpwm; | ||
| 101 | |||
| 102 | /* | ||
| 103 | * Find period count, duty count and prescale to suit duty_ns and | ||
| 104 | * period_ns. This is done according to formulas described below: | ||
| 105 | * | ||
| 106 | * period_ns = 10^9 * (PRESCALE + 1) * PC / PWM_CLK_RATE | ||
| 107 | * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE | ||
| 108 | * | ||
| 109 | * PC = (PWM_CLK_RATE * period_ns) / (10^9 * (PRESCALE + 1)) | ||
| 110 | * DC = (PWM_CLK_RATE * duty_ns) / (10^9 * (PRESCALE + 1)) | ||
| 111 | */ | ||
| 112 | |||
| 113 | rate = clk_get_rate(kp->clk); | ||
| 114 | |||
| 115 | while (1) { | ||
| 116 | div = 1000000000; | ||
| 117 | div *= 1 + prescale; | ||
| 118 | val = rate * period_ns; | ||
| 119 | pc = div64_u64(val, div); | ||
| 120 | val = rate * duty_ns; | ||
| 121 | dc = div64_u64(val, div); | ||
| 122 | |||
| 123 | /* If duty_ns or period_ns are not achievable then return */ | ||
| 124 | if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN) | ||
| 125 | return -EINVAL; | ||
| 126 | |||
| 127 | /* If pc and dc are in bounds, the calculation is done */ | ||
| 128 | if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX) | ||
| 129 | break; | ||
| 130 | |||
| 131 | /* Otherwise, increase prescale and recalculate pc and dc */ | ||
| 132 | if (++prescale > PRESCALE_MAX) | ||
| 133 | return -EINVAL; | ||
| 134 | } | ||
| 135 | |||
| 136 | /* If the PWM channel is enabled, write the settings to the HW */ | ||
| 137 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { | ||
| 138 | value = readl(kp->base + PRESCALE_OFFSET); | ||
| 139 | value &= ~PRESCALE_MASK(chan); | ||
| 140 | value |= prescale << PRESCALE_SHIFT(chan); | ||
| 141 | writel(value, kp->base + PRESCALE_OFFSET); | ||
| 142 | |||
| 143 | writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan)); | ||
| 144 | |||
| 145 | writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan)); | ||
| 146 | |||
| 147 | kona_pwmc_apply_settings(kp, chan); | ||
| 148 | } | ||
| 149 | |||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, | ||
| 154 | enum pwm_polarity polarity) | ||
| 155 | { | ||
| 156 | struct kona_pwmc *kp = to_kona_pwmc(chip); | ||
| 157 | unsigned int chan = pwm->hwpwm; | ||
| 158 | unsigned int value; | ||
| 159 | int ret; | ||
| 160 | |||
| 161 | ret = clk_prepare_enable(kp->clk); | ||
| 162 | if (ret < 0) { | ||
| 163 | dev_err(chip->dev, "failed to enable clock: %d\n", ret); | ||
| 164 | return ret; | ||
| 165 | } | ||
| 166 | |||
| 167 | value = readl(kp->base + PWM_CONTROL_OFFSET); | ||
| 168 | |||
| 169 | if (polarity == PWM_POLARITY_NORMAL) | ||
| 170 | value |= 1 << PWM_CONTROL_POLARITY_SHIFT(chan); | ||
| 171 | else | ||
| 172 | value &= ~(1 << PWM_CONTROL_POLARITY_SHIFT(chan)); | ||
| 173 | |||
| 174 | writel(value, kp->base + PWM_CONTROL_OFFSET); | ||
| 175 | |||
| 176 | kona_pwmc_apply_settings(kp, chan); | ||
| 177 | |||
| 178 | /* Wait for waveform to settle before gating off the clock */ | ||
| 179 | ndelay(400); | ||
| 180 | |||
| 181 | clk_disable_unprepare(kp->clk); | ||
| 182 | |||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm) | ||
| 187 | { | ||
| 188 | struct kona_pwmc *kp = to_kona_pwmc(chip); | ||
| 189 | int ret; | ||
| 190 | |||
| 191 | ret = clk_prepare_enable(kp->clk); | ||
| 192 | if (ret < 0) { | ||
| 193 | dev_err(chip->dev, "failed to enable clock: %d\n", ret); | ||
| 194 | return ret; | ||
| 195 | } | ||
| 196 | |||
| 197 | ret = kona_pwmc_config(chip, pwm, pwm->duty_cycle, pwm->period); | ||
| 198 | if (ret < 0) { | ||
| 199 | clk_disable_unprepare(kp->clk); | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | |||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm) | ||
| 207 | { | ||
| 208 | struct kona_pwmc *kp = to_kona_pwmc(chip); | ||
| 209 | unsigned int chan = pwm->hwpwm; | ||
| 210 | |||
| 211 | /* Simulate a disable by configuring for zero duty */ | ||
| 212 | writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan)); | ||
| 213 | kona_pwmc_apply_settings(kp, chan); | ||
| 214 | |||
| 215 | /* Wait for waveform to settle before gating off the clock */ | ||
| 216 | ndelay(400); | ||
| 217 | |||
| 218 | clk_disable_unprepare(kp->clk); | ||
| 219 | } | ||
| 220 | |||
| 221 | static const struct pwm_ops kona_pwm_ops = { | ||
| 222 | .config = kona_pwmc_config, | ||
| 223 | .set_polarity = kona_pwmc_set_polarity, | ||
| 224 | .enable = kona_pwmc_enable, | ||
| 225 | .disable = kona_pwmc_disable, | ||
| 226 | .owner = THIS_MODULE, | ||
| 227 | }; | ||
| 228 | |||
| 229 | static int kona_pwmc_probe(struct platform_device *pdev) | ||
| 230 | { | ||
| 231 | struct kona_pwmc *kp; | ||
| 232 | struct resource *res; | ||
| 233 | unsigned int chan; | ||
| 234 | unsigned int value = 0; | ||
| 235 | int ret = 0; | ||
| 236 | |||
| 237 | kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); | ||
| 238 | if (kp == NULL) | ||
| 239 | return -ENOMEM; | ||
| 240 | |||
| 241 | platform_set_drvdata(pdev, kp); | ||
| 242 | |||
| 243 | kp->chip.dev = &pdev->dev; | ||
| 244 | kp->chip.ops = &kona_pwm_ops; | ||
| 245 | kp->chip.base = -1; | ||
| 246 | kp->chip.npwm = 6; | ||
| 247 | kp->chip.of_xlate = of_pwm_xlate_with_flags; | ||
| 248 | kp->chip.of_pwm_n_cells = 3; | ||
| 249 | kp->chip.can_sleep = true; | ||
| 250 | |||
| 251 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 252 | kp->base = devm_ioremap_resource(&pdev->dev, res); | ||
| 253 | if (IS_ERR(kp->base)) | ||
| 254 | return PTR_ERR(kp->base); | ||
| 255 | |||
| 256 | kp->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 257 | if (IS_ERR(kp->clk)) { | ||
| 258 | dev_err(&pdev->dev, "failed to get clock: %ld\n", | ||
| 259 | PTR_ERR(kp->clk)); | ||
| 260 | return PTR_ERR(kp->clk); | ||
| 261 | } | ||
| 262 | |||
| 263 | ret = clk_prepare_enable(kp->clk); | ||
| 264 | if (ret < 0) { | ||
| 265 | dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); | ||
| 266 | return ret; | ||
| 267 | } | ||
| 268 | |||
| 269 | /* Set smooth mode, push/pull, and normal polarity for all channels */ | ||
| 270 | for (chan = 0; chan < kp->chip.npwm; chan++) { | ||
| 271 | value |= (1 << PWM_CONTROL_SMOOTH_SHIFT(chan)); | ||
| 272 | value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan)); | ||
| 273 | value |= (1 << PWM_CONTROL_POLARITY_SHIFT(chan)); | ||
| 274 | } | ||
| 275 | |||
| 276 | writel(value, kp->base + PWM_CONTROL_OFFSET); | ||
| 277 | |||
| 278 | clk_disable_unprepare(kp->clk); | ||
| 279 | |||
| 280 | ret = pwmchip_add(&kp->chip); | ||
| 281 | if (ret < 0) | ||
| 282 | dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); | ||
| 283 | |||
| 284 | return ret; | ||
| 285 | } | ||
| 286 | |||
| 287 | static int kona_pwmc_remove(struct platform_device *pdev) | ||
| 288 | { | ||
| 289 | struct kona_pwmc *kp = platform_get_drvdata(pdev); | ||
| 290 | unsigned int chan; | ||
| 291 | |||
| 292 | for (chan = 0; chan < kp->chip.npwm; chan++) | ||
| 293 | if (test_bit(PWMF_ENABLED, &kp->chip.pwms[chan].flags)) | ||
| 294 | clk_disable_unprepare(kp->clk); | ||
| 295 | |||
| 296 | return pwmchip_remove(&kp->chip); | ||
| 297 | } | ||
| 298 | |||
| 299 | static const struct of_device_id bcm_kona_pwmc_dt[] = { | ||
| 300 | { .compatible = "brcm,kona-pwm" }, | ||
| 301 | { }, | ||
| 302 | }; | ||
| 303 | MODULE_DEVICE_TABLE(of, bcm_kona_pwmc_dt); | ||
| 304 | |||
| 305 | static struct platform_driver kona_pwmc_driver = { | ||
| 306 | .driver = { | ||
| 307 | .name = "bcm-kona-pwm", | ||
| 308 | .of_match_table = bcm_kona_pwmc_dt, | ||
| 309 | }, | ||
| 310 | .probe = kona_pwmc_probe, | ||
| 311 | .remove = kona_pwmc_remove, | ||
| 312 | }; | ||
| 313 | module_platform_driver(kona_pwmc_driver); | ||
| 314 | |||
| 315 | MODULE_AUTHOR("Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>"); | ||
| 316 | MODULE_AUTHOR("Tim Kryger <tkryger@broadcom.com>"); | ||
| 317 | MODULE_DESCRIPTION("Broadcom Kona PWM driver"); | ||
| 318 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index 420169e96b5f..a18bc8fea385 100644 --- a/drivers/pwm/pwm-fsl-ftm.c +++ b/drivers/pwm/pwm-fsl-ftm.c | |||
| @@ -454,6 +454,7 @@ static int fsl_pwm_probe(struct platform_device *pdev) | |||
| 454 | fpc->chip.of_pwm_n_cells = 3; | 454 | fpc->chip.of_pwm_n_cells = 3; |
| 455 | fpc->chip.base = -1; | 455 | fpc->chip.base = -1; |
| 456 | fpc->chip.npwm = 8; | 456 | fpc->chip.npwm = 8; |
| 457 | fpc->chip.can_sleep = true; | ||
| 457 | 458 | ||
| 458 | ret = pwmchip_add(&fpc->chip); | 459 | ret = pwmchip_add(&fpc->chip); |
| 459 | if (ret < 0) { | 460 | if (ret < 0) { |
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index cc4773344874..d797c7b84c3f 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c | |||
| @@ -241,10 +241,8 @@ static int imx_pwm_probe(struct platform_device *pdev) | |||
| 241 | return -ENODEV; | 241 | return -ENODEV; |
| 242 | 242 | ||
| 243 | imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); | 243 | imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); |
| 244 | if (imx == NULL) { | 244 | if (imx == NULL) |
| 245 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 246 | return -ENOMEM; | 245 | return -ENOMEM; |
| 247 | } | ||
| 248 | 246 | ||
| 249 | imx->clk_per = devm_clk_get(&pdev->dev, "per"); | 247 | imx->clk_per = devm_clk_get(&pdev->dev, "per"); |
| 250 | if (IS_ERR(imx->clk_per)) { | 248 | if (IS_ERR(imx->clk_per)) { |
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index a40b9c34e9ff..2c39b0e50fa4 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c | |||
| @@ -278,6 +278,7 @@ static int lp3943_pwm_probe(struct platform_device *pdev) | |||
| 278 | lp3943_pwm->chip.dev = &pdev->dev; | 278 | lp3943_pwm->chip.dev = &pdev->dev; |
| 279 | lp3943_pwm->chip.ops = &lp3943_pwm_ops; | 279 | lp3943_pwm->chip.ops = &lp3943_pwm_ops; |
| 280 | lp3943_pwm->chip.npwm = LP3943_NUM_PWMS; | 280 | lp3943_pwm->chip.npwm = LP3943_NUM_PWMS; |
| 281 | lp3943_pwm->chip.can_sleep = true; | ||
| 281 | 282 | ||
| 282 | platform_set_drvdata(pdev, lp3943_pwm); | 283 | platform_set_drvdata(pdev, lp3943_pwm); |
| 283 | 284 | ||
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index 449e372050a0..44ce6c6103ae 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Author: Chew Kean Ho <kean.ho.chew@intel.com> | 6 | * Author: Chew Kean Ho <kean.ho.chew@intel.com> |
| 7 | * Author: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com> | 7 | * Author: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com> |
| 8 | * Author: Chew Chiau Ee <chiau.ee.chew@intel.com> | 8 | * Author: Chew Chiau Ee <chiau.ee.chew@intel.com> |
| 9 | * Author: Alan Cox <alan@linux.intel.com> | ||
| 9 | * | 10 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
| @@ -19,6 +20,9 @@ | |||
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/pwm.h> | 21 | #include <linux/pwm.h> |
| 21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/pci.h> | ||
| 24 | |||
| 25 | static int pci_drv, plat_drv; /* So we know which drivers registered */ | ||
| 22 | 26 | ||
| 23 | #define PWM 0x00000000 | 27 | #define PWM 0x00000000 |
| 24 | #define PWM_ENABLE BIT(31) | 28 | #define PWM_ENABLE BIT(31) |
| @@ -34,6 +38,16 @@ struct pwm_lpss_chip { | |||
| 34 | struct pwm_chip chip; | 38 | struct pwm_chip chip; |
| 35 | void __iomem *regs; | 39 | void __iomem *regs; |
| 36 | struct clk *clk; | 40 | struct clk *clk; |
| 41 | unsigned long clk_rate; | ||
| 42 | }; | ||
| 43 | |||
| 44 | struct pwm_lpss_boardinfo { | ||
| 45 | unsigned long clk_rate; | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* BayTrail */ | ||
| 49 | static const struct pwm_lpss_boardinfo byt_info = { | ||
| 50 | 25000000 | ||
| 37 | }; | 51 | }; |
| 38 | 52 | ||
| 39 | static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) | 53 | static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) |
| @@ -55,7 +69,7 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
| 55 | /* The equation is: base_unit = ((freq / c) * 65536) + correction */ | 69 | /* The equation is: base_unit = ((freq / c) * 65536) + correction */ |
| 56 | base_unit = freq * 65536; | 70 | base_unit = freq * 65536; |
| 57 | 71 | ||
| 58 | c = clk_get_rate(lpwm->clk); | 72 | c = lpwm->clk_rate; |
| 59 | if (!c) | 73 | if (!c) |
| 60 | return -EINVAL; | 74 | return -EINVAL; |
| 61 | 75 | ||
| @@ -113,52 +127,48 @@ static const struct pwm_ops pwm_lpss_ops = { | |||
| 113 | .owner = THIS_MODULE, | 127 | .owner = THIS_MODULE, |
| 114 | }; | 128 | }; |
| 115 | 129 | ||
| 116 | static const struct acpi_device_id pwm_lpss_acpi_match[] = { | 130 | static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, |
| 117 | { "80860F09", 0 }, | 131 | struct resource *r, |
| 118 | { }, | 132 | const struct pwm_lpss_boardinfo *info) |
| 119 | }; | ||
| 120 | MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match); | ||
| 121 | |||
| 122 | static int pwm_lpss_probe(struct platform_device *pdev) | ||
| 123 | { | 133 | { |
| 124 | struct pwm_lpss_chip *lpwm; | 134 | struct pwm_lpss_chip *lpwm; |
| 125 | struct resource *r; | ||
| 126 | int ret; | 135 | int ret; |
| 127 | 136 | ||
| 128 | lpwm = devm_kzalloc(&pdev->dev, sizeof(*lpwm), GFP_KERNEL); | 137 | lpwm = devm_kzalloc(dev, sizeof(*lpwm), GFP_KERNEL); |
| 129 | if (!lpwm) | 138 | if (!lpwm) |
| 130 | return -ENOMEM; | 139 | return ERR_PTR(-ENOMEM); |
| 131 | |||
| 132 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 133 | 140 | ||
| 134 | lpwm->regs = devm_ioremap_resource(&pdev->dev, r); | 141 | lpwm->regs = devm_ioremap_resource(dev, r); |
| 135 | if (IS_ERR(lpwm->regs)) | 142 | if (IS_ERR(lpwm->regs)) |
| 136 | return PTR_ERR(lpwm->regs); | 143 | return ERR_CAST(lpwm->regs); |
| 137 | 144 | ||
| 138 | lpwm->clk = devm_clk_get(&pdev->dev, NULL); | 145 | if (info) { |
| 139 | if (IS_ERR(lpwm->clk)) { | 146 | lpwm->clk_rate = info->clk_rate; |
| 140 | dev_err(&pdev->dev, "failed to get PWM clock\n"); | 147 | } else { |
| 141 | return PTR_ERR(lpwm->clk); | 148 | lpwm->clk = devm_clk_get(dev, NULL); |
| 149 | if (IS_ERR(lpwm->clk)) { | ||
| 150 | dev_err(dev, "failed to get PWM clock\n"); | ||
| 151 | return ERR_CAST(lpwm->clk); | ||
| 152 | } | ||
| 153 | lpwm->clk_rate = clk_get_rate(lpwm->clk); | ||
| 142 | } | 154 | } |
| 143 | 155 | ||
| 144 | lpwm->chip.dev = &pdev->dev; | 156 | lpwm->chip.dev = dev; |
| 145 | lpwm->chip.ops = &pwm_lpss_ops; | 157 | lpwm->chip.ops = &pwm_lpss_ops; |
| 146 | lpwm->chip.base = -1; | 158 | lpwm->chip.base = -1; |
| 147 | lpwm->chip.npwm = 1; | 159 | lpwm->chip.npwm = 1; |
| 148 | 160 | ||
| 149 | ret = pwmchip_add(&lpwm->chip); | 161 | ret = pwmchip_add(&lpwm->chip); |
| 150 | if (ret) { | 162 | if (ret) { |
| 151 | dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); | 163 | dev_err(dev, "failed to add PWM chip: %d\n", ret); |
| 152 | return ret; | 164 | return ERR_PTR(ret); |
| 153 | } | 165 | } |
| 154 | 166 | ||
| 155 | platform_set_drvdata(pdev, lpwm); | 167 | return lpwm; |
| 156 | return 0; | ||
| 157 | } | 168 | } |
| 158 | 169 | ||
| 159 | static int pwm_lpss_remove(struct platform_device *pdev) | 170 | static int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) |
| 160 | { | 171 | { |
| 161 | struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev); | ||
| 162 | u32 ctrl; | 172 | u32 ctrl; |
| 163 | 173 | ||
| 164 | ctrl = readl(lpwm->regs + PWM); | 174 | ctrl = readl(lpwm->regs + PWM); |
| @@ -167,15 +177,104 @@ static int pwm_lpss_remove(struct platform_device *pdev) | |||
| 167 | return pwmchip_remove(&lpwm->chip); | 177 | return pwmchip_remove(&lpwm->chip); |
| 168 | } | 178 | } |
| 169 | 179 | ||
| 170 | static struct platform_driver pwm_lpss_driver = { | 180 | static int pwm_lpss_probe_pci(struct pci_dev *pdev, |
| 181 | const struct pci_device_id *id) | ||
| 182 | { | ||
| 183 | const struct pwm_lpss_boardinfo *info; | ||
| 184 | struct pwm_lpss_chip *lpwm; | ||
| 185 | int err; | ||
| 186 | |||
| 187 | err = pci_enable_device(pdev); | ||
| 188 | if (err < 0) | ||
| 189 | return err; | ||
| 190 | |||
| 191 | info = (struct pwm_lpss_boardinfo *)id->driver_data; | ||
| 192 | lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info); | ||
| 193 | if (IS_ERR(lpwm)) | ||
| 194 | return PTR_ERR(lpwm); | ||
| 195 | |||
| 196 | pci_set_drvdata(pdev, lpwm); | ||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | static void pwm_lpss_remove_pci(struct pci_dev *pdev) | ||
| 201 | { | ||
| 202 | struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev); | ||
| 203 | |||
| 204 | pwm_lpss_remove(lpwm); | ||
| 205 | pci_disable_device(pdev); | ||
| 206 | } | ||
| 207 | |||
| 208 | static struct pci_device_id pwm_lpss_pci_ids[] = { | ||
| 209 | { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&byt_info}, | ||
| 210 | { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&byt_info}, | ||
| 211 | { }, | ||
| 212 | }; | ||
| 213 | MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids); | ||
| 214 | |||
| 215 | static struct pci_driver pwm_lpss_driver_pci = { | ||
| 216 | .name = "pwm-lpss", | ||
| 217 | .id_table = pwm_lpss_pci_ids, | ||
| 218 | .probe = pwm_lpss_probe_pci, | ||
| 219 | .remove = pwm_lpss_remove_pci, | ||
| 220 | }; | ||
| 221 | |||
| 222 | static int pwm_lpss_probe_platform(struct platform_device *pdev) | ||
| 223 | { | ||
| 224 | struct pwm_lpss_chip *lpwm; | ||
| 225 | struct resource *r; | ||
| 226 | |||
| 227 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 228 | |||
| 229 | lpwm = pwm_lpss_probe(&pdev->dev, r, NULL); | ||
| 230 | if (IS_ERR(lpwm)) | ||
| 231 | return PTR_ERR(lpwm); | ||
| 232 | |||
| 233 | platform_set_drvdata(pdev, lpwm); | ||
| 234 | return 0; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int pwm_lpss_remove_platform(struct platform_device *pdev) | ||
| 238 | { | ||
| 239 | struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev); | ||
| 240 | |||
| 241 | return pwm_lpss_remove(lpwm); | ||
| 242 | } | ||
| 243 | |||
| 244 | static const struct acpi_device_id pwm_lpss_acpi_match[] = { | ||
| 245 | { "80860F09", 0 }, | ||
| 246 | { }, | ||
| 247 | }; | ||
| 248 | MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match); | ||
| 249 | |||
| 250 | static struct platform_driver pwm_lpss_driver_platform = { | ||
| 171 | .driver = { | 251 | .driver = { |
| 172 | .name = "pwm-lpss", | 252 | .name = "pwm-lpss", |
| 173 | .acpi_match_table = pwm_lpss_acpi_match, | 253 | .acpi_match_table = pwm_lpss_acpi_match, |
| 174 | }, | 254 | }, |
| 175 | .probe = pwm_lpss_probe, | 255 | .probe = pwm_lpss_probe_platform, |
| 176 | .remove = pwm_lpss_remove, | 256 | .remove = pwm_lpss_remove_platform, |
| 177 | }; | 257 | }; |
| 178 | module_platform_driver(pwm_lpss_driver); | 258 | |
| 259 | static int __init pwm_init(void) | ||
| 260 | { | ||
| 261 | pci_drv = pci_register_driver(&pwm_lpss_driver_pci); | ||
| 262 | plat_drv = platform_driver_register(&pwm_lpss_driver_platform); | ||
| 263 | if (pci_drv && plat_drv) | ||
| 264 | return pci_drv; | ||
| 265 | |||
| 266 | return 0; | ||
| 267 | } | ||
| 268 | module_init(pwm_init); | ||
| 269 | |||
| 270 | static void __exit pwm_exit(void) | ||
| 271 | { | ||
| 272 | if (!pci_drv) | ||
| 273 | pci_unregister_driver(&pwm_lpss_driver_pci); | ||
| 274 | if (!plat_drv) | ||
| 275 | platform_driver_unregister(&pwm_lpss_driver_platform); | ||
| 276 | } | ||
| 277 | module_exit(pwm_exit); | ||
| 179 | 278 | ||
| 180 | MODULE_DESCRIPTION("PWM driver for Intel LPSS"); | 279 | MODULE_DESCRIPTION("PWM driver for Intel LPSS"); |
| 181 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); | 280 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); |
diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c index 9475bc7a6f97..4f1bb4e0a426 100644 --- a/drivers/pwm/pwm-mxs.c +++ b/drivers/pwm/pwm-mxs.c | |||
| @@ -147,6 +147,7 @@ static int mxs_pwm_probe(struct platform_device *pdev) | |||
| 147 | mxs->chip.dev = &pdev->dev; | 147 | mxs->chip.dev = &pdev->dev; |
| 148 | mxs->chip.ops = &mxs_pwm_ops; | 148 | mxs->chip.ops = &mxs_pwm_ops; |
| 149 | mxs->chip.base = -1; | 149 | mxs->chip.base = -1; |
| 150 | mxs->chip.can_sleep = true; | ||
| 150 | ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm); | 151 | ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm); |
| 151 | if (ret < 0) { | 152 | if (ret < 0) { |
| 152 | dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret); | 153 | dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret); |
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index cd356d870244..0b312ec420b6 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c | |||
| @@ -179,10 +179,8 @@ static int pwm_probe(struct platform_device *pdev) | |||
| 179 | return -EINVAL; | 179 | return -EINVAL; |
| 180 | 180 | ||
| 181 | pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); | 181 | pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); |
| 182 | if (pwm == NULL) { | 182 | if (pwm == NULL) |
| 183 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 184 | return -ENOMEM; | 183 | return -ENOMEM; |
| 185 | } | ||
| 186 | 184 | ||
| 187 | pwm->clk = devm_clk_get(&pdev->dev, NULL); | 185 | pwm->clk = devm_clk_get(&pdev->dev, NULL); |
| 188 | if (IS_ERR(pwm->clk)) | 186 | if (IS_ERR(pwm->clk)) |
diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index aff6ba9b49e7..3b71b42e89d5 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c | |||
| @@ -21,13 +21,14 @@ | |||
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
| 23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
| 24 | #include <linux/platform_data/pwm-renesas-tpu.h> | ||
| 25 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| 26 | #include <linux/pm_runtime.h> | 25 | #include <linux/pm_runtime.h> |
| 27 | #include <linux/pwm.h> | 26 | #include <linux/pwm.h> |
| 28 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| 29 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
| 30 | 29 | ||
| 30 | #define TPU_CHANNEL_MAX 4 | ||
| 31 | |||
| 31 | #define TPU_TSTR 0x00 /* Timer start register (shared) */ | 32 | #define TPU_TSTR 0x00 /* Timer start register (shared) */ |
| 32 | 33 | ||
| 33 | #define TPU_TCRn 0x00 /* Timer control register */ | 34 | #define TPU_TCRn 0x00 /* Timer control register */ |
| @@ -87,7 +88,6 @@ struct tpu_pwm_device { | |||
| 87 | 88 | ||
| 88 | struct tpu_device { | 89 | struct tpu_device { |
| 89 | struct platform_device *pdev; | 90 | struct platform_device *pdev; |
| 90 | enum pwm_polarity polarities[TPU_CHANNEL_MAX]; | ||
| 91 | struct pwm_chip chip; | 91 | struct pwm_chip chip; |
| 92 | spinlock_t lock; | 92 | spinlock_t lock; |
| 93 | 93 | ||
| @@ -229,7 +229,7 @@ static int tpu_pwm_request(struct pwm_chip *chip, struct pwm_device *_pwm) | |||
| 229 | 229 | ||
| 230 | pwm->tpu = tpu; | 230 | pwm->tpu = tpu; |
| 231 | pwm->channel = _pwm->hwpwm; | 231 | pwm->channel = _pwm->hwpwm; |
| 232 | pwm->polarity = tpu->polarities[pwm->channel]; | 232 | pwm->polarity = PWM_POLARITY_NORMAL; |
| 233 | pwm->prescaler = 0; | 233 | pwm->prescaler = 0; |
| 234 | pwm->period = 0; | 234 | pwm->period = 0; |
| 235 | pwm->duty = 0; | 235 | pwm->duty = 0; |
| @@ -388,16 +388,6 @@ static const struct pwm_ops tpu_pwm_ops = { | |||
| 388 | * Probe and remove | 388 | * Probe and remove |
| 389 | */ | 389 | */ |
| 390 | 390 | ||
| 391 | static void tpu_parse_pdata(struct tpu_device *tpu) | ||
| 392 | { | ||
| 393 | struct tpu_pwm_platform_data *pdata = tpu->pdev->dev.platform_data; | ||
| 394 | unsigned int i; | ||
| 395 | |||
| 396 | for (i = 0; i < ARRAY_SIZE(tpu->polarities); ++i) | ||
| 397 | tpu->polarities[i] = pdata ? pdata->channels[i].polarity | ||
| 398 | : PWM_POLARITY_NORMAL; | ||
| 399 | } | ||
| 400 | |||
| 401 | static int tpu_probe(struct platform_device *pdev) | 391 | static int tpu_probe(struct platform_device *pdev) |
| 402 | { | 392 | { |
| 403 | struct tpu_device *tpu; | 393 | struct tpu_device *tpu; |
| @@ -405,17 +395,12 @@ static int tpu_probe(struct platform_device *pdev) | |||
| 405 | int ret; | 395 | int ret; |
| 406 | 396 | ||
| 407 | tpu = devm_kzalloc(&pdev->dev, sizeof(*tpu), GFP_KERNEL); | 397 | tpu = devm_kzalloc(&pdev->dev, sizeof(*tpu), GFP_KERNEL); |
| 408 | if (tpu == NULL) { | 398 | if (tpu == NULL) |
| 409 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
| 410 | return -ENOMEM; | 399 | return -ENOMEM; |
| 411 | } | ||
| 412 | 400 | ||
| 413 | spin_lock_init(&tpu->lock); | 401 | spin_lock_init(&tpu->lock); |
| 414 | tpu->pdev = pdev; | 402 | tpu->pdev = pdev; |
| 415 | 403 | ||
| 416 | /* Initialize device configuration from platform data. */ | ||
| 417 | tpu_parse_pdata(tpu); | ||
| 418 | |||
| 419 | /* Map memory, get clock and pin control. */ | 404 | /* Map memory, get clock and pin control. */ |
| 420 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 405 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 421 | tpu->base = devm_ioremap_resource(&pdev->dev, res); | 406 | tpu->base = devm_ioremap_resource(&pdev->dev, res); |
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index d66529a995a1..ba6b650cf8dc 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c | |||
| @@ -335,9 +335,6 @@ static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
| 335 | writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm)); | 335 | writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm)); |
| 336 | writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm)); | 336 | writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm)); |
| 337 | 337 | ||
| 338 | if (test_bit(PWMF_ENABLED, &pwm->flags)) | ||
| 339 | pwm_samsung_enable(chip, pwm); | ||
| 340 | |||
| 341 | chan->period_ns = period_ns; | 338 | chan->period_ns = period_ns; |
| 342 | chan->tin_ns = tin_ns; | 339 | chan->tin_ns = tin_ns; |
| 343 | chan->duty_ns = duty_ns; | 340 | chan->duty_ns = duty_ns; |
diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c index cb2d4f0f9711..6fd93e6a4122 100644 --- a/drivers/pwm/pwm-spear.c +++ b/drivers/pwm/pwm-spear.c | |||
| @@ -179,10 +179,8 @@ static int spear_pwm_probe(struct platform_device *pdev) | |||
| 179 | u32 val; | 179 | u32 val; |
| 180 | 180 | ||
| 181 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); | 181 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); |
| 182 | if (!pc) { | 182 | if (!pc) |
| 183 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 184 | return -ENOMEM; | 183 | return -ENOMEM; |
| 185 | } | ||
| 186 | 184 | ||
| 187 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 185 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 188 | pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); | 186 | pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); |
| @@ -222,7 +220,7 @@ static int spear_pwm_probe(struct platform_device *pdev) | |||
| 222 | } | 220 | } |
| 223 | 221 | ||
| 224 | ret = pwmchip_add(&pc->chip); | 222 | ret = pwmchip_add(&pc->chip); |
| 225 | if (!ret) { | 223 | if (ret < 0) { |
| 226 | clk_unprepare(pc->clk); | 224 | clk_unprepare(pc->clk); |
| 227 | dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); | 225 | dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); |
| 228 | } | 226 | } |
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 74298c561c4e..61d86b9498ca 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c | |||
| @@ -173,10 +173,8 @@ static int tegra_pwm_probe(struct platform_device *pdev) | |||
| 173 | int ret; | 173 | int ret; |
| 174 | 174 | ||
| 175 | pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); | 175 | pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); |
| 176 | if (!pwm) { | 176 | if (!pwm) |
| 177 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 178 | return -ENOMEM; | 177 | return -ENOMEM; |
| 179 | } | ||
| 180 | 178 | ||
| 181 | pwm->dev = &pdev->dev; | 179 | pwm->dev = &pdev->dev; |
| 182 | 180 | ||
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 032092c7a6ae..74efbe7f20c3 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c | |||
| @@ -209,10 +209,8 @@ static int ecap_pwm_probe(struct platform_device *pdev) | |||
| 209 | u16 status; | 209 | u16 status; |
| 210 | 210 | ||
| 211 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); | 211 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); |
| 212 | if (!pc) { | 212 | if (!pc) |
| 213 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 214 | return -ENOMEM; | 213 | return -ENOMEM; |
| 215 | } | ||
| 216 | 214 | ||
| 217 | clk = devm_clk_get(&pdev->dev, "fck"); | 215 | clk = devm_clk_get(&pdev->dev, "fck"); |
| 218 | if (IS_ERR(clk)) { | 216 | if (IS_ERR(clk)) { |
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index aee4471424d1..cb75133085a8 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c | |||
| @@ -138,12 +138,12 @@ static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) | |||
| 138 | return container_of(chip, struct ehrpwm_pwm_chip, chip); | 138 | return container_of(chip, struct ehrpwm_pwm_chip, chip); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static u16 ehrpwm_read(void __iomem *base, int offset) | 141 | static inline u16 ehrpwm_read(void __iomem *base, int offset) |
| 142 | { | 142 | { |
| 143 | return readw(base + offset); | 143 | return readw(base + offset); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static void ehrpwm_write(void __iomem *base, int offset, unsigned int val) | 146 | static inline void ehrpwm_write(void __iomem *base, int offset, unsigned int val) |
| 147 | { | 147 | { |
| 148 | writew(val & 0xFFFF, base + offset); | 148 | writew(val & 0xFFFF, base + offset); |
| 149 | } | 149 | } |
| @@ -440,10 +440,8 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) | |||
| 440 | u16 status; | 440 | u16 status; |
| 441 | 441 | ||
| 442 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); | 442 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); |
| 443 | if (!pc) { | 443 | if (!pc) |
| 444 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 445 | return -ENOMEM; | 444 | return -ENOMEM; |
| 446 | } | ||
| 447 | 445 | ||
| 448 | clk = devm_clk_get(&pdev->dev, "fck"); | 446 | clk = devm_clk_get(&pdev->dev, "fck"); |
| 449 | if (IS_ERR(clk)) { | 447 | if (IS_ERR(clk)) { |
| @@ -531,6 +529,7 @@ static int ehrpwm_pwm_remove(struct platform_device *pdev) | |||
| 531 | return pwmchip_remove(&pc->chip); | 529 | return pwmchip_remove(&pc->chip); |
| 532 | } | 530 | } |
| 533 | 531 | ||
| 532 | #ifdef CONFIG_PM_SLEEP | ||
| 534 | static void ehrpwm_pwm_save_context(struct ehrpwm_pwm_chip *pc) | 533 | static void ehrpwm_pwm_save_context(struct ehrpwm_pwm_chip *pc) |
| 535 | { | 534 | { |
| 536 | pm_runtime_get_sync(pc->chip.dev); | 535 | pm_runtime_get_sync(pc->chip.dev); |
| @@ -557,7 +556,6 @@ static void ehrpwm_pwm_restore_context(struct ehrpwm_pwm_chip *pc) | |||
| 557 | ehrpwm_write(pc->mmio_base, TBCTL, pc->ctx.tbctl); | 556 | ehrpwm_write(pc->mmio_base, TBCTL, pc->ctx.tbctl); |
| 558 | } | 557 | } |
| 559 | 558 | ||
| 560 | #ifdef CONFIG_PM_SLEEP | ||
| 561 | static int ehrpwm_pwm_suspend(struct device *dev) | 559 | static int ehrpwm_pwm_suspend(struct device *dev) |
| 562 | { | 560 | { |
| 563 | struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev); | 561 | struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev); |
diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c index b99a50e626a6..04f76725d591 100644 --- a/drivers/pwm/pwm-twl.c +++ b/drivers/pwm/pwm-twl.c | |||
| @@ -265,14 +265,6 @@ static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
| 265 | 265 | ||
| 266 | ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); | 266 | ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); |
| 267 | if (ret < 0) { | 267 | if (ret < 0) { |
| 268 | dev_err(chip->dev, "%s: Failed to read TOGGLE3\n", pwm->label); | ||
| 269 | goto out; | ||
| 270 | } | ||
| 271 | |||
| 272 | val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN); | ||
| 273 | |||
| 274 | ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); | ||
| 275 | if (ret < 0) { | ||
| 276 | dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); | 268 | dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); |
| 277 | goto out; | 269 | goto out; |
| 278 | } | 270 | } |
diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 323125abf3f4..652e6b5b859b 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c | |||
| @@ -211,10 +211,8 @@ static int vt8500_pwm_probe(struct platform_device *pdev) | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); | 213 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); |
| 214 | if (chip == NULL) { | 214 | if (chip == NULL) |
| 215 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 216 | return -ENOMEM; | 215 | return -ENOMEM; |
| 217 | } | ||
| 218 | 216 | ||
| 219 | chip->chip.dev = &pdev->dev; | 217 | chip->chip.dev = &pdev->dev; |
| 220 | chip->chip.ops = &vt8500_pwm_ops; | 218 | chip->chip.ops = &vt8500_pwm_ops; |
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index b75201ff46f6..38ca88bc5c3e 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
| @@ -10,8 +10,8 @@ | |||
| 10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/gpio/consumer.h> | ||
| 13 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
| 14 | #include <linux/of_gpio.h> | ||
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| @@ -32,8 +32,7 @@ struct pwm_bl_data { | |||
| 32 | unsigned int *levels; | 32 | unsigned int *levels; |
| 33 | bool enabled; | 33 | bool enabled; |
| 34 | struct regulator *power_supply; | 34 | struct regulator *power_supply; |
| 35 | int enable_gpio; | 35 | struct gpio_desc *enable_gpio; |
| 36 | unsigned long enable_gpio_flags; | ||
| 37 | unsigned int scale; | 36 | unsigned int scale; |
| 38 | int (*notify)(struct device *, | 37 | int (*notify)(struct device *, |
| 39 | int brightness); | 38 | int brightness); |
| @@ -54,12 +53,8 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness) | |||
| 54 | if (err < 0) | 53 | if (err < 0) |
| 55 | dev_err(pb->dev, "failed to enable power supply\n"); | 54 | dev_err(pb->dev, "failed to enable power supply\n"); |
| 56 | 55 | ||
| 57 | if (gpio_is_valid(pb->enable_gpio)) { | 56 | if (pb->enable_gpio) |
| 58 | if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) | 57 | gpiod_set_value(pb->enable_gpio, 1); |
| 59 | gpio_set_value(pb->enable_gpio, 0); | ||
| 60 | else | ||
| 61 | gpio_set_value(pb->enable_gpio, 1); | ||
| 62 | } | ||
| 63 | 58 | ||
| 64 | pwm_enable(pb->pwm); | 59 | pwm_enable(pb->pwm); |
| 65 | pb->enabled = true; | 60 | pb->enabled = true; |
| @@ -73,12 +68,8 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb) | |||
| 73 | pwm_config(pb->pwm, 0, pb->period); | 68 | pwm_config(pb->pwm, 0, pb->period); |
| 74 | pwm_disable(pb->pwm); | 69 | pwm_disable(pb->pwm); |
| 75 | 70 | ||
| 76 | if (gpio_is_valid(pb->enable_gpio)) { | 71 | if (pb->enable_gpio) |
| 77 | if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) | 72 | gpiod_set_value(pb->enable_gpio, 0); |
| 78 | gpio_set_value(pb->enable_gpio, 1); | ||
| 79 | else | ||
| 80 | gpio_set_value(pb->enable_gpio, 0); | ||
| 81 | } | ||
| 82 | 73 | ||
| 83 | regulator_disable(pb->power_supply); | 74 | regulator_disable(pb->power_supply); |
| 84 | pb->enabled = false; | 75 | pb->enabled = false; |
| @@ -148,7 +139,6 @@ static int pwm_backlight_parse_dt(struct device *dev, | |||
| 148 | struct platform_pwm_backlight_data *data) | 139 | struct platform_pwm_backlight_data *data) |
| 149 | { | 140 | { |
| 150 | struct device_node *node = dev->of_node; | 141 | struct device_node *node = dev->of_node; |
| 151 | enum of_gpio_flags flags; | ||
| 152 | struct property *prop; | 142 | struct property *prop; |
| 153 | int length; | 143 | int length; |
| 154 | u32 value; | 144 | u32 value; |
| @@ -189,14 +179,6 @@ static int pwm_backlight_parse_dt(struct device *dev, | |||
| 189 | data->max_brightness--; | 179 | data->max_brightness--; |
| 190 | } | 180 | } |
| 191 | 181 | ||
| 192 | data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0, | ||
| 193 | &flags); | ||
| 194 | if (data->enable_gpio == -EPROBE_DEFER) | ||
| 195 | return -EPROBE_DEFER; | ||
| 196 | |||
| 197 | if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW)) | ||
| 198 | data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW; | ||
| 199 | |||
| 200 | return 0; | 182 | return 0; |
| 201 | } | 183 | } |
| 202 | 184 | ||
| @@ -256,8 +238,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
| 256 | } else | 238 | } else |
| 257 | pb->scale = data->max_brightness; | 239 | pb->scale = data->max_brightness; |
| 258 | 240 | ||
| 259 | pb->enable_gpio = data->enable_gpio; | ||
| 260 | pb->enable_gpio_flags = data->enable_gpio_flags; | ||
| 261 | pb->notify = data->notify; | 241 | pb->notify = data->notify; |
| 262 | pb->notify_after = data->notify_after; | 242 | pb->notify_after = data->notify_after; |
| 263 | pb->check_fb = data->check_fb; | 243 | pb->check_fb = data->check_fb; |
| @@ -265,26 +245,38 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
| 265 | pb->dev = &pdev->dev; | 245 | pb->dev = &pdev->dev; |
| 266 | pb->enabled = false; | 246 | pb->enabled = false; |
| 267 | 247 | ||
| 268 | if (gpio_is_valid(pb->enable_gpio)) { | 248 | pb->enable_gpio = devm_gpiod_get(&pdev->dev, "enable"); |
| 269 | unsigned long flags; | 249 | if (IS_ERR(pb->enable_gpio)) { |
| 270 | 250 | ret = PTR_ERR(pb->enable_gpio); | |
| 271 | if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) | 251 | if (ret == -ENOENT) |
| 272 | flags = GPIOF_OUT_INIT_HIGH; | 252 | pb->enable_gpio = NULL; |
| 273 | else | 253 | else |
| 274 | flags = GPIOF_OUT_INIT_LOW; | 254 | goto err_alloc; |
| 255 | } | ||
| 275 | 256 | ||
| 276 | ret = gpio_request_one(pb->enable_gpio, flags, "enable"); | 257 | /* |
| 258 | * Compatibility fallback for drivers still using the integer GPIO | ||
| 259 | * platform data. Must go away soon. | ||
| 260 | */ | ||
| 261 | if (!pb->enable_gpio && gpio_is_valid(data->enable_gpio)) { | ||
| 262 | ret = devm_gpio_request_one(&pdev->dev, data->enable_gpio, | ||
| 263 | GPIOF_OUT_INIT_HIGH, "enable"); | ||
| 277 | if (ret < 0) { | 264 | if (ret < 0) { |
| 278 | dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n", | 265 | dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n", |
| 279 | pb->enable_gpio, ret); | 266 | data->enable_gpio, ret); |
| 280 | goto err_alloc; | 267 | goto err_alloc; |
| 281 | } | 268 | } |
| 269 | |||
| 270 | pb->enable_gpio = gpio_to_desc(data->enable_gpio); | ||
| 282 | } | 271 | } |
| 283 | 272 | ||
| 273 | if (pb->enable_gpio) | ||
| 274 | gpiod_direction_output(pb->enable_gpio, 1); | ||
| 275 | |||
| 284 | pb->power_supply = devm_regulator_get(&pdev->dev, "power"); | 276 | pb->power_supply = devm_regulator_get(&pdev->dev, "power"); |
| 285 | if (IS_ERR(pb->power_supply)) { | 277 | if (IS_ERR(pb->power_supply)) { |
| 286 | ret = PTR_ERR(pb->power_supply); | 278 | ret = PTR_ERR(pb->power_supply); |
| 287 | goto err_gpio; | 279 | goto err_alloc; |
| 288 | } | 280 | } |
| 289 | 281 | ||
| 290 | pb->pwm = devm_pwm_get(&pdev->dev, NULL); | 282 | pb->pwm = devm_pwm_get(&pdev->dev, NULL); |
| @@ -295,7 +287,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
| 295 | if (IS_ERR(pb->pwm)) { | 287 | if (IS_ERR(pb->pwm)) { |
| 296 | dev_err(&pdev->dev, "unable to request legacy PWM\n"); | 288 | dev_err(&pdev->dev, "unable to request legacy PWM\n"); |
| 297 | ret = PTR_ERR(pb->pwm); | 289 | ret = PTR_ERR(pb->pwm); |
| 298 | goto err_gpio; | 290 | goto err_alloc; |
| 299 | } | 291 | } |
| 300 | } | 292 | } |
| 301 | 293 | ||
| @@ -304,12 +296,15 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
| 304 | /* | 296 | /* |
| 305 | * The DT case will set the pwm_period_ns field to 0 and store the | 297 | * The DT case will set the pwm_period_ns field to 0 and store the |
| 306 | * period, parsed from the DT, in the PWM device. For the non-DT case, | 298 | * period, parsed from the DT, in the PWM device. For the non-DT case, |
| 307 | * set the period from platform data. | 299 | * set the period from platform data if it has not already been set |
| 300 | * via the PWM lookup table. | ||
| 308 | */ | 301 | */ |
| 309 | if (data->pwm_period_ns > 0) | 302 | pb->period = pwm_get_period(pb->pwm); |
| 303 | if (!pb->period && (data->pwm_period_ns > 0)) { | ||
| 304 | pb->period = data->pwm_period_ns; | ||
| 310 | pwm_set_period(pb->pwm, data->pwm_period_ns); | 305 | pwm_set_period(pb->pwm, data->pwm_period_ns); |
| 306 | } | ||
| 311 | 307 | ||
| 312 | pb->period = pwm_get_period(pb->pwm); | ||
| 313 | pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale); | 308 | pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale); |
| 314 | 309 | ||
| 315 | memset(&props, 0, sizeof(struct backlight_properties)); | 310 | memset(&props, 0, sizeof(struct backlight_properties)); |
| @@ -320,7 +315,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
| 320 | if (IS_ERR(bl)) { | 315 | if (IS_ERR(bl)) { |
| 321 | dev_err(&pdev->dev, "failed to register backlight\n"); | 316 | dev_err(&pdev->dev, "failed to register backlight\n"); |
| 322 | ret = PTR_ERR(bl); | 317 | ret = PTR_ERR(bl); |
| 323 | goto err_gpio; | 318 | goto err_alloc; |
| 324 | } | 319 | } |
| 325 | 320 | ||
| 326 | if (data->dft_brightness > data->max_brightness) { | 321 | if (data->dft_brightness > data->max_brightness) { |
| @@ -336,9 +331,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
| 336 | platform_set_drvdata(pdev, bl); | 331 | platform_set_drvdata(pdev, bl); |
| 337 | return 0; | 332 | return 0; |
| 338 | 333 | ||
| 339 | err_gpio: | ||
| 340 | if (gpio_is_valid(pb->enable_gpio)) | ||
| 341 | gpio_free(pb->enable_gpio); | ||
| 342 | err_alloc: | 334 | err_alloc: |
| 343 | if (data->exit) | 335 | if (data->exit) |
| 344 | data->exit(&pdev->dev); | 336 | data->exit(&pdev->dev); |
| @@ -359,6 +351,14 @@ static int pwm_backlight_remove(struct platform_device *pdev) | |||
| 359 | return 0; | 351 | return 0; |
| 360 | } | 352 | } |
| 361 | 353 | ||
| 354 | static void pwm_backlight_shutdown(struct platform_device *pdev) | ||
| 355 | { | ||
| 356 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
| 357 | struct pwm_bl_data *pb = bl_get_data(bl); | ||
| 358 | |||
| 359 | pwm_backlight_power_off(pb); | ||
| 360 | } | ||
| 361 | |||
| 362 | #ifdef CONFIG_PM_SLEEP | 362 | #ifdef CONFIG_PM_SLEEP |
| 363 | static int pwm_backlight_suspend(struct device *dev) | 363 | static int pwm_backlight_suspend(struct device *dev) |
| 364 | { | 364 | { |
| @@ -404,6 +404,7 @@ static struct platform_driver pwm_backlight_driver = { | |||
| 404 | }, | 404 | }, |
| 405 | .probe = pwm_backlight_probe, | 405 | .probe = pwm_backlight_probe, |
| 406 | .remove = pwm_backlight_remove, | 406 | .remove = pwm_backlight_remove, |
| 407 | .shutdown = pwm_backlight_shutdown, | ||
| 407 | }; | 408 | }; |
| 408 | 409 | ||
| 409 | module_platform_driver(pwm_backlight_driver); | 410 | module_platform_driver(pwm_backlight_driver); |
diff --git a/include/linux/platform_data/pwm-renesas-tpu.h b/include/linux/platform_data/pwm-renesas-tpu.h deleted file mode 100644 index a7220b10ddab..000000000000 --- a/include/linux/platform_data/pwm-renesas-tpu.h +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | #ifndef __PWM_RENESAS_TPU_H__ | ||
| 2 | #define __PWM_RENESAS_TPU_H__ | ||
| 3 | |||
| 4 | #include <linux/pwm.h> | ||
| 5 | |||
| 6 | #define TPU_CHANNEL_MAX 4 | ||
| 7 | |||
| 8 | struct tpu_pwm_channel_data { | ||
| 9 | enum pwm_polarity polarity; | ||
| 10 | }; | ||
| 11 | |||
| 12 | struct tpu_pwm_platform_data { | ||
| 13 | struct tpu_pwm_channel_data channels[TPU_CHANNEL_MAX]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #endif /* __PWM_RENESAS_TPU_H__ */ | ||
diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 4717f54051cb..e90628cac8fa 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h | |||
| @@ -274,14 +274,18 @@ struct pwm_lookup { | |||
| 274 | unsigned int index; | 274 | unsigned int index; |
| 275 | const char *dev_id; | 275 | const char *dev_id; |
| 276 | const char *con_id; | 276 | const char *con_id; |
| 277 | unsigned int period; | ||
| 278 | enum pwm_polarity polarity; | ||
| 277 | }; | 279 | }; |
| 278 | 280 | ||
| 279 | #define PWM_LOOKUP(_provider, _index, _dev_id, _con_id) \ | 281 | #define PWM_LOOKUP(_provider, _index, _dev_id, _con_id, _period, _polarity) \ |
| 280 | { \ | 282 | { \ |
| 281 | .provider = _provider, \ | 283 | .provider = _provider, \ |
| 282 | .index = _index, \ | 284 | .index = _index, \ |
| 283 | .dev_id = _dev_id, \ | 285 | .dev_id = _dev_id, \ |
| 284 | .con_id = _con_id, \ | 286 | .con_id = _con_id, \ |
| 287 | .period = _period, \ | ||
| 288 | .polarity = _polarity \ | ||
| 285 | } | 289 | } |
| 286 | 290 | ||
| 287 | #if IS_ENABLED(CONFIG_PWM) | 291 | #if IS_ENABLED(CONFIG_PWM) |
diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h index 2de2e275b2cb..efdd9227a49c 100644 --- a/include/linux/pwm_backlight.h +++ b/include/linux/pwm_backlight.h | |||
| @@ -6,9 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #include <linux/backlight.h> | 7 | #include <linux/backlight.h> |
| 8 | 8 | ||
| 9 | /* TODO: convert to gpiod_*() API once it has been merged */ | ||
| 10 | #define PWM_BACKLIGHT_GPIO_ACTIVE_LOW (1 << 0) | ||
| 11 | |||
| 12 | struct platform_pwm_backlight_data { | 9 | struct platform_pwm_backlight_data { |
| 13 | int pwm_id; | 10 | int pwm_id; |
| 14 | unsigned int max_brightness; | 11 | unsigned int max_brightness; |
| @@ -16,8 +13,8 @@ struct platform_pwm_backlight_data { | |||
| 16 | unsigned int lth_brightness; | 13 | unsigned int lth_brightness; |
| 17 | unsigned int pwm_period_ns; | 14 | unsigned int pwm_period_ns; |
| 18 | unsigned int *levels; | 15 | unsigned int *levels; |
| 16 | /* TODO remove once all users are switched to gpiod_* API */ | ||
| 19 | int enable_gpio; | 17 | int enable_gpio; |
| 20 | unsigned long enable_gpio_flags; | ||
| 21 | int (*init)(struct device *dev); | 18 | int (*init)(struct device *dev); |
| 22 | int (*notify)(struct device *dev, int brightness); | 19 | int (*notify)(struct device *dev, int brightness); |
| 23 | void (*notify_after)(struct device *dev, int brightness); | 20 | void (*notify_after)(struct device *dev, int brightness); |
