Skip to content

Commit 4b6b513

Browse files
committed
Merge tag 'pwm/for-6.9-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux
Pull pwm fixes from Uwe Kleine-König: "The first patch fixes a regression in the suspend/resume path for the dwc pwm driver that was introduced in v6.9-rc1 when support for 16 channel devices was added. The second patch fixes a bunch of device tree binding check warnings" * tag 'pwm/for-6.9-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux: dt-bindings: pwm: mediatek,pwm-disp: Document power-domains property pwm: dwc: allow suspend/resume for 16 channels
2 parents 96fca68 + fb7c3d8 commit 4b6b513

File tree

4 files changed

+66
-32
lines changed

4 files changed

+66
-32
lines changed

Documentation/devicetree/bindings/pwm/mediatek,pwm-disp.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ properties:
5252
- const: main
5353
- const: mm
5454

55+
power-domains:
56+
maxItems: 1
57+
5558
required:
5659
- compatible
5760
- reg

drivers/pwm/pwm-dwc-core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ struct pwm_chip *dwc_pwm_alloc(struct device *dev)
172172
dwc->clk_ns = 10;
173173
chip->ops = &dwc_pwm_ops;
174174

175-
dev_set_drvdata(dev, chip);
176175
return chip;
177176
}
178177
EXPORT_SYMBOL_GPL(dwc_pwm_alloc);

drivers/pwm/pwm-dwc.c

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,34 @@ static const struct dwc_pwm_info ehl_pwm_info = {
3131
.size = 0x1000,
3232
};
3333

34-
static int dwc_pwm_init_one(struct device *dev, void __iomem *base, unsigned int offset)
34+
static int dwc_pwm_init_one(struct device *dev, struct dwc_pwm_drvdata *ddata, unsigned int idx)
3535
{
3636
struct pwm_chip *chip;
3737
struct dwc_pwm *dwc;
38+
int ret;
3839

3940
chip = dwc_pwm_alloc(dev);
4041
if (IS_ERR(chip))
4142
return PTR_ERR(chip);
4243

4344
dwc = to_dwc_pwm(chip);
44-
dwc->base = base + offset;
45+
dwc->base = ddata->io_base + (ddata->info->size * idx);
4546

46-
return devm_pwmchip_add(dev, chip);
47+
ret = devm_pwmchip_add(dev, chip);
48+
if (ret)
49+
return ret;
50+
51+
ddata->chips[idx] = chip;
52+
return 0;
4753
}
4854

4955
static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
5056
{
5157
const struct dwc_pwm_info *info;
5258
struct device *dev = &pci->dev;
53-
int i, ret;
59+
struct dwc_pwm_drvdata *ddata;
60+
unsigned int idx;
61+
int ret;
5462

5563
ret = pcim_enable_device(pci);
5664
if (ret)
@@ -63,17 +71,25 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
6371
return dev_err_probe(dev, ret, "Failed to iomap PCI BAR\n");
6472

6573
info = (const struct dwc_pwm_info *)id->driver_data;
66-
67-
for (i = 0; i < info->nr; i++) {
68-
/*
69-
* No need to check for pcim_iomap_table() failure,
70-
* pcim_iomap_regions() already does it for us.
71-
*/
72-
ret = dwc_pwm_init_one(dev, pcim_iomap_table(pci)[0], i * info->size);
74+
ddata = devm_kzalloc(dev, struct_size(ddata, chips, info->nr), GFP_KERNEL);
75+
if (!ddata)
76+
return -ENOMEM;
77+
78+
/*
79+
* No need to check for pcim_iomap_table() failure,
80+
* pcim_iomap_regions() already does it for us.
81+
*/
82+
ddata->io_base = pcim_iomap_table(pci)[0];
83+
ddata->info = info;
84+
85+
for (idx = 0; idx < ddata->info->nr; idx++) {
86+
ret = dwc_pwm_init_one(dev, ddata, idx);
7387
if (ret)
7488
return ret;
7589
}
7690

91+
dev_set_drvdata(dev, ddata);
92+
7793
pm_runtime_put(dev);
7894
pm_runtime_allow(dev);
7995

@@ -88,34 +104,44 @@ static void dwc_pwm_remove(struct pci_dev *pci)
88104

89105
static int dwc_pwm_suspend(struct device *dev)
90106
{
91-
struct pwm_chip *chip = dev_get_drvdata(dev);
92-
struct dwc_pwm *dwc = to_dwc_pwm(chip);
93-
int i;
94-
95-
for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
96-
if (chip->pwms[i].state.enabled) {
97-
dev_err(dev, "PWM %u in use by consumer (%s)\n",
98-
i, chip->pwms[i].label);
99-
return -EBUSY;
107+
struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
108+
unsigned int idx;
109+
110+
for (idx = 0; idx < ddata->info->nr; idx++) {
111+
struct pwm_chip *chip = ddata->chips[idx];
112+
struct dwc_pwm *dwc = to_dwc_pwm(chip);
113+
unsigned int i;
114+
115+
for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
116+
if (chip->pwms[i].state.enabled) {
117+
dev_err(dev, "PWM %u in use by consumer (%s)\n",
118+
i, chip->pwms[i].label);
119+
return -EBUSY;
120+
}
121+
dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i));
122+
dwc->ctx[i].cnt2 = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(i));
123+
dwc->ctx[i].ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(i));
100124
}
101-
dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i));
102-
dwc->ctx[i].cnt2 = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(i));
103-
dwc->ctx[i].ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(i));
104125
}
105126

106127
return 0;
107128
}
108129

109130
static int dwc_pwm_resume(struct device *dev)
110131
{
111-
struct pwm_chip *chip = dev_get_drvdata(dev);
112-
struct dwc_pwm *dwc = to_dwc_pwm(chip);
113-
int i;
114-
115-
for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
116-
dwc_pwm_writel(dwc, dwc->ctx[i].cnt, DWC_TIM_LD_CNT(i));
117-
dwc_pwm_writel(dwc, dwc->ctx[i].cnt2, DWC_TIM_LD_CNT2(i));
118-
dwc_pwm_writel(dwc, dwc->ctx[i].ctrl, DWC_TIM_CTRL(i));
132+
struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
133+
unsigned int idx;
134+
135+
for (idx = 0; idx < ddata->info->nr; idx++) {
136+
struct pwm_chip *chip = ddata->chips[idx];
137+
struct dwc_pwm *dwc = to_dwc_pwm(chip);
138+
unsigned int i;
139+
140+
for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
141+
dwc_pwm_writel(dwc, dwc->ctx[i].cnt, DWC_TIM_LD_CNT(i));
142+
dwc_pwm_writel(dwc, dwc->ctx[i].cnt2, DWC_TIM_LD_CNT2(i));
143+
dwc_pwm_writel(dwc, dwc->ctx[i].ctrl, DWC_TIM_CTRL(i));
144+
}
119145
}
120146

121147
return 0;

drivers/pwm/pwm-dwc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ struct dwc_pwm_info {
3838
unsigned int size;
3939
};
4040

41+
struct dwc_pwm_drvdata {
42+
const struct dwc_pwm_info *info;
43+
void __iomem *io_base;
44+
struct pwm_chip *chips[];
45+
};
46+
4147
struct dwc_pwm_ctx {
4248
u32 cnt;
4349
u32 cnt2;

0 commit comments

Comments
 (0)