예제 #1
0
static int exynos_tmu_probe(struct platform_device *pdev)
{
	struct exynos_tmu_data *data;
	struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
	int ret, i;

	if (!pdata)
		pdata = exynos_get_driver_data(pdev);

	if (!pdata) {
		dev_err(&pdev->dev, "No platform init data supplied.\n");
		return -ENODEV;
	}
	data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
					GFP_KERNEL);
	if (!data) {
		dev_err(&pdev->dev, "Failed to allocate driver structure\n");
		return -ENOMEM;
	}

	data->irq = platform_get_irq(pdev, 0);
	if (data->irq < 0) {
		dev_err(&pdev->dev, "Failed to get platform irq\n");
		return data->irq;
	}

	INIT_WORK(&data->irq_work, exynos_tmu_work);

	data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!data->mem) {
		dev_err(&pdev->dev, "Failed to get platform resource\n");
		return -ENOENT;
	}

	data->base = devm_ioremap_resource(&pdev->dev, data->mem);
	if (IS_ERR(data->base))
		return PTR_ERR(data->base);

	ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
		IRQF_TRIGGER_RISING, "exynos-tmu", data);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
		return ret;
	}

	data->clk = clk_get(NULL, "tmu_apbif");
	if (IS_ERR(data->clk)) {
		dev_err(&pdev->dev, "Failed to get clock\n");
		return  PTR_ERR(data->clk);
	}

	if (pdata->type == SOC_ARCH_EXYNOS ||
				pdata->type == SOC_ARCH_EXYNOS4210)
		data->soc = pdata->type;
	else {
		ret = -EINVAL;
		dev_err(&pdev->dev, "Platform not supported\n");
		goto err_clk;
	}

	data->pdata = pdata;
	platform_set_drvdata(pdev, data);
	mutex_init(&data->lock);

	ret = exynos_tmu_initialize(pdev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to initialize TMU\n");
		goto err_clk;
	}

	exynos_tmu_control(pdev, true);

	/* Register the sensor with thermal management interface */
	(&exynos_sensor_conf)->private_data = data;
	exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
			pdata->trigger_level1_en + pdata->trigger_level2_en +
			pdata->trigger_level3_en;

	for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
		exynos_sensor_conf.trip_data.trip_val[i] =
			pdata->threshold + pdata->trigger_levels[i];

	exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;

	exynos_sensor_conf.cooling_data.freq_clip_count =
						pdata->freq_tab_count;
	for (i = 0; i < pdata->freq_tab_count; i++) {
		exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
					pdata->freq_tab[i].freq_clip_max;
		exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
					pdata->freq_tab[i].temp_level;
	}

	ret = exynos_register_thermal(&exynos_sensor_conf);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register thermal interface\n");
		goto err_clk;
	}

	ret = create_emulation_sysfs(&pdev->dev);
	if (ret)
		dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n");

	return 0;
