From 7cfce2b80d5ff7aa713a7710bfe3a562707cb226 Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Thu, 8 Feb 2024 12:35:29 +0530 Subject: pwm: dwc: use pm_sleep_ptr() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we don't have runtime PM handles here, we should be using pm_sleep_ptr() macro, so that the compiler can discard it in case CONFIG_PM_SLEEP=n. Fixes: 30b5b066fa83 ("pwm: dwc: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions") Signed-off-by: Raag Jadav Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240212130247.9985-2-raag.jadav@intel.com Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-dwc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pwm/pwm-dwc.c') diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index 4929354f8cd9..a4a057ae03ea 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -120,7 +120,7 @@ static struct pci_driver dwc_pwm_driver = { .remove = dwc_pwm_remove, .id_table = dwc_pwm_id_table, .driver = { - .pm = pm_ptr(&dwc_pwm_pm_ops), + .pm = pm_sleep_ptr(&dwc_pwm_pm_ops), }, }; -- cgit v1.2.3 From 3ee35fd12b018e15ed540c921ce0bbb6254f4c2a Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Thu, 8 Feb 2024 12:35:28 +0530 Subject: pwm: dwc: access driver_data using dev_get_drvdata() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we're setting driver_data using dev_set_drvdata(), we can use dev_get_drvdata() for accessing it. Signed-off-by: Raag Jadav Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240212130247.9985-6-raag.jadav@intel.com Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-dwc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/pwm/pwm-dwc.c') diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index a4a057ae03ea..9a1b156ead26 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -73,8 +73,7 @@ static void dwc_pwm_remove(struct pci_dev *pci) static int dwc_pwm_suspend(struct device *dev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); - struct dwc_pwm *dwc = pci_get_drvdata(pdev); + struct dwc_pwm *dwc = dev_get_drvdata(dev); int i; for (i = 0; i < DWC_TIMERS_TOTAL; i++) { @@ -93,8 +92,7 @@ static int dwc_pwm_suspend(struct device *dev) static int dwc_pwm_resume(struct device *dev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); - struct dwc_pwm *dwc = pci_get_drvdata(pdev); + struct dwc_pwm *dwc = dev_get_drvdata(dev); int i; for (i = 0; i < DWC_TIMERS_TOTAL; i++) { -- cgit v1.2.3 From aaa3cc29a78e0db72762999d7ad1224d1cf3d45c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 14 Feb 2024 10:31:19 +0100 Subject: pwm: dwc: Prepare removing pwm_chip from driver data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prepares the driver for further changes that will drop struct pwm_chip chip from struct dwc_pwm. Use the pwm_chip as driver data and return value of dwc_pwm_alloc() instead of the dwc_pwm to get access to the pwm_chip in dwc_pwm_probe() and dwc_pwm_suspend() without using dwc->chip. Thanks to Raag Jadav for providing a hunk of this patch that Uwe missed during creation of this patch. Link: https://lore.kernel.org/r/008ce5ab84b8e3baa3e81ab6d36dbb0e4be5c319.1707900770.git.u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20240219033835.11369-2-raag.jadav@intel.com Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-dwc-core.c | 16 +++++++++------- drivers/pwm/pwm-dwc.c | 20 ++++++++++++-------- drivers/pwm/pwm-dwc.h | 2 +- 3 files changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers/pwm/pwm-dwc.c') diff --git a/drivers/pwm/pwm-dwc-core.c b/drivers/pwm/pwm-dwc-core.c index ea63dd741f5c..ac7a0b2cb8b9 100644 --- a/drivers/pwm/pwm-dwc-core.c +++ b/drivers/pwm/pwm-dwc-core.c @@ -159,21 +159,23 @@ static const struct pwm_ops dwc_pwm_ops = { .get_state = dwc_pwm_get_state, }; -struct dwc_pwm *dwc_pwm_alloc(struct device *dev) +struct pwm_chip *dwc_pwm_alloc(struct device *dev) { + struct pwm_chip *chip; struct dwc_pwm *dwc; dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); if (!dwc) - return NULL; + return ERR_PTR(-ENOMEM); + chip = &dwc->chip; dwc->clk_ns = 10; - dwc->chip.dev = dev; - dwc->chip.ops = &dwc_pwm_ops; - dwc->chip.npwm = DWC_TIMERS_TOTAL; + chip->dev = dev; + chip->ops = &dwc_pwm_ops; + chip->npwm = DWC_TIMERS_TOTAL; - dev_set_drvdata(dev, dwc); - return dwc; + dev_set_drvdata(dev, chip); + return chip; } EXPORT_SYMBOL_GPL(dwc_pwm_alloc); diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index 9a1b156ead26..c0e586688e57 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -28,12 +28,14 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) { struct device *dev = &pci->dev; + struct pwm_chip *chip; struct dwc_pwm *dwc; int ret; - dwc = dwc_pwm_alloc(dev); - if (!dwc) - return -ENOMEM; + chip = dwc_pwm_alloc(dev); + if (IS_ERR(chip)) + return PTR_ERR(chip); + dwc = to_dwc_pwm(chip); ret = pcim_enable_device(pci); if (ret) { @@ -55,7 +57,7 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) return -ENOMEM; } - ret = devm_pwmchip_add(dev, &dwc->chip); + ret = devm_pwmchip_add(dev, chip); if (ret) return ret; @@ -73,13 +75,14 @@ static void dwc_pwm_remove(struct pci_dev *pci) static int dwc_pwm_suspend(struct device *dev) { - struct dwc_pwm *dwc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct dwc_pwm *dwc = to_dwc_pwm(chip); int i; for (i = 0; i < DWC_TIMERS_TOTAL; i++) { - if (dwc->chip.pwms[i].state.enabled) { + if (chip->pwms[i].state.enabled) { dev_err(dev, "PWM %u in use by consumer (%s)\n", - i, dwc->chip.pwms[i].label); + i, chip->pwms[i].label); return -EBUSY; } dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i)); @@ -92,7 +95,8 @@ static int dwc_pwm_suspend(struct device *dev) static int dwc_pwm_resume(struct device *dev) { - struct dwc_pwm *dwc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct dwc_pwm *dwc = to_dwc_pwm(chip); int i; for (i = 0; i < DWC_TIMERS_TOTAL; i++) { diff --git a/drivers/pwm/pwm-dwc.h b/drivers/pwm/pwm-dwc.h index 64795247c54c..432a3b4c81fd 100644 --- a/drivers/pwm/pwm-dwc.h +++ b/drivers/pwm/pwm-dwc.h @@ -57,4 +57,4 @@ static inline void dwc_pwm_writel(struct dwc_pwm *dwc, u32 value, u32 offset) writel(value, dwc->base + offset); } -extern struct dwc_pwm *dwc_pwm_alloc(struct device *dev); +extern struct pwm_chip *dwc_pwm_alloc(struct device *dev); -- cgit v1.2.3 From 144a0008b30bc133cbaa9da7cf56d7cf2bacc4f9 Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Mon, 19 Feb 2024 09:08:33 +0530 Subject: pwm: dwc: drop redundant error check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pcim_iomap_table() fails only if pcim_iomap_regions() fails. No need to check for failure if the latter is already successful. Suggested-by: Andy Shevchenko Signed-off-by: Raag Jadav Tested-by: Jarkko Nikula Link: https://lore.kernel.org/r/20240219033835.11369-3-raag.jadav@intel.com Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-dwc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/pwm/pwm-dwc.c') diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index c0e586688e57..7dbb72c80ef5 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -51,11 +51,8 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) return ret; } + /* No need to check for failure, pcim_iomap_regions() does it for us. */ dwc->base = pcim_iomap_table(pci)[0]; - if (!dwc->base) { - dev_err(dev, "Base address missing\n"); - return -ENOMEM; - } ret = devm_pwmchip_add(dev, chip); if (ret) -- cgit v1.2.3 From ebf2c89eb95ec9598da19184632b765de72a7db4 Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Mon, 19 Feb 2024 09:08:34 +0530 Subject: pwm: dwc: Add 16 channel support for Intel Elkhart Lake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Intel Elkhart Lake PSE includes two instances of PWM as a single PCI function with 8 channels each. Add support for the remaining channels. Signed-off-by: Raag Jadav Tested-by: Jarkko Nikula Tested-by: Lakshmi Sowjanya D Link: https://lore.kernel.org/r/20240219033835.11369-4-raag.jadav@intel.com Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-dwc.c | 38 +++++++++++++++++++++++++++++--------- drivers/pwm/pwm-dwc.h | 5 +++++ 2 files changed, 34 insertions(+), 9 deletions(-) (limited to 'drivers/pwm/pwm-dwc.c') diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index 7dbb72c80ef5..de95352081fa 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -25,17 +25,32 @@ #include "pwm-dwc.h" -static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) +/* Elkhart Lake */ +static const struct dwc_pwm_info ehl_pwm_info = { + .nr = 2, + .size = 0x1000, +}; + +static int dwc_pwm_init_one(struct device *dev, void __iomem *base, unsigned int offset) { - struct device *dev = &pci->dev; struct pwm_chip *chip; struct dwc_pwm *dwc; - int ret; chip = dwc_pwm_alloc(dev); if (IS_ERR(chip)) return PTR_ERR(chip); + dwc = to_dwc_pwm(chip); + dwc->base = base + offset; + + return devm_pwmchip_add(dev, chip); +} + +static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) +{ + const struct dwc_pwm_info *info; + struct device *dev = &pci->dev; + int i, ret; ret = pcim_enable_device(pci); if (ret) { @@ -51,12 +66,17 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) return ret; } - /* No need to check for failure, pcim_iomap_regions() does it for us. */ - dwc->base = pcim_iomap_table(pci)[0]; + info = (const struct dwc_pwm_info *)id->driver_data; - ret = devm_pwmchip_add(dev, chip); - if (ret) - return ret; + for (i = 0; i < info->nr; i++) { + /* + * No need to check for pcim_iomap_table() failure, + * pcim_iomap_regions() already does it for us. + */ + ret = dwc_pwm_init_one(dev, pcim_iomap_table(pci)[0], i * info->size); + if (ret) + return ret; + } pm_runtime_put(dev); pm_runtime_allow(dev); @@ -108,7 +128,7 @@ static int dwc_pwm_resume(struct device *dev) 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 */ + { PCI_VDEVICE(INTEL, 0x4bb7), (kernel_ulong_t)&ehl_pwm_info }, { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table); diff --git a/drivers/pwm/pwm-dwc.h b/drivers/pwm/pwm-dwc.h index 5887371803fd..a8b074841ae8 100644 --- a/drivers/pwm/pwm-dwc.h +++ b/drivers/pwm/pwm-dwc.h @@ -33,6 +33,11 @@ MODULE_IMPORT_NS(dwc_pwm); #define DWC_TIM_CTRL_INT_MASK BIT(2) #define DWC_TIM_CTRL_PWM BIT(3) +struct dwc_pwm_info { + unsigned int nr; + unsigned int size; +}; + struct dwc_pwm_ctx { u32 cnt; u32 cnt2; -- cgit v1.2.3 From 9e3440d2d57b459cd12c5a4d15e95a1181568e4f Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Mon, 19 Feb 2024 09:08:35 +0530 Subject: pwm: dwc: simplify error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify error handling in ->probe() function using dev_err_probe() helper and while at it, drop error codes from the message to prevent duplication. Signed-off-by: Raag Jadav Tested-by: Jarkko Nikula Link: https://lore.kernel.org/r/20240219033835.11369-5-raag.jadav@intel.com Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-dwc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/pwm/pwm-dwc.c') diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index de95352081fa..676eaf8d7a53 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -53,18 +53,14 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) int i, ret; ret = pcim_enable_device(pci); - if (ret) { - dev_err(dev, "Failed to enable device (%pe)\n", ERR_PTR(ret)); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to enable device\n"); pci_set_master(pci); ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci)); - if (ret) { - dev_err(dev, "Failed to iomap PCI BAR (%pe)\n", ERR_PTR(ret)); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to iomap PCI BAR\n"); info = (const struct dwc_pwm_info *)id->driver_data; -- cgit v1.2.3