Пример #1
0
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
{
	int trips = 0;
	int result;
	acpi_status status;
	int i;

	if (tz->trips.critical.flags.valid)
		trips++;

	if (tz->trips.hot.flags.valid)
		trips++;

	if (tz->trips.passive.flags.valid)
		trips++;

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
			tz->trips.active[i].flags.valid; i++, trips++);

	if (tz->trips.passive.flags.valid)
		tz->thermal_zone =
			thermal_zone_device_register("acpitz", trips, 0, tz,
						&acpi_thermal_zone_ops, NULL,
						     tz->trips.passive.tsp*100,
						     tz->polling_frequency*100);
	else
		tz->thermal_zone =
			thermal_zone_device_register("acpitz", trips, 0, tz,
						&acpi_thermal_zone_ops, NULL,
						0, tz->polling_frequency*100);
	if (IS_ERR(tz->thermal_zone))
		return -ENODEV;

	result = sysfs_create_link(&tz->device->dev.kobj,
				   &tz->thermal_zone->device.kobj, "thermal_zone");
	if (result)
		return result;

	result = sysfs_create_link(&tz->thermal_zone->device.kobj,
				   &tz->device->dev.kobj, "device");
	if (result)
		return result;

	status = acpi_attach_data(tz->device->handle,
				  acpi_bus_private_data_handler,
				  tz->thermal_zone);
	if (ACPI_FAILURE(status)) {
		printk(KERN_ERR PREFIX
				"Error attaching device data\n");
		return -ENODEV;
	}

	tz->tz_enabled = 1;

	dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
		 tz->thermal_zone->id);
	return 0;
}
Пример #2
0
static int bcm2835_thermal_probe(struct platform_device *pdev)
{
	struct device_node *fw_np;
	struct rpi_firmware *fw;
	struct thermal_zone_device *tz;

	fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
/* Remove comment when booting without Device Tree is no longer supported
	if (!fw_np) {
		dev_err(&pdev->dev, "Missing firmware node\n");
		return -ENOENT;
	}
*/
	fw = rpi_firmware_get(fw_np);
	if (!fw)
		return -EPROBE_DEFER;

	tz = thermal_zone_device_register("bcm2835_thermal", 1, 0, fw, &ops,
					  NULL, 0, 0);
	if (IS_ERR(tz)) {
		dev_err(&pdev->dev, "Failed to register the thermal device\n");
		return PTR_ERR(tz);
	}

	platform_set_drvdata(pdev, tz);

	return 0;
}
Пример #3
0
static int int3403_sensor_add(struct int3403_priv *priv)
{
	int result = 0;
	acpi_status status;
	struct int3403_sensor *obj;
	unsigned long long trip_cnt;
	int trip_mask = 0;

	obj = devm_kzalloc(&priv->pdev->dev, sizeof(*obj), GFP_KERNEL);
	if (!obj)
		return -ENOMEM;

	priv->priv = obj;

	status = acpi_evaluate_integer(priv->adev->handle, "PATC", NULL,
						&trip_cnt);
	if (ACPI_FAILURE(status))
		trip_cnt = 0;

	if (trip_cnt) {
		/* We have to cache, thresholds can't be readback */
		obj->thresholds = devm_kzalloc(&priv->pdev->dev,
					sizeof(*obj->thresholds) * trip_cnt,
					GFP_KERNEL);
		if (!obj->thresholds) {
			result = -ENOMEM;
			goto err_free_obj;
		}
		trip_mask = BIT(trip_cnt) - 1;
	}

	obj->psv_trip_id = -1;
	if (!sys_get_trip_psv(priv->adev, &obj->psv_temp))
		obj->psv_trip_id = trip_cnt++;

	obj->crit_trip_id = -1;
	if (!sys_get_trip_crt(priv->adev, &obj->crit_temp))
		obj->crit_trip_id = trip_cnt++;

	obj->tzone = thermal_zone_device_register(acpi_device_bid(priv->adev),
				trip_cnt, trip_mask, priv, &tzone_ops,
				&int3403_thermal_params, 0, 0);
	if (IS_ERR(obj->tzone)) {
		result = PTR_ERR(obj->tzone);
		obj->tzone = NULL;
		goto err_free_obj;
	}

	result = acpi_install_notify_handler(priv->adev->handle,
			ACPI_DEVICE_NOTIFY, int3403_notify,
			(void *)priv);
	if (result)
		goto err_free_obj;

	return 0;

 err_free_obj:
	thermal_zone_device_unregister(obj->tzone);
	return result;
}
/* Register with the in-kernel thermal management */
int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
{
	int ret;
	struct cpumask mask_val;
	struct exynos_thermal_zone *th_zone;

	if (!sensor_conf || !sensor_conf->read_temperature) {
		pr_err("Temperature sensor not initialised\n");
		return -EINVAL;
	}

	th_zone = devm_kzalloc(sensor_conf->dev,
				sizeof(struct exynos_thermal_zone), GFP_KERNEL);
	if (!th_zone)
		return -ENOMEM;

	th_zone->sensor_conf = sensor_conf;
	/*
	 * TODO: 1) Handle multiple cooling devices in a thermal zone
	 *	 2) Add a flag/name in cooling info to map to specific
	 *	 sensor
	 */
	if (sensor_conf->cooling_data.freq_clip_count > 0) {
		cpumask_set_cpu(0, &mask_val);
		th_zone->cool_dev[th_zone->cool_dev_size] =
					cpufreq_cooling_register(&mask_val);
		if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) {
			dev_err(sensor_conf->dev,
				"Failed to register cpufreq cooling device\n");
			ret = -EINVAL;
			goto err_unregister;
		}
		th_zone->cool_dev_size++;
	}

	th_zone->therm_dev = thermal_zone_device_register(
			sensor_conf->name, sensor_conf->trip_data.trip_count,
			0, th_zone, &exynos_dev_ops, NULL, 0,
			sensor_conf->trip_data.trigger_falling ? 0 :
			IDLE_INTERVAL);

	if (IS_ERR(th_zone->therm_dev)) {
		dev_err(sensor_conf->dev,
			"Failed to register thermal zone device\n");
		ret = PTR_ERR(th_zone->therm_dev);
		goto err_unregister;
	}
	th_zone->mode = THERMAL_DEVICE_ENABLED;
	sensor_conf->pzone_data = th_zone;

	dev_info(sensor_conf->dev,
		"Exynos: Thermal zone(%s) registered\n", sensor_conf->name);

	return 0;

