Skip to content

Commit 4c7d00c

Browse files
committed
Merge tag 'pwm/for-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm
Pull pwm updates from Thierry Reding: "Mostly cleanups and minor improvements with some new chip support for some drivers" * tag 'pwm/for-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (37 commits) pwm: Remove set but not set variable 'pwm' pwm: sun4i: Initialize variables before use pwm: stm32: Remove automatic output enable pwm: sun4i: Narrow scope of local variable pwm: bcm2835: Allow building for ARCH_BRCMSTB pwm: imx27: Eliminate error message for defer probe pwm: sun4i: Fix inconsistent IS_ERR and PTR_ERR pwm: sun4i: Move pwm_calculate() out of spin_lock() pwm: omap-dmtimer: Allow compiling with COMPILE_TEST pwm: omap-dmtimer: put_device() after of_find_device_by_node() pwm: omap-dmtimer: Simplify error handling pwm: omap-dmtimer: Remove PWM chip in .remove before making it unfunctional pwm: Implement tracing for .get_state() and .apply_state() pwm: rcar: Document inability to set duty_cycle = 0 pwm: rcar: Drop useless call to pwm_get_state() pwm: Fix minor Kconfig whitespace issues pwm: atmel: Implement .get_state() pwm: atmel: Use register accessors for channels pwm: atmel: Document known weaknesses of both hardware and software pwm: atmel: Replace loop in prescale calculation by ad-hoc calculation ...
2 parents 18ea671 + 9871abf commit 4c7d00c

File tree

13 files changed

+539
-199
lines changed

13 files changed

+539
-199
lines changed

Documentation/devicetree/bindings/pwm/mxs-pwm.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Freescale MXS PWM controller
33
Required properties:
44
- compatible: should be "fsl,imx23-pwm"
55
- reg: physical base address and length of the controller's registers
6-
- #pwm-cells: should be 2. See pwm.yaml in this directory for a description of
6+
- #pwm-cells: should be 3. See pwm.yaml in this directory for a description of
77
the cells format.
88
- fsl,pwm-number: the number of PWM devices
99

@@ -12,6 +12,6 @@ Example:
1212
pwm: pwm@80064000 {
1313
compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
1414
reg = <0x80064000 0x2000>;
15-
#pwm-cells = <2>;
15+
#pwm-cells = <3>;
1616
fsl,pwm-number = <8>;
1717
};

drivers/pwm/Kconfig

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ config PWM_BCM_KONA
100100

101101
config PWM_BCM2835
102102
tristate "BCM2835 PWM support"
103-
depends on ARCH_BCM2835
103+
depends on ARCH_BCM2835 || ARCH_BRCMSTB
104104
help
105105
PWM framework driver for BCM2835 controller (Raspberry Pi)
106106

@@ -328,7 +328,8 @@ config PWM_MXS
328328

329329
config PWM_OMAP_DMTIMER
330330
tristate "OMAP Dual-Mode Timer PWM support"
331-
depends on OF && ARCH_OMAP && OMAP_DM_TIMER
331+
depends on OF
332+
depends on OMAP_DM_TIMER || COMPILE_TEST
332333
help
333334
Generic PWM framework driver for OMAP Dual-Mode Timer PWM output
334335

@@ -490,7 +491,7 @@ config PWM_TEGRA
490491
To compile this driver as a module, choose M here: the module
491492
will be called pwm-tegra.
492493

493-
config PWM_TIECAP
494+
config PWM_TIECAP
494495
tristate "ECAP PWM support"
495496
depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE || ARCH_K3
496497
help
@@ -499,7 +500,7 @@ config PWM_TIECAP
499500
To compile this driver as a module, choose M here: the module
500501
will be called pwm-tiecap.
501502

502-
config PWM_TIEHRPWM
503+
config PWM_TIEHRPWM
503504
tristate "EHRPWM PWM support"
504505
depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_K3
505506
help

drivers/pwm/core.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
#include <dt-bindings/pwm/pwm.h>
2222

23+
#define CREATE_TRACE_POINTS
24+
#include <trace/events/pwm.h>
25+
2326
#define MAX_PWMS 1024
2427

2528
static DEFINE_MUTEX(pwm_lookup_lock);
@@ -114,6 +117,11 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
114117
}
115118
}
116119

120+
if (pwm->chip->ops->get_state) {
121+
pwm->chip->ops->get_state(pwm->chip, pwm, &pwm->state);
122+
trace_pwm_get(pwm, &pwm->state);
123+
}
124+
117125
set_bit(PWMF_REQUESTED, &pwm->flags);
118126
pwm->label = label;
119127

@@ -283,9 +291,6 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
283291
pwm->hwpwm = i;
284292
pwm->state.polarity = polarity;
285293

286-
if (chip->ops->get_state)
287-
chip->ops->get_state(chip, pwm, &pwm->state);
288-
289294
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
290295
}
291296

@@ -472,6 +477,8 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
472477
if (err)
473478
return err;
474479

480+
trace_pwm_apply(pwm, state);
481+
475482
pwm->state = *state;
476483
} else {
477484
/*

drivers/pwm/pwm-atmel.c

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44
*
55
* Copyright (C) 2013 Atmel Corporation
66
* Bo Shen <[email protected]>
7+
*
8+
* Links to reference manuals for the supported PWM chips can be found in
9+
* Documentation/arm/microchip.rst.
10+
*
11+
* Limitations:
12+
* - Periods start with the inactive level.
13+
* - Hardware has to be stopped in general to update settings.
14+
*
15+
* Software bugs/possible improvements:
16+
* - When atmel_pwm_apply() is called with state->enabled=false a change in
17+
* state->polarity isn't honored.
18+
* - Instead of sleeping to wait for a completed period, the interrupt
19+
* functionality could be used.
720
*/
821

922
#include <linux/clk.h>
@@ -47,6 +60,8 @@
4760
#define PWMV2_CPRD 0x0C
4861
#define PWMV2_CPRDUPD 0x10
4962

63+
#define PWM_MAX_PRES 10
64+
5065
struct atmel_pwm_registers {
5166
u8 period;
5267
u8 period_upd;
@@ -55,8 +70,7 @@ struct atmel_pwm_registers {
5570
};
5671

5772
struct atmel_pwm_config {
58-
u32 max_period;
59-
u32 max_pres;
73+
u32 period_bits;
6074
};
6175

6276
struct atmel_pwm_data {
@@ -97,7 +111,7 @@ static inline u32 atmel_pwm_ch_readl(struct atmel_pwm_chip *chip,
97111
{
98112
unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
99113

100-
return readl_relaxed(chip->base + base + offset);
114+
return atmel_pwm_readl(chip, base + offset);
101115
}
102116

103117
static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
@@ -106,7 +120,7 @@ static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
106120
{
107121
unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
108122

109-
writel_relaxed(val, chip->base + base + offset);
123+
atmel_pwm_writel(chip, base + offset, val);
110124
}
111125

112126
static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
@@ -115,17 +129,27 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
115129
{
116130
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
117131
unsigned long long cycles = state->period;
132+
int shift;
118133

119134
/* Calculate the period cycles and prescale value */
120135
cycles *= clk_get_rate(atmel_pwm->clk);
121136
do_div(cycles, NSEC_PER_SEC);
122137

123-
for (*pres = 0; cycles > atmel_pwm->data->cfg.max_period; cycles >>= 1)
124-
(*pres)++;
138+
/*
139+
* The register for the period length is cfg.period_bits bits wide.
140+
* So for each bit the number of clock cycles is wider divide the input
141+
* clock frequency by two using pres and shift cprd accordingly.
142+
*/
143+
shift = fls(cycles) - atmel_pwm->data->cfg.period_bits;
125144

126-
if (*pres > atmel_pwm->data->cfg.max_pres) {
145+
if (shift > PWM_MAX_PRES) {
127146
dev_err(chip->dev, "pres exceeds the maximum value\n");
128147
return -EINVAL;
148+
} else if (shift > 0) {
149+
*pres = shift;
150+
cycles >>= *pres;
151+
} else {
152+
*pres = 0;
129153
}
130154

131155
*cprd = cycles;
@@ -271,8 +295,48 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
271295
return 0;
272296
}
273297

298+
static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
299+
struct pwm_state *state)
300+
{
301+
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
302+
u32 sr, cmr;
303+
304+
sr = atmel_pwm_readl(atmel_pwm, PWM_SR);
305+
cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
306+
307+
if (sr & (1 << pwm->hwpwm)) {
308+
unsigned long rate = clk_get_rate(atmel_pwm->clk);
309+
u32 cdty, cprd, pres;
310+
u64 tmp;
311+
312+
pres = cmr & PWM_CMR_CPRE_MSK;
313+
314+
cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
315+
atmel_pwm->data->regs.period);
316+
tmp = (u64)cprd * NSEC_PER_SEC;
317+
tmp <<= pres;
318+
state->period = DIV64_U64_ROUND_UP(tmp, rate);
319+
320+
cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
321+
atmel_pwm->data->regs.duty);
322+
tmp = (u64)cdty * NSEC_PER_SEC;
323+
tmp <<= pres;
324+
state->duty_cycle = DIV64_U64_ROUND_UP(tmp, rate);
325+
326+
state->enabled = true;
327+
} else {
328+
state->enabled = false;
329+
}
330+
331+
if (cmr & PWM_CMR_CPOL)
332+
state->polarity = PWM_POLARITY_INVERSED;
333+
else
334+
state->polarity = PWM_POLARITY_NORMAL;
335+
}
336+
274337
static const struct pwm_ops atmel_pwm_ops = {
275338
.apply = atmel_pwm_apply,
339+
.get_state = atmel_pwm_get_state,
276340
.owner = THIS_MODULE,
277341
};
278342

@@ -285,8 +349,7 @@ static const struct atmel_pwm_data atmel_sam9rl_pwm_data = {
285349
},
286350
.cfg = {
287351
/* 16 bits to keep period and duty. */
288-
.max_period = 0xffff,
289-
.max_pres = 10,
352+
.period_bits = 16,
290353
},
291354
};
292355

@@ -299,8 +362,7 @@ static const struct atmel_pwm_data atmel_sama5_pwm_data = {
299362
},
300363
.cfg = {
301364
/* 16 bits to keep period and duty. */
302-
.max_period = 0xffff,
303-
.max_pres = 10,
365+
.period_bits = 16,
304366
},
305367
};
306368