err_clk:
	platform_set_drvdata(pdev, NULL);
	clk_put(data->clk);
	return ret;
}
예제 #2
0
static int __devinit exynos_tmu_probe(struct platform_device *pdev)
{
	struct exynos_tmu_data *data;
	struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
	int ret, i;

	if (!pdata)
		pdata = exynos_get_driver_data(pdev);

	if (!pdata) {
		dev_err(&pdev->dev, "No platform init data supplied.\n");
		return -ENODEV;
	}
	data = kzalloc(sizeof(struct exynos_tmu_data), GFP_KERNEL);
	if (!data) {
		dev_err(&pdev->dev, "Failed to allocate driver structure\n");
		return -ENOMEM;
	}

	INIT_WORK(&data->irq_work, exynos_tmu_work);

	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		data->irq[i] = platform_get_irq(pdev, i);
		if (data->irq[i] < 0) {
			ret = data->irq[i];
			dev_err(&pdev->dev, "Failed to get platform irq\n");
			goto err_free;
		}

		data->mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
		if (!data->mem[i]) {
			ret = -ENOENT;
			dev_err(&pdev->dev, "Failed to get platform resource\n");
			goto err_free;
		}

		data->mem[i] = request_mem_region(data->mem[i]->start,
				resource_size(data->mem[i]), pdev->name);
		if (!data->mem[i]) {
			ret = -ENODEV;
			dev_err(&pdev->dev, "Failed to request memory region\n");
			goto err_free;
		}

		data->base[i] = ioremap(data->mem[i]->start, resource_size(data->mem[i]));
		if (!data->base[i]) {
			ret = -ENODEV;
			dev_err(&pdev->dev, "Failed to ioremap memory\n");
			goto err_mem_region;
		}

		ret = request_irq(data->irq[i], exynos_tmu_irq,
				IRQF_TRIGGER_RISING, "exynos-tmu", data);
		if (ret) {
			dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq[i]);
			goto err_io_remap;
		}
	}

	data->clk = clk_get(NULL, "tmu_apbif");
	if (IS_ERR(data->clk)) {
		ret = PTR_ERR(data->clk);
		dev_err(&pdev->dev, "Failed to get clock\n");
		goto err_irq;
	}

	if (pdata->type == SOC_ARCH_EXYNOS5 ||
				pdata->type == SOC_ARCH_EXYNOS4)
		data->soc = pdata->type;
	else {
		ret = -EINVAL;
		dev_err(&pdev->dev, "Platform not supported\n");
		goto err_clk;
	}

	data->pdata = pdata;
	platform_set_drvdata(pdev, data);
	mutex_init(&data->lock);

	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		ret = exynos_tmu_initialize(pdev, i);
		if (ret) {
			dev_err(&pdev->dev, "Failed to initialize TMU[%d]\n", i);
			goto err_clk;
		}

		exynos_tmu_control(pdev, i, true);
	}

	/*Register the sensor with thermal management interface*/
	(&exynos_sensor_conf)->private_data = data;
	exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
			pdata->trigger_level1_en + pdata->trigger_level2_en +
			pdata->trigger_level3_en;

	for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++) {
		exynos_sensor_conf.trip_data.trip_val[i] =
			pdata->threshold + pdata->trigger_levels[i];
		exynos_sensor_conf.trip_data.boost_trip_val[i] =
			pdata->threshold + pdata->boost_trigger_levels[i];
	}

	exynos_sensor_conf.cooling_data.freq_clip_count =
						pdata->freq_tab_count;
	exynos_sensor_conf.cooling_data.boost_mode = 0;

	for (i = 0; i < pdata->freq_tab_count; i++) {
		exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
					pdata->freq_tab[i].freq_clip_max;
		exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
					pdata->freq_tab[i].temp_level;
		exynos_sensor_conf.cooling_data.freq_data[i].mask_val = cpu_all_mask;
		exynos_sensor_conf.cooling_data.size[i] =
					pdata->size[i];

		exynos_sensor_conf.cooling_data.boost_temps[i] =
					pdata->boost_temps[i];
	}

	register_pm_notifier(&exynos_pm_nb);

	ret = exynos_register_thermal(&exynos_sensor_conf);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register thermal interface\n");
		goto err_clk;
	}

	th_zone->exynos4_dev = pdev;

	ret = sysfs_create_group(&pdev->dev.kobj, &exynos_thermal_sensor_attr_group);
	if (ret)
		dev_err(&pdev->dev, "cannot create thermal sensor attributes\n");

	return 0;
err_clk:
	platform_set_drvdata(pdev, NULL);
	clk_put(data->clk);
err_irq:
	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		if (data->irq[i])
			free_irq(data->irq[i], data);
	}
err_io_remap:
	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		if (data->base[i])
			iounmap(data->base[i]);
	}
err_mem_region:
	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		if (data->mem[i])
			release_mem_region(data->mem[i]->start, resource_size(data->mem[i]));
	}
