static int exynos_tmu_initialize()

in samsung/exynos_tmu.c [259:330]


static int exynos_tmu_initialize(struct platform_device *pdev)
{
	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
	struct thermal_zone_device *tzd = data->tzd;
	const struct thermal_trip * const trips =
		of_thermal_get_trip_points(tzd);
	unsigned int status;
	int ret = 0, temp, hyst;

	if (!trips) {
		dev_err(&pdev->dev,
			"Cannot get trip points from device tree!\n");
		return -ENODEV;
	}

	if (data->soc != SOC_ARCH_EXYNOS5433) /* FIXME */
		ret = tzd->ops->get_crit_temp(tzd, &temp);
	if (ret) {
		dev_err(&pdev->dev,
			"No CRITICAL trip point defined in device tree!\n");
		goto out;
	}

	if (of_thermal_get_ntrips(tzd) > data->ntrip) {
		dev_info(&pdev->dev,
			 "More trip points than supported by this TMU.\n");
		dev_info(&pdev->dev,
			 "%d trip points should be configured in polling mode.\n",
			 (of_thermal_get_ntrips(tzd) - data->ntrip));
	}

	mutex_lock(&data->lock);
	clk_enable(data->clk);
	if (!IS_ERR(data->clk_sec))
		clk_enable(data->clk_sec);

	status = readb(data->base + EXYNOS_TMU_REG_STATUS);
	if (!status) {
		ret = -EBUSY;
	} else {
		int i, ntrips =
			min_t(int, of_thermal_get_ntrips(tzd), data->ntrip);

		data->tmu_initialize(pdev);

		/* Write temperature code for rising and falling threshold */
		for (i = 0; i < ntrips; i++) {
			/* Write temperature code for rising threshold */
			ret = tzd->ops->get_trip_temp(tzd, i, &temp);
			if (ret)
				goto err;
			temp /= MCELSIUS;
			data->tmu_set_trip_temp(data, i, temp);

			/* Write temperature code for falling threshold */
			ret = tzd->ops->get_trip_hyst(tzd, i, &hyst);
			if (ret)
				goto err;
			hyst /= MCELSIUS;
			data->tmu_set_trip_hyst(data, i, temp, hyst);
		}

		data->tmu_clear_irqs(data);
	}
err:
	clk_disable(data->clk);
	mutex_unlock(&data->lock);
	if (!IS_ERR(data->clk_sec))
		clk_disable(data->clk_sec);
out:
	return ret;
}