diff options
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/core.c | 70 | ||||
-rw-r--r-- | drivers/pwm/pwm-atmel-hlcdc.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-atmel.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-bcm-kona.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-berlin.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-brcmstb.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-fsl-ftm.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-imx.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-lp3943.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-mxs.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-pca9685.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-sti.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-sun4i.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-twl-led.c | 1 | ||||
-rw-r--r-- | drivers/pwm/pwm-twl.c | 1 |
15 files changed, 37 insertions, 48 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 172ef8245811..a0860b30bd93 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -137,9 +137,14 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args) { struct pwm_device *pwm; + /* check, whether the driver supports a third cell for flags */ if (pc->of_pwm_n_cells < 3) return ERR_PTR(-EINVAL); + /* flags in the third cell are optional */ + if (args->args_count < 2) + return ERR_PTR(-EINVAL); + if (args->args[0] >= pc->npwm) return ERR_PTR(-EINVAL); @@ -148,11 +153,10 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args) return pwm; pwm->args.period = args->args[1]; + pwm->args.polarity = PWM_POLARITY_NORMAL; - if (args->args[2] & PWM_POLARITY_INVERTED) + if (args->args_count > 2 && args->args[2] & PWM_POLARITY_INVERTED) pwm->args.polarity = PWM_POLARITY_INVERSED; - else - pwm->args.polarity = PWM_POLARITY_NORMAL; return pwm; } @@ -163,9 +167,14 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) { struct pwm_device *pwm; + /* sanity check driver support */ if (pc->of_pwm_n_cells < 2) return ERR_PTR(-EINVAL); + /* all cells are required */ + if (args->args_count != pc->of_pwm_n_cells) + return ERR_PTR(-EINVAL); + if (args->args[0] >= pc->npwm) return ERR_PTR(-EINVAL); @@ -663,24 +672,17 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id) err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index, &args); if (err) { - pr_debug("%s(): can't parse \"pwms\" property\n", __func__); + pr_err("%s(): can't parse \"pwms\" property\n", __func__); return ERR_PTR(err); } pc = of_node_to_pwmchip(args.np); if (IS_ERR(pc)) { - pr_debug("%s(): PWM chip not found\n", __func__); + pr_err("%s(): PWM chip not found\n", __func__); pwm = ERR_CAST(pc); goto put; } - if (args.args_count != pc->of_pwm_n_cells) { - pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name, - args.np->full_name); - pwm = ERR_PTR(-EINVAL); - goto put; - } - pwm = pc->of_xlate(pc, &args); if (IS_ERR(pwm)) goto put; @@ -757,12 +759,13 @@ void pwm_remove_table(struct pwm_lookup *table, size_t num) */ struct pwm_device *pwm_get(struct device *dev, const char *con_id) { - struct pwm_device *pwm = ERR_PTR(-EPROBE_DEFER); const char *dev_id = dev ? dev_name(dev) : NULL; - struct pwm_chip *chip = NULL; + struct pwm_device *pwm; + struct pwm_chip *chip; unsigned int best = 0; struct pwm_lookup *p, *chosen = NULL; unsigned int match; + int err; /* look up via DT first */ if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) @@ -817,24 +820,35 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) } } - if (!chosen) { - pwm = ERR_PTR(-ENODEV); - goto out; - } + mutex_unlock(&pwm_lookup_lock); + + if (!chosen) + return ERR_PTR(-ENODEV); chip = pwmchip_find_by_name(chosen->provider); + + /* + * If the lookup entry specifies a module, load the module and retry + * the PWM chip lookup. This can be used to work around driver load + * ordering issues if driver's can't be made to properly support the + * deferred probe mechanism. + */ + if (!chip && chosen->module) { + err = request_module(chosen->module); + if (err == 0) + chip = pwmchip_find_by_name(chosen->provider); + } + if (!chip) - goto out; + return ERR_PTR(-EPROBE_DEFER); pwm = pwm_request_from_chip(chip, chosen->index, con_id ?: dev_id); if (IS_ERR(pwm)) - goto out; + return pwm; pwm->args.period = chosen->period; pwm->args.polarity = chosen->polarity; -out: - mutex_unlock(&pwm_lookup_lock); return pwm; } EXPORT_SYMBOL_GPL(pwm_get); @@ -960,18 +974,6 @@ void devm_pwm_put(struct device *dev, struct pwm_device *pwm) } EXPORT_SYMBOL_GPL(devm_pwm_put); -/** - * pwm_can_sleep() - report whether PWM access will sleep - * @pwm: PWM device - * - * Returns: True if accessing the PWM can sleep, false otherwise. - */ -bool pwm_can_sleep(struct pwm_device *pwm) -{ - return true; -} -EXPORT_SYMBOL_GPL(pwm_can_sleep); - #ifdef CONFIG_DEBUG_FS static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) { diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c index 14fc011faa32..999187277ea5 100644 --- a/drivers/pwm/pwm-atmel-hlcdc.c +++ b/drivers/pwm/pwm-atmel-hlcdc.c @@ -270,7 +270,6 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) chip->chip.npwm = 1; chip->chip.of_xlate = of_pwm_xlate_with_flags; chip->chip.of_pwm_n_cells = 3; - chip->chip.can_sleep = 1; ret = pwmchip_add_with_polarity(&chip->chip, PWM_POLARITY_INVERSED); if (ret) { diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c index e6b8b1b7e6ba..67a7023be5c2 100644 --- a/drivers/pwm/pwm-atmel.c +++ b/drivers/pwm/pwm-atmel.c @@ -385,7 +385,6 @@ static int atmel_pwm_probe(struct platform_device *pdev) atmel_pwm->chip.base = -1; atmel_pwm->chip.npwm = 4; - atmel_pwm->chip.can_sleep = true; atmel_pwm->config = data->config; atmel_pwm->updated_pwms = 0; mutex_init(&atmel_pwm->isr_lock); diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c index c63418322023..09a95aeb3a70 100644 --- a/drivers/pwm/pwm-bcm-kona.c +++ b/drivers/pwm/pwm-bcm-kona.c @@ -276,7 +276,6 @@ static int kona_pwmc_probe(struct platform_device *pdev) kp->chip.npwm = 6; kp->chip.of_xlate = of_pwm_xlate_with_flags; kp->chip.of_pwm_n_cells = 3; - kp->chip.can_sleep = true; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); kp->base = devm_ioremap_resource(&pdev->dev, res); diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c index 01339c152ab0..771859aca4be 100644 --- a/drivers/pwm/pwm-berlin.c +++ b/drivers/pwm/pwm-berlin.c @@ -206,7 +206,6 @@ static int berlin_pwm_probe(struct platform_device *pdev) pwm->chip.ops = &berlin_pwm_ops; pwm->chip.base = -1; pwm->chip.npwm = 4; - pwm->chip.can_sleep = true; pwm->chip.of_xlate = of_pwm_xlate_with_flags; pwm->chip.of_pwm_n_cells = 3; diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c index 5d5adee16886..8063cffa1c96 100644 --- a/drivers/pwm/pwm-brcmstb.c +++ b/drivers/pwm/pwm-brcmstb.c @@ -270,7 +270,6 @@ static int brcmstb_pwm_probe(struct platform_device *pdev) p->chip.ops = &brcmstb_pwm_ops; p->chip.base = -1; p->chip.npwm = 2; - p->chip.can_sleep = true; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); p->base = devm_ioremap_resource(&pdev->dev, res); diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index fad968eb75f6..557b4ea16796 100644 --- a/drivers/pwm/pwm-fsl-ftm.c +++ b/drivers/pwm/pwm-fsl-ftm.c @@ -446,7 +446,6 @@ static int fsl_pwm_probe(struct platform_device *pdev) fpc->chip.of_pwm_n_cells = 3; fpc->chip.base = -1; fpc->chip.npwm = 8; - fpc->chip.can_sleep = true; ret = pwmchip_add(&fpc->chip); if (ret < 0) { diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index 957099e82ed3..2ba5c3a398ff 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -289,7 +289,6 @@ static int imx_pwm_probe(struct platform_device *pdev) imx->chip.dev = &pdev->dev; imx->chip.base = -1; imx->chip.npwm = 1; - imx->chip.can_sleep = true; if (data->polarity_supported) { dev_dbg(&pdev->dev, "PWM supports output inversion\n"); diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 872ea76a4f19..52584e9962ed 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c @@ -278,7 +278,6 @@ static int lp3943_pwm_probe(struct platform_device *pdev) lp3943_pwm->chip.dev = &pdev->dev; lp3943_pwm->chip.ops = &lp3943_pwm_ops; lp3943_pwm->chip.npwm = LP3943_NUM_PWMS; - lp3943_pwm->chip.can_sleep = true; platform_set_drvdata(pdev, lp3943_pwm); diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c index 9a596324ebef..a6017ad9926c 100644 --- a/drivers/pwm/pwm-mxs.c +++ b/drivers/pwm/pwm-mxs.c @@ -151,7 +151,7 @@ static int mxs_pwm_probe(struct platform_device *pdev) mxs->chip.dev = &pdev->dev; mxs->chip.ops = &mxs_pwm_ops; mxs->chip.base = -1; - mxs->chip.can_sleep = true; + ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm); if (ret < 0) { dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret); diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c index 5566760f7dc4..0cfb3571a732 100644 --- a/drivers/pwm/pwm-pca9685.c +++ b/drivers/pwm/pwm-pca9685.c @@ -486,7 +486,6 @@ static int pca9685_pwm_probe(struct i2c_client *client, pca->chip.dev = &client->dev; pca->chip.base = -1; - pca->chip.can_sleep = true; ret = pwmchip_add(&pca->chip); if (ret < 0) diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c index dd82dc840af9..2b7c31c9d1ab 100644 --- a/drivers/pwm/pwm-sti.c +++ b/drivers/pwm/pwm-sti.c @@ -635,7 +635,6 @@ skip_cpt: pc->chip.ops = &sti_pwm_ops; pc->chip.base = -1; pc->chip.npwm = pc->cdata->pwm_num_devs; - pc->chip.can_sleep = true; ret = pwmchip_add(&pc->chip); if (ret < 0) { diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index b0803f6c64d9..1284ffa05921 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -340,7 +340,6 @@ static int sun4i_pwm_probe(struct platform_device *pdev) pwm->chip.ops = &sun4i_pwm_ops; pwm->chip.base = -1; pwm->chip.npwm = pwm->data->npwm; - pwm->chip.can_sleep = true; pwm->chip.of_xlate = of_pwm_xlate_with_flags; pwm->chip.of_pwm_n_cells = 3; diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c index b964470025c5..21eff991d0e3 100644 --- a/drivers/pwm/pwm-twl-led.c +++ b/drivers/pwm/pwm-twl-led.c @@ -303,7 +303,6 @@ static int twl_pwmled_probe(struct platform_device *pdev) twl->chip.dev = &pdev->dev; twl->chip.base = -1; - twl->chip.can_sleep = true; mutex_init(&twl->mutex); diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c index 7a993b056638..9de617b76680 100644 --- a/drivers/pwm/pwm-twl.c +++ b/drivers/pwm/pwm-twl.c @@ -323,7 +323,6 @@ static int twl_pwm_probe(struct platform_device *pdev) twl->chip.dev = &pdev->dev; twl->chip.base = -1; twl->chip.npwm = 2; - twl->chip.can_sleep = true; mutex_init(&twl->mutex); |