Message ID | 20190627211115.21138-3-digetx@gmail.com |
---|---|
State | Changes Requested |
Headers | show |
Series | More improvements for Tegra30 devfreq driver | expand |
>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 <thierry.reding@gmail.com> >Signed-off-by: Dmitry Osipenko <digetx@gmail.com> >--- > 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
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 <thierry.reding@gmail.com> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> >> --- >> 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.
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);
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 <thierry.reding@gmail.com> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> --- drivers/devfreq/tegra30-devfreq.c | 43 ++++++++++++++++--------------- 1 file changed, 22 insertions(+), 21 deletions(-)