in tegra30-devfreq.c [543:597]
static int tegra_actmon_resume(struct tegra_devfreq *tegra)
{
unsigned int i;
int err;
if (!tegra->devfreq->profile->polling_ms || !tegra->started)
return 0;
actmon_writel(tegra, tegra->devfreq->profile->polling_ms - 1,
ACTMON_GLB_PERIOD_CTRL);
/*
* CLK notifications are needed in order to reconfigure the upper
* consecutive watermark in accordance to the actual clock rate
* to avoid unnecessary upper interrupts.
*/
err = clk_notifier_register(tegra->emc_clock,
&tegra->clk_rate_change_nb);
if (err) {
dev_err(tegra->devfreq->dev.parent,
"Failed to register rate change notifier\n");
return err;
}
tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ;
for (i = 0; i < ARRAY_SIZE(tegra->devices); i++)
tegra_actmon_configure_device(tegra, &tegra->devices[i]);
/*
* We are estimating CPU's memory bandwidth requirement based on
* amount of memory accesses and system's load, judging by CPU's
* frequency. We also don't want to receive events about CPU's
* frequency transaction when governor is stopped, hence notifier
* is registered dynamically.
*/
err = cpufreq_register_notifier(&tegra->cpu_rate_change_nb,
CPUFREQ_TRANSITION_NOTIFIER);
if (err) {
dev_err(tegra->devfreq->dev.parent,
"Failed to register rate change notifier: %d\n", err);
goto err_stop;
}
enable_irq(tegra->irq);
return 0;
err_stop:
tegra_actmon_stop_devices(tegra);
clk_notifier_unregister(tegra->emc_clock, &tegra->clk_rate_change_nb);
return err;
}