2019-06-27 21:12:56

by Dmitry Osipenko

[permalink] [raw]
Subject: [PATCH v3 02/22] PM / devfreq: tegra30: Keep interrupt disabled while governor is stopped

There is no real need to keep interrupt always-enabled, will be nicer
to keep it disabled while governor is inactive.

Suggested-by: Thierry Reding <[email protected]>
Signed-off-by: Dmitry Osipenko <[email protected]>
---
drivers/devfreq/tegra30-devfreq.c | 43 ++++++++++++++++---------------
1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index a27300f40b0b..5e2b133babdd 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -11,6 +11,7 @@
#include <linux/devfreq.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/irq.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
@@ -416,8 +417,6 @@ static void tegra_actmon_start(struct tegra_devfreq *tegra)
{
unsigned int i;

- disable_irq(tegra->irq);
-
actmon_writel(tegra, ACTMON_SAMPLING_PERIOD - 1,
ACTMON_GLB_PERIOD_CTRL);

@@ -442,8 +441,6 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
}

actmon_write_barrier(tegra);
-
- enable_irq(tegra->irq);
}

static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
@@ -552,6 +549,12 @@ static int tegra_governor_event_handler(struct devfreq *devfreq,
{
struct tegra_devfreq *tegra = dev_get_drvdata(devfreq->dev.parent);

+ /*
+ * Couple device with the governor early as it is needed at
+ * the moment of governor's start (used by ISR).
+ */
+ tegra->devfreq = devfreq;
+
switch (event) {
case DEVFREQ_GOV_START:
devfreq_monitor_start(devfreq);
@@ -586,10 +589,11 @@ static struct devfreq_governor tegra_devfreq_governor = {

static int tegra_devfreq_probe(struct platform_device *pdev)
{
- struct tegra_devfreq *tegra;
struct tegra_devfreq_device *dev;
- unsigned int i;
+ struct tegra_devfreq *tegra;
+ struct devfreq *devfreq;
unsigned long rate;
+ unsigned int i;
int err;

tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
@@ -625,6 +629,16 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
}
tegra->irq = err;

+ irq_set_status_flags(tegra->irq, IRQ_NOAUTOEN);
+
+ err = devm_request_threaded_irq(&pdev->dev, tegra->irq, NULL,
+ actmon_thread_isr, IRQF_ONESHOT,
+ "tegra-devfreq", tegra);
+ if (err) {
+ dev_err(&pdev->dev, "Interrupt request failed: %d\n", err);
+ return err;
+ }
+
reset_control_assert(tegra->reset);

err = clk_prepare_enable(tegra->clock);
@@ -672,28 +686,15 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
}

tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
- tegra->devfreq = devfreq_add_device(&pdev->dev,
- &tegra_devfreq_profile,
- "tegra_actmon",
- NULL);
+ devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
+ "tegra_actmon", NULL);
if (IS_ERR(tegra->devfreq)) {
err = PTR_ERR(tegra->devfreq);
goto remove_governor;
}

- err = devm_request_threaded_irq(&pdev->dev, tegra->irq, NULL,
- actmon_thread_isr, IRQF_ONESHOT,
- "tegra-devfreq", tegra);
- if (err) {
- dev_err(&pdev->dev, "Interrupt request failed: %d\n", err);
- goto remove_devfreq;
- }
-
return 0;

-remove_devfreq:
- devfreq_remove_device(tegra->devfreq);
-
remove_governor:
devfreq_remove_governor(&tegra_devfreq_governor);

--
2.22.0


2019-06-28 06:49:35

by MyungJoo Ham

[permalink] [raw]
Subject: RE: [PATCH v3 02/22] PM / devfreq: tegra30: Keep interrupt disabled while governor is stopped

>There is no real need to keep interrupt always-enabled, will be nicer
>to keep it disabled while governor is inactive.
>
>Suggested-by: Thierry Reding <[email protected]>
>Signed-off-by: Dmitry Osipenko <[email protected]>
>---
> drivers/devfreq/tegra30-devfreq.c | 43 ++++++++++++++++---------------
> 1 file changed, 22 insertions(+), 21 deletions(-)
>
>diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
>index a27300f40b0b..5e2b133babdd 100644
>--- a/drivers/devfreq/tegra30-devfreq.c
>+++ b/drivers/devfreq/tegra30-devfreq.c
[]
>@@ -416,8 +417,6 @@ static void tegra_actmon_start(struct tegra_devfreq *tegra)
> {
> unsigned int i;
>
>- disable_irq(tegra->irq);
>-
> actmon_writel(tegra, ACTMON_SAMPLING_PERIOD - 1,
> ACTMON_GLB_PERIOD_CTRL);
>

I think this has nothing to do with
"keep it disabled while governor is inactive."

And this looks dangerous because it disables the safety measure
of disabling interrupt while you touch some looking-critical registers.
Anyway, as I do not know the internals of Tegra SoC, I cannot sure.

Cheers,
MyungJoo


2019-06-28 07:14:12

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: [PATCH v3 02/22] PM / devfreq: tegra30: Keep interrupt disabled while governor is stopped

28.06.2019 9:48, MyungJoo Ham пишет:
>> There is no real need to keep interrupt always-enabled, will be nicer
>> to keep it disabled while governor is inactive.
>>
>> Suggested-by: Thierry Reding <[email protected]>
>> Signed-off-by: Dmitry Osipenko <[email protected]>
>> ---
>> drivers/devfreq/tegra30-devfreq.c | 43 ++++++++++++++++---------------
>> 1 file changed, 22 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
>> index a27300f40b0b..5e2b133babdd 100644
>> --- a/drivers/devfreq/tegra30-devfreq.c
>> +++ b/drivers/devfreq/tegra30-devfreq.c
> []
>> @@ -416,8 +417,6 @@ static void tegra_actmon_start(struct tegra_devfreq *tegra)
>> {
>> unsigned int i;
>>
>> - disable_irq(tegra->irq);
>> -
>> actmon_writel(tegra, ACTMON_SAMPLING_PERIOD - 1,
>> ACTMON_GLB_PERIOD_CTRL);
>>
>
> I think this has nothing to do with
> "keep it disabled while governor is inactive."
>
> And this looks dangerous because it disables the safety measure
> of disabling interrupt while you touch some looking-critical registers.
> Anyway, as I do not know the internals of Tegra SoC, I cannot sure.

Sorry, I'm not sure what do you mean .. Before this patch we were disabling the
interrupt on a start of programming hardware configuration, now we don't needed to
disable the interrupt because it is already in the disabled state at that moment
since we're now requesting interrupt in the *disabled* state during of the driver's
probe using IRQ_NOAUTOEN flag.