Commit 45ce1d23 authored by Thierry Reding's avatar Thierry Reding

Merge branch 'for-4.11/fixes' into for-next

parents c1ae3cfa a900152b
...@@ -36,6 +36,14 @@ static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = { ...@@ -36,6 +36,14 @@ static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.clk_rate = 19200000, .clk_rate = 19200000,
.npwm = 4, .npwm = 4,
.base_unit_bits = 22, .base_unit_bits = 22,
.bypass = true,
};
/* Tangier */
static const struct pwm_lpss_boardinfo pwm_lpss_tng_info = {
.clk_rate = 19200000,
.npwm = 4,
.base_unit_bits = 22,
}; };
static int pwm_lpss_probe_pci(struct pci_dev *pdev, static int pwm_lpss_probe_pci(struct pci_dev *pdev,
...@@ -97,7 +105,7 @@ static const struct pci_device_id pwm_lpss_pci_ids[] = { ...@@ -97,7 +105,7 @@ static const struct pci_device_id pwm_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info}, { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info},
{ PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info}, { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
{ PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info}, { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info},
{ PCI_VDEVICE(INTEL, 0x11a5), (unsigned long)&pwm_lpss_bxt_info}, { PCI_VDEVICE(INTEL, 0x11a5), (unsigned long)&pwm_lpss_tng_info},
{ PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bxt_info}, { PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bxt_info},
{ PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info}, { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info},
{ PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info}, { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info},
......
...@@ -37,6 +37,7 @@ static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = { ...@@ -37,6 +37,7 @@ static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.clk_rate = 19200000, .clk_rate = 19200000,
.npwm = 4, .npwm = 4,
.base_unit_bits = 22, .base_unit_bits = 22,
.bypass = true,
}; };
static int pwm_lpss_probe_platform(struct platform_device *pdev) static int pwm_lpss_probe_platform(struct platform_device *pdev)
......
...@@ -57,7 +57,7 @@ static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value) ...@@ -57,7 +57,7 @@ static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value)
writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM); writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
} }
static int pwm_lpss_update(struct pwm_device *pwm) static int pwm_lpss_wait_for_update(struct pwm_device *pwm)
{ {
struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip); struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
const void __iomem *addr = lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM; const void __iomem *addr = lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM;
...@@ -65,8 +65,6 @@ static int pwm_lpss_update(struct pwm_device *pwm) ...@@ -65,8 +65,6 @@ static int pwm_lpss_update(struct pwm_device *pwm)
u32 val; u32 val;
int err; int err;
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
/* /*
* PWM Configuration register has SW_UPDATE bit that is set when a new * PWM Configuration register has SW_UPDATE bit that is set when a new
* configuration is written to the register. The bit is automatically * configuration is written to the register. The bit is automatically
...@@ -122,6 +120,12 @@ static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm, ...@@ -122,6 +120,12 @@ static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm,
pwm_lpss_write(pwm, ctrl); pwm_lpss_write(pwm, ctrl);
} }
static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond)
{
if (cond)
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
}
static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm, static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state) struct pwm_state *state)
{ {
...@@ -137,18 +141,21 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -137,18 +141,21 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret; return ret;
} }
pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
ret = pwm_lpss_update(pwm); pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false);
ret = pwm_lpss_wait_for_update(pwm);
if (ret) { if (ret) {
pm_runtime_put(chip->dev); pm_runtime_put(chip->dev);
return ret; return ret;
} }
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE); pwm_lpss_cond_enable(pwm, lpwm->info->bypass == true);
} else { } else {
ret = pwm_lpss_is_updating(pwm); ret = pwm_lpss_is_updating(pwm);
if (ret) if (ret)
return ret; return ret;
pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
return pwm_lpss_update(pwm); pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
return pwm_lpss_wait_for_update(pwm);
} }
} else if (pwm_is_enabled(pwm)) { } else if (pwm_is_enabled(pwm)) {
pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE); pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
......
...@@ -22,6 +22,7 @@ struct pwm_lpss_boardinfo { ...@@ -22,6 +22,7 @@ struct pwm_lpss_boardinfo {
unsigned long clk_rate; unsigned long clk_rate;
unsigned int npwm; unsigned int npwm;
unsigned long base_unit_bits; unsigned long base_unit_bits;
bool bypass;
}; };
struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r, struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
......
...@@ -191,6 +191,28 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -191,6 +191,28 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
return 0; return 0;
} }
static int rockchip_pwm_enable(struct pwm_chip *chip,
struct pwm_device *pwm,
bool enable,
enum pwm_polarity polarity)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
int ret;
if (enable) {
ret = clk_enable(pc->clk);
if (ret)
return ret;
}
pc->data->set_enable(chip, pwm, enable, polarity);
if (!enable)
clk_disable(pc->clk);
return 0;
}
static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state) struct pwm_state *state)
{ {
...@@ -207,22 +229,26 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -207,22 +229,26 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret; return ret;
if (state->polarity != curstate.polarity && enabled) { if (state->polarity != curstate.polarity && enabled) {
pc->data->set_enable(chip, pwm, false, state->polarity); ret = rockchip_pwm_enable(chip, pwm, false, state->polarity);
if (ret)
goto out;
enabled = false; enabled = false;
} }
ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period); ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
if (ret) { if (ret) {
if (enabled != curstate.enabled) if (enabled != curstate.enabled)
pc->data->set_enable(chip, pwm, !enabled, rockchip_pwm_enable(chip, pwm, !enabled,
state->polarity); state->polarity);
goto out; goto out;
} }
if (state->enabled != enabled) if (state->enabled != enabled) {
pc->data->set_enable(chip, pwm, state->enabled, ret = rockchip_pwm_enable(chip, pwm, state->enabled,
state->polarity); state->polarity);
if (ret)
goto out;
}
/* /*
* Update the state with the real hardware, which can differ a bit * Update the state with the real hardware, which can differ a bit
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment