2020-03-05 08:29:54

by Lokesh Vutla

[permalink] [raw]
Subject: [PATCH v3 0/6] clocksource: timer-ti-dm: Prepare for dynamic pwm period updates

This series fixes dm_timer_ops used for enabling the pwm and enables
cpu_pm notifier for context save and restore. This acts as a preparatory
series for enabling dynamic period updates for pwm omap dm timer driver.

Changes since v2:
- Incorporated changes from Tony

Changes since v1:
- Updated License header to use SPDX identifier
- Implemented cpu_pm notfier
- Added support for getting pwm current status
- Extended set_pwm functionality.

Lokesh Vutla (5):
clocksource: timer-ti-dm: Convert to SPDX identifier
clocksource: timer-ti-dm: Implement cpu_pm notifier for context save
and restore
clocksource: timer-ti-dm: Do not update counter on updating the period
clocksource: timer-ti-dm: Add support to get pwm current status
clocksource: timer-ti-dm: Enable autoreload in set_pwm

Tony Lindgren (1):
clocksource: timer-ti-dm: Prepare for using cpuidle

drivers/clocksource/timer-ti-dm.c | 186 ++++++++++++---------
drivers/pwm/pwm-omap-dmtimer.c | 8 +-
include/clocksource/timer-ti-dm.h | 4 +-
include/linux/platform_data/dmtimer-omap.h | 6 +-
4 files changed, 121 insertions(+), 83 deletions(-)

--
2.23.0


2020-03-05 08:30:00

by Lokesh Vutla

[permalink] [raw]
Subject: [PATCH v3 2/6] clocksource: timer-ti-dm: Prepare for using cpuidle

From: Tony Lindgren <[email protected]>

Let's add runtime_suspend and resume functions and atomic enabled
flag. This way we can use these when converting to use cpuidle
for saving and restoring device context.

And we need to maintain the driver state in the driver as documented
in "9. Autosuspend, or automatically-delayed suspends" in the
Documentation/power/runtime_pm.rst document related to using driver
private lock and races with runtime_suspend().

Signed-off-by: Tony Lindgren <[email protected]>
Signed-off-by: Lokesh Vutla <[email protected]>
---
drivers/clocksource/timer-ti-dm.c | 36 ++++++++++++++++++++++++++-----
include/clocksource/timer-ti-dm.h | 1 +
2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index bf132d321ecc..dae91969018d 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -460,7 +460,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)

int omap_dm_timer_trigger(struct omap_dm_timer *timer)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__);
return -EINVAL;
}
@@ -659,7 +659,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{
unsigned int l;

- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__);
return 0;
}
@@ -671,7 +671,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)

static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
+ if (unlikely(!timer || !atomic_read(&timer->enabled)))
return -EINVAL;

__omap_dm_timer_write_status(timer, value);
@@ -681,7 +681,7 @@ static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int

static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not iavailable or enabled.\n", __func__);
return 0;
}
@@ -691,7 +691,7 @@ static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)

static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__);
return -EINVAL;
}
@@ -719,6 +719,29 @@ int omap_dm_timers_active(void)
return 0;
}

+static int __maybe_unused omap_dm_timer_runtime_suspend(struct device *dev)
+{
+ struct omap_dm_timer *timer = dev_get_drvdata(dev);
+
+ atomic_set(&timer->enabled, 0);
+
+ return 0;
+}
+
+static int __maybe_unused omap_dm_timer_runtime_resume(struct device *dev)
+{
+ struct omap_dm_timer *timer = dev_get_drvdata(dev);
+
+ atomic_set(&timer->enabled, 1);
+
+ return 0;
+}
+
+static const struct dev_pm_ops omap_dm_timer_pm_ops = {
+ SET_RUNTIME_PM_OPS(omap_dm_timer_runtime_suspend,
+ omap_dm_timer_runtime_resume, NULL)
+};
+
static const struct of_device_id omap_timer_match[];

/**
@@ -760,6 +783,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
if (IS_ERR(timer->io_base))
return PTR_ERR(timer->io_base);

+ platform_set_drvdata(pdev, timer);
+
if (dev->of_node) {
if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
timer->capability |= OMAP_TIMER_ALWON;
@@ -905,6 +930,7 @@ static struct platform_driver omap_dm_timer_driver = {
.driver = {
.name = "omap_timer",
.of_match_table = of_match_ptr(omap_timer_match),
+ .pm = &omap_dm_timer_pm_ops,
},
};

diff --git a/include/clocksource/timer-ti-dm.h b/include/clocksource/timer-ti-dm.h
index 7d9598dc578d..eef5de300731 100644
--- a/include/clocksource/timer-ti-dm.h
+++ b/include/clocksource/timer-ti-dm.h
@@ -105,6 +105,7 @@ struct omap_dm_timer {
void __iomem *pend; /* write pending */
void __iomem *func_base; /* function register base */

+ atomic_t enabled;
unsigned long rate;
unsigned reserved:1;
unsigned posted:1;
--
2.23.0

2020-03-05 08:30:40

by Lokesh Vutla

[permalink] [raw]
Subject: [PATCH v3 6/6] clocksource: timer-ti-dm: Enable autoreload in set_pwm

dm timer ops set_load() api allows to configure the load value and to
set the auto reload feature. But auto reload feature is independent of
load value and should be part of configuring pwm. This way pwm can be
disabled by disabling auto reload feature using set_pwm() so that the
current pwm cycle will be completed. Else pwm disabling causes the
cycle to be stopped abruptly.

Signed-off-by: Lokesh Vutla <[email protected]>
---
drivers/clocksource/timer-ti-dm.c | 16 +++++-----------
drivers/pwm/pwm-omap-dmtimer.c | 8 +++++---
include/linux/platform_data/dmtimer-omap.h | 5 ++---
3 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index 10e1d08bfc4c..1f210ef60b22 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -531,21 +531,13 @@ static int omap_dm_timer_stop(struct omap_dm_timer *timer)
return 0;
}

-static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+static int omap_dm_timer_set_load(struct omap_dm_timer *timer,
unsigned int load)
{
- u32 l;
-
if (unlikely(!timer))
return -EINVAL;

omap_dm_timer_enable(timer);
- l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
- if (autoreload)
- l |= OMAP_TIMER_CTRL_AR;
- else
- l &= ~OMAP_TIMER_CTRL_AR;
- omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);

omap_dm_timer_disable(timer);
@@ -574,7 +566,7 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
}

static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
- int toggle, int trigger)
+ int toggle, int trigger, int autoreload)
{
u32 l;

@@ -584,12 +576,14 @@ static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
- OMAP_TIMER_CTRL_PT | (0x03 << 10));
+ OMAP_TIMER_CTRL_PT | (0x03 << 10) | OMAP_TIMER_CTRL_AR);
if (def_on)
l |= OMAP_TIMER_CTRL_SCPWM;
if (toggle)
l |= OMAP_TIMER_CTRL_PT;
l |= trigger << 10;
+ if (autoreload)
+ l |= OMAP_TIMER_CTRL_AR;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);

omap_dm_timer_disable(timer);
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 88a3c5690fea..9e4378dc6897 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -183,7 +183,7 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
if (timer_active)
omap->pdata->stop(omap->dm_timer);

- omap->pdata->set_load(omap->dm_timer, true, load_value);
+ omap->pdata->set_load(omap->dm_timer, load_value);
omap->pdata->set_match(omap->dm_timer, true, match_value);

dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n",
@@ -192,7 +192,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
omap->pdata->set_pwm(omap->dm_timer,
pwm_get_polarity(pwm) == PWM_POLARITY_INVERSED,
true,
- PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+ PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE,
+ true);

/* If config was called while timer was running it must be reenabled. */
if (timer_active)
@@ -222,7 +223,8 @@ static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
omap->pdata->set_pwm(omap->dm_timer,
polarity == PWM_POLARITY_INVERSED,
true,
- PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+ PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE,
+ true);
mutex_unlock(&omap->mutex);

return 0;
diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index 3173b7b6ff6f..95d852aef130 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -30,12 +30,11 @@ struct omap_dm_timer_ops {
int (*stop)(struct omap_dm_timer *timer);
int (*set_source)(struct omap_dm_timer *timer, int source);

- int (*set_load)(struct omap_dm_timer *timer, int autoreload,
- unsigned int value);
+ int (*set_load)(struct omap_dm_timer *timer, unsigned int value);
int (*set_match)(struct omap_dm_timer *timer, int enable,
unsigned int match);
int (*set_pwm)(struct omap_dm_timer *timer, int def_on,
- int toggle, int trigger);
+ int toggle, int trigger, int autoreload);
int (*get_pwm_status)(struct omap_dm_timer *timer);
int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler);

--
2.23.0

2020-03-06 17:18:53

by Tony Lindgren

[permalink] [raw]
Subject: Re: [PATCH v3 6/6] clocksource: timer-ti-dm: Enable autoreload in set_pwm

* Lokesh Vutla <[email protected]> [200305 08:29]:
> dm timer ops set_load() api allows to configure the load value and to
> set the auto reload feature. But auto reload feature is independent of
> load value and should be part of configuring pwm. This way pwm can be
> disabled by disabling auto reload feature using set_pwm() so that the
> current pwm cycle will be completed. Else pwm disabling causes the
> cycle to be stopped abruptly.

Acked-by: Tony Lindgren <[email protected]>

2020-03-06 17:20:59

by Tony Lindgren

[permalink] [raw]
Subject: Re: [PATCH v3 0/6] clocksource: timer-ti-dm: Prepare for dynamic pwm period updates

* Lokesh Vutla <[email protected]> [200305 08:29]:
> This series fixes dm_timer_ops used for enabling the pwm and enables
> cpu_pm notifier for context save and restore. This acts as a preparatory
> series for enabling dynamic period updates for pwm omap dm timer driver.
>
> Changes since v2:
> - Incorporated changes from Tony

I just gave this series another try here and it still works
for me just fine and is good to go as far as I'm concerned.

Thanks for doing this.

Regards,

Tony

2020-03-12 11:11:40

by Daniel Lezcano

[permalink] [raw]
Subject: Re: [PATCH v3 0/6] clocksource: timer-ti-dm: Prepare for dynamic pwm period updates

On 06/03/2020 18:19, Tony Lindgren wrote:
> * Lokesh Vutla <[email protected]> [200305 08:29]:
>> This series fixes dm_timer_ops used for enabling the pwm and enables
>> cpu_pm notifier for context save and restore. This acts as a preparatory
>> series for enabling dynamic period updates for pwm omap dm timer driver.
>>
>> Changes since v2:
>> - Incorporated changes from Tony
>
> I just gave this series another try here and it still works
> for me just fine and is good to go as far as I'm concerned.

How do you want this series to be merged?

Shall I pick the patches falling under drivers/clocksource or ack them?

> Thanks for doing this.
>
> Regards,
>
> Tony
>


--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

2020-03-12 17:27:37

by Tony Lindgren

[permalink] [raw]
Subject: Re: [PATCH v3 0/6] clocksource: timer-ti-dm: Prepare for dynamic pwm period updates

Hi,

* Daniel Lezcano <[email protected]> [200312 11:11]:
> On 06/03/2020 18:19, Tony Lindgren wrote:
> > * Lokesh Vutla <[email protected]> [200305 08:29]:
> >> This series fixes dm_timer_ops used for enabling the pwm and enables
> >> cpu_pm notifier for context save and restore. This acts as a preparatory
> >> series for enabling dynamic period updates for pwm omap dm timer driver.
> >>
> >> Changes since v2:
> >> - Incorporated changes from Tony
> >
> > I just gave this series another try here and it still works
> > for me just fine and is good to go as far as I'm concerned.
>
> How do you want this series to be merged?
>
> Shall I pick the patches falling under drivers/clocksource or ack them?