@@ -313,8 +375,7 @@ static const struct atmel_pwm_data mchp_sam9x60_pwm_data = {
313375
},
314376
.cfg = {
315377
/* 32 bits to keep period and duty. */
316-
.max_period = 0xffffffff,
317-
.max_pres = 10,
378+
.period_bits = 32,
318379
},
319380
};
320381

drivers/pwm/pwm-cros-ec.c

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,39 @@ struct cros_ec_pwm_device {
2525
struct pwm_chip chip;
2626
};
2727

28+
/**
29+
* struct cros_ec_pwm - per-PWM driver data
30+
* @duty_cycle: cached duty cycle
31+
*/
32+
struct cros_ec_pwm {
33+
u16 duty_cycle;
34+
};
35+
2836
static inline struct cros_ec_pwm_device *pwm_to_cros_ec_pwm(struct pwm_chip *c)
2937
{
3038
return container_of(c, struct cros_ec_pwm_device, chip);
3139
}
3240

41+
static int cros_ec_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
42+
{
43+
struct cros_ec_pwm *channel;
44+
45+
channel = kzalloc(sizeof(*channel), GFP_KERNEL);
46+
if (!channel)
47+
return -ENOMEM;
48+
49+
pwm_set_chip_data(pwm, channel);
50+
51+
return 0;
52+
}
53+
54+
static void cros_ec_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
55+
{
56+
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
57+
58+
kfree(channel);
59+
}
60+
3361
static int cros_ec_pwm_set_duty(struct cros_ec_device *ec, u8 index, u16 duty)
3462
{
3563
struct {
@@ -96,7 +124,9 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
96124
const struct pwm_state *state)
97125
{
98126
struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
99-
int duty_cycle;
127+
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
128+
u16 duty_cycle;
129+
int ret;
100130

101131
/* The EC won't let us change the period */
102132
if (state->period != EC_PWM_MAX_DUTY)
@@ -108,13 +138,20 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
108138
*/
109139
duty_cycle = state->enabled ? state->duty_cycle : 0;
110140

111-
return cros_ec_pwm_set_duty(ec_pwm->ec, pwm->hwpwm, duty_cycle);
141+
ret = cros_ec_pwm_set_duty(ec_pwm->ec, pwm->hwpwm, duty_cycle);
142+
if (ret < 0)
143+
return ret;
144+
145+
channel->duty_cycle = state->duty_cycle;
146+
147+
return 0;
112148
}
113149

114150
static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
115151
struct pwm_state *state)
116152
{
117153
struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
154+
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
118155
int ret;
119156

120157
ret = cros_ec_pwm_get_duty(ec_pwm->ec, pwm->hwpwm);
@@ -126,8 +163,19 @@ static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
126163
state->enabled = (ret > 0);
127164
state->period = EC_PWM_MAX_DUTY;
128165

129-
/* Note that "disabled" and "duty cycle == 0" are treated the same */
130-
state->duty_cycle = ret;
166+
/*
167+
* Note that "disabled" and "duty cycle == 0" are treated the same. If
168+
* the cached duty cycle is not zero, used the cached duty cycle. This
169+
* ensures that the configured duty cycle is kept across a disable and
170+
* enable operation and avoids potentially confusing consumers.
171+
*
172+
* For the case of the initial hardware readout, channel->duty_cycle
173+
* will be 0 and the actual duty cycle read from the EC is used.
174+
*/
175+
if (ret == 0 && channel->duty_cycle > 0)
176+
state->duty_cycle = channel->duty_cycle;
177+
else
178+
state->duty_cycle = ret;
131179
}
132180

133181
static struct pwm_device *
@@ -149,6 +197,8 @@ cros_ec_pwm_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
149197
}
150198

151199
static const struct pwm_ops cros_ec_pwm_ops = {
200+
.request = cros_ec_pwm_request,
201+
.free = cros_ec_pwm_free,
152202
.get_state = cros_ec_pwm_get_state,
153203
.apply = cros_ec_pwm_apply,
154204
.owner = THIS_MODULE,

0 commit comments

Comments
 (0)