static int tegra_actmon_resume()

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;
}