err_unregister:
	exynos_unregister_thermal(sensor_conf);
	return ret;
}
Пример #5
0
static int omap3_thermal_probe(struct platform_device *pdev)
{
    struct thermal_zone_device *omap3_thermal = NULL;
    struct omap3_thermal_dev *tdev;
    int ret = 0;
    struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    if (!stres) {
        dev_err(&pdev->dev, "memory resource missing\n");
        return -ENODEV;
    }

    tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
    if (!tdev)
        return -ENOMEM;

    tdev->dev = &pdev->dev;

    if (cpu_is_omap3630()) {
        tdev->bgap_soc_mask = BIT(9);
        tdev->bgap_eocz_mask = BIT(8);
        tdev->adc_to_temp = omap3630_adc_to_temp;
    } else if (cpu_is_omap34xx()) {
        tdev->bgap_soc_mask = BIT(8);
        tdev->bgap_eocz_mask = BIT(7);
        tdev->adc_to_temp = omap3530_adc_to_temp;
    } else {
        dev_err(&pdev->dev, "not OMAP3 family\n");
        return -ENODEV;
    }

    tdev->thermal_base = devm_ioremap(&pdev->dev, stres->start,
                                      resource_size(stres));
    if (!tdev->thermal_base) {
        dev_err(&pdev->dev, "ioremap failed\n");
        return -ENOMEM;
    }

    pm_runtime_enable(&pdev->dev);
    pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
    pm_runtime_use_autosuspend(&pdev->dev);

    omap3_thermal = thermal_zone_device_register("omap3-thermal", 0,
                    tdev, &omap3_thermal_ops, 0, 0, 0, 0);
    if (!omap3_thermal) {
        dev_err(&pdev->dev, "thermal zone device is NULL\n");
        ret = -EINVAL;
        goto put_pm;
    }

    platform_set_drvdata(pdev, omap3_thermal);

    return 0;

put_pm:
    pm_runtime_disable(&pdev->dev);
    return ret;
}
Пример #6
0
static int spear_thermal_probe(struct platform_device *pdev)
{
	struct thermal_zone_device *spear_thermal = NULL;
	struct spear_thermal_dev *stdev;
	struct device_node *np = pdev->dev.of_node;
	struct resource *res;
	int ret = 0, val;

	if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
		dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
		return -EINVAL;
	}

	stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
	if (!stdev)
		return -ENOMEM;

	/* Enable thermal sensor */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	stdev->thermal_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(stdev->thermal_base))
		return PTR_ERR(stdev->thermal_base);

	stdev->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(stdev->clk)) {
		dev_err(&pdev->dev, "Can't get clock\n");
		return PTR_ERR(stdev->clk);
	}

	ret = clk_enable(stdev->clk);
	if (ret) {
		dev_err(&pdev->dev, "Can't enable clock\n");
		return ret;
	}

	stdev->flags = val;
	writel_relaxed(stdev->flags, stdev->thermal_base);

	spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
				stdev, &ops, NULL, 0, 0);
	if (IS_ERR(spear_thermal)) {
		dev_err(&pdev->dev, "thermal zone device is NULL\n");
		ret = PTR_ERR(spear_thermal);
		goto disable_clk;
	}

	platform_set_drvdata(pdev, spear_thermal);

	dev_info(&spear_thermal->device, "Thermal Sensor Loaded at: 0x%p.\n",
			stdev->thermal_base);

	return 0;

disable_clk:
	clk_disable(stdev->clk);

	return ret;
}
/* Register with the in-kernel thermal management */
static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
{
	int ret, count, tab_size, pos = 0;
	struct freq_clip_table *tab_ptr, *clip_data;

	if (!sensor_conf || !sensor_conf->read_temperature) {
		pr_err("Temperature sensor not initialised\n");
		return -EINVAL;
	}

	th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
	if (!th_zone)
		return -ENOMEM;

	th_zone->sensor_conf = sensor_conf;

	tab_ptr = (struct freq_clip_table *)sensor_conf->cooling_data.freq_data;

	/* Register the cpufreq cooling device */
	for (count = 0; count < EXYNOS_ZONE_COUNT; count++) {
		tab_size = sensor_conf->cooling_data.size[count];
		if (tab_size == 0)
			continue;

		clip_data = (struct freq_clip_table *)&(tab_ptr[pos]);

		th_zone->cool_dev[count] = cpufreq_cooling_register(
						clip_data, tab_size);
		pos += tab_size;

		if (IS_ERR(th_zone->cool_dev[count])) {
			pr_err("Failed to register cpufreq cooling device\n");
			ret = -EINVAL;
			th_zone->cool_dev_size = count;
			goto err_unregister;
		}
	}
	th_zone->cool_dev_size = count;

	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
			EXYNOS_ZONE_COUNT, 7, NULL, &exynos_dev_ops, 1, 1, PASSIVE_INTERVAL,
			IDLE_INTERVAL);

	if (IS_ERR(th_zone->therm_dev)) {
		pr_err("Failed to register thermal zone device\n");
		ret = -EINVAL;
		goto err_unregister;
	}
	th_zone->mode = THERMAL_DEVICE_ENABLED;

	pr_info("Exynos: Kernel Thermal management registered\n");

	return 0;

err_unregister:
	exynos_unregister_thermal();
	return ret;
}
int exynos4_register_thermal(struct thermal_sensor_conf *sensor_conf)
{
	int ret;

	if (!sensor_conf) {
		pr_err("Temperature sensor not initialised\n");
		return -EINVAL;
	}

	th_zone = kzalloc(sizeof(struct exynos4_thermal_zone), GFP_KERNEL);
	if (!th_zone) {
		ret = -ENOMEM;
		goto err_unregister;
	}

	th_zone->sensor_conf = sensor_conf;

	th_zone->sensor_data = sensor_conf->sensor_data;
	if (!th_zone->sensor_data) {
		pr_err("Temperature sensor data not initialised\n");
		ret = -EINVAL;
		goto err_unregister;
	}

	th_zone->cool_dev = cpufreq_cooling_register(
		(struct freq_pctg_table *)th_zone->sensor_data->freq_tab,
		th_zone->sensor_data->freq_tab_count, cpumask_of(0));

	if (IS_ERR(th_zone->cool_dev)) {
		pr_err("Failed to register cpufreq cooling device\n");
		ret = -EINVAL;
		goto err_unregister;
	}

	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
				4, NULL, &exynos4_dev_ops, 0, 0, 0, 1000);
	if (IS_ERR(th_zone->therm_dev)) {
		pr_err("Failed to register thermal zone device\n");
		ret = -EINVAL;
		goto err_unregister;
	}

	th_zone->active_interval = 5;
	th_zone->idle_interval = 10;

	exynos4_set_mode(th_zone->therm_dev, THERMAL_DEVICE_DISABLED);

	pr_info("Exynos: Kernel Thermal management registered\n");

	return 0;

err_unregister:
	exynos4_unregister_thermal();
	return ret;
}
Пример #9
0
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
{
	int trips = 0;
	int result;
	acpi_status status;
	int i;

	if (tz->trips.critical.flags.valid)
		trips++;

	if (tz->trips.hot.flags.valid)
		trips++;

	if (tz->trips.passive.flags.valid)
		trips++;

	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
			tz->trips.active[i].flags.valid; i++, trips++);

	if (tz->trips.passive.flags.valid)
		tz->thermal_zone =
			thermal_zone_device_register("acpitz", trips, 0, tz,
						&acpi_thermal_zone_ops, NULL,
						     tz->trips.passive.tsp*100,
						     tz->polling_frequency*100);
	else
		tz->thermal_zone =
			thermal_zone_device_register("acpitz", trips, 0, tz,
						&acpi_thermal_zone_ops, NULL,
						0, tz->polling_frequency*100);
	if (IS_ERR(tz->thermal_zone))
		return -ENODEV;

	result = sysfs_create_link(&tz->device->dev.kobj,
				   &tz->thermal_zone->device.kobj, "thermal_zone");
	if (result)
		return result;

	result = sysfs_create_link(&tz->thermal_zone->device.kobj,
				   &tz->device->dev.kobj, "device");
	if
