mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	pwm: dwc: Add 16 channel support for Intel Elkhart Lake
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 <raag.jadav@intel.com> Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Tested-by: Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com> Link: https://lore.kernel.org/r/20240219033835.11369-4-raag.jadav@intel.com Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
This commit is contained in:
		
							parent
							
								
									144a0008b3
								
							
						
					
					
						commit
						ebf2c89eb9
					
				
					 2 changed files with 34 additions and 9 deletions
				
			
		| 
						 | 
					@ -25,17 +25,32 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pwm-dwc.h"
 | 
					#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 pwm_chip *chip;
 | 
				
			||||||
	struct dwc_pwm *dwc;
 | 
						struct dwc_pwm *dwc;
 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip = dwc_pwm_alloc(dev);
 | 
						chip = dwc_pwm_alloc(dev);
 | 
				
			||||||
	if (IS_ERR(chip))
 | 
						if (IS_ERR(chip))
 | 
				
			||||||
		return PTR_ERR(chip);
 | 
							return PTR_ERR(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dwc = to_dwc_pwm(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);
 | 
						ret = pcim_enable_device(pci);
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
| 
						 | 
					@ -51,12 +66,17 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* No need to check for failure, pcim_iomap_regions() does it for us. */
 | 
						info = (const struct dwc_pwm_info *)id->driver_data;
 | 
				
			||||||
	dwc->base = pcim_iomap_table(pci)[0];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = devm_pwmchip_add(dev, chip);
 | 
						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)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pm_runtime_put(dev);
 | 
						pm_runtime_put(dev);
 | 
				
			||||||
	pm_runtime_allow(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 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[] = {
 | 
					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 */
 | 
						{  }	/* Terminating Entry */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table);
 | 
					MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,11 @@ MODULE_IMPORT_NS(dwc_pwm);
 | 
				
			||||||
#define DWC_TIM_CTRL_INT_MASK	BIT(2)
 | 
					#define DWC_TIM_CTRL_INT_MASK	BIT(2)
 | 
				
			||||||
#define DWC_TIM_CTRL_PWM	BIT(3)
 | 
					#define DWC_TIM_CTRL_PWM	BIT(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dwc_pwm_info {
 | 
				
			||||||
 | 
						unsigned int nr;
 | 
				
			||||||
 | 
						unsigned int size;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dwc_pwm_ctx {
 | 
					struct dwc_pwm_ctx {
 | 
				
			||||||
	u32 cnt;
 | 
						u32 cnt;
 | 
				
			||||||
	u32 cnt2;
 | 
						u32 cnt2;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue