diff options
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/Kconfig | 9 | ||||
-rw-r--r-- | drivers/pwm/Makefile | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-bfin.c | 157 | ||||
-rw-r--r-- | drivers/pwm/pwm-omap-dmtimer.c | 68 |
4 files changed, 42 insertions, 193 deletions
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index db4501d1dc1a..4635cb35008c 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -113,15 +113,6 @@ config PWM_BERLIN To compile this driver as a module, choose M here: the module will be called pwm-berlin. -config PWM_BFIN - tristate "Blackfin PWM support" - depends on BFIN_GPTIMERS - help - Generic PWM framework driver for Blackfin. - - To compile this driver as a module, choose M here: the module - will be called pwm-bfin. - config PWM_BRCMSTB tristate "Broadcom STB PWM support" depends on ARCH_BRCMSTB || BMIPS_GENERIC diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 0258a745f30c..9c676a0dadf5 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_PWM_BCM_IPROC) += pwm-bcm-iproc.o obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-kona.o obj-$(CONFIG_PWM_BCM2835) += pwm-bcm2835.o obj-$(CONFIG_PWM_BERLIN) += pwm-berlin.o -obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o obj-$(CONFIG_PWM_BRCMSTB) += pwm-brcmstb.o obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o obj-$(CONFIG_PWM_CRC) += pwm-crc.o diff --git a/drivers/pwm/pwm-bfin.c b/drivers/pwm/pwm-bfin.c deleted file mode 100644 index a9a88137f2cb..000000000000 --- a/drivers/pwm/pwm-bfin.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Blackfin Pulse Width Modulation (PWM) core - * - * Copyright (c) 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/pwm.h> -#include <linux/slab.h> - -#include <asm/gptimers.h> -#include <asm/portmux.h> - -struct bfin_pwm_chip { - struct pwm_chip chip; -}; - -struct bfin_pwm { - unsigned short pin; -}; - -static const unsigned short pwm_to_gptimer_per[] = { - P_TMR0, P_TMR1, P_TMR2, P_TMR3, P_TMR4, P_TMR5, - P_TMR6, P_TMR7, P_TMR8, P_TMR9, P_TMR10, P_TMR11, -}; - -static int bfin_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct bfin_pwm *priv; - int ret; - - if (pwm->hwpwm >= ARRAY_SIZE(pwm_to_gptimer_per)) - return -EINVAL; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->pin = pwm_to_gptimer_per[pwm->hwpwm]; - - ret = peripheral_request(priv->pin, NULL); - if (ret) { - kfree(priv); - return ret; - } - - pwm_set_chip_data(pwm, priv); - - return 0; -} - -static void bfin_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct bfin_pwm *priv = pwm_get_chip_data(pwm); - - if (priv) { - peripheral_free(priv->pin); - kfree(priv); - } -} - -static int bfin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - int duty_ns, int period_ns) -{ - struct bfin_pwm *priv = pwm_get_chip_data(pwm); - unsigned long period, duty; - unsigned long long val; - - val = (unsigned long long)get_sclk() * period_ns; - do_div(val, NSEC_PER_SEC); - period = val; - - val = (unsigned long long)period * duty_ns; - do_div(val, period_ns); - duty = period - val; - - if (duty >= period) - duty = period - 1; - - set_gptimer_config(priv->pin, TIMER_MODE_PWM | TIMER_PERIOD_CNT); - set_gptimer_pwidth(priv->pin, duty); - set_gptimer_period(priv->pin, period); - - return 0; -} - -static int bfin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct bfin_pwm *priv = pwm_get_chip_data(pwm); - - enable_gptimer(priv->pin); - - return 0; -} - -static void bfin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct bfin_pwm *priv = pwm_get_chip_data(pwm); - - disable_gptimer(priv->pin); -} - -static const struct pwm_ops bfin_pwm_ops = { - .request = bfin_pwm_request, - .free = bfin_pwm_free, - .config = bfin_pwm_config, - .enable = bfin_pwm_enable, - .disable = bfin_pwm_disable, - .owner = THIS_MODULE, -}; - -static int bfin_pwm_probe(struct platform_device *pdev) -{ - struct bfin_pwm_chip *pwm; - int ret; - - pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); - if (!pwm) - return -ENOMEM; - - platform_set_drvdata(pdev, pwm); - - pwm->chip.dev = &pdev->dev; - pwm->chip.ops = &bfin_pwm_ops; - pwm->chip.base = -1; - pwm->chip.npwm = 12; - - ret = pwmchip_add(&pwm->chip); - if (ret < 0) { - dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); - return ret; - } - - return 0; -} - -static int bfin_pwm_remove(struct platform_device *pdev) -{ - struct bfin_pwm_chip *pwm = platform_get_drvdata(pdev); - - return pwmchip_remove(&pwm->chip); -} - -static struct platform_driver bfin_pwm_driver = { - .driver = { - .name = "bfin-pwm", - }, - .probe = bfin_pwm_probe, - .remove = bfin_pwm_remove, -}; - -module_platform_driver(bfin_pwm_driver); - -MODULE_LICENSE("GPL"); diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c index 5ad42f33e70c..665da3c8fbce 100644 --- a/drivers/pwm/pwm-omap-dmtimer.c +++ b/drivers/pwm/pwm-omap-dmtimer.c @@ -23,6 +23,7 @@ #include <linux/mutex.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/platform_data/dmtimer-omap.h> #include <linux/platform_data/pwm_omap_dmtimer.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip { struct pwm_chip chip; struct mutex mutex; pwm_omap_dmtimer *dm_timer; - struct pwm_omap_dmtimer_pdata *pdata; + const struct omap_dm_timer_ops *pdata; struct platform_device *dm_timer_pdev; }; @@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *timer; + struct platform_device *timer_pdev; struct pwm_omap_dmtimer_chip *omap; - struct pwm_omap_dmtimer_pdata *pdata; + struct dmtimer_platform_data *timer_pdata; + const struct omap_dm_timer_ops *pdata; pwm_omap_dmtimer *dm_timer; u32 v; - int status; + int ret = 0; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "Missing dmtimer platform data\n"); - return -EINVAL; + timer = of_parse_phandle(np, "ti,timers", 0); + if (!timer) + return -ENODEV; + + timer_pdev = of_find_device_by_node(timer); + if (!timer_pdev) { + dev_err(&pdev->dev, "Unable to find Timer pdev\n"); + ret = -ENODEV; + goto put; } - if (!pdata->request_by_node || + timer_pdata = dev_get_platdata(&timer_pdev->dev); + if (!timer_pdata) { + dev_err(&pdev->dev, "dmtimer pdata structure NULL\n"); + ret = -EINVAL; + goto put; + } + + pdata = timer_pdata->timer_ops; + + if (!pdata || !pdata->request_by_node || !pdata->free || !pdata->enable || !pdata->disable || @@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) !pdata->set_prescaler || !pdata->write_counter) { dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); - return -EINVAL; + ret = -EINVAL; + goto put; } - timer = of_parse_phandle(np, "ti,timers", 0); - if (!timer) - return -ENODEV; - if (!of_get_property(timer, "ti,timer-pwm", NULL)) { dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); - return -ENODEV; + ret = -ENODEV; + goto put; } dm_timer = pdata->request_by_node(timer); - if (!dm_timer) - return -EPROBE_DEFER; + if (!dm_timer) { + ret = -EPROBE_DEFER; + goto put; + } + +put: + of_node_put(timer); + if (ret < 0) + return ret; omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); if (!omap) { @@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) omap->pdata = pdata; omap->dm_timer = dm_timer; - - omap->dm_timer_pdev = of_find_device_by_node(timer); - if (!omap->dm_timer_pdev) { - dev_err(&pdev->dev, "Unable to find timer pdev\n"); - omap->pdata->free(dm_timer); - return -EINVAL; - } + omap->dm_timer_pdev = timer_pdev; /* * Ensure that the timer is stopped before we allow PWM core to call @@ -322,11 +338,11 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) mutex_init(&omap->mutex); - status = pwmchip_add(&omap->chip); - if (status < 0) { + ret = pwmchip_add(&omap->chip); + if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM\n"); omap->pdata->free(omap->dm_timer); - return status; + return ret; } platform_set_drvdata(pdev, omap); |