Пример #10
0
/* Register with the in-kernel thermal management */
static int exynos4_register_thermal(struct thermal_sensor_conf *sensor_conf)
{
	int ret, count, tab_size;
	struct freq_clip_table *tab_ptr;

	if (!sensor_conf || !sensor_conf->read_temperature) {
		pr_err("Temperature sensor not initialised\n");
		return -EINVAL;
	}

	th_zone = kzalloc(sizeof(struct exynos4_thermal_zone), GFP_KERNEL);
	if (!th_zone) {
		ret = -ENOMEM;
		goto err_unregister;
	}

	th_zone->sensor_conf = sensor_conf;

	tab_ptr = (struct freq_clip_table *)sensor_conf->cooling_data.freq_data;
	tab_size = sensor_conf->cooling_data.freq_clip_count;

	/* Register the cpufreq cooling device */
	th_zone->cool_dev_size = 1;
	count = 0;
	th_zone->cool_dev[count] = cpufreq_cooling_register(
			(struct freq_clip_table *)&(tab_ptr[count]),
			tab_size, cpumask_of(0), THERMAL_TRIP_STATE_INSTANCE);

	if (IS_ERR(th_zone->cool_dev[count])) {
		pr_err("Failed to register cpufreq cooling device\n");
		ret = -EINVAL;
		th_zone->cool_dev_size = 0;
		goto err_unregister;
	}

	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
			3, NULL, &exynos4_dev_ops, 0, 0, 0, IDLE_INTERVAL);

	if (IS_ERR(th_zone->therm_dev)) {
		pr_err("Failed to register thermal zone device\n");
		ret = -EINVAL;
		goto err_unregister;
	}
	th_zone->mode = THERMAL_DEVICE_ENABLED;

	pr_info("Exynos: Kernel Thermal management registered\n");

	return 0;

err_unregister:
	exynos4_unregister_thermal();
	return ret;
}
/**
 * mid_thermal_probe - mfld thermal initialize
 * @pdev: platform device structure
 *
 * mid thermal probe initializes the hardware and registers
 * all the sensors with the generic thermal framework. Can sleep.
 */
static int mid_thermal_probe(struct platform_device *pdev)
{
	static char *name[MSIC_THERMAL_SENSORS] = {
		"skin0", "skin1", "sys", "msicdie"
	};

	int ret;
	int i;
	struct platform_info *pinfo;

	pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL);
	if (!pinfo)
		return -ENOMEM;

	/* Initializing the hardware */
	ret = mid_initialize_adc(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "ADC init failed");
		kfree(pinfo);
		return ret;
	}

	/* Register each sensor with the generic thermal framework*/
	for (i = 0; i < MSIC_THERMAL_SENSORS; i++) {
		struct thermal_device_info *td_info = initialize_sensor(i);

		if (!td_info) {
			ret = -ENOMEM;
			goto err;
		}
		pinfo->tzd[i] = thermal_zone_device_register(name[i],
				0, 0, td_info, &tzd_ops, NULL, 0, 0);
		if (IS_ERR(pinfo->tzd[i])) {
			kfree(td_info);
			ret = PTR_ERR(pinfo->tzd[i]);
			goto err;
		}
	}

	pinfo->pdev = pdev;
	platform_set_drvdata(pdev, pinfo);
	return 0;

err:
	while (--i >= 0) {
		kfree(pinfo->tzd[i]->devdata);
		thermal_zone_device_unregister(pinfo->tzd[i]);
	}
	configure_adc(0);
	kfree(pinfo);
	return ret;
}
Пример #12
0
/**
 * mid_thermal_probe - mfld thermal initialize
 * @ipcdev: ipc device structure
 *
 * mid thermal probe initializes the hardware and registers
 * all the sensors with the generic thermal framework. Can sleep.
 */
static int mid_thermal_probe(struct ipc_device *ipcdev)
{
	int ret;
	int i;
	ipcinfo = kzalloc(sizeof(struct ipc_info), GFP_KERNEL);
	if (!ipcinfo)
		return -ENOMEM;

	/* initialize mutex locks */
	mutex_init(&ipcinfo->cacheinfo.lock);

#ifdef CONFIG_BOARD_CTP
	/* Allocate ADC channels for all sensors */
	ipcinfo->therm_adc_handle = intel_mid_gpadc_alloc(MSIC_THERMAL_SENSORS,
					0x04 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x04 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x03 | CH_NEED_VCALIB,
					0x09 | CH_NEED_VREF | CH_NEED_VCALIB);
#else
	/* Allocate ADC channels for all sensors */
	ipcinfo->therm_adc_handle = intel_mid_gpadc_alloc(MSIC_THERMAL_SENSORS,
					0x08 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x08 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x0A | CH_NEED_VREF | CH_NEED_VCALIB,
					0x03 | CH_NEED_VCALIB);
#endif
	if (!ipcinfo->therm_adc_handle) {
		ret = -ENOMEM;
		goto alloc_fail;
	}

	/* Register each sensor with the generic thermal framework*/
	for (i = 0; i < MSIC_THERMAL_SENSORS; i++) {
		ipcinfo->tzd[i] = thermal_zone_device_register(name[i],
					0, 0, initialize_sensor(i),
					&tzd_ops, 0, 0, 0, 0);
		if (IS_ERR(ipcinfo->tzd[i]))
			goto reg_fail;
	}

	ipcinfo->ipcdev = ipcdev;
	ipc_set_drvdata(ipcdev, ipcinfo);
	return 0;

reg_fail:
	ret = PTR_ERR(ipcinfo->tzd[i]);
	while (--i >= 0)
		thermal_zone_device_unregister(ipcinfo->tzd[i]);
alloc_fail:
	kfree(ipcinfo);
	return ret;
}
Пример #13
0
static int anatop_thermal_register_thermal_zone(struct anatop_thermal *tz)
{
	int trips = 0;

	if (tz->trips.critical.flags.valid)
		trips++;

	if (tz->trips.hot.flags.valid)
		trips++;

	if (tz->trips.passive.flags.valid)
		trips++;

	if (tz->trips.active.flags.valid)
		trips++;

	if (tz->trips.passive.flags.valid)
		tz->thermal_zone =
			thermal_zone_device_register("anatoptz", trips, tz,
						     &anatop_thermal_zone_ops,
						     tz->trips.passive.tc1,
						     tz->trips.passive.tc2,
						     tz->trips.passive.tsp*100,
						     tz->polling_frequency*100);
	else
		tz->thermal_zone =
			thermal_zone_device_register("anatoptz", trips, tz,
						     &anatop_thermal_zone_ops,
						     0, 0, 0,
						     tz->polling_frequency);
	tz->tz_enabled = 1;

	printk(KERN_INFO "%s registered as thermal_zone%d\n",
		 tz->device->name, tz->thermal_zone->id);
	return 0;
}
/* Register with the in-kernel thermal management */
static int amlogic_register_thermal(struct amlogic_thermal_platform_data *pdata, struct platform_device *pdev)
{
    int ret=0, j;
    struct cpumask mask_val;

    memset(&mask_val,0,sizeof(struct cpumask));
    cpumask_set_cpu(0, &mask_val);
    pdata->cpu_cool_dev= cpufreq_cooling_register(&mask_val);
    if (IS_ERR(pdata->cpu_cool_dev)) {
        THERMAL_ERR("Failed to register cpufreq cooling device\n");
        ret = -EINVAL;
        goto err_unregister;
    }
    pdata->cpucore_cool_dev = cpucore_cooling_register();
    if (IS_ERR(pdata->cpucore_cool_dev)) {
        THERMAL_ERR("Failed to register cpufreq cooling device\n");
        ret = -EINVAL;
        goto err_unregister;
    }

    pdata->therm_dev = thermal_zone_device_register(pdata->name,
                                                    pdata->temp_trip_count,
                                                    ((1 << pdata->temp_trip_count) - 1),
                                                    pdata,
                                                    &amlogic_dev_ops,
                                                    NULL,
                                                    0,
                                                    pdata->idle_interval);

    if (IS_ERR(pdata->therm_dev)) {
        THERMAL_ERR("Failed to register thermal zone device, err:%p\n", pdata->therm_dev);
        ret = -EINVAL;
        goto err_unregister;
    }

    if (pdata->keep_mode) {                                     // create sysfs for keep_mode
        for (j = 0; j < ARRAY_SIZE(amlogic_thermal_attr); j++) {
            device_create_file(&pdata->therm_dev->device, &amlogic_thermal_attr[j]);
        }
    }

    return 0;

err_unregister:
    amlogic_unregister_thermal(pdata);
    return ret;
}
Пример #15
0
/* Register with the in-kernel thermal management */
static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
{
	int ret;
	struct cpumask mask_val;

	if (!sensor_conf || !sensor_conf->read_temperature) {
		pr_err("Temperature sensor not initialised\n");
		return -EINVAL;
	}

	th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
	if (!th_zone)
		return -ENOMEM;

	th_zone->sensor_conf = sensor_conf;
	cpumask_set_cpu(0, &mask_val);
	th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
	if (IS_ERR(th_zone->cool_dev[0])) {
		pr_err("Failed to register cpufreq cooling device\n");
		ret = -EINVAL;
		goto err_unregister;
	}
	th_zone->cool_dev_size++;

	th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
			EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
			sensor_conf->trip_data.trigger_falling ?
			0 : IDLE_INTERVAL);

	if (IS_ERR(th_zone->therm_dev)) {
		pr_err("Failed to register thermal zone device\n");
		ret = PTR_ERR(th_zone->therm_dev);
		goto err_unregister;
	}
	th_zone->mode = THERMAL_DEVICE_ENABLED;

	pr_info("Exynos: Kernel Thermal management registered\n");

	return 0;