I think best would be if you picked them and applied them into
an immutable branch against v5.6-rc1 that can also be merged
into pwm driver branch as needed.

Regards,

Tony

2020-03-16 12:42:21

by Daniel Lezcano

[permalink] [raw]
Subject: Re: [PATCH v3 0/6] clocksource: timer-ti-dm: Prepare for dynamic pwm period updates


Hi Tony,

On 12/03/2020 18:26, Tony Lindgren wrote:
> Hi,
>
> * Daniel Lezcano <[email protected]> [200312 11:11]:
>> On 06/03/2020 18:19, Tony Lindgren wrote:
>>> * Lokesh Vutla <[email protected]> [200305 08:29]:
>>>> This series fixes dm_timer_ops used for enabling the pwm and enables
>>>> cpu_pm notifier for context save and restore. This acts as a preparatory
>>>> series for enabling dynamic period updates for pwm omap dm timer driver.
>>>>
>>>> Changes since v2:
>>>> - Incorporated changes from Tony
>>>
>>> I just gave this series another try here and it still works
>>> for me just fine and is good to go as far as I'm concerned.
>>
>> How do you want this series to be merged?
>>
>> Shall I pick the patches falling under drivers/clocksource or ack them?
>
> I think best would be if you picked them and applied them into
> an immutable branch against v5.6-rc1 that can also be merged
> into pwm driver branch as needed.

Immutable branch based on v5.6-rc1:


https://git.linaro.org/people/dlezcano/linux.git/log/?h=timers/drivers/timer-ti-dm

and merged to timers/drivers/next:


https://git.linaro.org/people/dlezcano/linux.git/log/?h=timers/drivers/next

with a small conflict (fixed) with:


https://git.linaro.org/people/dlezcano/linux.git/commit/?h=timers/drivers/next&id=6ce4fcb015a1a1290ffafcf3554901b40f9322df

Regards

-- Daniel

--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

2020-03-19 08:48:30

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: timers/core] clocksource/drivers/timer-ti-dm: Prepare for using cpuidle

The following commit has been merged into the timers/core branch of tip:

Commit-ID: 5e20931c6a750b4b1ea9a2f7b863cc2dd9222ead
Gitweb: https://git.kernel.org/tip/5e20931c6a750b4b1ea9a2f7b863cc2dd9222ead
Author: Tony Lindgren <[email protected]>
AuthorDate: Thu, 05 Mar 2020 13:57:11 +05:30
Committer: Daniel Lezcano <[email protected]>
CommitterDate: Mon, 16 Mar 2020 12:40:21 +01:00

clocksource/drivers/timer-ti-dm: Prepare for using cpuidle

Let's add runtime_suspend and resume functions and atomic enabled
flag. This way we can use these when converting to use cpuidle
for saving and restoring device context.

And we need to maintain the driver state in the driver as documented
in "9. Autosuspend, or automatically-delayed suspends" in the
Documentation/power/runtime_pm.rst document related to using driver
private lock and races with runtime_suspend().

Signed-off-by: Tony Lindgren <[email protected]>
Signed-off-by: Lokesh Vutla <[email protected]>
Signed-off-by: Daniel Lezcano <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
drivers/clocksource/timer-ti-dm.c | 36 +++++++++++++++++++++++++-----
include/clocksource/timer-ti-dm.h | 1 +-
2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index c0e9e99..fe939d1 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -491,7 +491,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)

int omap_dm_timer_trigger(struct omap_dm_timer *timer)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__);
return -EINVAL;
}
@@ -690,7 +690,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{
unsigned int l;

- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__);
return 0;
}
@@ -702,7 +702,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)

static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
+ if (unlikely(!timer || !atomic_read(&timer->enabled)))
return -EINVAL;

__omap_dm_timer_write_status(timer, value);
@@ -712,7 +712,7 @@ static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int

static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not iavailable or enabled.\n", __func__);
return 0;
}
@@ -722,7 +722,7 @@ static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)

static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{
- if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__);
return -EINVAL;
}
@@ -750,6 +750,29 @@ int omap_dm_timers_active(void)
return 0;
}

+static int __maybe_unused omap_dm_timer_runtime_suspend(struct device *dev)
+{
+ struct omap_dm_timer *timer = dev_get_drvdata(dev);
+
+ atomic_set(&timer->enabled, 0);
+
+ return 0;
+}
+
+static int __maybe_unused omap_dm_timer_runtime_resume(struct device *dev)
+{
+ struct omap_dm_timer *timer = dev_get_drvdata(dev);
+
+ atomic_set(&timer->enabled, 1);
+
+ return 0;
+}
+
+static const struct dev_pm_ops omap_dm_timer_pm_ops = {
+ SET_RUNTIME_PM_OPS(omap_dm_timer_runtime_suspend,
+ omap_dm_timer_runtime_resume, NULL)
+};
+
static const struct of_device_id omap_timer_match[];

/**
@@ -791,6 +814,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
if (IS_ERR(timer->io_base))
return PTR_ERR(timer->io_base);

+ platform_set_drvdata(pdev, timer);
+
if (dev->of_node) {
if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
timer->capability |= OMAP_TIMER_ALWON;
@@ -936,6 +961,7 @@ static struct platform_driver omap_dm_timer_driver = {
.driver = {
.name = "omap_timer",
.of_match_table = of_match_ptr(omap_timer_match),
+ .pm = &omap_dm_timer_pm_ops,
},
};

diff --git a/include/clocksource/timer-ti-dm.h b/include/clocksource/timer-ti-dm.h
index 7d9598d..eef5de3 100644
--- a/include/clocksource/timer-ti-dm.h
+++ b/include/clocksource/timer-ti-dm.h
@@ -105,6 +105,7 @@ struct omap_dm_timer {
void __iomem *pend; /* write pending */
void __iomem *func_base; /* function register base */

+ atomic_t enabled;
unsigned long rate;
unsigned reserved:1;
unsigned posted:1;

2020-03-19 08:48:31

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: timers/core] clocksource/drivers/timer-ti-dm: Enable autoreload in set_pwm

The following commit has been merged into the timers/core branch of tip:

Commit-ID: 02e6d546e3bdc1a8a764343cd1ba354da07e8623
Gitweb: https://git.kernel.org/tip/02e6d546e3bdc1a8a764343cd1ba354da07e8623
Author: Lokesh Vutla <[email protected]>
AuthorDate: Thu, 05 Mar 2020 13:57:15 +05:30
Committer: Daniel Lezcano <[email protected]>
CommitterDate: Mon, 16 Mar 2020 12:40:51 +01:00

clocksource/drivers/timer-ti-dm: Enable autoreload in set_pwm

dm timer ops set_load() api allows to configure the load value and to
set the auto reload feature. But auto reload feature is independent of
load value and should be part of configuring pwm. This way pwm can be
disabled by disabling auto reload feature using set_pwm() so that the
current pwm cycle will be completed. Else pwm disabling causes the
cycle to be stopped abruptly.

Signed-off-by: Lokesh Vutla <[email protected]>
Acked-by: Tony Lindgren <[email protected]>
Signed-off-by: Daniel Lezcano <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
drivers/clocksource/timer-ti-dm.c | 16 +++++-----------
drivers/pwm/pwm-omap-dmtimer.c | 8 +++++---
include/linux/platform_data/dmtimer-omap.h | 5 ++---
3 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
index 73ac73e..f5c73eb 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -562,21 +562,13 @@ static int omap_dm_timer_stop(struct omap_dm_timer *timer)
return 0;
}

