Skip to content

Commit

Permalink
Merge tag 'pwm/for-5.1-rc1' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
 "The changes for this cycle are across the board.

  The bulk of it is cleanups, but there's also new device support in
  some drivers as well as more conversions to the atomic API"

* tag 'pwm/for-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (24 commits)
  pwm: atmel: Remove useless symbolic definitions
  pwm: bcm-kona: Update macros to remove braces around numbers
  pwm: imx27: Only enable the clocks once in .get_state()
  pwm: rcar: Improve calculation of divider
  pwm: rcar: Remove legacy APIs
  pwm: rcar: Use "atomic" API on rcar_pwm_resume()
  pwm: rcar: Add support "atomic" API
  pwm: atmel: Add support for SAM9X60's PWM controller
  pwm: atmel: Add PWM binding for SAM9X60
  pwm: atmel: Rename objects of type atmel_pwm_data
  pwm: atmel: Add support for controllers with 32 bit counters
  pwm: atmel: Add struct atmel_pwm_data
  pwm: Add MediaTek MT8183 display PWM driver support
  pwm: hibvt: Add hi3559v100 support
  dt-bindings: pwm: hibvt: Add hi3559v100 support
  pwm: hibvt: Use individual struct per of-data
  pwm: imx: Signedness bug in imx_pwm_get_state()
  pwm: imx: Split into two drivers
  pwm: imx: Don't print an error on -EPROBE_DEFER
  pwm: imx: Set driver data earlier simplifying the end of ->probe()
  ...
  • Loading branch information
torvalds committed Mar 13, 2019
2 parents 3a186d3 + d7d9631 commit add8462
Show file tree
Hide file tree
Showing 13 changed files with 474 additions and 300 deletions.
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/pwm/atmel-pwm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Required properties:
- "atmel,at91sam9rl-pwm"
- "atmel,sama5d3-pwm"
- "atmel,sama5d2-pwm"
- "microchip,sam9x60-pwm"
- reg: physical base address and length of the controller's registers
- #pwm-cells: Should be 3. See pwm.txt in this directory for a
description of the cells format.
Expand Down
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/pwm/pwm-hibvt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Required properties:
The SoC specific strings supported including:
"hisilicon,hi3516cv300-pwm"
"hisilicon,hi3519v100-pwm"
"hisilicon,hi3559v100-shub-pwm"
"hisilicon,hi3559v100-pwm
- reg: physical base address and length of the controller's registers.
- clocks: phandle and clock specifier of the PWM reference clock.
- resets: phandle and reset specifier for the PWM controller reset.
Expand Down
17 changes: 13 additions & 4 deletions drivers/pwm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,23 @@ config PWM_IMG
To compile this driver as a module, choose M here: the module
will be called pwm-img

config PWM_IMX
tristate "i.MX PWM support"
config PWM_IMX1
tristate "i.MX1 PWM support"
depends on ARCH_MXC
help
Generic PWM framework driver for i.MX.
Generic PWM framework driver for i.MX1 and i.MX21

To compile this driver as a module, choose M here: the module
will be called pwm-imx.
will be called pwm-imx1.

config PWM_IMX27
tristate "i.MX27 PWM support"
depends on ARCH_MXC
help
Generic PWM framework driver for i.MX27 and later i.MX SoCs.

To compile this driver as a module, choose M here: the module
will be called pwm-imx27.

config PWM_JZ4740
tristate "Ingenic JZ47xx PWM support"
Expand Down
3 changes: 2 additions & 1 deletion drivers/pwm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
obj-$(CONFIG_PWM_HIBVT) += pwm-hibvt.o
obj-$(CONFIG_PWM_IMG) += pwm-img.o
obj-$(CONFIG_PWM_IMX) += pwm-imx.o
obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o
obj-$(CONFIG_PWM_IMX27) += pwm-imx27.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o
obj-$(CONFIG_PWM_LPC18XX_SCT) += pwm-lpc18xx-sct.o
Expand Down
10 changes: 5 additions & 5 deletions drivers/pwm/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,10 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
state->duty_cycle > state->period)
return -EINVAL;

if (!memcmp(state, &pwm->state, sizeof(*state)))
if (state->period == pwm->state.period &&
state->duty_cycle == pwm->state.duty_cycle &&
state->polarity == pwm->state.polarity &&
state->enabled == pwm->state.enabled)
return 0;

if (pwm->chip->ops->apply) {
Expand Down Expand Up @@ -1033,10 +1036,7 @@ static int pwm_seq_show(struct seq_file *s, void *v)
dev_name(chip->dev), chip->npwm,
(chip->npwm != 1) ? "s" : "");

if (chip->ops->dbg_show)
chip->ops->dbg_show(chip, s);
else
pwm_dbg_show(chip, s);
pwm_dbg_show(chip, s);

return 0;
}
Expand Down
111 changes: 71 additions & 40 deletions drivers/pwm/pwm-atmel.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,28 @@
#define PWMV2_CPRD 0x0C
#define PWMV2_CPRDUPD 0x10

/*
* Max value for duty and period
*
* Although the duty and period register is 32 bit,
* however only the LSB 16 bits are significant.
*/
#define PWM_MAX_DTY 0xFFFF
#define PWM_MAX_PRD 0xFFFF
#define PRD_MAX_PRES 10

struct atmel_pwm_registers {
u8 period;
u8 period_upd;
u8 duty;
u8 duty_upd;
};

struct atmel_pwm_config {
u32 max_period;
u32 max_pres;
};

struct atmel_pwm_data {
struct atmel_pwm_registers regs;
struct atmel_pwm_config cfg;
};

struct atmel_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
void __iomem *base;
const struct atmel_pwm_registers *regs;
const struct atmel_pwm_data *data;

unsigned int updated_pwms;
/* ISR is cleared when read, ensure only one thread does that */
Expand Down Expand Up @@ -121,10 +121,10 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
cycles *= clk_get_rate(atmel_pwm->clk);
do_div(cycles, NSEC_PER_SEC);

for (*pres = 0; cycles > PWM_MAX_PRD; cycles >>= 1)
for (*pres = 0; cycles > atmel_pwm->data->cfg.max_period; cycles >>= 1)
(*pres)++;

if (*pres > PRD_MAX_PRES) {
if (*pres > atmel_pwm->data->cfg.max_pres) {
dev_err(chip->dev, "pres exceeds the maximum value\n");
return -EINVAL;
}
Expand All @@ -150,15 +150,15 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, struct pwm_device *pwm,
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
u32 val;

if (atmel_pwm->regs->duty_upd ==
atmel_pwm->regs->period_upd) {
if (atmel_pwm->data->regs.duty_upd ==
atmel_pwm->data->regs.period_upd) {
val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
val &= ~PWM_CMR_UPD_CDTY;
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
}

atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
atmel_pwm->regs->duty_upd, cdty);
atmel_pwm->data->regs.duty_upd, cdty);
}

static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
Expand All @@ -168,9 +168,9 @@ static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);

atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
atmel_pwm->regs->duty, cdty);
atmel_pwm->data->regs.duty, cdty);
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
atmel_pwm->regs->period, cprd);
atmel_pwm->data->regs.period, cprd);
}

static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
Expand Down Expand Up @@ -225,7 +225,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
cstate.polarity == state->polarity &&
cstate.period == state->period) {
cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
atmel_pwm->regs->period);
atmel_pwm->data->regs.period);
atmel_pwm_calculate_cdty(state, cprd, &cdty);
atmel_pwm_update_cdty(chip, pwm, cdty);
return 0;
Expand Down Expand Up @@ -277,27 +277,55 @@ static const struct pwm_ops atmel_pwm_ops = {
.owner = THIS_MODULE,
};