err_free:
	kfree(data);

	return ret;
}
static int __devinit exynos_tmu_probe(struct platform_device *pdev)
{
	struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
	int ret, i, count = 0;
	int trigger_level_en[TRIP_EN_COUNT];

	if (!pdata)
		pdata = exynos_get_driver_data(pdev);

	if (!pdata) {
		dev_err(&pdev->dev, "No platform init data supplied.\n");
		return -ENODEV;
	}
	tmudata = kzalloc(sizeof(struct exynos_tmu_data), GFP_KERNEL);
	if (!tmudata) {
		dev_err(&pdev->dev, "Failed to allocate driver structure\n");
		return -ENOMEM;
	}

	INIT_WORK(&tmudata->irq_work, exynos_tmu_work);

#ifndef CONFIG_ARM_TRUSTZONE
	/* ioremap for drex base address */
	exynos4_base_drex0 = ioremap(EXYNOS4_PA_DMC0_4X12, SZ_64K);
	exynos4_base_drex1 = ioremap(EXYNOS4_PA_DMC1_4X12, SZ_64K);
	if(!exynos4_base_drex0 || !exynos4_base_drex1) {
		ret = -ENOMEM;
		goto err_drex_ioremap;
	}
#endif

	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		tmudata->irq[i] = platform_get_irq(pdev, i);
		if (tmudata->irq[i] < 0) {
			ret = tmudata->irq[i];
			dev_err(&pdev->dev, "Failed to get platform irq\n");
			goto err_get_resource;
		}

		tmudata->mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
		if (!tmudata->mem[i]) {
			ret = -ENOENT;
			dev_err(&pdev->dev, "Failed to get platform resource\n");
			goto err_get_resource;
		}

		tmudata->mem[i] = request_mem_region(tmudata->mem[i]->start,
				resource_size(tmudata->mem[i]), pdev->name);
		if (!tmudata->mem[i]) {
			ret = -ENODEV;
			dev_err(&pdev->dev, "Failed to request memory region\n");
			goto err_mem_region;
		}

		tmudata->base[i] = ioremap(tmudata->mem[i]->start, resource_size(tmudata->mem[i]));
		if (!tmudata->base[i]) {
			ret = -ENODEV;
			dev_err(&pdev->dev, "Failed to ioremap memory\n");
			goto err_io_remap;
		}

		ret = request_irq(tmudata->irq[i], exynos_tmu_irq,
				IRQF_TRIGGER_RISING, "exynos-tmu", tmudata);
		if (ret) {
			dev_err(&pdev->dev, "Failed to request irq: %d\n", tmudata->irq[i]);
			goto err_irq;
		}
	}

	tmudata->clk = clk_get(NULL, "tmu");
	if (IS_ERR(tmudata->clk)) {
		ret = PTR_ERR(tmudata->clk);
		dev_err(&pdev->dev, "Failed to get clock\n");
		goto err_clk;
	}

	if (pdata->type == SOC_ARCH_EXYNOS5 ||
				pdata->type == SOC_ARCH_EXYNOS4)
		tmudata->soc = pdata->type;
	else {
		ret = -EINVAL;
		dev_err(&pdev->dev, "Platform not supported\n");
		goto err_soc_type;
	}

	tmudata->pdata = pdata;
	platform_set_drvdata(pdev, tmudata);
	mutex_init(&tmudata->lock);

	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		ret = exynos_tmu_initialize(pdev, i);
		if (ret) {
			dev_err(&pdev->dev, "Failed to initialize TMU[%d]\n", i);
			goto err_tmu;
		}

		exynos_tmu_control(pdev, i, true);
	}

	/*Register the sensor with thermal management interface*/
	(&exynos_sensor_conf)->private_data = tmudata;
	exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
			pdata->trigger_level1_en + pdata->trigger_level2_en +
			pdata->trigger_level3_en;

	trigger_level_en[0] = pdata->trigger_level0_en;
	trigger_level_en[1] = pdata->trigger_level1_en;
	trigger_level_en[2] = pdata->trigger_level2_en;
	trigger_level_en[3] = pdata->trigger_level3_en;

	for (i = 0; i < TRIP_EN_COUNT; i++) {
		if (trigger_level_en[i]) {
			exynos_sensor_conf.trip_data.trip_val[count] =
				pdata->threshold + pdata->trigger_levels[i];
			count++;
		}
	}

	exynos_sensor_conf.cooling_data.freq_clip_count =
						pdata->freq_tab_count;

	for (i = 0; i <= THERMAL_TRIP_CRITICAL; i++)
		exynos_sensor_conf.cooling_data.size[i] = pdata->size[i];

	for (i = 0; i < pdata->freq_tab_count; i++) {
		exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
					pdata->freq_tab[i].freq_clip_max;
		exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
					pdata->freq_tab[i].temp_level;
		exynos_sensor_conf.cooling_data.freq_data[i].mask_val = cpu_all_mask;
	}

	register_pm_notifier(&exynos_pm_nb);

	ret = exynos_register_thermal(&exynos_sensor_conf);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register thermal interface\n");
		goto err_register;
	}

	th_zone->exynos4_dev = pdev;

	/* For low temperature compensation when boot time */
	exynos_tmu_call_notifier(1, 0);
	
#ifdef CONFIG_EXYNOS4_EXPORT_TEMP
	tmu_curr_temperature = 35; // seems reasonable :-|
#endif

	return 0;

err_register:
	unregister_pm_notifier(&exynos_pm_nb);
err_tmu:
	platform_set_drvdata(pdev, NULL);
err_soc_type:
	clk_put(tmudata->clk);
err_clk:
	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		if (tmudata->irq[i])
			free_irq(tmudata->irq[i], tmudata);
	}
err_irq:
	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		if (tmudata->base[i])
			iounmap(tmudata->base[i]);
	}
err_io_remap:
	for (i = 0; i < EXYNOS_TMU_COUNT; i++) {
		if (tmudata->mem[i])
			release_mem_region(tmudata->mem[i]->start, resource_size(tmudata->mem[i]));
	}
err_mem_region:
err_get_resource:
#ifndef  CONFIG_ARM_TRUSTZONE
	iounmap(exynos4_base_drex0);
	iounmap(exynos4_base_drex1);
err_drex_ioremap:
	kfree(tmudata);
#endif

	return ret;
}