-static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+static int omap_dm_timer_set_load(struct omap_dm_timer *timer,
unsigned int load)
{
- u32 l;
-
if (unlikely(!timer))
return -EINVAL;

omap_dm_timer_enable(timer);
- l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
- if (autoreload)
- l |= OMAP_TIMER_CTRL_AR;
- else
- l &= ~OMAP_TIMER_CTRL_AR;
- omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);

omap_dm_timer_disable(timer);
@@ -605,7 +597,7 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
}

static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
- int toggle, int trigger)
+ int toggle, int trigger, int autoreload)
{
u32 l;

@@ -615,12 +607,14 @@ static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
- OMAP_TIMER_CTRL_PT | (0x03 << 10));
+ OMAP_TIMER_CTRL_PT | (0x03 << 10) | OMAP_TIMER_CTRL_AR);
if (def_on)
l |= OMAP_TIMER_CTRL_SCPWM;
if (toggle)
l |= OMAP_TIMER_CTRL_PT;
l |= trigger << 10;
+ if (autoreload)
+ l |= OMAP_TIMER_CTRL_AR;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);

omap_dm_timer_disable(timer);
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 88a3c56..9e4378d 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -183,7 +183,7 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
if (timer_active)
omap->pdata->stop(omap->dm_timer);

- omap->pdata->set_load(omap->dm_timer, true, load_value);
+ omap->pdata->set_load(omap->dm_timer, load_value);
omap->pdata->set_match(omap->dm_timer, true, match_value);

dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n",
@@ -192,7 +192,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
omap->pdata->set_pwm(omap->dm_timer,
pwm_get_polarity(pwm) == PWM_POLARITY_INVERSED,
true,
- PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+ PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE,
+ true);

/* If config was called while timer was running it must be reenabled. */
if (timer_active)
@@ -222,7 +223,8 @@ static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
omap->pdata->set_pwm(omap->dm_timer,
polarity == PWM_POLARITY_INVERSED,
true,
- PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+ PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE,
+ true);
mutex_unlock(&omap->mutex);

return 0;
diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index 3173b7b..95d852a 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -30,12 +30,11 @@ struct omap_dm_timer_ops {
int (*stop)(struct omap_dm_timer *timer);
int (*set_source)(struct omap_dm_timer *timer, int source);

- int (*set_load)(struct omap_dm_timer *timer, int autoreload,
- unsigned int value);
+ int (*set_load)(struct omap_dm_timer *timer, unsigned int value);
int (*set_match)(struct omap_dm_timer *timer, int enable,
unsigned int match);
int (*set_pwm)(struct omap_dm_timer *timer, int def_on,
- int toggle, int trigger);
+ int toggle, int trigger, int autoreload);
int (*get_pwm_status)(struct omap_dm_timer *timer);
int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler);

2020-03-30 13:25:59

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v3 6/6] clocksource: timer-ti-dm: Enable autoreload in set_pwm

On Thu, Mar 05, 2020 at 01:57:15PM +0530, Lokesh Vutla wrote:
> dm timer ops set_load() api allows to configure the load value and to
> set the auto reload feature. But auto reload feature is independent of
> load value and should be part of configuring pwm. This way pwm can be
> disabled by disabling auto reload feature using set_pwm() so that the
> current pwm cycle will be completed. Else pwm disabling causes the
> cycle to be stopped abruptly.
>
> Signed-off-by: Lokesh Vutla <[email protected]>
> ---
> drivers/clocksource/timer-ti-dm.c | 16 +++++-----------
> drivers/pwm/pwm-omap-dmtimer.c | 8 +++++---
> include/linux/platform_data/dmtimer-omap.h | 5 ++---
> 3 files changed, 12 insertions(+), 17 deletions(-)

Acked-by: Thierry Reding <[email protected]>


Attachments:
(No filename) (820.00 B)
signature.asc (849.00 B)
Download all attachments