static const struct atmel_pwm_registers atmel_pwm_regs_v1 = {
.period = PWMV1_CPRD,
.period_upd = PWMV1_CUPD,
.duty = PWMV1_CDTY,
.duty_upd = PWMV1_CUPD,
static const struct atmel_pwm_data atmel_sam9rl_pwm_data = {
.regs = {
.period = PWMV1_CPRD,
.period_upd = PWMV1_CUPD,
.duty = PWMV1_CDTY,
.duty_upd = PWMV1_CUPD,
},
.cfg = {
/* 16 bits to keep period and duty. */
.max_period = 0xffff,
.max_pres = 10,
},
};

static const struct atmel_pwm_data atmel_sama5_pwm_data = {
.regs = {
.period = PWMV2_CPRD,
.period_upd = PWMV2_CPRDUPD,
.duty = PWMV2_CDTY,
.duty_upd = PWMV2_CDTYUPD,
},
.cfg = {
/* 16 bits to keep period and duty. */
.max_period = 0xffff,
.max_pres = 10,
},
};

static const struct atmel_pwm_registers atmel_pwm_regs_v2 = {
.period = PWMV2_CPRD,
.period_upd = PWMV2_CPRDUPD,
.duty = PWMV2_CDTY,
.duty_upd = PWMV2_CDTYUPD,
static const struct atmel_pwm_data mchp_sam9x60_pwm_data = {
.regs = {
.period = PWMV1_CPRD,
.period_upd = PWMV1_CUPD,
.duty = PWMV1_CDTY,
.duty_upd = PWMV1_CUPD,
},
.cfg = {
/* 32 bits to keep period and duty. */
.max_period = 0xffffffff,
.max_pres = 10,
},
};

static const struct platform_device_id atmel_pwm_devtypes[] = {
{
.name = "at91sam9rl-pwm",
.driver_data = (kernel_ulong_t)&atmel_pwm_regs_v1,
.driver_data = (kernel_ulong_t)&atmel_sam9rl_pwm_data,
}, {
.name = "sama5d3-pwm",
.driver_data = (kernel_ulong_t)&atmel_pwm_regs_v2,
.driver_data = (kernel_ulong_t)&atmel_sama5_pwm_data,
}, {
/* sentinel */
},
Expand All @@ -307,20 +335,23 @@ MODULE_DEVICE_TABLE(platform, atmel_pwm_devtypes);
static const struct of_device_id atmel_pwm_dt_ids[] = {
{
.compatible = "atmel,at91sam9rl-pwm",
.data = &atmel_pwm_regs_v1,
.data = &atmel_sam9rl_pwm_data,
}, {
.compatible = "atmel,sama5d3-pwm",
.data = &atmel_pwm_regs_v2,
.data = &atmel_sama5_pwm_data,
}, {
.compatible = "atmel,sama5d2-pwm",
.data = &atmel_pwm_regs_v2,
.data = &atmel_sama5_pwm_data,
}, {
.compatible = "microchip,sam9x60-pwm",
.data = &mchp_sam9x60_pwm_data,
}, {
/* sentinel */
},
};
MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);

static inline const struct atmel_pwm_registers *
static inline const struct atmel_pwm_data *
atmel_pwm_get_driver_data(struct platform_device *pdev)
{
const struct platform_device_id *id;
Expand All @@ -330,18 +361,18 @@ atmel_pwm_get_driver_data(struct platform_device *pdev)

id = platform_get_device_id(pdev);

return (struct atmel_pwm_registers *)id->driver_data;
return (struct atmel_pwm_data *)id->driver_data;
}

static int atmel_pwm_probe(struct platform_device *pdev)
{
const struct atmel_pwm_registers *regs;
const struct atmel_pwm_data *data;
struct atmel_pwm_chip *atmel_pwm;
struct resource *res;
int ret;

regs = atmel_pwm_get_driver_data(pdev);
if (!regs)
data = atmel_pwm_get_driver_data(pdev);
if (!data)
return -ENODEV;

atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL);
Expand Down Expand Up @@ -373,7 +404,7 @@ static int atmel_pwm_probe(struct platform_device *pdev)

atmel_pwm->chip.base = -1;
atmel_pwm->chip.npwm = 4;
atmel_pwm->regs = regs;
atmel_pwm->data = data;
atmel_pwm->updated_pwms = 0;
mutex_init(&atmel_pwm->isr_lock);

Expand Down
16 changes: 8 additions & 8 deletions drivers/pwm/pwm-bcm-kona.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,25 @@
* high or low depending on its state at that exact instant.
*/

#define PWM_CONTROL_OFFSET (0x00000000)
#define PWM_CONTROL_OFFSET 0x00000000
#define PWM_CONTROL_SMOOTH_SHIFT(chan) (24 + (chan))
#define PWM_CONTROL_TYPE_SHIFT(chan) (16 + (chan))
#define PWM_CONTROL_POLARITY_SHIFT(chan) (8 + (chan))
#define PWM_CONTROL_TRIGGER_SHIFT(chan) (chan)

#define PRESCALE_OFFSET (0x00000004)
#define PRESCALE_OFFSET 0x00000004
#define PRESCALE_SHIFT(chan) ((chan) << 2)
#define PRESCALE_MASK(chan) (0x7 << PRESCALE_SHIFT(chan))
#define PRESCALE_MIN (0x00000000)
#define PRESCALE_MAX (0x00000007)
#define PRESCALE_MIN 0x00000000
#define PRESCALE_MAX 0x00000007

#define PERIOD_COUNT_OFFSET(chan) (0x00000008 + ((chan) << 3))
#define PERIOD_COUNT_MIN (0x00000002)
#define PERIOD_COUNT_MAX (0x00ffffff)
#define PERIOD_COUNT_MIN 0x00000002
#define PERIOD_COUNT_MAX 0x00ffffff

#define DUTY_CYCLE_HIGH_OFFSET(chan) (0x0000000c + ((chan) << 3))
#define DUTY_CYCLE_HIGH_MIN (0x00000000)
#define DUTY_CYCLE_HIGH_MAX (0x00ffffff)
#define DUTY_CYCLE_HIGH_MIN 0x00000000
#define DUTY_CYCLE_HIGH_MAX 0x00ffffff

struct kona_pwmc {
struct pwm_chip chip;
Expand Down
Loading

0 comments on commit add8462

Please sign in to comment.