err_unregister:
	exynos_unregister_thermal();
	return ret;
}
Пример #16
0
static int bcm2835_thermal_probe(struct platform_device *pdev)
{
    print_debug("IN");
    print_debug("THERMAL Driver has been probed!");

    /* check that the device isn't null!*/
    if(pdev == NULL)
    {
        print_debug("Platform device is empty!");
        return -ENODEV;
    }

    if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal",	1, NULL, &ops,1,1,1000,1000)))
    {
        print_debug("Unable to register the thermal device!");
        return -EFAULT;
    }
    return 0;
}
static struct thermald_sensor *create_test_tzone(int id)
{
	struct thermald_sensor *sensor;
	char name[20];

	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
	if (!sensor)
		return NULL;

	snprintf(name, sizeof(name), "thd_test_%d", id);
	sensor->tzone = thermal_zone_device_register(name, 1, 0, sensor,
						     &tzone_ops,
                                                     NULL, 0, 0);
	if (IS_ERR(sensor->tzone)) {
		kfree(sensor);
		return NULL;
	}

	return sensor;
}
Пример #18
0
static int mtktspmic_register_thermal(void)
{
    mtktspmic_dprintk("[mtktspmic_register_thermal] \n");

    /* cooling devices */
	cl_dev_1000 = thermal_cooling_device_register("mtktspmic-freq-1000", NULL,
						 &mtktspmic_cooling_1000_ops);
	cl_dev_500 = thermal_cooling_device_register("mtktspmic-freq-500", NULL,
						 &mtktspmic_cooling_500_ops);
	cl_dev_250 = thermal_cooling_device_register("mtktspmic-freq-250", NULL,
						 &mtktspmic_cooling_250_ops);
	cl_dev_166 = thermal_cooling_device_register("mtktspmic-freq-166", NULL,
						 &mtktspmic_cooling_166_ops);
    cl_dev_sysrst = thermal_cooling_device_register("mtktspmic-sysrst", NULL,
						 &mtktspmic_cooling_sysrst_ops);

    /* trips : trip 0~2 */
	thz_dev = thermal_zone_device_register("mtktspmic", 3, NULL,
					      &mtktspmic_dev_ops, 0, 0, 0, interval*1000);

	return 0;
}
/* Register with the in-kernel thermal management */
static int amlogic_register_thermal(struct amlogic_thermal_platform_data *pdata)
{
	int ret=0;
	struct cpumask mask_val;
	memset(&mask_val,0,sizeof(struct cpumask));
	cpumask_set_cpu(0, &mask_val);
	pdata->cpu_cool_dev= cpufreq_cooling_register(&mask_val);
	if (IS_ERR(pdata->cpu_cool_dev)) {
		pr_err("Failed to register cpufreq cooling device\n");
		ret = -EINVAL;
		goto err_unregister;
	}
	pdata->cpucore_cool_dev = cpucore_cooling_register();
	if (IS_ERR(pdata->cpucore_cool_dev)) {
		pr_err("Failed to register cpufreq cooling device\n");
		ret = -EINVAL;
		goto err_unregister;
	}

	pdata->therm_dev = thermal_zone_device_register(pdata->name,
			pdata->temp_trip_count, 7, pdata, &amlogic_dev_ops, NULL, 0,
			pdata->idle_interval);

	if (IS_ERR(pdata->therm_dev)) {
		pr_err("Failed to register thermal zone device\n");
		ret = -EINVAL;
		goto err_unregister;
	}

	pr_info("amlogic: Kernel Thermal management registered\n");

	return 0;

err_unregister:
	amlogic_unregister_thermal(pdata);
	return ret;
}
Пример #20
0
struct thermal_freq *thermal_freq_register(char *domain,
	int (*get_temp)(void *), void *sensordata,
	struct thermal_freq_table *trip_table, int table_size,
	int polling_interval)
{
	struct thermal_freq *therm;

	if (table_size <= 0)
		return NULL;
	therm = kzalloc(sizeof(struct thermal_freq), GFP_KERNEL);
	therm->get_temp = get_temp;
	therm->privdata = sensordata;
	therm->trip_table = trip_table;
	therm->trip_count = table_size;
	therm->state = -1;
	therm->idle_polling_delay = polling_interval;
	therm->cdev = thermal_cooling_device_register(domain, therm,
		&thc_ops);
	therm->tdev = thermal_zone_device_register(domain, table_size, therm,
		&thz_ops, 1, 1, polling_interval, polling_interval);
	cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
		CPUFREQ_POLICY_NOTIFIER);
	return therm;
}
Пример #21
0
static int __devinit therm_est_probe(struct platform_device *pdev)
{
	int i;
	struct therm_estimator *est;
	struct therm_est_data *data;

	est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
	if (IS_ERR_OR_NULL(est))
		return -ENOMEM;

	platform_set_drvdata(pdev, est);

	data = therm_est_get_pdata(&pdev->dev);

	est->devs = data->devs;
	est->ndevs = data->ndevs;
	est->toffset = data->toffset;
	est->polling_period = data->polling_period;
	est->tc1 = data->tc1;
	est->tc2 = data->tc2;

	/* initialize history */
	therm_est_init_history(est);

	/* initialize timer trips */
	est->num_timer_trips = data->num_timer_trips;
	est->timer_trips = data->timer_trips;
	therm_est_init_timer_trips(est);
	mutex_init(&est->timer_trip_lock);
	INIT_DELAYED_WORK(&est->timer_trip_work,
			  therm_est_timer_trip_work_func);

	est->workqueue = alloc_workqueue(dev_name(&pdev->dev),
				    WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
	if (!est->workqueue)
		goto err;

	INIT_DELAYED_WORK(&est->therm_est_work, therm_est_work_func);

	queue_delayed_work(est->workqueue,
				&est->therm_est_work,
				msecs_to_jiffies(est->polling_period));

	est->num_trips = data->num_trips;
	est->trips = data->trips;
	est->tzp = data->tzp;

	est->thz = thermal_zone_device_register(dev_name(&pdev->dev),
						est->num_trips,
						(1 << est->num_trips) - 1,
						est,
						&therm_est_ops,
						est->tzp,
						data->passive_delay,
						0);
	if (IS_ERR_OR_NULL(est->thz))
		goto err;

	for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
		device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr);

#ifdef CONFIG_PM
	est->pm_nb.notifier_call = therm_est_pm_notify,
	register_pm_notifier(&est->pm_nb);
#endif

	return 0;
err:
	cancel_delayed_work_sync(&est->therm_est_work);
	if (est->workqueue)
		destroy_workqueue(est->workqueue);
	kfree(est);
	return -EINVAL;
}
Пример #22
0
static int __devinit qpnp_tm_probe(struct spmi_device *spmi)
{
	struct device_node *node;
	struct resource *res;
	struct qpnp_tm_chip *chip;
	struct thermal_zone_device_ops *tz_ops;
	char *tm_name;
	u32 default_temperature;
	int rc = 0;
	u8 raw_type[2], type, subtype;

	if (!spmi || !(&spmi->dev) || !spmi->dev.of_node) {
		dev_err(&spmi->dev, "%s: device tree node not found\n",
			__func__);
		return -EINVAL;
	}

	node = spmi->dev.of_node;

	chip = kzalloc(sizeof(struct qpnp_tm_chip), GFP_KERNEL);
	if (!chip) {
		dev_err(&spmi->dev, "%s: Can't allocate qpnp_tm_chip\n",
			__func__);
		return -ENOMEM;
	}

	dev_set_drvdata(&spmi->dev, chip);

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&spmi->dev, "%s: node is missing base address\n",
			__func__);
		rc = -EINVAL;
		goto free_chip;
	}
	chip->base_addr	= res->start;
	chip->spmi_dev	= spmi;

	chip->irq = spmi_get_irq(spmi, NULL, 0);
	if (chip->irq < 0) {
		rc = chip->irq;
		dev_err(&spmi->dev, "%s: node is missing irq, rc=%d\n",
			__func__, rc);
		goto free_chip;
	}

	chip->tm_name = of_get_property(node, "label", NULL);
	if (chip->tm_name == NULL) {
		dev_err(&spmi->dev, "%s: node is missing label\n",
			__func__);
		rc = -EINVAL;
		goto free_chip;
	}

	tm_name = kstrdup(chip->tm_name, GFP_KERNEL);
	if (tm_name == NULL) {
		dev_err(&spmi->dev, "%s: could not allocate memory for label\n",
			__func__);
		rc = -ENOMEM;
		goto free_chip;
	}
	chip->tm_name = tm_name;

	INIT_DELAYED_WORK(&chip->irq_work, qpnp_tm_work);

	/* These bindings are optional, so it is okay if they are not found. */
	chip->thresh = THRESH_MAX + 1;
	rc = of_property_read_u32(node, "qcom,threshold-set", &chip->thresh);
	if (!rc && (chip->thresh < THRESH_MIN || chip->thresh > THRESH_MAX))
		dev_err(&spmi->dev, "%s: invalid qcom,threshold-set=%u specified\n",
			__func__, chip->thresh);

	chip->adc_type = QPNP_TM_ADC_NONE;
	rc = of_property_read_u32(node, "qcom,channel-num", &chip->adc_channel);
	if (!rc) {
		if (chip->adc_channel < 0 || chip->adc_channel >= ADC_MAX_NUM) {
			dev_err(&spmi->dev, "%s: invalid qcom,channel-num=%d specified\n",
				__func__, chip->adc_channel);
		} else {
			chip->adc_type = QPNP_TM_ADC_QPNP_ADC;
			rc = qpnp_vadc_is_ready();
			if (rc) {
				/* Probe retry, do not print an error message */
				goto err_cancel_work;
			}
		}
	}

	if (chip->adc_type == QPNP_TM_ADC_QPNP_ADC)
		tz_ops = &qpnp_thermal_zone_ops_qpnp_adc;
	else
		tz_ops = &qpnp_thermal_zone_ops_no_adc;

	chip->allow_software_override
		= of_property_read_bool(node, "qcom,allow-override");

	default_temperature = DEFAULT_NO_ADC_TEMP;
	rc = of_property_read_u32(node, "qcom,default-temp",
					&default_temperature);
	chip->temperature = default_temperature;

	rc = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, raw_type, 2);
	if (rc) {
		dev_err(&spmi->dev, "%s: could not read type register, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}
	type = raw_type[0];
	subtype = raw_type[1];

	if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) {
		dev_err(&spmi->dev, "%s: invalid type=%02X or subtype=%02X register value\n",
			__func__, type, subtype);
		rc = -ENODEV;
		goto err_cancel_work;
	}

	rc = qpnp_tm_init_reg(chip);
	if (rc) {
		dev_err(&spmi->dev, "%s: qpnp_tm_init_reg() failed, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}

	if (chip->adc_type == QPNP_TM_ADC_NONE) {
		rc = qpnp_tm_init_temp_no_adc(chip);
		if (rc) {
			dev_err(&spmi->dev, "%s: qpnp_tm_init_temp_no_adc() failed, rc=%d\n",
				__func__, rc);
			goto err_cancel_work;
		}
	}

	/* Start in HW control; switch to SW control when user changes mode. */
	chip->mode = THERMAL_DEVICE_DISABLED;
	rc = qpnp_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
	if (rc) {
		dev_err(&spmi->dev, "%s: qpnp_tm_shutdown_override() failed, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}

	chip->tz_dev = thermal_zone_device_register(tm_name, TRIP_NUM, chip,
			tz_ops, 0, 0, 0, 0);
	if (chip->tz_dev == NULL) {
		dev_err(&spmi->dev, "%s: thermal_zone_device_register() failed.\n",
			__func__);
		rc = -ENODEV;
		goto err_cancel_work;
	}

	rc = request_irq(chip->irq, qpnp_tm_isr, IRQF_TRIGGER_RISING, tm_name,
			chip);
	if (rc < 0) {
		dev_err(&spmi->dev, "%s: request_irq(%d) failed: %d\n",
			__func__, chip->irq, rc);
		goto err_free_tz;
	}

	return 0;

err_free_tz:
	thermal_zone_device_unregister(chip->tz_dev);
err_cancel_work:
	cancel_delayed_work_sync(&chip->irq_work);
	kfree(chip->tm_name);
free_chip:
	dev_set_drvdata(&spmi->dev, NULL);
	kfree(chip);
	return rc;
}
Пример #23
0
static int __devinit pmic8901_tm_probe(struct platform_device *pdev)
{
	struct pm8901_tm_device	*tmdev;
	struct pm8901_chip *pm_chip;
	unsigned int irq, hi_irq;
	int rc;

	pm_chip = platform_get_drvdata(pdev);
	if (pm_chip == NULL) {
		pr_err("%s: no driver data passed in.\n", __func__);
		return -EFAULT;
	}

	irq = platform_get_irq(pdev, 0);
	if (!irq) {
		pr_err("%s: no IRQ passed in.\n", __func__);
		return -EFAULT;
	}
	hi_irq = platform_get_irq(pdev, 1);
	if (!hi_irq) {
		pr_err("%s: no HI IRQ passed in.\n", __func__);
		return -EFAULT;
	}

	tmdev = kzalloc(sizeof *tmdev, GFP_KERNEL);
	if (tmdev == NULL) {
		pr_err("%s: kzalloc() failed.\n", __func__);
		return -ENOMEM;
	}

	tmdev->tz_dev = thermal_zone_device_register("pm8901_tz",
						     PM8901_TRIP_NUM, tmdev,
						     &pm8901_thermal_zone_ops,
						     0, 0, 0, 0);
	if (tmdev->tz_dev == NULL) {
		pr_err("%s: thermal_zone_device_register() failed.\n",
		       __func__);
		kfree(tmdev);
		return -ENODEV;
	}

	tmdev->pm_chip = pm_chip;
	rc = pm8901_tm_init_reg(tmdev);
	pm8901_tm_shutdown_override(tmdev->pm_chip, SOFTWARE_OVERRIDE_DISABLED);
	if (rc < 0) {
		thermal_zone_device_unregister(tmdev->tz_dev);
		kfree(tmdev);
		return rc;
	}

	/* start in HW control, switch to SW control when user changes mode */
	tmdev->mode = THERMAL_DEVICE_DISABLED;
	thermal_zone_device_update(tmdev->tz_dev);

	platform_set_drvdata(pdev, tmdev);

	rc = request_threaded_irq(irq, pm8901_tm_isr1, NULL,
			 IRQF_TRIGGER_RISING | IRQF_DISABLED,
			 "pm8901-tm-irq", tmdev);
	if (rc < 0) {
		pr_err("%s: request_threaded_irq(%d) FAIL: %d\n",
		       __func__, irq, rc);

		thermal_zone_device_unregister(tmdev->tz_dev);
		platform_set_drvdata(pdev, tmdev->pm_chip);
		kfree(tmdev);
		return -ENODEV;
	}
	tmdev->irq = irq;

	rc = request_threaded_irq(hi_irq, pm8901_tm_isr2, NULL,
			 IRQF_TRIGGER_RISING | IRQF_DISABLED,
			 "pm8901-tm-irq2", tmdev);
	if (rc < 0) {
		pr_err("%s: request_threaded_irq(%d) FAIL: %d\n",
		       __func__, hi_irq, rc);

		free_irq(irq, tmdev);
		thermal_zone_device_unregister(tmdev->tz_dev);
		platform_set_drvdata(pdev, tmdev->pm_chip);
		kfree(tmdev);
		return -ENODEV;
	}
	tmdev->hi_irq = hi_irq;

	pr_notice("%s: OK\n", __func__);
	return 0;
}
Пример #24
0
static int db8500_thermal_probe(struct platform_device *pdev)
{
	struct db8500_thermal_zone *pzone = NULL;
	struct db8500_thsens_platform_data *ptrips = NULL;
	struct device_node *np = pdev->dev.of_node;
	int low_irq, high_irq, ret = 0;
	unsigned long dft_low, dft_high;

	if (np)
		ptrips = db8500_thermal_parse_dt(pdev);
	else
		ptrips = dev_get_platdata(&pdev->dev);

	if (!ptrips)
		return -EINVAL;

	pzone = devm_kzalloc(&pdev->dev, sizeof(*pzone), GFP_KERNEL);
	if (!pzone)
		return -ENOMEM;

	mutex_init(&pzone->th_lock);
	mutex_lock(&pzone->th_lock);

	pzone->mode = THERMAL_DEVICE_DISABLED;
	pzone->trip_tab = ptrips;

	INIT_WORK(&pzone->therm_work, db8500_thermal_work);

	low_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_LOW");
	if (low_irq < 0) {
		dev_err(&pdev->dev, "Get IRQ_HOTMON_LOW failed.\n");
		ret = low_irq;
		goto out_unlock;
	}

	ret = devm_request_threaded_irq(&pdev->dev, low_irq, NULL,
		prcmu_low_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,
		"dbx500_temp_low", pzone);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to allocate temp low irq.\n");
		goto out_unlock;
	}

	high_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_HIGH");
	if (high_irq < 0) {
		dev_err(&pdev->dev, "Get IRQ_HOTMON_HIGH failed.\n");
		ret = high_irq;
		goto out_unlock;
	}

	ret = devm_request_threaded_irq(&pdev->dev, high_irq, NULL,
		prcmu_high_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT,
		"dbx500_temp_high", pzone);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to allocate temp high irq.\n");
		goto out_unlock;
	}

	pzone->therm_dev = thermal_zone_device_register("db8500_thermal_zone",
		ptrips->num_trips, 0, pzone, &thdev_ops, NULL, 0, 0);

	if (IS_ERR(pzone->therm_dev)) {
		dev_err(&pdev->dev, "Register thermal zone device failed.\n");
		ret = PTR_ERR(pzone->therm_dev);
		goto out_unlock;
	}
	dev_info(&pdev->dev, "Thermal zone device registered.\n");

	dft_low = PRCMU_DEFAULT_LOW_TEMP;
	dft_high = ptrips->trip_points[0].temp;

	db8500_thermal_update_config(pzone, 0, THERMAL_TREND_STABLE,
		dft_low, dft_high);

	platform_set_drvdata(pdev, pzone);
	pzone->mode = THERMAL_DEVICE_ENABLED;

out_unlock:
	mutex_unlock(&pzone->th_lock);

	return ret;
}
Пример #25
0
static int imx_thermal_probe(struct platform_device *pdev)
{
	struct imx_thermal_data *data;
	struct cpumask clip_cpus;
	struct regmap *map;
	int measure_freq;
	int ret;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
	if (IS_ERR(map)) {
		ret = PTR_ERR(map);
		dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
		return ret;
	}
	data->tempmon = map;

	data->irq = platform_get_irq(pdev, 0);
	if (data->irq < 0)
		return data->irq;

	ret = devm_request_threaded_irq(&pdev->dev, data->irq,
			imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
			0, "imx_thermal", data);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, data);

	ret = imx_get_sensor_data(pdev);
	if (ret) {
		dev_err(&pdev->dev, "failed to get sensor data\n");
		return ret;
	}

	/* Make sure sensor is in known good state for measurements */
	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
	regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
	regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF);
	regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);

	cpumask_set_cpu(0, &clip_cpus);
	data->cdev = cpufreq_cooling_register(&clip_cpus);
	if (IS_ERR(data->cdev)) {
		ret = PTR_ERR(data->cdev);
		dev_err(&pdev->dev,
			"failed to register cpufreq cooling device: %d\n", ret);
		return ret;
	}

	data->tz = thermal_zone_device_register("imx_thermal_zone",
						IMX_TRIP_NUM,
						BIT(IMX_TRIP_PASSIVE), data,
						&imx_tz_ops, NULL,
						IMX_PASSIVE_DELAY,
						IMX_POLLING_DELAY);
	if (IS_ERR(data->tz)) {
		ret = PTR_ERR(data->tz);
		dev_err(&pdev->dev,
			"failed to register thermal zone device %d\n", ret);
		cpufreq_cooling_unregister(data->cdev);
		return ret;
	}

	data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(data->thermal_clk)) {
		dev_warn(&pdev->dev, "failed to get thermal clk!\n");
	} else {
		/*
		 * Thermal sensor needs clk on to get correct value, normally
		 * we should enable its clk before taking measurement and disable
		 * clk after measurement is done, but if alarm function is enabled,
		 * hardware will auto measure the temperature periodically, so we
		 * need to keep the clk always on for alarm function.
		 */
		ret = clk_prepare_enable(data->thermal_clk);
		if (ret)
			dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
	}

	/* Enable measurements at ~ 10 Hz */
	regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
	measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
	regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq);
	imx_set_alarm_temp(data, data->temp_passive);
	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
	regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);

	data->irq_enabled = true;
	data->mode = THERMAL_DEVICE_ENABLED;

	return 0;
}
static int __devinit pmic8058_tm_probe(struct platform_device *pdev)
{
	DECLARE_COMPLETION_ONSTACK(wait);
	struct pm8058_tm_device *tmdev;
	struct pm8058_chip *pm_chip;
	unsigned int irq;
	int rc;

	pm_chip = platform_get_drvdata(pdev);
	if (pm_chip == NULL) {
		pr_err("%s: no driver data passed in.\n", __func__);
		return -EFAULT;
	}

	irq = platform_get_irq(pdev, 0);
	if (!irq) {
		pr_err("%s: no IRQ passed in.\n", __func__);
		return -EFAULT;
	}

	tmdev = kzalloc(sizeof *tmdev, GFP_KERNEL);
	if (tmdev == NULL) {
		pr_err("%s: kzalloc() failed.\n", __func__);
		return -ENOMEM;
	}

	rc = adc_channel_open(PM8058_TEMP_ADC_CH, &(tmdev->adc_handle));
	if (rc < 0) {
		pr_err("%s: adc_channel_open() failed.\n", __func__);
		kfree(tmdev);
		return rc;
	}

	/* calibrate the die temperature sensor */
	if (adc_calib_request(tmdev->adc_handle, &wait) == CALIB_STARTED)
		wait_for_completion(&wait);

	tmdev->pm_chip = pm_chip;
	tmdev->tz_dev = thermal_zone_device_register("pm8058_tz",
						     PM8058_TRIP_NUM, tmdev,
						     &pm8058_thermal_zone_ops,
						     0, 0, 0, 0);
	if (tmdev->tz_dev == NULL) {
		pr_err("%s: thermal_zone_device_register() failed.\n",
		       __func__);
		adc_channel_close(tmdev->adc_handle);
		kfree(tmdev);
		return -ENODEV;
	}

	rc = pm8058_tm_init_reg(tmdev);
	pm8058_tm_shutdown_override(tmdev->pm_chip, SOFTWARE_OVERRIDE_DISABLED);
	if (rc < 0) {
		thermal_zone_device_unregister(tmdev->tz_dev);
		adc_channel_close(tmdev->adc_handle);
		kfree(tmdev);
		return rc;
	}

	/* start in HW control, switch to SW control when user changes mode */
	tmdev->mode = THERMAL_DEVICE_DISABLED;
	thermal_zone_device_update(tmdev->tz_dev);

	platform_set_drvdata(pdev, tmdev);

	rc = request_threaded_irq(irq, NULL, pm8058_tm_isr,
			 IRQF_TRIGGER_RISING | IRQF_DISABLED,
			 "pm8058-tm-irq", tmdev);
	if (rc < 0) {
		pr_err("%s: request_irq(%d) FAIL: %d\n", __func__, irq, rc);
		thermal_zone_device_unregister(tmdev->tz_dev);
		platform_set_drvdata(pdev, tmdev->pm_chip);
		adc_channel_close(tmdev->adc_handle);
		kfree(tmdev);
		return rc;
	}
	tmdev->irq = irq;

	pr_notice("%s: OK\n", __func__);
	return 0;
}
Пример #27
0
static int __devinit pm8xxx_tm_probe(struct platform_device *pdev)
{
	const struct pm8xxx_tm_core_data *cdata = pdev->dev.platform_data;
	struct thermal_zone_device_ops *tz_ops;
	struct pm8xxx_tm_chip *chip;
	struct resource *res;
	int rc = 0;

	if (!cdata) {
		pr_err("missing core data\n");
		return -EINVAL;
	}

	chip = kzalloc(sizeof(struct pm8xxx_tm_chip), GFP_KERNEL);
	if (chip == NULL) {
		pr_err("kzalloc() failed.\n");
		return -ENOMEM;
	}

	chip->dev = &pdev->dev;
	memcpy(&(chip->cdata), cdata, sizeof(struct pm8xxx_tm_core_data));

	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
		chip->cdata.irq_name_temp_stat);
	if (res) {
		chip->tempstat_irq = res->start;
	} else {
		pr_err("temp stat IRQ not specified\n");
		goto err_free_chip;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
		chip->cdata.irq_name_over_temp);
	if (res) {
		chip->overtemp_irq = res->start;
	} else {
		pr_err("over temp IRQ not specified\n");
		goto err_free_chip;
	}

	rc = pm8xxx_init_adc(chip, true);
	if (rc < 0) {
		pr_err("Unable to initialize adc\n");
		goto err_free_chip;
	}

	/* Select proper thermal zone ops functions based on ADC type. */
	if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8XXX_ADC)
		tz_ops = &pm8xxx_thermal_zone_ops_pm8xxx_adc;
	else if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8058_ADC)
		tz_ops = &pm8xxx_thermal_zone_ops_pm8058_adc;
	else
		tz_ops = &pm8xxx_thermal_zone_ops_no_adc;

	chip->tz_dev = thermal_zone_device_register(chip->cdata.tm_name,
			TRIP_NUM, chip, tz_ops, 0, 0, 0, 0);

	if (chip->tz_dev == NULL) {
		pr_err("thermal_zone_device_register() failed.\n");
		rc = -ENODEV;
		goto err_fail_adc;
	}

	rc = pm8xxx_tm_init_reg(chip);
	if (rc < 0)
		goto err_free_tz;
	rc = pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
	if (rc < 0)
		goto err_free_tz;

	if (chip->cdata.adc_type == PM8XXX_TM_ADC_NONE) {
		rc = pm8xxx_tm_init_temp_no_adc(chip);
		if (rc < 0)
			goto err_free_tz;
	}

	/* Start in HW control; switch to SW control when user changes mode. */
	chip->mode = THERMAL_DEVICE_DISABLED;
	thermal_zone_device_update(chip->tz_dev);

	INIT_DELAYED_WORK(&chip->irq_work, pm8xxx_tm_work);

	rc = request_irq(chip->tempstat_irq, pm8xxx_tm_isr, IRQF_TRIGGER_RISING,
		chip->cdata.irq_name_temp_stat, chip);
	if (rc < 0) {
		pr_err("request_irq(%d) failed: %d\n", chip->tempstat_irq, rc);
		goto err_cancel_work;
	}

	rc = request_irq(chip->overtemp_irq, pm8xxx_tm_isr, IRQF_TRIGGER_RISING,
		chip->cdata.irq_name_over_temp, chip);
	if (rc < 0) {
		pr_err("request_irq(%d) failed: %d\n", chip->overtemp_irq, rc);
		goto err_free_irq_tempstat;
	}

	platform_set_drvdata(pdev, chip);

	pr_info("OK\n");

	return 0;

