From f3e25e68ceb2abaeefcac8f930c940c4494705d0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 14 Nov 2023 12:20:11 +0100 Subject: pwm: Drop unused member "pwm" from struct pwm_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This member is only assigned to and never read. So drop it. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/core.c | 1 - include/linux/pwm.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 29078486534d..24bb796d15f6 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -265,7 +265,6 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner) pwm = &chip->pwms[i]; pwm->chip = chip; - pwm->pwm = chip->base + i; pwm->hwpwm = i; } diff --git a/include/linux/pwm.h b/include/linux/pwm.h index cda3597b84f2..8cadf9ee8d26 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -79,7 +79,6 @@ struct pwm_device { const char *label; unsigned long flags; unsigned int hwpwm; - unsigned int pwm; struct pwm_chip *chip; struct pwm_args args; -- cgit From 54c86dd20bba23109e32e4e2f94ff93dd9863bc3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 14 Nov 2023 12:20:12 +0100 Subject: pwm: Replace PWM chip unique base by unique ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Traditionally each PWM device had a unique ID stored in the "pwm" member of struct pwm_device. However this number was hardly used and dropped in the previous commit. To identify a certain PWM you're supposed to use the chip's ID and the hwpwm of the PWM device now. With the PWM chip base gone PWM chips can get their IDs better and simpler using an idr. This is expected to change the numbering of PWM chips, but nothing should rely on the numbering anyhow. Other than that the side effects are: - The PWM chip IDs are smaller and in most cases consecutive. - The ordering in /sys/kernel/debug/pwm is ordered by ascending PWM chip ID. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/core.c | 67 ++++++++++++++++++++--------------------------------- drivers/pwm/sysfs.c | 2 +- include/linux/pwm.h | 3 +-- 3 files changed, 27 insertions(+), 45 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 24bb796d15f6..ebe404dfdf5b 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -23,52 +24,25 @@ #define CREATE_TRACE_POINTS #include -#define MAX_PWMS 1024 - static DEFINE_MUTEX(pwm_lookup_lock); static LIST_HEAD(pwm_lookup_list); -/* protects access to pwm_chips and allocated_pwms */ +/* protects access to pwm_chips */ static DEFINE_MUTEX(pwm_lock); -static LIST_HEAD(pwm_chips); -static DECLARE_BITMAP(allocated_pwms, MAX_PWMS); - -/* Called with pwm_lock held */ -static int alloc_pwms(unsigned int count) -{ - unsigned int start; - - start = bitmap_find_next_zero_area(allocated_pwms, MAX_PWMS, 0, - count, 0); - - if (start + count > MAX_PWMS) - return -ENOSPC; - - bitmap_set(allocated_pwms, start, count); - - return start; -} - -/* Called with pwm_lock held */ -static void free_pwms(struct pwm_chip *chip) -{ - bitmap_clear(allocated_pwms, chip->base, chip->npwm); - - kfree(chip->pwms); - chip->pwms = NULL; -} +static DEFINE_IDR(pwm_chips); static struct pwm_chip *pwmchip_find_by_name(const char *name) { struct pwm_chip *chip; + unsigned long id, tmp; if (!name) return NULL; mutex_lock(&pwm_lock); - list_for_each_entry(chip, &pwm_chips, list) { + idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) { const char *chip_name = dev_name(chip->dev); if (chip_name && strcmp(chip_name, name) == 0) { @@ -252,14 +226,14 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner) mutex_lock(&pwm_lock); - ret = alloc_pwms(chip->npwm); + ret = idr_alloc(&pwm_chips, chip, 0, 0, GFP_KERNEL); if (ret < 0) { mutex_unlock(&pwm_lock); kfree(chip->pwms); return ret; } - chip->base = ret; + chip->id = ret; for (i = 0; i < chip->npwm; i++) { pwm = &chip->pwms[i]; @@ -268,8 +242,6 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner) pwm->hwpwm = i; } - list_add(&chip->list, &pwm_chips); - mutex_unlock(&pwm_lock); if (IS_ENABLED(CONFIG_OF)) @@ -296,11 +268,11 @@ void pwmchip_remove(struct pwm_chip *chip) mutex_lock(&pwm_lock); - list_del_init(&chip->list); - - free_pwms(chip); + idr_remove(&pwm_chips, chip->id); mutex_unlock(&pwm_lock); + + kfree(chip->pwms); } EXPORT_SYMBOL_GPL(pwmchip_remove); @@ -596,10 +568,11 @@ EXPORT_SYMBOL_GPL(pwm_adjust_config); static struct pwm_chip *fwnode_to_pwmchip(struct fwnode_handle *fwnode) { struct pwm_chip *chip; + unsigned long id, tmp; mutex_lock(&pwm_lock); - list_for_each_entry(chip, &pwm_chips, list) + idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) if (chip->dev && device_match_fwnode(chip->dev, fwnode)) { mutex_unlock(&pwm_lock); return chip; @@ -1057,17 +1030,27 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) static void *pwm_seq_start(struct seq_file *s, loff_t *pos) { + unsigned long id = *pos; + void *ret; + mutex_lock(&pwm_lock); s->private = ""; - return seq_list_start(&pwm_chips, *pos); + ret = idr_get_next_ul(&pwm_chips, &id); + *pos = id; + return ret; } static void *pwm_seq_next(struct seq_file *s, void *v, loff_t *pos) { + unsigned long id = *pos + 1; + void *ret; + s->private = "\n"; - return seq_list_next(v, &pwm_chips, pos); + ret = idr_get_next_ul(&pwm_chips, &id); + *pos = id; + return ret; } static void pwm_seq_stop(struct seq_file *s, void *v) @@ -1077,7 +1060,7 @@ static void pwm_seq_stop(struct seq_file *s, void *v) static int pwm_seq_show(struct seq_file *s, void *v) { - struct pwm_chip *chip = list_entry(v, struct pwm_chip, list); + struct pwm_chip *chip = v; seq_printf(s, "%s%s/%s, %d PWM device%s\n", (char *)s->private, chip->dev->bus ? chip->dev->bus->name : "no-bus", diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index 8d1254761e4d..4edb994fa2e1 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -510,7 +510,7 @@ void pwmchip_sysfs_export(struct pwm_chip *chip) * the kernel it's just not exported. */ parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip, - "pwmchip%d", chip->base); + "pwmchip%d", chip->id); if (IS_ERR(parent)) { dev_warn(chip->dev, "device_create failed for pwm_chip sysfs export\n"); diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 8cadf9ee8d26..c27a4bb76012 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -292,7 +292,7 @@ struct pwm_chip { struct device *dev; const struct pwm_ops *ops; struct module *owner; - int base; + unsigned int id; unsigned int npwm; struct pwm_device * (*of_xlate)(struct pwm_chip *chip, @@ -300,7 +300,6 @@ struct pwm_chip { unsigned int of_pwm_n_cells; /* only used internally by the PWM framework */ - struct list_head list; struct pwm_device *pwms; }; -- cgit From 0360a48733729f9329483409acd048d04b43ee17 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 14 Nov 2023 12:20:13 +0100 Subject: pwm: Mention PWM chip ID in /sys/kernel/debug/pwm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While it's not hard to match the entries from /sys/kernel/debug/pwm to the corresponding pwmchip in /sys/class/pwm, it's a bit simpler to have the number mentioned in /sys/kernel/debug/pwm. Link: https://lore.kernel.org/r/20230808165250.942396-3-u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index ebe404dfdf5b..fb36b3d559a7 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -1062,7 +1062,8 @@ static int pwm_seq_show(struct seq_file *s, void *v) { struct pwm_chip *chip = v; - seq_printf(s, "%s%s/%s, %d PWM device%s\n", (char *)s->private, + seq_printf(s, "%s%d: %s/%s, %d PWM device%s\n", + (char *)s->private, chip->id, chip->dev->bus ? chip->dev->bus->name : "no-bus", dev_name(chip->dev), chip->npwm, (chip->npwm != 1) ? "s" : ""); -- cgit From 6c4406ce609fb5857d52c1e42a40cb5e7e8ee94a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 16 Nov 2023 11:52:13 +0100 Subject: pwm: cros-ec: Drop unused member from driver private data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .dev is unused since the driver was introduced in commit 1f0d3bb02785 ("pwm: Add ChromeOS EC PWM driver"). Drop it. Signed-off-by: Uwe Kleine-König Reviewed-by: Tzung-Bi Shih Signed-off-by: Thierry Reding --- drivers/pwm/pwm-cros-ec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c index 4fbd23e4ef69..9a8f1b6a4e13 100644 --- a/drivers/pwm/pwm-cros-ec.c +++ b/drivers/pwm/pwm-cros-ec.c @@ -25,7 +25,6 @@ * @channel: array with per-channel data */ struct cros_ec_pwm_device { - struct device *dev; struct cros_ec_device *ec; struct pwm_chip chip; bool use_pwm_type; -- cgit From ded38f874eff2bb6fc46a0377aa8dcdcf4b43a2e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:18 +0200 Subject: pwm: atmel-hlcdc: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Reviewed-by: Jonathan Cameron Signed-off-by: Uwe Kleine-König Acked-by: Nicolas Ferre Signed-off-by: Thierry Reding --- drivers/pwm/pwm-atmel-hlcdc.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c index 07920e034757..3f2c5031a3ba 100644 --- a/drivers/pwm/pwm-atmel-hlcdc.c +++ b/drivers/pwm/pwm-atmel-hlcdc.c @@ -180,7 +180,6 @@ static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = { .div1_clk_erratum = true, }; -#ifdef CONFIG_PM_SLEEP static int atmel_hlcdc_pwm_suspend(struct device *dev) { struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev); @@ -210,10 +209,9 @@ static int atmel_hlcdc_pwm_resume(struct device *dev) return atmel_hlcdc_pwm_apply(&atmel->chip, &atmel->chip.pwms[0], &state); } -#endif -static SIMPLE_DEV_PM_OPS(atmel_hlcdc_pwm_pm_ops, - atmel_hlcdc_pwm_suspend, atmel_hlcdc_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(atmel_hlcdc_pwm_pm_ops, + atmel_hlcdc_pwm_suspend, atmel_hlcdc_pwm_resume); static const struct of_device_id atmel_hlcdc_dt_ids[] = { { @@ -297,7 +295,7 @@ static struct platform_driver atmel_hlcdc_pwm_driver = { .driver = { .name = "atmel-hlcdc-pwm", .of_match_table = atmel_hlcdc_pwm_dt_ids, - .pm = &atmel_hlcdc_pwm_pm_ops, + .pm = pm_ptr(&atmel_hlcdc_pwm_pm_ops), }, .probe = atmel_hlcdc_pwm_probe, .remove_new = atmel_hlcdc_pwm_remove, -- cgit From a7bab37f87c2a551ce12aefc30648a206550cd78 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:19 +0200 Subject: pwm: atmel-tcb: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Reviewed-by: Jonathan Cameron Signed-off-by: Uwe Kleine-König Acked-by: Nicolas Ferre Signed-off-by: Thierry Reding --- drivers/pwm/pwm-atmel-tcb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c index 98b33c016c3c..d42c897cb85e 100644 --- a/drivers/pwm/pwm-atmel-tcb.c +++ b/drivers/pwm/pwm-atmel-tcb.c @@ -489,7 +489,6 @@ static const struct of_device_id atmel_tcb_pwm_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt_ids); -#ifdef CONFIG_PM_SLEEP static int atmel_tcb_pwm_suspend(struct device *dev) { struct atmel_tcb_pwm_chip *tcbpwm = dev_get_drvdata(dev); @@ -522,16 +521,15 @@ static int atmel_tcb_pwm_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(atmel_tcb_pwm_pm_ops, atmel_tcb_pwm_suspend, - atmel_tcb_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(atmel_tcb_pwm_pm_ops, atmel_tcb_pwm_suspend, + atmel_tcb_pwm_resume); static struct platform_driver atmel_tcb_pwm_driver = { .driver = { .name = "atmel-tcb-pwm", .of_match_table = atmel_tcb_pwm_dt_ids, - .pm = &atmel_tcb_pwm_pm_ops, + .pm = pm_ptr(&atmel_tcb_pwm_pm_ops), }, .probe = atmel_tcb_pwm_probe, .remove_new = atmel_tcb_pwm_remove, -- cgit From fac37751c46836fa5dc9e1f958ae160e75cd24f1 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:20 +0200 Subject: pwm: berlin: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-berlin.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c index ba2d79991769..442913232dc0 100644 --- a/drivers/pwm/pwm-berlin.c +++ b/drivers/pwm/pwm-berlin.c @@ -226,7 +226,6 @@ static int berlin_pwm_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP static int berlin_pwm_suspend(struct device *dev) { struct berlin_pwm_chip *bpc = dev_get_drvdata(dev); @@ -267,17 +266,16 @@ static int berlin_pwm_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend, - berlin_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend, + berlin_pwm_resume); static struct platform_driver berlin_pwm_driver = { .probe = berlin_pwm_probe, .driver = { .name = "berlin-pwm", .of_match_table = berlin_pwm_match, - .pm = &berlin_pwm_pm_ops, + .pm = pm_ptr(&berlin_pwm_pm_ops), }, }; module_platform_driver(berlin_pwm_driver); -- cgit From d6b81be1f5f991bdbeabc734db04cec7dd79426b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:21 +0200 Subject: pwm: brcmstb: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Acked-by: Florian Fainelli Reviewed-by: Jonathan Cameron Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-brcmstb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c index b723c2d4f485..0fdeb0b2dbf3 100644 --- a/drivers/pwm/pwm-brcmstb.c +++ b/drivers/pwm/pwm-brcmstb.c @@ -259,7 +259,6 @@ static int brcmstb_pwm_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP static int brcmstb_pwm_suspend(struct device *dev) { struct brcmstb_pwm *p = dev_get_drvdata(dev); @@ -275,17 +274,16 @@ static int brcmstb_pwm_resume(struct device *dev) return clk_prepare_enable(p->clk); } -#endif -static SIMPLE_DEV_PM_OPS(brcmstb_pwm_pm_ops, brcmstb_pwm_suspend, - brcmstb_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(brcmstb_pwm_pm_ops, brcmstb_pwm_suspend, + brcmstb_pwm_resume); static struct platform_driver brcmstb_pwm_driver = { .probe = brcmstb_pwm_probe, .driver = { .name = "pwm-brcmstb", .of_match_table = brcmstb_pwm_of_match, - .pm = &brcmstb_pwm_pm_ops, + .pm = pm_ptr(&brcmstb_pwm_pm_ops), }, }; module_platform_driver(brcmstb_pwm_driver); -- cgit From 30b5b066fa839b7471ca1222713b055d93681a77 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:22 +0200 Subject: pwm: dwc: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-dwc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index bd9cadb497d7..4929354f8cd9 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -71,7 +71,6 @@ static void dwc_pwm_remove(struct pci_dev *pci) pm_runtime_get_noresume(&pci->dev); } -#ifdef CONFIG_PM_SLEEP static int dwc_pwm_suspend(struct device *dev) { struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); @@ -106,9 +105,8 @@ static int dwc_pwm_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(dwc_pwm_pm_ops, dwc_pwm_suspend, dwc_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(dwc_pwm_pm_ops, dwc_pwm_suspend, dwc_pwm_resume); static const struct pci_device_id dwc_pwm_id_table[] = { { PCI_VDEVICE(INTEL, 0x4bb7) }, /* Elkhart Lake */ @@ -122,7 +120,7 @@ static struct pci_driver dwc_pwm_driver = { .remove = dwc_pwm_remove, .id_table = dwc_pwm_id_table, .driver = { - .pm = &dwc_pwm_pm_ops, + .pm = pm_ptr(&dwc_pwm_pm_ops), }, }; -- cgit From 9676b40e1885fca203ced4be49adfc3ca6ed6f16 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:23 +0200 Subject: pwm: imx-tpm: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding __maybe_unused can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Reviewed-by: Jonathan Cameron Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-imx-tpm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c index dc6aafeb9f7b..9fc290e647e1 100644 --- a/drivers/pwm/pwm-imx-tpm.c +++ b/drivers/pwm/pwm-imx-tpm.c @@ -371,7 +371,7 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev) return 0; } -static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev) +static int pwm_imx_tpm_suspend(struct device *dev) { struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev); @@ -390,7 +390,7 @@ static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev) return 0; } -static int __maybe_unused pwm_imx_tpm_resume(struct device *dev) +static int pwm_imx_tpm_resume(struct device *dev) { struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev); int ret = 0; @@ -402,8 +402,8 @@ static int __maybe_unused pwm_imx_tpm_resume(struct device *dev) return ret; } -static SIMPLE_DEV_PM_OPS(imx_tpm_pwm_pm, - pwm_imx_tpm_suspend, pwm_imx_tpm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(imx_tpm_pwm_pm, + pwm_imx_tpm_suspend, pwm_imx_tpm_resume); static const struct of_device_id imx_tpm_pwm_dt_ids[] = { { .compatible = "fsl,imx7ulp-pwm", }, @@ -415,7 +415,7 @@ static struct platform_driver imx_tpm_pwm_driver = { .driver = { .name = "imx7ulp-tpm-pwm", .of_match_table = imx_tpm_pwm_dt_ids, - .pm = &imx_tpm_pwm_pm, + .pm = pm_ptr(&imx_tpm_pwm_pm), }, .probe = pwm_imx_tpm_probe, }; -- cgit From e9ebab624d0a8322203cfbcc15510656b0a177d0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:24 +0200 Subject: pwm: samsung: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Reviewed-by: Jonathan Cameron Signed-off-by: Uwe Kleine-König Reviewed-by: Andi Shyti Signed-off-by: Thierry Reding --- drivers/pwm/pwm-samsung.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index 69d9f4577b34..6e77302f7368 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -620,7 +620,6 @@ static void pwm_samsung_remove(struct platform_device *pdev) clk_disable_unprepare(our_chip->base_clk); } -#ifdef CONFIG_PM_SLEEP static int pwm_samsung_resume(struct device *dev) { struct samsung_pwm_chip *our_chip = dev_get_drvdata(dev); @@ -653,14 +652,13 @@ static int pwm_samsung_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(pwm_samsung_pm_ops, NULL, pwm_samsung_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(pwm_samsung_pm_ops, NULL, pwm_samsung_resume); static struct platform_driver pwm_samsung_driver = { .driver = { .name = "samsung-pwm", - .pm = &pwm_samsung_pm_ops, + .pm = pm_ptr(&pwm_samsung_pm_ops), .of_match_table = of_match_ptr(samsung_pwm_matches), }, .probe = pwm_samsung_probe, -- cgit From 39dfb60c724c59103412abe369d78b7243b31d35 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:25 +0200 Subject: pwm: stm32-lp: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding __maybe_unused can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Reviewed-by: Jonathan Cameron Signed-off-by: Uwe Kleine-König Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stm32-lp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c index b67974cc1872..439068f3eca1 100644 --- a/drivers/pwm/pwm-stm32-lp.c +++ b/drivers/pwm/pwm-stm32-lp.c @@ -218,7 +218,7 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev) return 0; } -static int __maybe_unused stm32_pwm_lp_suspend(struct device *dev) +static int stm32_pwm_lp_suspend(struct device *dev) { struct stm32_pwm_lp *priv = dev_get_drvdata(dev); struct pwm_state state; @@ -233,13 +233,13 @@ static int __maybe_unused stm32_pwm_lp_suspend(struct device *dev) return pinctrl_pm_select_sleep_state(dev); } -static int __maybe_unused stm32_pwm_lp_resume(struct device *dev) +static int stm32_pwm_lp_resume(struct device *dev) { return pinctrl_pm_select_default_state(dev); } -static SIMPLE_DEV_PM_OPS(stm32_pwm_lp_pm_ops, stm32_pwm_lp_suspend, - stm32_pwm_lp_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(stm32_pwm_lp_pm_ops, stm32_pwm_lp_suspend, + stm32_pwm_lp_resume); static const struct of_device_id stm32_pwm_lp_of_match[] = { { .compatible = "st,stm32-pwm-lp", }, @@ -252,7 +252,7 @@ static struct platform_driver stm32_pwm_lp_driver = { .driver = { .name = "stm32-pwm-lp", .of_match_table = stm32_pwm_lp_of_match, - .pm = &stm32_pwm_lp_pm_ops, + .pm = pm_ptr(&stm32_pwm_lp_pm_ops), }, }; module_platform_driver(stm32_pwm_lp_driver); -- cgit From 3d67277607c755160531ebd6b756ffd7195de627 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:26 +0200 Subject: pwm: stm32: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding __maybe_unused can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Reviewed-by: Jonathan Cameron Signed-off-by: Uwe Kleine-König Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stm32.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 3303a754ea02..8be037757b8b 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -645,7 +645,7 @@ static int stm32_pwm_probe(struct platform_device *pdev) return 0; } -static int __maybe_unused stm32_pwm_suspend(struct device *dev) +static int stm32_pwm_suspend(struct device *dev) { struct stm32_pwm *priv = dev_get_drvdata(dev); unsigned int i; @@ -666,7 +666,7 @@ static int __maybe_unused stm32_pwm_suspend(struct device *dev) return pinctrl_pm_select_sleep_state(dev); } -static int __maybe_unused stm32_pwm_resume(struct device *dev) +static int stm32_pwm_resume(struct device *dev) { struct stm32_pwm *priv = dev_get_drvdata(dev); int ret; @@ -679,7 +679,7 @@ static int __maybe_unused stm32_pwm_resume(struct device *dev) return stm32_pwm_apply_breakinputs(priv); } -static SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_resume); static const struct of_device_id stm32_pwm_of_match[] = { { .compatible = "st,stm32-pwm", }, @@ -692,7 +692,7 @@ static struct platform_driver stm32_pwm_driver = { .driver = { .name = "stm32-pwm", .of_match_table = stm32_pwm_of_match, - .pm = &stm32_pwm_pm_ops, + .pm = pm_ptr(&stm32_pwm_pm_ops), }, }; module_platform_driver(stm32_pwm_driver); -- cgit From 5d5a0aa5e261eaaea81de4f30c26d22323026714 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:27 +0200 Subject: pwm: tiecap: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tiecap.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 11e3549cf103..d974f4414ac9 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -269,7 +269,6 @@ static void ecap_pwm_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static void ecap_pwm_save_context(struct ecap_pwm_chip *pc) { pm_runtime_get_sync(pc->chip.dev); @@ -312,15 +311,14 @@ static int ecap_pwm_resume(struct device *dev) ecap_pwm_restore_context(pc); return 0; } -#endif -static SIMPLE_DEV_PM_OPS(ecap_pwm_pm_ops, ecap_pwm_suspend, ecap_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(ecap_pwm_pm_ops, ecap_pwm_suspend, ecap_pwm_resume); static struct platform_driver ecap_pwm_driver = { .driver = { .name = "ecap", .of_match_table = ecap_of_match, - .pm = &ecap_pwm_pm_ops, + .pm = pm_ptr(&ecap_pwm_pm_ops), }, .probe = ecap_pwm_probe, .remove_new = ecap_pwm_remove, -- cgit From fb1b517fd87649add1e8acb813f4f8af5a28d4d9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 23 Oct 2023 19:46:28 +0200 Subject: pwm: tiehrpwm: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro has the advantage over SIMPLE_DEV_PM_OPS that we don't have to care about when the functions are actually used, so the corresponding #ifdef can be dropped. Also make use of pm_ptr() to discard all PM related stuff if CONFIG_PM isn't enabled. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tiehrpwm.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index 66ac2655845f..af231fa74fa9 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -521,7 +521,6 @@ static void ehrpwm_pwm_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static void ehrpwm_pwm_save_context(struct ehrpwm_pwm_chip *pc) { pm_runtime_get_sync(pc->chip.dev); @@ -589,16 +588,15 @@ static int ehrpwm_pwm_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(ehrpwm_pwm_pm_ops, ehrpwm_pwm_suspend, - ehrpwm_pwm_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(ehrpwm_pwm_pm_ops, ehrpwm_pwm_suspend, + ehrpwm_pwm_resume); static struct platform_driver ehrpwm_pwm_driver = { .driver = { .name = "ehrpwm", .of_match_table = ehrpwm_of_match, - .pm = &ehrpwm_pwm_pm_ops, + .pm = pm_ptr(&ehrpwm_pwm_pm_ops), }, .probe = ehrpwm_pwm_probe, .remove_new = ehrpwm_pwm_remove, -- cgit From 1c9a2ad84f5a7450265a2ffcdb27715dbca2b980 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 23 Nov 2023 09:33:23 +0100 Subject: pwm: jz4740: Add trailing \n to error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Error messages are supposed to end in \n. Add the line terminator to the two error messages that lack this. Suggested-by: Paul Cercueil Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-jz4740.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c index e9375de60ad6..73f96cef1662 100644 --- a/drivers/pwm/pwm-jz4740.c +++ b/drivers/pwm/pwm-jz4740.c @@ -149,7 +149,7 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, */ rate = clk_round_rate(clk, tmp); if (rate < 0) { - dev_err(chip->dev, "Unable to round rate: %ld", rate); + dev_err(chip->dev, "Unable to round rate: %ld\n", rate); return rate; } @@ -170,7 +170,7 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, err = clk_set_rate(clk, rate); if (err) { - dev_err(chip->dev, "Unable to set rate: %d", err); + dev_err(chip->dev, "Unable to set rate: %d\n", err); return err; } -- cgit From b0445a18d3eef36b7dc4e07a0ccb4f7178251942 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 23 Nov 2023 10:56:20 +0100 Subject: pwm: Narrow scope of struct pwm_device pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the expression determining the size of the allocation for chip->pwms it's more natural to use sizeof(*chip->pwms) than sizeof(*pwm). With that changed, the variable pwm is only used in a for loop and its scope can be reduced accordingly. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index fb36b3d559a7..b0e50ca9398a 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -208,7 +208,6 @@ static bool pwm_ops_check(const struct pwm_chip *chip) */ int __pwmchip_add(struct pwm_chip *chip, struct module *owner) { - struct pwm_device *pwm; unsigned int i; int ret; @@ -220,7 +219,7 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner) chip->owner = owner; - chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL); + chip->pwms = kcalloc(chip->npwm, sizeof(*chip->pwms), GFP_KERNEL); if (!chip->pwms) return -ENOMEM; @@ -236,7 +235,7 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner) chip->id = ret; for (i = 0; i < chip->npwm; i++) { - pwm = &chip->pwms[i]; + struct pwm_device *pwm = &chip->pwms[i]; pwm->chip = chip; pwm->hwpwm = i; -- cgit From 7ee2273197f1c1755ebdad8716eab50689401aff Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 26 Oct 2023 14:54:17 -0500 Subject: pwm: Use device_get_match_data() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use preferred device_get_match_data() instead of of_match_device() to get the driver match data. With this, adjust the includes to explicitly include the correct headers. As these drivers only do DT based matching, of_match_device() will never return NULL if we've gotten to probe(). Therefore, the NULL check and error returns can be dropped. Signed-off-by: Rob Herring Reviewed-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-img.c | 8 ++------ drivers/pwm/pwm-rockchip.c | 9 ++------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index 116fa060e302..0d218c0b690e 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -13,9 +13,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -260,7 +260,6 @@ static int img_pwm_probe(struct platform_device *pdev) u64 val; unsigned long clk_rate; struct img_pwm_chip *imgchip; - const struct of_device_id *of_dev_id; imgchip = devm_kzalloc(&pdev->dev, sizeof(*imgchip), GFP_KERNEL); if (!imgchip) @@ -272,10 +271,7 @@ static int img_pwm_probe(struct platform_device *pdev) if (IS_ERR(imgchip->base)) return PTR_ERR(imgchip->base); - of_dev_id = of_match_device(img_pwm_of_match, &pdev->dev); - if (!of_dev_id) - return -ENODEV; - imgchip->data = of_dev_id->data; + imgchip->data = device_get_match_data(&pdev->dev); imgchip->periph_regs = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "img,cr-periph"); diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index cce4381e188a..a7c647e37837 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include #include #include @@ -296,16 +296,11 @@ MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids); static int rockchip_pwm_probe(struct platform_device *pdev) { - const struct of_device_id *id; struct rockchip_pwm_chip *pc; u32 enable_conf, ctrl; bool enabled; int ret, count; - id = of_match_device(rockchip_pwm_dt_ids, &pdev->dev); - if (!id) - return -EINVAL; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); if (!pc) return -ENOMEM; @@ -344,7 +339,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pc); - pc->data = id->data; + pc->data = device_get_match_data(&pdev->dev); pc->chip.dev = &pdev->dev; pc->chip.ops = &rockchip_pwm_ops; pc->chip.npwm = 1; -- cgit From e495f47274a145dd802748fed66608f46d9ae11d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 19 Oct 2023 22:07:00 +0200 Subject: pwm: stm32: Replace write_ccrx with regmap_write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TIM_CCR1...4 registers are consecutive, so replace the switch case with a simple calculation. Since ch is known to be in the 0...3 range (it is set to hwpwm < npwm <= 4), drop the unnecessary error handling. The return value was not checked anyway. What remains does not warrant keeping the write_ccrx() function around, so instead call regmap_write() directly at the singular call site. Signed-off-by: Philipp Zabel Signed-off-by: Uwe Kleine-König Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stm32.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 8be037757b8b..2dcf6ecab4be 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -52,21 +52,6 @@ static u32 active_channels(struct stm32_pwm *dev) return ccer & TIM_CCER_CCXE; } -static int write_ccrx(struct stm32_pwm *dev, int ch, u32 value) -{ - switch (ch) { - case 0: - return regmap_write(dev->regmap, TIM_CCR1, value); - case 1: - return regmap_write(dev->regmap, TIM_CCR2, value); - case 2: - return regmap_write(dev->regmap, TIM_CCR3, value); - case 3: - return regmap_write(dev->regmap, TIM_CCR4, value); - } - return -EINVAL; -} - #define TIM_CCER_CC12P (TIM_CCER_CC1P | TIM_CCER_CC2P) #define TIM_CCER_CC12E (TIM_CCER_CC1E | TIM_CCER_CC2E) #define TIM_CCER_CC34P (TIM_CCER_CC3P | TIM_CCER_CC4P) @@ -369,7 +354,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, dty = prd * duty_ns; do_div(dty, period_ns); - write_ccrx(priv, ch, dty); + regmap_write(priv->regmap, TIM_CCR1 + 4 * ch, dty); /* Configure output mode */ shift = (ch & 0x1) * CCMR_CHANNEL_SHIFT; -- cgit From c0504f59ced46b080520c2fc15b2b58d70f9ec83 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 19 Oct 2023 22:07:01 +0200 Subject: pwm: stm32: Make ch parameter unsigned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The channel parameter is only ever set to pwm->hwpwm. Make it unsigned int as well. Signed-off-by: Philipp Zabel Signed-off-by: Uwe Kleine-König Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stm32.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 2dcf6ecab4be..67c9e262dc57 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -308,7 +308,7 @@ unlock: return ret; } -static int stm32_pwm_config(struct stm32_pwm *priv, int ch, +static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch, int duty_ns, int period_ns) { unsigned long long prd, div, dty; @@ -371,7 +371,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, return 0; } -static int stm32_pwm_set_polarity(struct stm32_pwm *priv, int ch, +static int stm32_pwm_set_polarity(struct stm32_pwm *priv, unsigned int ch, enum pwm_polarity polarity) { u32 mask; @@ -386,7 +386,7 @@ static int stm32_pwm_set_polarity(struct stm32_pwm *priv, int ch, return 0; } -static int stm32_pwm_enable(struct stm32_pwm *priv, int ch) +static int stm32_pwm_enable(struct stm32_pwm *priv, unsigned int ch) { u32 mask; int ret; @@ -411,7 +411,7 @@ static int stm32_pwm_enable(struct stm32_pwm *priv, int ch) return 0; } -static void stm32_pwm_disable(struct stm32_pwm *priv, int ch) +static void stm32_pwm_disable(struct stm32_pwm *priv, unsigned int ch) { u32 mask; -- cgit From 41fa8f57c0d269243fe3bde2bce71e82c884b9ad Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 19 Oct 2023 22:07:02 +0200 Subject: pwm: stm32: Use hweight32 in stm32_pwm_detect_channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use hweight32() to count the CCxE bits in stm32_pwm_detect_channels(). Since the return value is assigned to chip.npwm, change it to unsigned int as well. Signed-off-by: Philipp Zabel Signed-off-by: Uwe Kleine-König Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stm32.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 67c9e262dc57..0da371291cef 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -563,10 +563,9 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) priv->have_complementary_output = (ccer != 0); } -static int stm32_pwm_detect_channels(struct stm32_pwm *priv) +static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv) { u32 ccer; - int npwm = 0; /* * If channels enable bits don't exist writing 1 will have no @@ -576,19 +575,7 @@ static int stm32_pwm_detect_channels(struct stm32_pwm *priv) regmap_read(priv->regmap, TIM_CCER, &ccer); regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); - if (ccer & TIM_CCER_CC1E) - npwm++; - - if (ccer & TIM_CCER_CC2E) - npwm++; - - if (ccer & TIM_CCER_CC3E) - npwm++; - - if (ccer & TIM_CCER_CC4E) - npwm++; - - return npwm; + return hweight32(ccer & TIM_CCER_CCXE); } static int stm32_pwm_probe(struct platform_device *pdev) -- cgit From e56ec7b7527c2be54a0c15064c71838fd5c49d4b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 19 Oct 2023 22:07:03 +0200 Subject: pwm: stm32: Implement .get_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the &pwm_ops->get_state callback so drivers can inherit PWM state set by the bootloader. Signed-off-by: Philipp Zabel [ukl: split off from a patch that also fixes clk enable count in .probe()] Signed-off-by: Uwe Kleine-König Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stm32.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 0da371291cef..9a7d7891edde 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -471,8 +471,50 @@ static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm, return ret; } +static int stm32_pwm_get_state(struct pwm_chip *chip, + struct pwm_device *pwm, struct pwm_state *state) +{ + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); + int ch = pwm->hwpwm; + unsigned long rate; + u32 ccer, psc, arr, ccr; + u64 dty, prd; + int ret; + + mutex_lock(&priv->lock); + + ret = regmap_read(priv->regmap, TIM_CCER, &ccer); + if (ret) + goto out; + + state->enabled = ccer & (TIM_CCER_CC1E << (ch * 4)); + state->polarity = (ccer & (TIM_CCER_CC1P << (ch * 4))) ? + PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; + ret = regmap_read(priv->regmap, TIM_PSC, &psc); + if (ret) + goto out; + ret = regmap_read(priv->regmap, TIM_ARR, &arr); + if (ret) + goto out; + ret = regmap_read(priv->regmap, TIM_CCR1 + 4 * ch, &ccr); + if (ret) + goto out; + + rate = clk_get_rate(priv->clk); + + prd = (u64)NSEC_PER_SEC * (psc + 1) * (arr + 1); + state->period = DIV_ROUND_UP_ULL(prd, rate); + dty = (u64)NSEC_PER_SEC * (psc + 1) * ccr; + state->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); + +out: + mutex_unlock(&priv->lock); + return ret; +} + static const struct pwm_ops stm32pwm_ops = { .apply = stm32_pwm_apply_locked, + .get_state = stm32_pwm_get_state, .capture = IS_ENABLED(CONFIG_DMA_ENGINE) ? stm32_pwm_capture : NULL, }; -- cgit From 19f1016ea9600ed89bc24247c36ff5934ad94fbb Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 19 Oct 2023 22:07:04 +0200 Subject: pwm: stm32: Fix enable count for clk in .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the driver take over hardware state without disabling in .probe() and enable the clock for each enabled channel. Signed-off-by: Philipp Zabel [ukleinek: split off from a patch that also implemented .get_state()] Signed-off-by: Uwe Kleine-König Fixes: 7edf7369205b ("pwm: Add driver for STM32 plaftorm") Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stm32.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 9a7d7891edde..5f10cba492ec 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -605,17 +605,21 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) priv->have_complementary_output = (ccer != 0); } -static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv) +static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, + unsigned int *num_enabled) { - u32 ccer; + u32 ccer, ccer_backup; /* * If channels enable bits don't exist writing 1 will have no * effect so we can detect and count them. */ + regmap_read(priv->regmap, TIM_CCER, &ccer_backup); regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); regmap_read(priv->regmap, TIM_CCER, &ccer); - regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); + regmap_write(priv->regmap, TIM_CCER, ccer_backup); + + *num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE); return hweight32(ccer & TIM_CCER_CCXE); } @@ -626,6 +630,8 @@ static int stm32_pwm_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); struct stm32_pwm *priv; + unsigned int num_enabled; + unsigned int i; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -648,7 +654,11 @@ static int stm32_pwm_probe(struct platform_device *pdev) priv->chip.dev = dev; priv->chip.ops = &stm32pwm_ops; - priv->chip.npwm = stm32_pwm_detect_channels(priv); + priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); + + /* Initialize clock refcount to number of enabled PWM channels. */ + for (i = 0; i < num_enabled; i++) + clk_enable(priv->clk); ret = devm_pwmchip_add(dev, &priv->chip); if (ret < 0) -- cgit From 74ade42105bb80e67b7b07b7e88cdaaa8c3402b6 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 23 Nov 2023 14:47:16 +0100 Subject: dt-bindings: pwm: remove Xinlei's mail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xinlei Lee's mail is bouncing: : host mailgw02.mediatek.com[216.200.240.185] said: 550 Relaying mail to xinlei.lee@mediatek.com is not allowed (in reply to RCPT TO command) Remove it. Signed-off-by: Michael Walle Acked-by: Uwe Kleine-König Acked-by: Conor Dooley Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/pwm/mediatek,pwm-disp.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pwm/mediatek,pwm-disp.yaml b/Documentation/devicetree/bindings/pwm/mediatek,pwm-disp.yaml index 153e146df7d4..afcdeed4e88a 100644 --- a/Documentation/devicetree/bindings/pwm/mediatek,pwm-disp.yaml +++ b/Documentation/devicetree/bindings/pwm/mediatek,pwm-disp.yaml @@ -8,7 +8,6 @@ title: MediaTek DISP_PWM Controller maintainers: - Jitao Shi - - Xinlei Lee allOf: - $ref: pwm.yaml# -- cgit From 2d91123ae5614b8737abd3a519b81265309a1ac3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 29 Nov 2023 11:18:32 +0100 Subject: pwm: Update kernel doc for struct pwm_chip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit c572f3b9c8b7 ("pwm: Replace PWM chip unique base by unique ID") changed the members of struct pwm_chip, but failed to update the documentation accordingly. Catch up and document the new member and drop description for the two removed ones. Reported-by: Stephen Rothwell Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- include/linux/pwm.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/pwm.h b/include/linux/pwm.h index c27a4bb76012..f87655c06c82 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -281,11 +281,10 @@ struct pwm_ops { * @dev: device providing the PWMs * @ops: callbacks for this PWM controller * @owner: module providing this chip - * @base: number of first PWM controlled by this chip + * @id: unique number of this PWM chip * @npwm: number of PWMs controlled by this chip * @of_xlate: request a PWM device given a device tree PWM specifier * @of_pwm_n_cells: number of cells expected in the device tree PWM specifier - * @list: list node for internal use * @pwms: array of PWM devices allocated by the framework */ struct pwm_chip { -- cgit From 80943bbdcfa8138eca3bfd71a8ed4bdf1e107f6b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 1 Dec 2023 11:22:53 +0100 Subject: pwm: Stop referencing pwm->chip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drivers have access to the chip via a function argument already, so there is no need to reference it via the PWM device. Reviewed-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-bcm-kona.c | 2 +- drivers/pwm/pwm-img.c | 2 +- drivers/pwm/pwm-jz4740.c | 2 +- drivers/pwm/pwm-lpc18xx-sct.c | 2 +- drivers/pwm/pwm-lpc32xx.c | 2 +- drivers/pwm/pwm-mediatek.c | 2 +- drivers/pwm/pwm-renesas-tpu.c | 2 +- drivers/pwm/pwm-sti.c | 2 +- drivers/pwm/pwm-stmpe.c | 2 +- drivers/pwm/pwm-tegra.c | 2 +- drivers/pwm/pwm-twl-led.c | 4 ++-- drivers/pwm/pwm-twl.c | 4 ++-- drivers/pwm/pwm-vt8500.c | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c index 15d6ed03c3ce..45046a5c20a5 100644 --- a/drivers/pwm/pwm-bcm-kona.c +++ b/drivers/pwm/pwm-bcm-kona.c @@ -260,7 +260,7 @@ static int kona_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm, return err; } - err = kona_pwmc_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = kona_pwmc_config(chip, pwm, state->duty_cycle, state->period); if (err && !pwm->state.enabled) clk_disable_unprepare(kp->clk); diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index 0d218c0b690e..5965ac35b32e 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -196,7 +196,7 @@ static int img_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = img_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = img_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c index 73f96cef1662..80dcff237a15 100644 --- a/drivers/pwm/pwm-jz4740.c +++ b/drivers/pwm/pwm-jz4740.c @@ -123,7 +123,7 @@ static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { - struct jz4740_pwm_chip *jz = to_jz4740(pwm->chip); + struct jz4740_pwm_chip *jz = to_jz4740(chip); unsigned long long tmp = 0xffffull * NSEC_PER_SEC; struct clk *clk = jz->clk[pwm->hwpwm]; unsigned long period, duty; diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c index ef7d0da137ed..b3d4a955aa31 100644 --- a/drivers/pwm/pwm-lpc18xx-sct.c +++ b/drivers/pwm/pwm-lpc18xx-sct.c @@ -328,7 +328,7 @@ static int lpc18xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = lpc18xx_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = lpc18xx_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index 78f664e41e6e..1d9f3e7a2434 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -103,7 +103,7 @@ static int lpc32xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = lpc32xx_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = lpc32xx_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index 373abfd25acb..17d290f847af 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -217,7 +217,7 @@ static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = pwm_mediatek_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = pwm_mediatek_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 4239f2c3e8b2..ce92db1f8511 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -416,7 +416,7 @@ static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = tpu_pwm_config(pwm->chip, pwm, + err = tpu_pwm_config(chip, pwm, state->duty_cycle, state->period, enabled); if (err) return err; diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c index dc92cea31cd0..6cf55cf34d39 100644 --- a/drivers/pwm/pwm-sti.c +++ b/drivers/pwm/pwm-sti.c @@ -407,7 +407,7 @@ static int sti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = sti_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = sti_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-stmpe.c b/drivers/pwm/pwm-stmpe.c index a46f5b4dd816..d730631c6583 100644 --- a/drivers/pwm/pwm-stmpe.c +++ b/drivers/pwm/pwm-stmpe.c @@ -275,7 +275,7 @@ static int stmpe_24xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = stmpe_24xx_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = stmpe_24xx_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 39ea51e08c94..82ee2f0754f9 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -256,7 +256,7 @@ static int tegra_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = tegra_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = tegra_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c index 625233f4703a..8a870d0db3c6 100644 --- a/drivers/pwm/pwm-twl-led.c +++ b/drivers/pwm/pwm-twl-led.c @@ -175,7 +175,7 @@ static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, * pwm_apply_state because of !state->enabled and so the two values in * pwm->state might not be configured in hardware. */ - ret = twl4030_pwmled_config(pwm->chip, pwm, + ret = twl4030_pwmled_config(chip, pwm, state->duty_cycle, state->period); if (ret) return ret; @@ -275,7 +275,7 @@ static int twl6030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = twl6030_pwmled_config(pwm->chip, pwm, + err = twl6030_pwmled_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c index 603d31f27470..68e02c9a6bf9 100644 --- a/drivers/pwm/pwm-twl.c +++ b/drivers/pwm/pwm-twl.c @@ -294,7 +294,7 @@ static int twl4030_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = twl_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = twl_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; @@ -319,7 +319,7 @@ static int twl6030_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = twl_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = twl_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 5568d5312d3c..bdea60389487 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c @@ -209,7 +209,7 @@ static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, * pwm_apply_state because of !state->enabled and so the two values in * pwm->state might not be configured in hardware. */ - err = vt8500_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); + err = vt8500_pwm_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; -- cgit From c748a6d77c06a78651030e17da6beb278a1c9470 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 19 Dec 2023 16:30:24 +0000 Subject: pwm: Rename pwm_apply_state() to pwm_apply_might_sleep() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to introduce a pwm api which can be used from atomic context, we will need two functions for applying pwm changes: int pwm_apply_might_sleep(struct pwm *, struct pwm_state *); int pwm_apply_atomic(struct pwm *, struct pwm_state *); This commit just deals with renaming pwm_apply_state(), a following commit will introduce the pwm_apply_atomic() function. Acked-by: Uwe Kleine-König Acked-by: Guenter Roeck Acked-by: Mark Brown Acked-by: Dmitry Torokhov # for input Acked-by: Hans de Goede Acked-by: Jani Nikula Acked-by: Lee Jones Signed-off-by: Sean Young Signed-off-by: Thierry Reding --- Documentation/driver-api/pwm.rst | 8 ++++---- MAINTAINERS | 2 +- drivers/gpu/drm/i915/display/intel_backlight.c | 6 +++--- drivers/gpu/drm/solomon/ssd130x.c | 2 +- drivers/hwmon/pwm-fan.c | 8 ++++---- drivers/input/misc/da7280.c | 4 ++-- drivers/input/misc/pwm-beeper.c | 4 ++-- drivers/input/misc/pwm-vibra.c | 8 ++++---- drivers/leds/leds-pwm.c | 2 +- drivers/leds/rgb/leds-pwm-multicolor.c | 4 ++-- drivers/media/rc/pwm-ir-tx.c | 4 ++-- drivers/platform/x86/lenovo-yogabook.c | 2 +- drivers/pwm/core.c | 18 ++++++++--------- drivers/pwm/pwm-twl-led.c | 2 +- drivers/pwm/pwm-vt8500.c | 2 +- drivers/pwm/sysfs.c | 10 ++++----- drivers/regulator/pwm-regulator.c | 4 ++-- drivers/video/backlight/lm3630a_bl.c | 2 +- drivers/video/backlight/lp855x_bl.c | 2 +- drivers/video/backlight/pwm_bl.c | 12 +++++------ drivers/video/fbdev/ssd1307fb.c | 2 +- include/linux/pwm.h | 28 +++++++++++++------------- 22 files changed, 68 insertions(+), 68 deletions(-) diff --git a/Documentation/driver-api/pwm.rst b/Documentation/driver-api/pwm.rst index bb264490a87a..f1d8197c8c43 100644 --- a/Documentation/driver-api/pwm.rst +++ b/Documentation/driver-api/pwm.rst @@ -41,7 +41,7 @@ the getter, devm_pwm_get() and devm_fwnode_pwm_get(), also exist. After being requested, a PWM has to be configured using:: - int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state); + int pwm_apply_might_sleep(struct pwm_device *pwm, struct pwm_state *state); This API controls both the PWM period/duty_cycle config and the enable/disable state. @@ -57,13 +57,13 @@ If supported by the driver, the signal can be optimized, for example to improve EMI by phase shifting the individual channels of a chip. The pwm_config(), pwm_enable() and pwm_disable() functions are just wrappers -around pwm_apply_state() and should not be used if the user wants to change +around pwm_apply_might_sleep() and should not be used if the user wants to change several parameter at once. For example, if you see pwm_config() and pwm_{enable,disable}() calls in the same function, this probably means you -should switch to pwm_apply_state(). +should switch to pwm_apply_might_sleep(). The PWM user API also allows one to query the PWM state that was passed to the -last invocation of pwm_apply_state() using pwm_get_state(). Note this is +last invocation of pwm_apply_might_sleep() using pwm_get_state(). Note this is different to what the driver has actually implemented if the request cannot be satisfied exactly with the hardware in use. There is currently no way for consumers to get the actually implemented settings. diff --git a/MAINTAINERS b/MAINTAINERS index 97f51d5ec1cf..c58480595220 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17576,7 +17576,7 @@ F: drivers/video/backlight/pwm_bl.c F: include/dt-bindings/pwm/ F: include/linux/pwm.h F: include/linux/pwm_backlight.h -K: pwm_(config|apply_state|ops) +K: pwm_(config|apply_might_sleep|ops) PXA GPIO DRIVER M: Robert Jarzmik diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 2e8f17c04522..ff9b9918b0a1 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -274,7 +274,7 @@ static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel; pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); - pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); + pwm_apply_might_sleep(panel->backlight.pwm, &panel->backlight.pwm_state); } static void @@ -427,7 +427,7 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn intel_backlight_set_pwm_level(old_conn_state, level); panel->backlight.pwm_state.enabled = false; - pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); + pwm_apply_might_sleep(panel->backlight.pwm, &panel->backlight.pwm_state); } void intel_backlight_disable(const struct drm_connector_state *old_conn_state) @@ -749,7 +749,7 @@ static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); panel->backlight.pwm_state.enabled = true; - pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); + pwm_apply_might_sleep(panel->backlight.pwm, &panel->backlight.pwm_state); } static void __intel_backlight_enable(const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index e0174f82e353..cce043a4a1dc 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -319,7 +319,7 @@ static int ssd130x_pwm_enable(struct ssd130x_device *ssd130x) pwm_init_state(ssd130x->pwm, &pwmstate); pwm_set_relative_duty_cycle(&pwmstate, 50, 100); - pwm_apply_state(ssd130x->pwm, &pwmstate); + pwm_apply_might_sleep(ssd130x->pwm, &pwmstate); /* Enable the PWM */ pwm_enable(ssd130x->pwm); diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 6e4516c2ab89..b67bc9e833c0 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -151,7 +151,7 @@ static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) } state->enabled = true; - ret = pwm_apply_state(ctx->pwm, state); + ret = pwm_apply_might_sleep(ctx->pwm, state); if (ret) { dev_err(ctx->dev, "failed to enable PWM\n"); goto disable_regulator; @@ -181,7 +181,7 @@ static int pwm_fan_power_off(struct pwm_fan_ctx *ctx) state->enabled = false; state->duty_cycle = 0; - ret = pwm_apply_state(ctx->pwm, state); + ret = pwm_apply_might_sleep(ctx->pwm, state); if (ret) { dev_err(ctx->dev, "failed to disable PWM\n"); return ret; @@ -207,7 +207,7 @@ static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) period = state->period; state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); - ret = pwm_apply_state(ctx->pwm, state); + ret = pwm_apply_might_sleep(ctx->pwm, state); if (ret) return ret; ret = pwm_fan_power_on(ctx); @@ -278,7 +278,7 @@ static int pwm_fan_update_enable(struct pwm_fan_ctx *ctx, long val) state, &enable_regulator); - pwm_apply_state(ctx->pwm, state); + pwm_apply_might_sleep(ctx->pwm, state); pwm_fan_switch_power(ctx, enable_regulator); pwm_fan_update_state(ctx, 0); } diff --git a/drivers/input/misc/da7280.c b/drivers/input/misc/da7280.c index ce82548916bb..c1fa75c0f970 100644 --- a/drivers/input/misc/da7280.c +++ b/drivers/input/misc/da7280.c @@ -352,7 +352,7 @@ static int da7280_haptic_set_pwm(struct da7280_haptic *haptics, bool enabled) state.duty_cycle = period_mag_multi; } - error = pwm_apply_state(haptics->pwm_dev, &state); + error = pwm_apply_might_sleep(haptics->pwm_dev, &state); if (error) dev_err(haptics->dev, "Failed to apply pwm state: %d\n", error); @@ -1175,7 +1175,7 @@ static int da7280_probe(struct i2c_client *client) /* Sync up PWM state and ensure it is off. */ pwm_init_state(haptics->pwm_dev, &state); state.enabled = false; - error = pwm_apply_state(haptics->pwm_dev, &state); + error = pwm_apply_might_sleep(haptics->pwm_dev, &state); if (error) { dev_err(dev, "Failed to apply PWM state: %d\n", error); return error; diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 1e731d8397c6..5b9aedf4362f 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -39,7 +39,7 @@ static int pwm_beeper_on(struct pwm_beeper *beeper, unsigned long period) state.period = period; pwm_set_relative_duty_cycle(&state, 50, 100); - error = pwm_apply_state(beeper->pwm, &state); + error = pwm_apply_might_sleep(beeper->pwm, &state); if (error) return error; @@ -138,7 +138,7 @@ static int pwm_beeper_probe(struct platform_device *pdev) /* Sync up PWM state and ensure it is off. */ pwm_init_state(beeper->pwm, &state); state.enabled = false; - error = pwm_apply_state(beeper->pwm, &state); + error = pwm_apply_might_sleep(beeper->pwm, &state); if (error) { dev_err(dev, "failed to apply initial PWM state: %d\n", error); diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c index acac79c488aa..3e5ed685ed8f 100644 --- a/drivers/input/misc/pwm-vibra.c +++ b/drivers/input/misc/pwm-vibra.c @@ -56,7 +56,7 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) pwm_set_relative_duty_cycle(&state, vibrator->level, 0xffff); state.enabled = true; - err = pwm_apply_state(vibrator->pwm, &state); + err = pwm_apply_might_sleep(vibrator->pwm, &state); if (err) { dev_err(pdev, "failed to apply pwm state: %d\n", err); return err; @@ -67,7 +67,7 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) state.duty_cycle = vibrator->direction_duty_cycle; state.enabled = true; - err = pwm_apply_state(vibrator->pwm_dir, &state); + err = pwm_apply_might_sleep(vibrator->pwm_dir, &state); if (err) { dev_err(pdev, "failed to apply dir-pwm state: %d\n", err); pwm_disable(vibrator->pwm); @@ -160,7 +160,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) /* Sync up PWM state and ensure it is off. */ pwm_init_state(vibrator->pwm, &state); state.enabled = false; - err = pwm_apply_state(vibrator->pwm, &state); + err = pwm_apply_might_sleep(vibrator->pwm, &state); if (err) { dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", err); @@ -174,7 +174,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) /* Sync up PWM state and ensure it is off. */ pwm_init_state(vibrator->pwm_dir, &state); state.enabled = false; - err = pwm_apply_state(vibrator->pwm_dir, &state); + err = pwm_apply_might_sleep(vibrator->pwm_dir, &state); if (err) { dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", err); diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 2b3bf1353b70..4e3936a39d0e 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -54,7 +54,7 @@ static int led_pwm_set(struct led_classdev *led_cdev, led_dat->pwmstate.duty_cycle = duty; led_dat->pwmstate.enabled = true; - return pwm_apply_state(led_dat->pwm, &led_dat->pwmstate); + return pwm_apply_might_sleep(led_dat->pwm, &led_dat->pwmstate); } __attribute__((nonnull)) diff --git a/drivers/leds/rgb/leds-pwm-multicolor.c b/drivers/leds/rgb/leds-pwm-multicolor.c index 46cd062b8b24..e1a81e0109e8 100644 --- a/drivers/leds/rgb/leds-pwm-multicolor.c +++ b/drivers/leds/rgb/leds-pwm-multicolor.c @@ -51,8 +51,8 @@ static int led_pwm_mc_set(struct led_classdev *cdev, priv->leds[i].state.duty_cycle = duty; priv->leds[i].state.enabled = duty > 0; - ret = pwm_apply_state(priv->leds[i].pwm, - &priv->leds[i].state); + ret = pwm_apply_might_sleep(priv->leds[i].pwm, + &priv->leds[i].state); if (ret) break; } diff --git a/drivers/media/rc/pwm-ir-tx.c b/drivers/media/rc/pwm-ir-tx.c index c5f37c03af9c..cf51e2760975 100644 --- a/drivers/media/rc/pwm-ir-tx.c +++ b/drivers/media/rc/pwm-ir-tx.c @@ -68,7 +68,7 @@ static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf, for (i = 0; i < count; i++) { state.enabled = !(i % 2); - pwm_apply_state(pwm, &state); + pwm_apply_might_sleep(pwm, &state); edge = ktime_add_us(edge, txbuf[i]); delta = ktime_us_delta(edge, ktime_get()); @@ -77,7 +77,7 @@ static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf, } state.enabled = false; - pwm_apply_state(pwm, &state); + pwm_apply_might_sleep(pwm, &state); return count; } diff --git a/drivers/platform/x86/lenovo-yogabook.c b/drivers/platform/x86/lenovo-yogabook.c index b8d0239192cb..fd62bf746ebd 100644 --- a/drivers/platform/x86/lenovo-yogabook.c +++ b/drivers/platform/x86/lenovo-yogabook.c @@ -435,7 +435,7 @@ static int yogabook_pdev_set_kbd_backlight(struct yogabook_data *data, u8 level) .enabled = level, }; - pwm_apply_state(data->kbd_bl_pwm, &state); + pwm_apply_might_sleep(data->kbd_bl_pwm, &state); gpiod_set_value(data->kbd_bl_led_enable, level ? 1 : 0); return 0; } diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index b0e50ca9398a..c6228843a1a7 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -326,8 +326,8 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, } EXPORT_SYMBOL_GPL(pwm_request_from_chip); -static void pwm_apply_state_debug(struct pwm_device *pwm, - const struct pwm_state *state) +static void pwm_apply_debug(struct pwm_device *pwm, + const struct pwm_state *state) { struct pwm_state *last = &pwm->last; struct pwm_chip *chip = pwm->chip; @@ -433,11 +433,11 @@ static void pwm_apply_state_debug(struct pwm_device *pwm, } /** - * pwm_apply_state() - atomically apply a new state to a PWM device + * pwm_apply_might_sleep() - atomically apply a new state to a PWM device * @pwm: PWM device * @state: new state to apply */ -int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) +int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state) { struct pwm_chip *chip; int err; @@ -445,7 +445,7 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) /* * Some lowlevel driver's implementations of .apply() make use of * mutexes, also with some drivers only returning when the new - * configuration is active calling pwm_apply_state() from atomic context + * configuration is active calling pwm_apply_might_sleep() from atomic context * is a bad idea. So make it explicit that calling this function might * sleep. */ @@ -475,11 +475,11 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) * only do this after pwm->state was applied as some * implementations of .get_state depend on this */ - pwm_apply_state_debug(pwm, state); + pwm_apply_debug(pwm, state); return 0; } -EXPORT_SYMBOL_GPL(pwm_apply_state); +EXPORT_SYMBOL_GPL(pwm_apply_might_sleep); /** * pwm_capture() - capture and report a PWM signal @@ -537,7 +537,7 @@ int pwm_adjust_config(struct pwm_device *pwm) state.period = pargs.period; state.polarity = pargs.polarity; - return pwm_apply_state(pwm, &state); + return pwm_apply_might_sleep(pwm, &state); } /* @@ -560,7 +560,7 @@ int pwm_adjust_config(struct pwm_device *pwm) state.duty_cycle = state.period - state.duty_cycle; } - return pwm_apply_state(pwm, &state); + return pwm_apply_might_sleep(pwm, &state); } EXPORT_SYMBOL_GPL(pwm_adjust_config); diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c index 8a870d0db3c6..c670ccb81653 100644 --- a/drivers/pwm/pwm-twl-led.c +++ b/drivers/pwm/pwm-twl-led.c @@ -172,7 +172,7 @@ static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, * We cannot skip calling ->config even if state->period == * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle * because we might have exited early in the last call to - * pwm_apply_state because of !state->enabled and so the two values in + * pwm_apply_might_sleep because of !state->enabled and so the two values in * pwm->state might not be configured in hardware. */ ret = twl4030_pwmled_config(chip, pwm, diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index bdea60389487..7bfeacee05d0 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c @@ -206,7 +206,7 @@ static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, * We cannot skip calling ->config even if state->period == * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle * because we might have exited early in the last call to - * pwm_apply_state because of !state->enabled and so the two values in + * pwm_apply_might_sleep because of !state->enabled and so the two values in * pwm->state might not be configured in hardware. */ err = vt8500_pwm_config(chip, pwm, state->duty_cycle, state->period); diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index 4edb994fa2e1..1698609d91c8 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -62,7 +62,7 @@ static ssize_t period_store(struct device *child, mutex_lock(&export->lock); pwm_get_state(pwm, &state); state.period = val; - ret = pwm_apply_state(pwm, &state); + ret = pwm_apply_might_sleep(pwm, &state); mutex_unlock(&export->lock); return ret ? : size; @@ -97,7 +97,7 @@ static ssize_t duty_cycle_store(struct device *child, mutex_lock(&export->lock); pwm_get_state(pwm, &state); state.duty_cycle = val; - ret = pwm_apply_state(pwm, &state); + ret = pwm_apply_might_sleep(pwm, &state); mutex_unlock(&export->lock); return ret ? : size; @@ -144,7 +144,7 @@ static ssize_t enable_store(struct device *child, goto unlock; } - ret = pwm_apply_state(pwm, &state); + ret = pwm_apply_might_sleep(pwm, &state); unlock: mutex_unlock(&export->lock); @@ -194,7 +194,7 @@ static ssize_t polarity_store(struct device *child, mutex_lock(&export->lock); pwm_get_state(pwm, &state); state.polarity = polarity; - ret = pwm_apply_state(pwm, &state); + ret = pwm_apply_might_sleep(pwm, &state); mutex_unlock(&export->lock); return ret ? : size; @@ -401,7 +401,7 @@ static int pwm_class_apply_state(struct pwm_export *export, struct pwm_device *pwm, struct pwm_state *state) { - int ret = pwm_apply_state(pwm, state); + int ret = pwm_apply_might_sleep(pwm, state); /* release lock taken in pwm_class_get_state */ mutex_unlock(&export->lock); diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 2aff6db748e2..698c420e0869 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -90,7 +90,7 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev, pwm_set_relative_duty_cycle(&pstate, drvdata->duty_cycle_table[selector].dutycycle, 100); - ret = pwm_apply_state(drvdata->pwm, &pstate); + ret = pwm_apply_might_sleep(drvdata->pwm, &pstate); if (ret) { dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); return ret; @@ -216,7 +216,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, pwm_set_relative_duty_cycle(&pstate, dutycycle, duty_unit); - ret = pwm_apply_state(drvdata->pwm, &pstate); + ret = pwm_apply_might_sleep(drvdata->pwm, &pstate); if (ret) { dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); return ret; diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c index 8fcb62be597b..a3412c936ca2 100644 --- a/drivers/video/backlight/lm3630a_bl.c +++ b/drivers/video/backlight/lm3630a_bl.c @@ -180,7 +180,7 @@ static int lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max) pchip->pwmd_state.enabled = pchip->pwmd_state.duty_cycle ? true : false; - return pwm_apply_state(pchip->pwmd, &pchip->pwmd_state); + return pwm_apply_might_sleep(pchip->pwmd, &pchip->pwmd_state); } /* update and get brightness */ diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index da1f124db69c..7075bfab59c4 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -234,7 +234,7 @@ static int lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) state.duty_cycle = div_u64(br * state.period, max_br); state.enabled = state.duty_cycle; - return pwm_apply_state(lp->pwm, &state); + return pwm_apply_might_sleep(lp->pwm, &state); } static int lp855x_bl_update_status(struct backlight_device *bl) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 289bd9ce4d36..35c716e9043c 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -103,7 +103,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) pwm_get_state(pb->pwm, &state); state.duty_cycle = compute_duty_cycle(pb, brightness, &state); state.enabled = true; - pwm_apply_state(pb->pwm, &state); + pwm_apply_might_sleep(pb->pwm, &state); pwm_backlight_power_on(pb); } else { @@ -120,7 +120,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) * inactive output. */ state.enabled = !pb->power_supply && !pb->enable_gpio; - pwm_apply_state(pb->pwm, &state); + pwm_apply_might_sleep(pb->pwm, &state); } if (pb->notify_after) @@ -528,7 +528,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) if (!state.period && (data->pwm_period_ns > 0)) state.period = data->pwm_period_ns; - ret = pwm_apply_state(pb->pwm, &state); + ret = pwm_apply_might_sleep(pb->pwm, &state); if (ret) { dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", ret); @@ -633,7 +633,7 @@ static void pwm_backlight_remove(struct platform_device *pdev) pwm_get_state(pb->pwm, &state); state.duty_cycle = 0; state.enabled = false; - pwm_apply_state(pb->pwm, &state); + pwm_apply_might_sleep(pb->pwm, &state); if (pb->exit) pb->exit(&pdev->dev); @@ -649,7 +649,7 @@ static void pwm_backlight_shutdown(struct platform_device *pdev) pwm_get_state(pb->pwm, &state); state.duty_cycle = 0; state.enabled = false; - pwm_apply_state(pb->pwm, &state); + pwm_apply_might_sleep(pb->pwm, &state); } #ifdef CONFIG_PM_SLEEP @@ -673,7 +673,7 @@ static int pwm_backlight_suspend(struct device *dev) pwm_get_state(pb->pwm, &state); state.duty_cycle = 0; state.enabled = false; - pwm_apply_state(pb->pwm, &state); + pwm_apply_might_sleep(pb->pwm, &state); if (pb->notify_after) pb->notify_after(pb->dev, 0); diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 5ae48e36fccb..1a4f90ea7d5a 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -347,7 +347,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) pwm_init_state(par->pwm, &pwmstate); pwm_set_relative_duty_cycle(&pwmstate, 50, 100); - pwm_apply_state(par->pwm, &pwmstate); + pwm_apply_might_sleep(par->pwm, &pwmstate); /* Enable the PWM */ pwm_enable(par->pwm); diff --git a/include/linux/pwm.h b/include/linux/pwm.h index f87655c06c82..b64b8a82415c 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -92,8 +92,8 @@ struct pwm_device { * @state: state to fill with the current PWM state * * The returned PWM state represents the state that was applied by a previous call to - * pwm_apply_state(). Drivers may have to slightly tweak that state before programming it to - * hardware. If pwm_apply_state() was never called, this returns either the current hardware + * pwm_apply_might_sleep(). Drivers may have to slightly tweak that state before programming it to + * hardware. If pwm_apply_might_sleep() was never called, this returns either the current hardware * state (if supported) or the default settings. */ static inline void pwm_get_state(const struct pwm_device *pwm, @@ -157,20 +157,20 @@ static inline void pwm_get_args(const struct pwm_device *pwm, } /** - * pwm_init_state() - prepare a new state to be applied with pwm_apply_state() + * pwm_init_state() - prepare a new state to be applied with pwm_apply_might_sleep() * @pwm: PWM device * @state: state to fill with the prepared PWM state * * This functions prepares a state that can later be tweaked and applied - * to the PWM device with pwm_apply_state(). This is a convenient function + * to the PWM device with pwm_apply_might_sleep(). This is a convenient function * that first retrieves the current PWM state and the replaces the period * and polarity fields with the reference values defined in pwm->args. * Once the function returns, you can adjust the ->enabled and ->duty_cycle - * fields according to your needs before calling pwm_apply_state(). + * fields according to your needs before calling pwm_apply_might_sleep(). * * ->duty_cycle is initially set to zero to avoid cases where the current * ->duty_cycle value exceed the pwm_args->period one, which would trigger - * an error if the user calls pwm_apply_state() without adjusting ->duty_cycle + * an error if the user calls pwm_apply_might_sleep() without adjusting ->duty_cycle * first. */ static inline void pwm_init_state(const struct pwm_device *pwm, @@ -226,7 +226,7 @@ pwm_get_relative_duty_cycle(const struct pwm_state *state, unsigned int scale) * * pwm_init_state(pwm, &state); * pwm_set_relative_duty_cycle(&state, 50, 100); - * pwm_apply_state(pwm, &state); + * pwm_apply_might_sleep(pwm, &state); * * This functions returns -EINVAL if @duty_cycle and/or @scale are * inconsistent (@scale == 0 or @duty_cycle > @scale). @@ -304,7 +304,7 @@ struct pwm_chip { #if IS_ENABLED(CONFIG_PWM) /* PWM user APIs */ -int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state); +int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state); int pwm_adjust_config(struct pwm_device *pwm); /** @@ -332,7 +332,7 @@ static inline int pwm_config(struct pwm_device *pwm, int duty_ns, state.duty_cycle = duty_ns; state.period = period_ns; - return pwm_apply_state(pwm, &state); + return pwm_apply_might_sleep(pwm, &state); } /** @@ -353,7 +353,7 @@ static inline int pwm_enable(struct pwm_device *pwm) return 0; state.enabled = true; - return pwm_apply_state(pwm, &state); + return pwm_apply_might_sleep(pwm, &state); } /** @@ -372,7 +372,7 @@ static inline void pwm_disable(struct pwm_device *pwm) return; state.enabled = false; - pwm_apply_state(pwm, &state); + pwm_apply_might_sleep(pwm, &state); } /* PWM provider APIs */ @@ -403,8 +403,8 @@ struct pwm_device *devm_fwnode_pwm_get(struct device *dev, struct fwnode_handle *fwnode, const char *con_id); #else -static inline int pwm_apply_state(struct pwm_device *pwm, - const struct pwm_state *state) +static inline int pwm_apply_might_sleep(struct pwm_device *pwm, + const struct pwm_state *state) { might_sleep(); return -ENOTSUPP; @@ -521,7 +521,7 @@ static inline void pwm_apply_args(struct pwm_device *pwm) state.period = pwm->args.period; state.usage_power = false; - pwm_apply_state(pwm, &state); + pwm_apply_might_sleep(pwm, &state); } struct pwm_lookup { -- cgit From dc518b378dced419baa95d76a85f4c8c405722bc Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 19 Dec 2023 16:30:25 +0000 Subject: pwm: Replace ENOTSUPP with EOPNOTSUPP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to Documentation/dev-tools/checkpatch.rst ENOTSUPP is not recommended and EOPNOTSUPP should be used instead. Signed-off-by: Sean Young Acked-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- include/linux/pwm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/pwm.h b/include/linux/pwm.h index b64b8a82415c..c9cb87b59ac8 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -407,12 +407,12 @@ static inline int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state) { might_sleep(); - return -ENOTSUPP; + return -EOPNOTSUPP; } static inline int pwm_adjust_config(struct pwm_device *pwm) { - return -ENOTSUPP; + return -EOPNOTSUPP; } static inline int pwm_config(struct pwm_device *pwm, int duty_ns, -- cgit From 752193da3f8b0aa819a27fc741d46ab046be315e Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 19 Dec 2023 16:30:26 +0000 Subject: pwm: renesas: Remove unused include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No mutex is used in this driver. Reviewed-by: Uwe Kleine-König Signed-off-by: Sean Young Signed-off-by: Thierry Reding --- drivers/pwm/pwm-renesas-tpu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index ce92db1f8511..28265fdfc92a 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include -- cgit From 7170d3beafc2373dd76b6b5d6e617d89e4e42b8b Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 19 Dec 2023 16:30:27 +0000 Subject: pwm: Make it possible to apply PWM changes in atomic context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some PWM devices require sleeping, for example if the pwm device is connected over I2C. However, many PWM devices could be used from atomic context, e.g. memory mapped PWM. This is useful for, for example, the pwm-ir-tx driver which requires precise timing. Sleeping causes havoc with the generated IR signal. Since not all PWM devices can support atomic context, we also add a pwm_might_sleep() function to check if is not supported. Signed-off-by: Sean Young Reviewed-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- Documentation/driver-api/pwm.rst | 9 ++++++ MAINTAINERS | 2 +- drivers/pwm/core.c | 62 +++++++++++++++++++++++++++++++++------- include/linux/pwm.h | 25 ++++++++++++++++ 4 files changed, 86 insertions(+), 12 deletions(-) diff --git a/Documentation/driver-api/pwm.rst b/Documentation/driver-api/pwm.rst index f1d8197c8c43..3c28ccc4b611 100644 --- a/Documentation/driver-api/pwm.rst +++ b/Documentation/driver-api/pwm.rst @@ -46,6 +46,15 @@ After being requested, a PWM has to be configured using:: This API controls both the PWM period/duty_cycle config and the enable/disable state. +PWM devices can be used from atomic context, if the PWM does not sleep. You +can check if this the case with:: + + bool pwm_might_sleep(struct pwm_device *pwm); + +If false, the PWM can also be configured from atomic context with:: + + int pwm_apply_atomic(struct pwm_device *pwm, struct pwm_state *state); + As a consumer, don't rely on the output's state for a disabled PWM. If it's easily possible, drivers are supposed to emit the inactive state, but some drivers cannot. If you rely on getting the inactive state, use .duty_cycle=0, diff --git a/MAINTAINERS b/MAINTAINERS index c58480595220..5342cf32d73f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17576,7 +17576,7 @@ F: drivers/video/backlight/pwm_bl.c F: include/dt-bindings/pwm/ F: include/linux/pwm.h F: include/linux/pwm_backlight.h -K: pwm_(config|apply_might_sleep|ops) +K: pwm_(config|apply_might_sleep|apply_atomic|ops) PXA GPIO DRIVER M: Robert Jarzmik diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index c6228843a1a7..f1ded8ce5ea4 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -433,24 +433,15 @@ static void pwm_apply_debug(struct pwm_device *pwm, } /** - * pwm_apply_might_sleep() - atomically apply a new state to a PWM device + * __pwm_apply() - atomically apply a new state to a PWM device * @pwm: PWM device * @state: new state to apply */ -int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state) +static int __pwm_apply(struct pwm_device *pwm, const struct pwm_state *state) { struct pwm_chip *chip; int err; - /* - * Some lowlevel driver's implementations of .apply() make use of - * mutexes, also with some drivers only returning when the new - * configuration is active calling pwm_apply_might_sleep() from atomic context - * is a bad idea. So make it explicit that calling this function might - * sleep. - */ - might_sleep(); - if (!pwm || !state || !state->period || state->duty_cycle > state->period) return -EINVAL; @@ -479,8 +470,57 @@ int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state) return 0; } + +/** + * pwm_apply_might_sleep() - atomically apply a new state to a PWM device + * Cannot be used in atomic context. + * @pwm: PWM device + * @state: new state to apply + */ +int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state) +{ + int err; + + /* + * Some lowlevel driver's implementations of .apply() make use of + * mutexes, also with some drivers only returning when the new + * configuration is active calling pwm_apply_might_sleep() from atomic context + * is a bad idea. So make it explicit that calling this function might + * sleep. + */ + might_sleep(); + + if (IS_ENABLED(CONFIG_PWM_DEBUG) && pwm->chip->atomic) { + /* + * Catch any drivers that have been marked as atomic but + * that will sleep anyway. + */ + non_block_start(); + err = __pwm_apply(pwm, state); + non_block_end(); + } else { + err = __pwm_apply(pwm, state); + } + + return err; +} EXPORT_SYMBOL_GPL(pwm_apply_might_sleep); +/** + * pwm_apply_atomic() - apply a new state to a PWM device from atomic context + * Not all PWM devices support this function, check with pwm_might_sleep(). + * @pwm: PWM device + * @state: new state to apply + */ +int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state) +{ + WARN_ONCE(!pwm->chip->atomic, + "sleeping PWM driver used in atomic context\n"); + + return __pwm_apply(pwm, state); +} +EXPORT_SYMBOL_GPL(pwm_apply_atomic); + /** * pwm_capture() - capture and report a PWM signal * @pwm: PWM device diff --git a/include/linux/pwm.h b/include/linux/pwm.h index c9cb87b59ac8..495af3627939 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -285,6 +285,7 @@ struct pwm_ops { * @npwm: number of PWMs controlled by this chip * @of_xlate: request a PWM device given a device tree PWM specifier * @of_pwm_n_cells: number of cells expected in the device tree PWM specifier + * @atomic: can the driver's ->apply() be called in atomic context * @pwms: array of PWM devices allocated by the framework */ struct pwm_chip { @@ -297,6 +298,7 @@ struct pwm_chip { struct pwm_device * (*of_xlate)(struct pwm_chip *chip, const struct of_phandle_args *args); unsigned int of_pwm_n_cells; + bool atomic; /* only used internally by the PWM framework */ struct pwm_device *pwms; @@ -305,6 +307,7 @@ struct pwm_chip { #if IS_ENABLED(CONFIG_PWM) /* PWM user APIs */ int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state); +int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state); int pwm_adjust_config(struct pwm_device *pwm); /** @@ -375,6 +378,17 @@ static inline void pwm_disable(struct pwm_device *pwm) pwm_apply_might_sleep(pwm, &state); } +/** + * pwm_might_sleep() - is pwm_apply_atomic() supported? + * @pwm: PWM device + * + * Returns: false if pwm_apply_atomic() can be called from atomic context. + */ +static inline bool pwm_might_sleep(struct pwm_device *pwm) +{ + return !pwm->chip->atomic; +} + /* PWM provider APIs */ int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, unsigned long timeout); @@ -403,6 +417,11 @@ struct pwm_device *devm_fwnode_pwm_get(struct device *dev, struct fwnode_handle *fwnode, const char *con_id); #else +static inline bool pwm_might_sleep(struct pwm_device *pwm) +{ + return true; +} + static inline int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state) { @@ -410,6 +429,12 @@ static inline int pwm_apply_might_sleep(struct pwm_device *pwm, return -EOPNOTSUPP; } +static inline int pwm_apply_atomic(struct pwm_device *pwm, + const struct pwm_state *state) +{ + return -EOPNOTSUPP; +} + static inline int pwm_adjust_config(struct pwm_device *pwm) { return -EOPNOTSUPP; -- cgit From fcc76072935935082efa127b97c7ddd880d2d793 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Wed, 20 Dec 2023 14:24:25 +0000 Subject: pwm: bcm2835: Allow PWM driver to be used in atomic context clk_get_rate() may do a mutex lock. Fetch the clock rate once, and prevent rate changes using clk_rate_exclusive_get(). Signed-off-by: Sean Young Reviewed-by: Florian Fainelli Signed-off-by: Thierry Reding --- drivers/pwm/pwm-bcm2835.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c index ab30667f4f95..307c0bd5f885 100644 --- a/drivers/pwm/pwm-bcm2835.c +++ b/drivers/pwm/pwm-bcm2835.c @@ -28,6 +28,7 @@ struct bcm2835_pwm { struct device *dev; void __iomem *base; struct clk *clk; + unsigned long rate; }; static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) @@ -63,17 +64,11 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, { struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); - unsigned long rate = clk_get_rate(pc->clk); unsigned long long period_cycles; u64 max_period; u32 val; - if (!rate) { - dev_err(pc->dev, "failed to get clock rate\n"); - return -EINVAL; - } - /* * period_cycles must be a 32 bit value, so period * rate / NSEC_PER_SEC * must be <= U32_MAX. As U32_MAX * NSEC_PER_SEC < U64_MAX the @@ -88,13 +83,13 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, * <=> period < ((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate * <=> period <= ceil((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate) - 1 */ - max_period = DIV_ROUND_UP_ULL((u64)U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC / 2, rate) - 1; + max_period = DIV_ROUND_UP_ULL((u64)U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC / 2, pc->rate) - 1; if (state->period > max_period) return -EINVAL; /* set period */ - period_cycles = DIV_ROUND_CLOSEST_ULL(state->period * rate, NSEC_PER_SEC); + period_cycles = DIV_ROUND_CLOSEST_ULL(state->period * pc->rate, NSEC_PER_SEC); /* don't accept a period that is too small */ if (period_cycles < PERIOD_MIN) @@ -103,7 +98,7 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, writel(period_cycles, pc->base + PERIOD(pwm->hwpwm)); /* set duty cycle */ - val = DIV_ROUND_CLOSEST_ULL(state->duty_cycle * rate, NSEC_PER_SEC); + val = DIV_ROUND_CLOSEST_ULL(state->duty_cycle * pc->rate, NSEC_PER_SEC); writel(val, pc->base + DUTY(pwm->hwpwm)); /* set polarity */ @@ -131,6 +126,13 @@ static const struct pwm_ops bcm2835_pwm_ops = { .apply = bcm2835_pwm_apply, }; +static void devm_clk_rate_exclusive_put(void *data) +{ + struct clk *clk = data; + + clk_rate_exclusive_put(clk); +} + static int bcm2835_pwm_probe(struct platform_device *pdev) { struct bcm2835_pwm *pc; @@ -151,8 +153,26 @@ static int bcm2835_pwm_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk), "clock not found\n"); + ret = clk_rate_exclusive_get(pc->clk); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "fail to get exclusive rate\n"); + + ret = devm_add_action_or_reset(&pdev->dev, devm_clk_rate_exclusive_put, + pc->clk); + if (ret) { + clk_rate_exclusive_put(pc->clk); + return ret; + } + + pc->rate = clk_get_rate(pc->clk); + if (!pc->rate) + return dev_err_probe(&pdev->dev, -EINVAL, + "failed to get clock rate\n"); + pc->chip.dev = &pdev->dev; pc->chip.ops = &bcm2835_pwm_ops; + pc->chip.atomic = true; pc->chip.npwm = 2; platform_set_drvdata(pdev, pc); -- cgit From 363d0e56285e80cda997d41d94c22313b673557d Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 19 Dec 2023 16:30:29 +0000 Subject: media: pwm-ir-tx: Trigger edges from hrtimer interrupt context This makes the generated IR much more precise. Before this change, the driver is unreliable and many users opted to use gpio-ir-tx instead. Signed-off-by: Sean Young Signed-off-by: Thierry Reding --- drivers/media/rc/pwm-ir-tx.c | 83 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/pwm-ir-tx.c b/drivers/media/rc/pwm-ir-tx.c index cf51e2760975..fe368aebbc13 100644 --- a/drivers/media/rc/pwm-ir-tx.c +++ b/drivers/media/rc/pwm-ir-tx.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #define DRIVER_NAME "pwm-ir-tx" @@ -17,8 +19,14 @@ struct pwm_ir { struct pwm_device *pwm; - unsigned int carrier; - unsigned int duty_cycle; + struct hrtimer timer; + struct completion tx_done; + struct pwm_state *state; + u32 carrier; + u32 duty_cycle; + const unsigned int *txbuf; + unsigned int txbuf_len; + unsigned int txbuf_index; }; static const struct of_device_id pwm_ir_of_match[] = { @@ -49,8 +57,8 @@ static int pwm_ir_set_carrier(struct rc_dev *dev, u32 carrier) return 0; } -static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf, - unsigned int count) +static int pwm_ir_tx_sleep(struct rc_dev *dev, unsigned int *txbuf, + unsigned int count) { struct pwm_ir *pwm_ir = dev->priv; struct pwm_device *pwm = pwm_ir->pwm; @@ -82,6 +90,62 @@ static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf, return count; } +static int pwm_ir_tx_atomic(struct rc_dev *dev, unsigned int *txbuf, + unsigned int count) +{ + struct pwm_ir *pwm_ir = dev->priv; + struct pwm_device *pwm = pwm_ir->pwm; + struct pwm_state state; + + pwm_init_state(pwm, &state); + + state.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, pwm_ir->carrier); + pwm_set_relative_duty_cycle(&state, pwm_ir->duty_cycle, 100); + + pwm_ir->txbuf = txbuf; + pwm_ir->txbuf_len = count; + pwm_ir->txbuf_index = 0; + pwm_ir->state = &state; + + hrtimer_start(&pwm_ir->timer, 0, HRTIMER_MODE_REL); + + wait_for_completion(&pwm_ir->tx_done); + + return count; +} + +static enum hrtimer_restart pwm_ir_timer(struct hrtimer *timer) +{ + struct pwm_ir *pwm_ir = container_of(timer, struct pwm_ir, timer); + ktime_t now; + + /* + * If we happen to hit an odd latency spike, loop through the + * pulses until we catch up. + */ + do { + u64 ns; + + pwm_ir->state->enabled = !(pwm_ir->txbuf_index % 2); + pwm_apply_atomic(pwm_ir->pwm, pwm_ir->state); + + if (pwm_ir->txbuf_index >= pwm_ir->txbuf_len) { + complete(&pwm_ir->tx_done); + + return HRTIMER_NORESTART; + } + + ns = US_TO_NS(pwm_ir->txbuf[pwm_ir->txbuf_index]); + hrtimer_add_expires_ns(timer, ns); + + pwm_ir->txbuf_index++; + + now = timer->base->get_time(); + } while (hrtimer_get_expires_tv64(timer) < now); + + return HRTIMER_RESTART; +} + static int pwm_ir_probe(struct platform_device *pdev) { struct pwm_ir *pwm_ir; @@ -103,10 +167,19 @@ static int pwm_ir_probe(struct platform_device *pdev) if (!rcdev) return -ENOMEM; + if (pwm_might_sleep(pwm_ir->pwm)) { + dev_info(&pdev->dev, "TX will not be accurate as PWM device might sleep\n"); + rcdev->tx_ir = pwm_ir_tx_sleep; + } else { + init_completion(&pwm_ir->tx_done); + hrtimer_init(&pwm_ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pwm_ir->timer.function = pwm_ir_timer; + rcdev->tx_ir = pwm_ir_tx_atomic; + } + rcdev->priv = pwm_ir; rcdev->driver_name = DRIVER_NAME; rcdev->device_name = DEVICE_NAME; - rcdev->tx_ir = pwm_ir_tx; rcdev->s_tx_duty_cycle = pwm_ir_set_duty_cycle; rcdev->s_tx_carrier = pwm_ir_set_carrier; -- cgit From 46cfec2a865ae967ea4366287a7d9a16ad5b8b6f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 14 Nov 2023 10:27:06 +0200 Subject: dt-bindings: pwm: ti,pwm-omap-dmtimer: Update binding for yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update for yaml and remove the old txt binding. As we can replace most of the custom timer API with standard Linux frameworks such as clock framework, let's tag the properties for ti,prescaler and ti,clock-source as deprecated. Cc: Cc: Nishanth Menon Cc: Thierry Reding Cc: Uwe Kleine-König Cc: Vignesh Raghavendra Reviewed-by: Krzysztof Kozlowski Signed-off-by: Tony Lindgren Reviewed-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- .../devicetree/bindings/pwm/pwm-omap-dmtimer.txt | 22 -------- .../bindings/pwm/ti,omap-dmtimer-pwm.yaml | 59 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 22 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt create mode 100644 Documentation/devicetree/bindings/pwm/ti,omap-dmtimer-pwm.yaml diff --git a/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt b/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt deleted file mode 100644 index 25ecfe14c698..000000000000 --- a/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt +++ /dev/null @@ -1,22 +0,0 @@ -* OMAP PWM for dual-mode timers - -Required properties: -- compatible: Shall contain "ti,omap-dmtimer-pwm". -- ti,timers: phandle to PWM capable OMAP timer. See timer/ti,timer-dm.yaml for info - about these timers. -- #pwm-cells: Should be 3. See pwm.yaml in this directory for a description of - the cells format. - -Optional properties: -- ti,prescaler: Should be a value between 0 and 7, see the timers datasheet -- ti,clock-source: Set dmtimer parent clock, values between 0 and 2: - - 0x00 - high-frequency system clock (timer_sys_ck) - - 0x01 - 32-kHz always-on clock (timer_32k_ck) - - 0x02 - external clock (timer_ext_ck, OMAP2 only) - -Example: - pwm9: dmtimer-pwm@9 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer9>; - #pwm-cells = <3>; - }; diff --git a/Documentation/devicetree/bindings/pwm/ti,omap-dmtimer-pwm.yaml b/Documentation/devicetree/bindings/pwm/ti,omap-dmtimer-pwm.yaml new file mode 100644 index 000000000000..1e8e094aad74 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/ti,omap-dmtimer-pwm.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/ti,omap-dmtimer-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI dual mode timer PWM controller + +maintainers: + - Tony Lindgren + +description: + TI dual mode timer instances have an IO pin for PWM capability + +allOf: + - $ref: pwm.yaml# + +properties: + compatible: + const: ti,omap-dmtimer-pwm + + "#pwm-cells": + const: 3 + + ti,timers: + description: Timer instance phandle for the PWM + $ref: /schemas/types.yaml#/definitions/phandle + + ti,prescaler: + description: | + Legacy clock prescaler for timer. The timer counter is prescaled + with 2^n where n is the prescaler. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + deprecated: true + + ti,clock-source: + description: | + Legacy clock for timer, please use assigned-clocks instead. + 0x00 - high-frequency system clock (timer_sys_ck) + 0x01 - 32-kHz always-on clock (timer_32k_ck) + 0x02 - external clock (timer_ext_ck, OMAP2 only) + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2 ] + deprecated: true + +required: + - compatible + - ti,timers + +unevaluatedProperties: false + +examples: + - | + pwm9: pwm { + compatible = "ti,omap-dmtimer-pwm"; + ti,timers = <&timer9>; + #pwm-cells = <3>; + }; -- cgit From 01b571fbbac40bfc266c03e84ab9a8ab2ddd2486 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 5 Dec 2023 10:56:17 +0100 Subject: pwm: omap-dmtimer: Drop locking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pwm driver only provides a single PWM line, so there are no concurrent calls of the callbacks from different consumers. A single consumer is expected not to do concurrent calls into the pwm framework. So there is nothing to serialize and the lock can go away. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-omap-dmtimer.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c index 13161e08dd6e..496bd73d29fe 100644 --- a/drivers/pwm/pwm-omap-dmtimer.c +++ b/drivers/pwm/pwm-omap-dmtimer.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -55,7 +54,6 @@ * struct pwm_omap_dmtimer_chip - Structure representing a pwm chip * corresponding to omap dmtimer. * @chip: PWM chip structure representing PWM controller - * @mutex: Mutex to protect pwm apply state * @dm_timer: Pointer to omap dm timer. * @pdata: Pointer to omap dm timer ops. * @dm_timer_pdev: Pointer to omap dm timer platform device @@ -63,7 +61,6 @@ struct pwm_omap_dmtimer_chip { struct pwm_chip chip; /* Mutex to protect pwm apply state */ - struct mutex mutex; struct omap_dm_timer *dm_timer; const struct omap_dm_timer_ops *pdata; struct platform_device *dm_timer_pdev; @@ -277,13 +274,11 @@ static int pwm_omap_dmtimer_apply(struct pwm_chip *chip, const struct pwm_state *state) { struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); - int ret = 0; - - mutex_lock(&omap->mutex); + int ret; if (pwm_omap_dmtimer_is_enabled(omap) && !state->enabled) { omap->pdata->stop(omap->dm_timer); - goto unlock_mutex; + return 0; } if (pwm_omap_dmtimer_polarity(omap) != state->polarity) @@ -292,7 +287,7 @@ static int pwm_omap_dmtimer_apply(struct pwm_chip *chip, ret = pwm_omap_dmtimer_config(chip, pwm, state->duty_cycle, state->period); if (ret) - goto unlock_mutex; + return ret; if (!pwm_omap_dmtimer_is_enabled(omap) && state->enabled) { omap->pdata->set_pwm(omap->dm_timer, @@ -303,10 +298,7 @@ static int pwm_omap_dmtimer_apply(struct pwm_chip *chip, pwm_omap_dmtimer_start(omap); } -unlock_mutex: - mutex_unlock(&omap->mutex); - - return ret; + return 0; } static const struct pwm_ops pwm_omap_dmtimer_ops = { @@ -404,8 +396,6 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) omap->chip.ops = &pwm_omap_dmtimer_ops; omap->chip.npwm = 1; - mutex_init(&omap->mutex); - ret = pwmchip_add(&omap->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM\n"); @@ -452,8 +442,6 @@ static void pwm_omap_dmtimer_remove(struct platform_device *pdev) omap->pdata->free(omap->dm_timer); put_device(&omap->dm_timer_pdev->dev); - - mutex_destroy(&omap->mutex); } static const struct of_device_id pwm_omap_dmtimer_of_match[] = { -- cgit From d243221dc9e202d85ca196136d8eaa029091b42c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 30 Nov 2023 08:41:34 +0100 Subject: pwm: crc: Use consistent variable naming for driver data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All but one local variable of type pointer to struct crystalcove_pwm are called "crc_pwm", the one outlier is called "pwm" which is usually reserved for variables of type pointer to struct pwm_device. So rename that one "pwm" to "crc_pwm" for consistency. Signed-off-by: Uwe Kleine-König Reviewed-by: Hans de Goede Signed-off-by: Thierry Reding --- drivers/pwm/pwm-crc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/pwm/pwm-crc.c b/drivers/pwm/pwm-crc.c index 2b0b659eee97..e09358901ab5 100644 --- a/drivers/pwm/pwm-crc.c +++ b/drivers/pwm/pwm-crc.c @@ -160,22 +160,22 @@ static const struct pwm_ops crc_pwm_ops = { static int crystalcove_pwm_probe(struct platform_device *pdev) { - struct crystalcove_pwm *pwm; + struct crystalcove_pwm *crc_pwm; struct device *dev = pdev->dev.parent; struct intel_soc_pmic *pmic = dev_get_drvdata(dev); - pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); - if (!pwm) + crc_pwm = devm_kzalloc(&pdev->dev, sizeof(*crc_pwm), GFP_KERNEL); + if (!crc_pwm) return -ENOMEM; - pwm->chip.dev = &pdev->dev; - pwm->chip.ops = &crc_pwm_ops; - pwm->chip.npwm = 1; + crc_pwm->chip.dev = &pdev->dev; + crc_pwm->chip.ops = &crc_pwm_ops; + crc_pwm->chip.npwm = 1; /* get the PMIC regmap */ - pwm->regmap = pmic->regmap; + crc_pwm->regmap = pmic->regmap; - return devm_pwmchip_add(&pdev->dev, &pwm->chip); + return devm_pwmchip_add(&pdev->dev, &crc_pwm->chip); } static struct platform_driver crystalcove_pwm_driver = { -- cgit From efb704abedc7168cee8068da08eb2ca8c1eb1893 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 30 Nov 2023 08:21:06 +0100 Subject: pwm: Reduce number of pointer dereferences in pwm_device_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pwm->chip and pwm->chip->ops are used several times in this function. Introduce local variables for these. There is no semantical change, but with ARCH=arm, allmodconfig and gcc-13 bloat-o-meter reports a slight improvement: add/remove: 1/1 grow/shrink: 1/1 up/down: 8/-36 (-28) Function old new delta pwm_apply_state 476 480 +4 __initcall__kmod_core__307_1092_pwm_debugfs_init4 - 4 +4 __initcall__kmod_core__307_1090_pwm_debugfs_init4 4 - -4 pwm_request_from_chip 628 596 -32 Total: Before=15091, After=15063, chg -0.19% Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/core.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index f1ded8ce5ea4..9a4c720c88aa 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -59,22 +59,24 @@ static struct pwm_chip *pwmchip_find_by_name(const char *name) static int pwm_device_request(struct pwm_device *pwm, const char *label) { int err; + struct pwm_chip *chip = pwm->chip; + const struct pwm_ops *ops = chip->ops; if (test_bit(PWMF_REQUESTED, &pwm->flags)) return -EBUSY; - if (!try_module_get(pwm->chip->owner)) + if (!try_module_get(chip->owner)) return -ENODEV; - if (pwm->chip->ops->request) { - err = pwm->chip->ops->request(pwm->chip, pwm); + if (ops->request) { + err = ops->request(chip, pwm); if (err) { - module_put(pwm->chip->owner); + module_put(chip->owner); return err; } } - if (pwm->chip->ops->get_state) { + if (ops->get_state) { /* * Zero-initialize state because most drivers are unaware of * .usage_power. The other members of state are supposed to be @@ -84,7 +86,7 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label) */ struct pwm_state state = { 0, }; - err = pwm->chip->ops->get_state(pwm->chip, pwm, &state); + err = ops->get_state(chip, pwm, &state); trace_pwm_get(pwm, &state, err); if (!err) -- cgit From d9eb24c6f499bf8f6625c5fea05d7511a2fecf52 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 6 Dec 2023 18:30:43 +0100 Subject: pwm: stmpe: Silence duplicate error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stmpe_reg_read() and stmpe_reg_write() already emit error messages when they fail. So the extra error messages in the pwm driver are only little useful. They are useful in some situation, as they give a bit of context to the failing register write. So don't remove them but degrade them to dev_dbg(). Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-stmpe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pwm/pwm-stmpe.c b/drivers/pwm/pwm-stmpe.c index d730631c6583..19c0c0f39675 100644 --- a/drivers/pwm/pwm-stmpe.c +++ b/drivers/pwm/pwm-stmpe.c @@ -44,7 +44,7 @@ static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS); if (ret < 0) { - dev_err(chip->dev, "error reading PWM#%u control\n", + dev_dbg(chip->dev, "error reading PWM#%u control\n", pwm->hwpwm); return ret; } @@ -53,7 +53,7 @@ static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value); if (ret) { - dev_err(chip->dev, "error writing PWM#%u control\n", + dev_dbg(chip->dev, "error writing PWM#%u control\n", pwm->hwpwm); return ret; } @@ -70,7 +70,7 @@ static int stmpe_24xx_pwm_disable(struct pwm_chip *chip, ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS); if (ret < 0) { - dev_err(chip->dev, "error reading PWM#%u control\n", + dev_dbg(chip->dev, "error reading PWM#%u control\n", pwm->hwpwm); return ret; } @@ -79,7 +79,7 @@ static int stmpe_24xx_pwm_disable(struct pwm_chip *chip, ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value); if (ret) - dev_err(chip->dev, "error writing PWM#%u control\n", + dev_dbg(chip->dev, "error writing PWM#%u control\n", pwm->hwpwm); return ret; } @@ -233,7 +233,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value); if (ret) { - dev_err(chip->dev, "error writing register %02x: %d\n", + dev_dbg(chip->dev, "error writing register %02x: %d\n", offset, ret); return ret; } @@ -242,7 +242,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value); if (ret) { - dev_err(chip->dev, "error writing register %02x: %d\n", + dev_dbg(chip->dev, "error writing register %02x: %d\n", offset, ret); return ret; } -- cgit From b41ccc3bc9da96678c1db31b9ed021b8388657f6 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 6 Dec 2023 22:48:18 +0100 Subject: pwm: meson: Simplify using dev_err_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using dev_err_probe() emitting an error message mentioning a return value and returning that value can be done in a single statement. Make use of that to simplify the probe part of the driver. This has the additional advantage to emit the symbolic name for the error instead of the integer error value. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-meson.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index 5bea53243ed2..2971bbf3b5e7 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -468,10 +468,9 @@ static int meson_pwm_init_channels(struct meson_pwm *meson) channel->mux.hw.init = &init; err = devm_clk_hw_register(dev, &channel->mux.hw); - if (err) { - dev_err(dev, "failed to register %s: %d\n", name, err); - return err; - } + if (err) + return dev_err_probe(dev, err, + "failed to register %s\n", name); snprintf(name, sizeof(name), "%s#div%u", dev_name(dev), i); @@ -491,10 +490,9 @@ static int meson_pwm_init_channels(struct meson_pwm *meson) channel->div.lock = &meson->lock; err = devm_clk_hw_register(dev, &channel->div.hw); - if (err) { - dev_err(dev, "failed to register %s: %d\n", name, err); - return err; - } + if (err) + return dev_err_probe(dev, err, + "failed to register %s\n", name); snprintf(name, sizeof(name), "%s#gate%u", dev_name(dev), i); @@ -513,17 +511,13 @@ static int meson_pwm_init_channels(struct meson_pwm *meson) channel->gate.lock = &meson->lock; err = devm_clk_hw_register(dev, &channel->gate.hw); - if (err) { - dev_err(dev, "failed to register %s: %d\n", name, err); - return err; - } + if (err) + return dev_err_probe(dev, err, "failed to register %s\n", name); channel->clk = devm_clk_hw_get_clk(dev, &channel->gate.hw, NULL); - if (IS_ERR(channel->clk)) { - err = PTR_ERR(channel->clk); - dev_err(dev, "failed to register %s: %d\n", name, err); - return err; - } + if (IS_ERR(channel->clk)) + return dev_err_probe(dev, PTR_ERR(channel->clk), + "failed to register %s\n", name); } return 0; @@ -554,10 +548,9 @@ static int meson_pwm_probe(struct platform_device *pdev) return err; err = devm_pwmchip_add(&pdev->dev, &meson->chip); - if (err < 0) { - dev_err(&pdev->dev, "failed to register PWM chip: %d\n", err); - return err; - } + if (err < 0) + return dev_err_probe(&pdev->dev, err, + "failed to register PWM chip\n"); return 0; } -- cgit From 4430d02dc1dfb811b0b39bb58662f006f1e4749d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 10 Dec 2023 00:00:46 +0100 Subject: pwm: lpc18xx-sct: Don't modify the cached period of other PWM outputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even though the hardware only supports a single period for all PWM outputs, modifying the other (disabled) outputs's period is strange and wrong. Only the pwm core is supposed to update these values. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-lpc18xx-sct.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c index b3d4a955aa31..fe891fa71a1d 100644 --- a/drivers/pwm/pwm-lpc18xx-sct.c +++ b/drivers/pwm/pwm-lpc18xx-sct.c @@ -194,7 +194,7 @@ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip); - int requested_events, i; + int requested_events; if (period_ns < lpc18xx_pwm->min_period_ns || period_ns > lpc18xx_pwm->max_period_ns) { @@ -223,8 +223,6 @@ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if ((requested_events <= 2 && lpc18xx_pwm->period_ns != period_ns) || !lpc18xx_pwm->period_ns) { lpc18xx_pwm->period_ns = period_ns; - for (i = 0; i < chip->npwm; i++) - pwm_set_period(&chip->pwms[i], period_ns); lpc18xx_pwm_config_period(chip, period_ns); } -- cgit From 80e4a9987999e682366d60f43a7b2adefc48e222 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 10 Dec 2023 00:00:47 +0100 Subject: pwm: Drop two unused API functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These functions are unused. Also I think there is no valid use case where these are correct to be called. So drop them. Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- include/linux/pwm.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 495af3627939..5dd665d8c909 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -111,12 +111,6 @@ static inline bool pwm_is_enabled(const struct pwm_device *pwm) return state.enabled; } -static inline void pwm_set_period(struct pwm_device *pwm, u64 period) -{ - if (pwm) - pwm->state.period = period; -} - static inline u64 pwm_get_period(const struct pwm_device *pwm) { struct pwm_state state; @@ -126,12 +120,6 @@ static inline u64 pwm_get_period(const struct pwm_device *pwm) return state.period; } -static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) -{ - if (pwm) - pwm->state.duty_cycle = duty; -} - static inline u64 pwm_get_duty_cycle(const struct pwm_device *pwm) { struct pwm_state state; -- cgit From 881791886bfa8e353c3203f95bfbaaeee25d2d50 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 19 Dec 2023 07:33:17 +0100 Subject: pwm: cros-ec: Drop documentation for dropped struct member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recently an unused member was removed from struct cros_ec_pwm_device, but the kernel doc wasn't adapted accordingly. Catch up and drop the documentation, too. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202312190757.O4M9dsln-lkp@intel.com/ Fixes: 6c4406ce609f ("pwm: cros-ec: Drop unused member from driver private data") Signed-off-by: Uwe Kleine-König Reviewed-by: Tzung-Bi Shih Signed-off-by: Thierry Reding --- drivers/pwm/pwm-cros-ec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c index 9a8f1b6a4e13..5fe303b8656d 100644 --- a/drivers/pwm/pwm-cros-ec.c +++ b/drivers/pwm/pwm-cros-ec.c @@ -18,7 +18,6 @@ /** * struct cros_ec_pwm_device - Driver data for EC PWM * - * @dev: Device node * @ec: Pointer to EC device * @chip: PWM controller chip * @use_pwm_type: Use PWM types instead of generic channels -- cgit From c2e64baac4f36f7e0365218c7523bb9ba4639250 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 21 Dec 2023 11:08:02 +0100 Subject: pwm: Add pwm_apply_state() compatibility stub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to make the transition to the new pwm_apply_might_sleep() a bit smoother, add a compatibility stub. This will prevent new calls to the old function introduced via other subsystems from breaking builds. Once the next merge window has closed we can take another stab at removing the stub. Reviewed-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- include/linux/pwm.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 5dd665d8c909..2a5e1154652e 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -537,6 +537,13 @@ static inline void pwm_apply_args(struct pwm_device *pwm) pwm_apply_might_sleep(pwm, &state); } +/* only for backwards-compatibility, new code should not use this */ +static inline int pwm_apply_state(struct pwm_device *pwm, + const struct pwm_state *state) +{ + return pwm_apply_might_sleep(pwm, state); +} + struct pwm_lookup { struct list_head list; const char *provider; -- cgit From d73f444d06fb8a42a5c0623453f3ea1fe9880229 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 22 Dec 2023 21:06:20 -0800 Subject: pwm: linux/pwm.h: fix Excess kernel-doc description warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the @pwm: line to prevent the kernel-doc warning: include/linux/pwm.h:87: warning: Excess struct member 'pwm' description in 'pwm_device' Signed-off-by: Randy Dunlap Cc: Thierry Reding Cc: Uwe Kleine-König Cc: Fixes: f3e25e68ceb2 ("pwm: Drop unused member "pwm" from struct pwm_device") Reviewed-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- include/linux/pwm.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 2a5e1154652e..fcc2c4496f73 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -69,7 +69,6 @@ struct pwm_state { * @label: name of the PWM device * @flags: flags associated with the PWM device * @hwpwm: per-chip relative index of the PWM device - * @pwm: global index of the PWM device * @chip: PWM chip providing this PWM device * @args: PWM arguments * @state: last applied state -- cgit From 7afc0e7f681e6efd6b826f003fc14c17b5093643 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 22 Dec 2023 06:56:39 +0100 Subject: MAINTAINERS: pwm: Thierry steps down, Uwe takes over MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not easy to let go responsibility for a subsystem that one cared for for a long time, but Thierry realized that his heart isn't in the pwm framework any more. Thierry cared for the pwm subsystem (commit 200efedd8766 ("pwm: Take over maintainership of the PWM subsystem")) as a maintainer during nearly 12 years. A big thanks for the time, effort and dedication spend during that time. Uwe takes over maintenance. Reviewed-by: Neil Armstrong Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- MAINTAINERS | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5342cf32d73f..c6c7b50e6ef6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17561,12 +17561,11 @@ F: Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.yaml F: drivers/media/rc/pwm-ir-tx.c PWM SUBSYSTEM -M: Thierry Reding -R: Uwe Kleine-König +M: Uwe Kleine-König L: linux-pwm@vger.kernel.org S: Maintained Q: https://patchwork.ozlabs.org/project/linux-pwm/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git +T: git https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git F: Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml F: Documentation/devicetree/bindings/pwm/ F: Documentation/driver-api/pwm.rst -- cgit