err_free_irq_tempstat:
	free_irq(chip->tempstat_irq, chip);
err_cancel_work:
	cancel_delayed_work_sync(&chip->irq_work);
err_free_tz:
	thermal_zone_device_unregister(chip->tz_dev);
err_fail_adc:
	pm8xxx_init_adc(chip, false);
err_free_chip:
	kfree(chip);
	return rc;
}
Пример #28
0
static int imx_thermal_probe(struct platform_device *pdev)
{
	struct imx_thermal_data *data;
	struct cpumask clip_cpus;
	struct regmap *map;
	int measure_freq;
	int ret;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
	if (IS_ERR(map)) {
		ret = PTR_ERR(map);
		dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
		return ret;
	}
	data->tempmon = map;

	data->irq = platform_get_irq(pdev, 0);
	if (data->irq < 0)
		return data->irq;

	ret = devm_request_threaded_irq(&pdev->dev, data->irq,
			imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
			0, "imx_thermal", data);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, data);

	ret = imx_get_sensor_data(pdev);
	if (ret) {
		dev_err(&pdev->dev, "failed to get sensor data\n");
		return ret;
	}

	/* Make sure sensor is in known good state for measurements */
	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
	regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
	regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF);
	regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);

	cpumask_set_cpu(0, &clip_cpus);
	data->cdev = cpufreq_cooling_register(&clip_cpus);
	if (IS_ERR(data->cdev)) {
		ret = PTR_ERR(data->cdev);
		dev_err(&pdev->dev,
			"failed to register cpufreq cooling device: %d\n", ret);
		return ret;
	}

	data->tz = thermal_zone_device_register("imx_thermal_zone",
						IMX_TRIP_NUM,
						BIT(IMX_TRIP_PASSIVE), data,
						&imx_tz_ops, NULL,
						IMX_PASSIVE_DELAY,
						IMX_POLLING_DELAY);
	if (IS_ERR(data->tz)) {
		ret = PTR_ERR(data->tz);
		dev_err(&pdev->dev,
			"failed to register thermal zone device %d\n", ret);
		cpufreq_cooling_unregister(data->cdev);
		return ret;
	}

	/* Enable measurements at ~ 10 Hz */
	regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
	measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
	regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq);
	imx_set_alarm_temp(data, data->temp_passive);
	regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
	regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);

	data->irq_enabled = true;
	data->mode = THERMAL_DEVICE_ENABLED;

	return 0;
}
static int spear_thermal_probe(struct platform_device *pdev)
{
	struct thermal_zone_device *spear_thermal = NULL;
	struct spear_thermal_dev *stdev;
	struct spear_thermal_pdata *pdata;
	int ret = 0;
	struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!stres) {
		dev_err(&pdev->dev, "memory resource missing\n");
		return -ENODEV;
	}

	pdata = dev_get_platdata(&pdev->dev);
	if (!pdata) {
		dev_err(&pdev->dev, "platform data is NULL\n");
		return -EINVAL;
	}

	stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
	if (!stdev) {
		dev_err(&pdev->dev, "kzalloc fail\n");
		return -ENOMEM;
	}

	/*                       */
	stdev->thermal_base = devm_ioremap(&pdev->dev, stres->start,
			resource_size(stres));
	if (!stdev->thermal_base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		return -ENOMEM;
	}

	stdev->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(stdev->clk)) {
		dev_err(&pdev->dev, "Can't get clock\n");
		return PTR_ERR(stdev->clk);
	}

	ret = clk_enable(stdev->clk);
	if (ret) {
		dev_err(&pdev->dev, "Can't enable clock\n");
		goto put_clk;
	}

	stdev->flags = pdata->thermal_flags;
	writel_relaxed(stdev->flags, stdev->thermal_base);

	spear_thermal = thermal_zone_device_register("spear_thermal", 0,
				stdev, &ops, 0, 0, 0, 0);
	if (IS_ERR(spear_thermal)) {
		dev_err(&pdev->dev, "thermal zone device is NULL\n");
		ret = PTR_ERR(spear_thermal);
		goto disable_clk;
	}

	platform_set_drvdata(pdev, spear_thermal);

	dev_info(&spear_thermal->device, "Thermal Sensor Loaded at: 0x%p.\n",
			stdev->thermal_base);

	return 0;

disable_clk:
	clk_disable(stdev->clk);
put_clk:
	clk_put(stdev->clk);

	return ret;
}
Пример #30
0
static int therm_fan_est_probe(struct platform_device *pdev)
{
	int i, j;
	long temp;
	struct therm_fan_estimator *est;
	struct therm_fan_est_subdevice *dev;
	struct therm_fan_est_data *data;

	est = devm_kzalloc(&pdev->dev,
				sizeof(struct therm_fan_estimator), GFP_KERNEL);
	if (IS_ERR_OR_NULL(est))
		return -ENOMEM;

	platform_set_drvdata(pdev, est);

	data = pdev->dev.platform_data;

	est->devs = data->devs;
	est->ndevs = data->ndevs;
	est->toffset = data->toffset;
	est->polling_period = data->polling_period;

	for (i = 0; i < MAX_ACTIVE_STATES; i++) {
		est->active_trip_temps[i] = data->active_trip_temps[i];
		est->active_hysteresis[i] = data->active_hysteresis[i];
	}

	est->active_trip_temps_hyst[0] = data->active_trip_temps[0];

	for (i = 1; i < MAX_ACTIVE_STATES; i++)
		fan_set_trip_temp_hyst(est, i,
			data->active_hysteresis[i], est->active_trip_temps[i]);

	/* initialize history */
	for (i = 0; i < data->ndevs; i++) {
		dev = &est->devs[i];

		if (dev->get_temp(dev->dev_data, &temp))
			return -EINVAL;

		for (j = 0; j < HIST_LEN; j++)
			dev->hist[j] = temp;
	}

	est->workqueue = alloc_workqueue(dev_name(&pdev->dev),
				    WQ_HIGHPRI | WQ_UNBOUND, 1);
	if (!est->workqueue)
		return -ENOMEM;

	est->current_trip_index = 0;

	INIT_DELAYED_WORK(&est->therm_fan_est_work, therm_fan_est_work_func);

	queue_delayed_work(est->workqueue,
				&est->therm_fan_est_work,
				msecs_to_jiffies(est->polling_period));
	est->cdev_type = data->cdev_type;
	est->thz = thermal_zone_device_register((char *) dev_name(&pdev->dev),
					10, 0x3FF, est,
					&therm_fan_est_ops, data->tzp, 0, 0);
	if (IS_ERR_OR_NULL(est->thz))
		return -EINVAL;
	for (i = 0; i < ARRAY_SIZE(therm_fan_est_nodes); i++)
		device_create_file(&pdev->dev,
			&therm_fan_est_nodes[i].dev_attr);

	return 0;
}