Esempio n. 1
0
static void mtktspmic_unregister_thermal(void)
{
    mtktspmic_dprintk("[mtktspmic_unregister_thermal] \n");
    
	if (cl_dev_1000) {
		thermal_cooling_device_unregister(cl_dev_1000);
		cl_dev_1000 = NULL;
	}
    if (cl_dev_500) {
		thermal_cooling_device_unregister(cl_dev_500);
		cl_dev_500 = NULL;
	}    
    if (cl_dev_250) {
		thermal_cooling_device_unregister(cl_dev_250);
		cl_dev_250 = NULL;
	}
    if (cl_dev_166) {
		thermal_cooling_device_unregister(cl_dev_166);
		cl_dev_166 = NULL;
	}
    if (cl_dev_sysrst) {
		thermal_cooling_device_unregister(cl_dev_sysrst);
		cl_dev_sysrst = NULL;
	}

	if (thz_dev) {
		thermal_zone_device_unregister(thz_dev);
		thz_dev = NULL;
	}
}
Esempio n. 2
0
static int int3403_cdev_remove(struct int3403_priv *priv)
{
	struct int3403_cdev *obj = priv->priv;

	thermal_cooling_device_unregister(obj->cdev);
	return 0;
}
static int pwm_fan_remove(struct platform_device *pdev)
{
	struct fan_dev_data *fan_data = platform_get_drvdata(pdev);

	if (!fan_data)
		return -EINVAL;
	debugfs_remove_recursive(fan_debugfs_root);
	free_irq(fan_data->tach_irq, NULL);
	gpio_free(fan_data->tach_gpio);
	pwm_config(fan_data->pwm_dev, 0, fan_data->pwm_period);
	pwm_disable(fan_data->pwm_dev);
	pwm_free(fan_data->pwm_dev);
	thermal_cooling_device_unregister(fan_data->cdev);
	cancel_delayed_work(&fan_data->fan_tach_work);
	destroy_workqueue(fan_data->tach_workqueue);
	cancel_delayed_work(&fan_data->fan_ramp_work);
	destroy_workqueue(fan_data->workqueue);
	devm_kfree(&pdev->dev, (void *)(fan_data->fan_pwm));
	devm_kfree(&pdev->dev, (void *)(fan_data->fan_state_cap_lookup));
	devm_kfree(&pdev->dev, (void *)(fan_data->fan_rrd));
	devm_kfree(&pdev->dev, (void *)(fan_data->fan_rru));
	devm_kfree(&pdev->dev, (void *)(fan_data->fan_rpm));
	devm_kfree(&pdev->dev, (void *)fan_data);
	remove_sysfs_entry(&pdev->dev);

	if (fan_data->fan_reg)
		regulator_put(fan_data->fan_reg);
	return 0;
}
void tegra_throttle_exit(void)
{
	if (cdev) {
		thermal_cooling_device_unregister(cdev);
		cdev = NULL;
	}
}
Esempio n. 5
0
static int acpi_processor_stop(struct device *dev)
{
	struct acpi_device *device;
	struct acpi_processor *pr;

	if (acpi_bus_get_device(ACPI_HANDLE(dev), &device))
		return 0;

	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
				   acpi_processor_notify);

	pr = acpi_driver_data(device);
	if (!pr)
		return 0;

	acpi_processor_power_exit(pr);

	if (pr->cdev) {
		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
		sysfs_remove_link(&pr->cdev->device.kobj, "device");
		thermal_cooling_device_unregister(pr->cdev);
		pr->cdev = NULL;
	}
	return 0;
}
Esempio n. 6
0
void mwl_thermal_unregister(struct mwl_priv *priv)
{
	if (priv->chip_type != MWL8897)
		return;

	sysfs_remove_link(&priv->dev->kobj, "cooling_device");
	thermal_cooling_device_unregister(priv->cdev);
}
Esempio n. 7
0
void ath10k_thermal_unregister(struct ath10k *ar)
{
	if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
		return;

	sysfs_remove_link(&ar->dev->kobj, "cooling_device");
	thermal_cooling_device_unregister(ar->thermal.cdev);
}
static void destroy_test_cdev(struct thermald_cdev *cdev)
{
	if (!cdev)
		return;

	thermal_cooling_device_unregister(cdev->cdev);
	kfree(cdev);
}
Esempio n. 9
0
void thermal_freq_register_unregister(struct thermal_freq *therm)
{
	cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
		CPUFREQ_POLICY_NOTIFIER);
	thermal_zone_device_unregister(therm->tdev);
	thermal_cooling_device_unregister(therm->cdev);
	kzfree(therm);
}
Esempio n. 10
0
int ath10k_thermal_register(struct ath10k *ar)
{
	struct thermal_cooling_device *cdev;
	struct device *hwmon_dev;
	int ret;

	if (!test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
		return 0;

	cdev = thermal_cooling_device_register("ath10k_thermal", ar,
					       &ath10k_thermal_ops);

	if (IS_ERR(cdev)) {
		ath10k_err(ar, "failed to setup thermal device result: %ld\n",
			   PTR_ERR(cdev));
		return -EINVAL;
	}

	ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj,
				"cooling_device");
	if (ret) {
		ath10k_err(ar, "failed to create cooling device symlink\n");
		goto err_cooling_destroy;
	}

	ar->thermal.cdev = cdev;
	ar->thermal.quiet_period = ATH10K_QUIET_PERIOD_DEFAULT;

	/* Do not register hwmon device when temperature reading is not
	 * supported by firmware
	 */
	if (!(ar->wmi.ops->gen_pdev_get_temperature))
		return 0;

	/* Avoid linking error on devm_hwmon_device_register_with_groups, I
	 * guess linux/hwmon.h is missing proper stubs.
	 */
	if (!IS_REACHABLE(CONFIG_HWMON))
		return 0;

	hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev,
							   "ath10k_hwmon", ar,
							   ath10k_hwmon_groups);
	if (IS_ERR(hwmon_dev)) {
		ath10k_err(ar, "failed to register hwmon device: %ld\n",
			   PTR_ERR(hwmon_dev));
		ret = -EINVAL;
		goto err_remove_link;
	}
	return 0;

err_remove_link:
	sysfs_remove_link(&ar->dev->kobj, "cooling_device");
err_cooling_destroy:
	thermal_cooling_device_unregister(cdev);
	return ret;
}
Esempio n. 11
0
static void acpi_pss_perf_exit(struct acpi_processor *pr,
                               struct acpi_device *device)
{
    if (pr->cdev) {
        sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
        sysfs_remove_link(&pr->cdev->device.kobj, "device");
        thermal_cooling_device_unregister(pr->cdev);
        pr->cdev = NULL;
    }
}
static void yeeloong_thermal_exit(struct device *dev)
{
	if (yeeloong_thermal_cdev) {
		if (dev)
			sysfs_remove_link(&dev->kobj, "thermal_cooling");
		sysfs_remove_link(&yeeloong_thermal_cdev->device.kobj,
				  "device");
		thermal_cooling_device_unregister(yeeloong_thermal_cdev);
		yeeloong_thermal_cdev = NULL;
	}
}
Esempio n. 13
0
/*
 * acpi_processor_start() is called by the cpu_hotplug_notifier func:
 * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the
 * root cause seem to be that acpi_processor_uninstall_hotplug_notify()
 * is in the module_exit (__exit) func. Allowing acpi_processor_start()
 * to not be in __cpuinit section, but being called from __cpuinit funcs
 * via __ref looks like the right thing to do here.
 */
static __ref int acpi_processor_start(struct acpi_processor *pr)
{
	struct acpi_device *device = per_cpu(processor_device_array, pr->id);
	int result = 0;

#ifdef CONFIG_CPU_FREQ
	acpi_processor_ppc_has_changed(pr, 0);
	acpi_processor_load_module(pr);
#endif
	acpi_processor_get_throttling_info(pr);
	acpi_processor_get_limit_info(pr);

	if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
		acpi_processor_power_init(pr);

	pr->cdev = thermal_cooling_device_register("Processor", device,
						   &processor_cooling_ops);
	if (IS_ERR(pr->cdev)) {
		result = PTR_ERR(pr->cdev);
		goto err_power_exit;
	}

	dev_dbg(&device->dev, "registered as cooling_device%d\n",
		pr->cdev->id);

	result = sysfs_create_link(&device->dev.kobj,
				   &pr->cdev->device.kobj,
				   "thermal_cooling");
	if (result) {
		dev_err(&device->dev,
			"Failed to create sysfs link 'thermal_cooling'\n");
		goto err_thermal_unregister;
	}
	result = sysfs_create_link(&pr->cdev->device.kobj,
				   &device->dev.kobj,
				   "device");
	if (result) {
		dev_err(&pr->cdev->device,
			"Failed to create sysfs link 'device'\n");
		goto err_remove_sysfs_thermal;
	}

	return 0;

err_remove_sysfs_thermal:
	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
err_thermal_unregister:
	thermal_cooling_device_unregister(pr->cdev);
err_power_exit:
	acpi_processor_power_exit(pr);

	return result;
}
Esempio n. 14
0
int mwl_thermal_register(struct mwl_priv *priv)
{
	struct thermal_cooling_device *cdev;
	struct device *hwmon_dev;
	int ret;

	if (priv->chip_type != MWL8897)
		return 0;

	cdev = thermal_cooling_device_register("mwlwifi_thermal", priv,
					       &mwl_thermal_ops);
	if (IS_ERR(cdev)) {
		wiphy_err(priv->hw->wiphy,
			  "failed to setup thermal device result: %ld\n",
			  PTR_ERR(cdev));
		return -EINVAL;
	}

	ret = sysfs_create_link(&priv->dev->kobj, &cdev->device.kobj,
				"cooling_device");
	if (ret) {
		wiphy_err(priv->hw->wiphy,
			  "failed to create cooling device symlink\n");
		goto err_cooling_destroy;
	}

	priv->cdev = cdev;
	priv->quiet_period = SYSADPT_QUIET_PERIOD_DEFAULT;

	if (!IS_ENABLED(CONFIG_HWMON))
		return 0;

	hwmon_dev =
		devm_hwmon_device_register_with_groups(priv->dev,
						       "mwlwifi_hwmon", priv,
						       mwl_hwmon_groups);
	if (IS_ERR(hwmon_dev)) {
		wiphy_err(priv->hw->wiphy,
			  "failed to register hwmon device: %ld\n",
			  PTR_ERR(hwmon_dev));
		ret = -EINVAL;
		goto err_remove_link;
	}

	return 0;

err_remove_link:
	sysfs_remove_link(&priv->dev->kobj, "cooling_device");
err_cooling_destroy:
	thermal_cooling_device_unregister(cdev);

	return ret;
}
Esempio n. 15
0
File: fan.c Progetto: 08opt/linux
static int acpi_fan_remove(struct acpi_device *device, int type)
{
	struct thermal_cooling_device *cdev = acpi_driver_data(device);

	if (!device || !cdev)
		return -EINVAL;

	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
	sysfs_remove_link(&cdev->device.kobj, "device");
	thermal_cooling_device_unregister(cdev);

	return 0;
}
/**
 * gpufreq_cooling_unregister - function to remove gpufreq cooling device.
 * @cdev: thermal cooling device pointer.
 *
 * This interface function unregisters the "thermal-gpufreq-%x" cooling device.
 */
void gpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
{
	struct gpufreq_cooling_device *gpufreq_dev;

	if (!cdev)
		return;

	gpufreq_dev = cdev->devdata;

	thermal_cooling_device_unregister(gpufreq_dev->cool_dev);
	release_idr(&gpufreq_idr, gpufreq_dev->id);
	kfree(gpufreq_dev);
}
Esempio n. 17
0
static int acpi_pss_perf_init(struct acpi_processor *pr,
                              struct acpi_device *device)
{
    int result = 0;

    acpi_processor_ppc_has_changed(pr, 0);

    acpi_processor_get_throttling_info(pr);

    if (pr->flags.throttling)
        pr->flags.limit = 1;

    pr->cdev = thermal_cooling_device_register("Processor", device,
               &processor_cooling_ops);
    if (IS_ERR(pr->cdev)) {
        result = PTR_ERR(pr->cdev);
        return result;
    }

    dev_dbg(&device->dev, "registered as cooling_device%d\n",
            pr->cdev->id);

    result = sysfs_create_link(&device->dev.kobj,
                               &pr->cdev->device.kobj,
                               "thermal_cooling");
    if (result) {
        dev_err(&device->dev,
                "Failed to create sysfs link 'thermal_cooling'\n");
        goto err_thermal_unregister;
    }

    result = sysfs_create_link(&pr->cdev->device.kobj,
                               &device->dev.kobj,
                               "device");
    if (result) {
        dev_err(&pr->cdev->device,
                "Failed to create sysfs link 'device'\n");
        goto err_remove_sysfs_thermal;
    }

    return 0;

err_remove_sysfs_thermal:
    sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
err_thermal_unregister:
    thermal_cooling_device_unregister(pr->cdev);

    return result;
}
Esempio n. 18
0
/**
 * clock_cooling_unregister - function to remove clock cooling device.
 * @cdev: thermal cooling device pointer.
 *
 * This interface function unregisters the "thermal-clock-%x" cooling device.
 */
void clock_cooling_unregister(struct thermal_cooling_device *cdev)
{
	struct clock_cooling_device *ccdev;

	if (!cdev)
		return;

	ccdev = cdev->devdata;

	clk_notifier_unregister(ccdev->clk, &ccdev->clk_rate_change_nb);
	dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table);

	thermal_cooling_device_unregister(ccdev->cdev);
	release_idr(ccdev->id);
}
Esempio n. 19
0
static int pwm_fan_remove(struct platform_device *pdev)
{
	struct fan_dev_data *fan_data = platform_get_drvdata(pdev);

	if (!fan_data)
		return -EINVAL;
	debugfs_remove_recursive(fan_debugfs_root);
	free_irq(fan_data->tach_irq, NULL);
	gpio_free(fan_data->tach_gpio);
	pwm_config(fan_data->pwm_dev, 0, fan_data->pwm_period);
	pwm_disable(fan_data->pwm_dev);
	pwm_free(fan_data->pwm_dev);
	thermal_cooling_device_unregister(fan_data->cdev);
	remove_sysfs_entry(&pdev->dev);
	return 0;
}
Esempio n. 20
0
/**
 * isp_cooling_unregister - function to remove isp cooling device.
 * @cdev: thermal cooling device pointer.
 *
 * This interface function unregisters the "thermal-isp-%x" cooling device.
 */
void isp_cooling_unregister(struct thermal_cooling_device *cdev)
{
	struct isp_cooling_device *isp_dev;

	if (!cdev)
		return;

	isp_dev = cdev->devdata;
	mutex_lock(&cooling_isp_lock);
	isp_dev_count--;
	mutex_unlock(&cooling_isp_lock);

	thermal_cooling_device_unregister(isp_dev->cool_dev);
	release_idr(&isp_idr, isp_dev->id);
	kfree(isp_dev);
}
Esempio n. 21
0
/**
 * devfreq_cooling_unregister() - Unregister devfreq cooling device.
 * @dfc: Pointer to devfreq cooling device to unregister.
 */
void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
{
	struct devfreq_cooling_device *dfc;

	if (!cdev)
		return;

	dfc = cdev->devdata;

	thermal_cooling_device_unregister(dfc->cdev);
	ida_simple_remove(&devfreq_ida, dfc->id);
	kfree(dfc->power_table);
	kfree(dfc->freq_table);

	kfree(dfc);
}
Esempio n. 22
0
/**
 * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
 * @cdev: thermal cooling device pointer.
 *
 * This interface function unregisters the "thermal-cpufreq-%x" cooling device.
 */
void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
{
	struct cpufreq_cooling_device *cpufreq_dev = cdev->devdata;

	mutex_lock(&cooling_cpufreq_lock);
	cpufreq_dev_count--;

	/* Unregister the notifier for the last cpufreq cooling device */
	if (cpufreq_dev_count == 0)
		cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
					    CPUFREQ_POLICY_NOTIFIER);
	mutex_unlock(&cooling_cpufreq_lock);

	thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
	release_idr(&cpufreq_idr, cpufreq_dev->id);
	kfree(cpufreq_dev);
}
Esempio n. 23
0
static int acpi_processor_remove(struct acpi_device *device, int type)
{
	acpi_status status = AE_OK;
	struct acpi_processor *pr = NULL;


	if (!device || !acpi_driver_data(device))
		return -EINVAL;

	pr = acpi_driver_data(device);

	if (pr->id >= nr_cpu_ids)
		goto free;

	if (type == ACPI_BUS_REMOVAL_EJECT) {
		if (acpi_processor_handle_eject(pr))
			return -EINVAL;
	}

	acpi_processor_power_exit(pr, device);

	status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
					    acpi_processor_notify);

	sysfs_remove_link(&device->dev.kobj, "sysdev");

	acpi_processor_remove_fs(device);

	if (pr->cdev) {
		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
		sysfs_remove_link(&pr->cdev->device.kobj, "device");
		thermal_cooling_device_unregister(pr->cdev);
		pr->cdev = NULL;
	}

	per_cpu(processors, pr->id) = NULL;
	per_cpu(processor_device_array, pr->id) = NULL;

free:
	free_cpumask_var(pr->throttling.shared_cpu_map);
	kfree(pr);

	return 0;
}
Esempio n. 24
0
static int acpi_processor_remove(struct acpi_device *device)
{
	struct acpi_processor *pr = NULL;


	if (!device || !acpi_driver_data(device))
		return -EINVAL;

	pr = acpi_driver_data(device);

	if (pr->id >= nr_cpu_ids)
		goto free;

	if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) {
		if (acpi_processor_handle_eject(pr))
			return -EINVAL;
	}

	acpi_processor_power_exit(pr);

	sysfs_remove_link(&device->dev.kobj, "sysdev");

	if (pr->cdev) {
		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
		sysfs_remove_link(&pr->cdev->device.kobj, "device");
		thermal_cooling_device_unregister(pr->cdev);
		pr->cdev = NULL;
	}

	per_cpu(processors, pr->id) = NULL;
	per_cpu(processor_device_array, pr->id) = NULL;
	try_offline_node(cpu_to_node(pr->id));

free:
	free_cpumask_var(pr->throttling.shared_cpu_map);
	kfree(pr);

	return 0;
}
Esempio n. 25
0
static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
	struct acpi_processor *pr = NULL;
	int result = 0;
	struct sys_device *sysdev;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
		kfree(pr);
		return -ENOMEM;
	}

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

	result = acpi_processor_get_info(device);
	if (result) {
		/* Processor is physically not present */
		return 0;
	}

	BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));

	/*
	 * Buggy BIOS check
	 * ACPI id of processors can be reported wrongly by the BIOS.
	 * Don't trust it blindly
	 */
	if (per_cpu(processor_device_array, pr->id) != NULL &&
	    per_cpu(processor_device_array, pr->id) != device) {
		printk(KERN_WARNING "BIOS reported wrong ACPI id "
			"for the processor\n");
		result = -ENODEV;
		goto err_free_cpumask;
	}
	per_cpu(processor_device_array, pr->id) = device;

	per_cpu(processors, pr->id) = pr;

	result = acpi_processor_add_fs(device);
	if (result)
		goto err_free_cpumask;

	sysdev = get_cpu_sysdev(pr->id);
	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
		result = -EFAULT;
		goto err_remove_fs;
	}

	/* _PDC call should be done before doing anything else (if reqd.). */
	arch_acpi_processor_init_pdc(pr);
	acpi_processor_set_pdc(pr);
	arch_acpi_processor_cleanup_pdc(pr);

#ifdef CONFIG_CPU_FREQ
	acpi_processor_ppc_has_changed(pr);
#endif
	acpi_processor_get_throttling_info(pr);
	acpi_processor_get_limit_info(pr);


	acpi_processor_power_init(pr, device);

	pr->cdev = thermal_cooling_device_register("Processor", device,
						&processor_cooling_ops);
	if (IS_ERR(pr->cdev)) {
		result = PTR_ERR(pr->cdev);
		goto err_power_exit;
	}

	dev_info(&device->dev, "registered as cooling_device%d\n",
		 pr->cdev->id);

	result = sysfs_create_link(&device->dev.kobj,
				   &pr->cdev->device.kobj,
				   "thermal_cooling");
	if (result) {
		printk(KERN_ERR PREFIX "Create sysfs link\n");
		goto err_thermal_unregister;
	}
	result = sysfs_create_link(&pr->cdev->device.kobj,
				   &device->dev.kobj,
				   "device");
	if (result) {
		printk(KERN_ERR PREFIX "Create sysfs link\n");
		goto err_remove_sysfs;
	}

	return 0;

err_remove_sysfs:
	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
err_thermal_unregister:
	thermal_cooling_device_unregister(pr->cdev);
err_power_exit:
	acpi_processor_power_exit(pr, device);
err_remove_fs:
	acpi_processor_remove_fs(device);
err_free_cpumask:
	free_cpumask_var(pr->throttling.shared_cpu_map);

	return result;
}
Esempio n. 26
0
static int pwm_fan_probe(struct platform_device *pdev)
{
	int i;
	struct pwm_fan_platform_data *data;
	struct fan_dev_data *fan_data;
	int *rpm_data;
	int err = 0;

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

	fan_data = devm_kzalloc(&pdev->dev,
				sizeof(struct fan_dev_data), GFP_KERNEL);
	if (!fan_data)
		return -ENOMEM;

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

	fan_data->fan_rpm = rpm_data;
	fan_data->fan_pwm = rpm_data + data->active_steps;
	fan_data->fan_rru = fan_data->fan_pwm + data->active_steps;
	fan_data->fan_rrd = fan_data->fan_rru + data->active_steps;
	fan_data->fan_state_cap_lookup = fan_data->fan_rrd + data->active_steps;

	mutex_init(&fan_data->fan_state_lock);

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

	INIT_DELAYED_WORK(&(fan_data->fan_ramp_work), fan_ramping_work_func);

	fan_data->step_time = data->step_time;
	fan_data->active_steps = data->active_steps;
	fan_data->pwm_period = data->pwm_period;
	fan_data->fan_pwm_max = data->active_pwm_max;
	fan_data->dev = &pdev->dev;
	fan_data->fan_state_cap = data->state_cap;
	fan_data->pwm_gpio = data->pwm_gpio;
	fan_data->pwm_id = data->pwm_id;

	for (i = 0; i < fan_data->active_steps; i++) {
		fan_data->fan_rpm[i] = data->active_rpm[i];
		fan_data->fan_pwm[i] = data->active_pwm[i];
		fan_data->fan_rru[i] = data->active_rru[i];
		fan_data->fan_rrd[i] = data->active_rrd[i];
		fan_data->fan_state_cap_lookup[i] = data->state_cap_lookup[i];
		dev_info(&pdev->dev,
			"rpm=%d, pwm=%d, rru=%d, rrd=%d state:%d\n",
			fan_data->fan_rpm[i],
			fan_data->fan_pwm[i],
			fan_data->fan_rru[i],
			fan_data->fan_rrd[i],
			fan_data->fan_state_cap_lookup[i]);
	}
	fan_data->fan_cap_pwm = data->active_pwm[data->state_cap];
	fan_data->precision_multiplier =
			data->pwm_period / data->active_pwm_max;
	dev_info(&pdev->dev, "cap state:%d, cap pwm:%d\n",
			fan_data->fan_state_cap, fan_data->fan_cap_pwm);

	fan_data->cdev =
		thermal_cooling_device_register((char *)dev_name(&pdev->dev),
					fan_data, &pwm_fan_cooling_ops);

	if (IS_ERR_OR_NULL(fan_data->cdev)) {
		dev_err(&pdev->dev, "Failed to register cooling device\n");
		return -EINVAL;
	}

	gpio_free(fan_data->pwm_gpio);
	fan_data->pwm_dev = pwm_request(data->pwm_id, dev_name(&pdev->dev));
	if (IS_ERR_OR_NULL(fan_data->pwm_dev)) {
		dev_err(&pdev->dev, "unable to request PWM for fan\n");
		err = -ENODEV;
		goto pwm_req_fail;
	} else {
		dev_info(&pdev->dev, "got pwm for fan\n");
	}


	fan_data->tach_gpio = data->tach_gpio;
	fan_data->tach_enabled = 0;

	if (fan_data->tach_gpio != -1) {
		/* init fan tach */
		fan_data->tach_irq = gpio_to_irq(fan_data->tach_gpio);
		err = gpio_request(fan_data->tach_gpio, "pwm-fan-tach");
		if (err < 0) {
			dev_err(&pdev->dev, "fan tach gpio request failed\n");
			goto tach_gpio_request_fail;
		}

		err = gpio_direction_input(fan_data->tach_gpio);
		if (err < 0) {
			dev_err(&pdev->dev, "fan tach set gpio direction input failed\n");
			goto tach_request_irq_fail;
		}

		err = gpio_sysfs_set_active_low(fan_data->tach_gpio, 1);
		if (err < 0) {
			dev_err(&pdev->dev, "fan tach set gpio active low failed\n");
			goto tach_request_irq_fail;
		}

		err = request_irq(fan_data->tach_irq, fan_tach_isr,
			IRQF_TRIGGER_FALLING , "pwm-fan-tach", NULL);
		if (err < 0)
			goto tach_request_irq_fail;
		disable_irq_nosync(fan_data->tach_irq);
	}

	platform_set_drvdata(pdev, fan_data);

	/*turn temp control on*/
	fan_data->fan_temp_control_flag = 1;
	set_pwm_duty_cycle(fan_data->fan_pwm[0], fan_data);

	if (add_sysfs_entry(&pdev->dev) < 0) {
		dev_err(&pdev->dev, "FAN:Can't create syfs node");
		err = -ENOMEM;
		goto sysfs_fail;
	}

	if (pwm_fan_debug_init(fan_data) < 0) {
		dev_err(&pdev->dev, "FAN:Can't create debug fs nodes");
		/*Just continue without debug fs*/
	}
	return err;

sysfs_fail:
	pwm_free(fan_data->pwm_dev);
	free_irq(fan_data->tach_irq, NULL);
tach_request_irq_fail:
	gpio_free(fan_data->tach_gpio);
tach_gpio_request_fail:
pwm_req_fail:
	thermal_cooling_device_unregister(fan_data->cdev);
	return err;
}
Esempio n. 27
0
static int __acpi_processor_start(struct acpi_device *device)
{
	struct acpi_processor *pr = acpi_driver_data(device);
	acpi_status status;
	int result = 0;

	if (!pr)
		return -ENODEV;

	if (pr->flags.need_hotplug_init)
		return 0;

#ifdef CONFIG_CPU_FREQ
	acpi_processor_ppc_has_changed(pr, 0);
	acpi_processor_load_module(pr);
#endif
	acpi_processor_get_throttling_info(pr);
	acpi_processor_get_limit_info(pr);

	if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
		acpi_processor_power_init(pr);

	pr->cdev = thermal_cooling_device_register("Processor", device,
						   &processor_cooling_ops);
	if (IS_ERR(pr->cdev)) {
		result = PTR_ERR(pr->cdev);
		goto err_power_exit;
	}

	dev_dbg(&device->dev, "registered as cooling_device%d\n",
		pr->cdev->id);

	result = sysfs_create_link(&device->dev.kobj,
				   &pr->cdev->device.kobj,
				   "thermal_cooling");
	if (result) {
		dev_err(&device->dev,
			"Failed to create sysfs link 'thermal_cooling'\n");
		goto err_thermal_unregister;
	}
	result = sysfs_create_link(&pr->cdev->device.kobj,
				   &device->dev.kobj,
				   "device");
	if (result) {
		dev_err(&pr->cdev->device,
			"Failed to create sysfs link 'device'\n");
		goto err_remove_sysfs_thermal;
	}

	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
					     acpi_processor_notify, device);
	if (ACPI_SUCCESS(status))
		return 0;

	sysfs_remove_link(&pr->cdev->device.kobj, "device");
 err_remove_sysfs_thermal:
	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
 err_thermal_unregister:
	thermal_cooling_device_unregister(pr->cdev);
 err_power_exit:
	acpi_processor_power_exit(pr);
	return result;
}
Esempio n. 28
0
static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
	struct acpi_processor *pr = NULL;
	int result = 0;
	struct sys_device *sysdev;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
		kfree(pr);
		return -ENOMEM;
	}

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

 	processor_extcntl_init();

	result = acpi_processor_get_info(device);
	if (result ||
	    ((pr->id == -1) && !processor_cntl_external())) {
		/* Processor is physically not present */
		return 0;
	}

	BUG_ON(!processor_cntl_external() &&
	       ((pr->id >= nr_cpu_ids) || (pr->id < 0)));

	/*
	 * Buggy BIOS check
	 * ACPI id of processors can be reported wrongly by the BIOS.
	 * Don't trust it blindly
	 */
#ifndef CONFIG_XEN
	if (per_cpu(processor_device_array, pr->id) != NULL &&
	    per_cpu(processor_device_array, pr->id) != device) {
#else
	BUG_ON(pr->acpi_id >= NR_ACPI_CPUS);
	if (processor_device_array[pr->acpi_id] != NULL &&
	    processor_device_array[pr->acpi_id] != device) {
#endif
		printk(KERN_WARNING "BIOS reported wrong ACPI id "
			"for the processor\n");
		result = -ENODEV;
		goto err_free_cpumask;
	}
#ifndef CONFIG_XEN
	per_cpu(processor_device_array, pr->id) = device;

	per_cpu(processors, pr->id) = pr;
#else
	processor_device_array[pr->acpi_id] = device;
	if (pr->id != -1)
		per_cpu(processors, pr->id) = pr;
#endif

	result = acpi_processor_add_fs(device);
	if (result)
		goto err_free_cpumask;

	if (pr->id != -1) {
		sysdev = get_cpu_sysdev(pr->id);
		if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
			result = -EFAULT;
			goto err_remove_fs;
		}
	}

	/* _PDC call should be done before doing anything else (if reqd.). */
	arch_acpi_processor_init_pdc(pr);
	acpi_processor_set_pdc(pr);
	arch_acpi_processor_cleanup_pdc(pr);

#if defined(CONFIG_CPU_FREQ) || defined(CONFIG_PROCESSOR_EXTERNAL_CONTROL)
	acpi_processor_ppc_has_changed(pr);
#endif

	/*
	 * pr->id may equal to -1 while processor_cntl_external enabled.
	 * throttle and thermal module don't support this case.
	 * Tx only works when dom0 vcpu == pcpu num by far, as we give
	 * control to dom0.
	 */
	if (pr->id != -1) {
		acpi_processor_get_throttling_info(pr);
		acpi_processor_get_limit_info(pr);
	}

	acpi_processor_power_init(pr, device);

	result = processor_extcntl_prepare(pr);
	if (result)
		goto err_power_exit;

	pr->cdev = thermal_cooling_device_register("Processor", device,
						&processor_cooling_ops);
	if (IS_ERR(pr->cdev)) {
		result = PTR_ERR(pr->cdev);
		goto err_power_exit;
	}

	dev_info(&device->dev, "registered as cooling_device%d\n",
		 pr->cdev->id);

	result = sysfs_create_link(&device->dev.kobj,
				   &pr->cdev->device.kobj,
				   "thermal_cooling");
	if (result) {
		printk(KERN_ERR PREFIX "Create sysfs link\n");
		goto err_thermal_unregister;
	}
	result = sysfs_create_link(&pr->cdev->device.kobj,
				   &device->dev.kobj,
				   "device");
	if (result) {
		printk(KERN_ERR PREFIX "Create sysfs link\n");
		goto err_remove_sysfs;
	}

	return 0;

err_remove_sysfs:
	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
err_thermal_unregister:
	thermal_cooling_device_unregister(pr->cdev);
err_power_exit:
	acpi_processor_power_exit(pr, device);
err_remove_fs:
	acpi_processor_remove_fs(device);
err_free_cpumask:
	free_cpumask_var(pr->throttling.shared_cpu_map);

	return result;
}

static int acpi_processor_remove(struct acpi_device *device, int type)
{
	struct acpi_processor *pr = NULL;


	if (!device || !acpi_driver_data(device))
		return -EINVAL;

	pr = acpi_driver_data(device);

	if (!processor_cntl_external() && pr->id >= nr_cpu_ids)
		goto free;

	if (type == ACPI_BUS_REMOVAL_EJECT) {
		if (acpi_processor_handle_eject(pr))
			return -EINVAL;
	}

	acpi_processor_power_exit(pr, device);

	if (pr->id != -1)
		sysfs_remove_link(&device->dev.kobj, "sysdev");

	acpi_processor_remove_fs(device);

	if (pr->cdev) {
		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
		sysfs_remove_link(&pr->cdev->device.kobj, "device");
		thermal_cooling_device_unregister(pr->cdev);
		pr->cdev = NULL;
	}

#ifndef CONFIG_XEN
	per_cpu(processors, pr->id) = NULL;
	per_cpu(processor_device_array, pr->id) = NULL;
#else
	if (pr->id != -1)
		per_cpu(processors, pr->id) = NULL;
	processor_device_array[pr->acpi_id] = NULL;
#endif

free:
	free_cpumask_var(pr->throttling.shared_cpu_map);
	kfree(pr);

	return 0;
}

#ifdef CONFIG_ACPI_HOTPLUG_CPU
/****************************************************************************
 * 	Acpi processor hotplug support 				       	    *
 ****************************************************************************/

static int is_processor_present(acpi_handle handle)
{
	acpi_status status;
	unsigned long long sta = 0;


	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);

	if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
		return 1;

	/*
	 * _STA is mandatory for a processor that supports hot plug
	 */
	if (status == AE_NOT_FOUND)
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				"Processor does not support hot plug\n"));
	else
		ACPI_EXCEPTION((AE_INFO, status,
				"Processor Device is not present"));
	return 0;
}
static int pwm_fan_probe(struct platform_device *pdev)
{
	int i;
	struct fan_dev_data *fan_data = NULL;
	int *rpm_data;
	int *rru_data;
	int *rrd_data;
	int *lookup_data;
	int *pwm_data;
	int err = 0;
	int of_err = 0;
	struct device_node *node = NULL;
	struct device_node *data_node = NULL;
	u32 value;
	int pwm_fan_gpio;
	int gpio_free_flag = 0;

	if (!pdev)
		return -EINVAL;

	node = pdev->dev.of_node;
	if (!node) {
		pr_err("FAN: dev of_node NULL\n");
		return -EINVAL;
	}

	data_node = of_parse_phandle(node, "shared_data", 0);
	if (!data_node) {
		pr_err("PWM shared data node NULL, parse phandle failed\n");
		return -EINVAL;
	}

	fan_data = devm_kzalloc(&pdev->dev,
				sizeof(struct fan_dev_data), GFP_KERNEL);
	if (!fan_data)
		return -ENOMEM;

	fan_data->dev = &pdev->dev;

	fan_data->fan_reg = regulator_get(fan_data->dev, "vdd-fan");
	if (IS_ERR_OR_NULL(fan_data->fan_reg)) {
		pr_err("FAN: coudln't get the regulator\n");
		devm_kfree(&pdev->dev, (void *)fan_data);
		return -ENODEV;
	}

	of_err |= of_property_read_string(node, "name", &fan_data->name);
	pr_info("FAN dev name: %s\n", fan_data->name);

	of_err |= of_property_read_u32(data_node, "pwm_gpio", &value);
	pwm_fan_gpio = (int)value;

	err = gpio_request(pwm_fan_gpio, "pwm-fan");
	if (err < 0) {
		pr_err("FAN:gpio request failed\n");
		err = -EINVAL;
		goto gpio_request_fail;
	} else {
		pr_info("FAN:gpio request success.\n");
	}

	of_err |= of_property_read_u32(data_node, "active_steps", &value);
	fan_data->active_steps = (int)value;

	of_err |= of_property_read_u32(data_node, "pwm_period", &value);
	fan_data->pwm_period = (int)value;

	of_err |= of_property_read_u32(data_node, "pwm_id", &value);
	fan_data->pwm_id = (int)value;

	of_err |= of_property_read_u32(data_node, "step_time", &value);
	fan_data->step_time = (int)value;

	of_err |= of_property_read_u32(data_node, "active_pwm_max", &value);
	fan_data->fan_pwm_max = (int)value;

	of_err |= of_property_read_u32(data_node, "state_cap", &value);
	fan_data->fan_state_cap = (int)value;

	fan_data->pwm_gpio = pwm_fan_gpio;

	if (of_err) {
		err = -ENXIO;
		goto rpm_alloc_fail;
	}

	if (of_property_read_u32(data_node, "tach_gpio", &value)) {
		fan_data->tach_gpio = -1;
		pr_info("FAN: can't find tach_gpio\n");
	} else
		fan_data->tach_gpio = (int)value;

	/* rpm array */
	rpm_data = devm_kzalloc(&pdev->dev,
			sizeof(int) * (fan_data->active_steps), GFP_KERNEL);
	if (!rpm_data) {
		err = -ENOMEM;
		goto rpm_alloc_fail;
	}
	of_err |= of_property_read_u32_array(data_node, "active_rpm", rpm_data,
		(size_t) fan_data->active_steps);
	fan_data->fan_rpm = rpm_data;

	/* rru array */
	rru_data = devm_kzalloc(&pdev->dev,
			sizeof(int) * (fan_data->active_steps), GFP_KERNEL);
	if (!rru_data) {
		err = -ENOMEM;
		goto rru_alloc_fail;
	}
	of_err |= of_property_read_u32_array(data_node, "active_rru", rru_data,
		(size_t) fan_data->active_steps);
	fan_data->fan_rru = rru_data;

	/* rrd array */
	rrd_data = devm_kzalloc(&pdev->dev,
			sizeof(int) * (fan_data->active_steps), GFP_KERNEL);
	if (!rrd_data) {
		err = -ENOMEM;
		goto rrd_alloc_fail;
	}
	of_err |= of_property_read_u32_array(data_node, "active_rrd", rrd_data,
		(size_t) fan_data->active_steps);
	fan_data->fan_rrd = rrd_data;

	/* state_cap_lookup array */
	lookup_data = devm_kzalloc(&pdev->dev,
			sizeof(int) * (fan_data->active_steps), GFP_KERNEL);
	if (!lookup_data) {
		err = -ENOMEM;
		goto lookup_alloc_fail;
	}
	of_err |= of_property_read_u32_array(data_node, "state_cap_lookup",
		lookup_data, (size_t) fan_data->active_steps);
	fan_data->fan_state_cap_lookup = lookup_data;

	/* pwm array */
	pwm_data = devm_kzalloc(&pdev->dev,
			sizeof(int) * (fan_data->active_steps), GFP_KERNEL);
	if (!pwm_data) {
		err = -ENOMEM;
		goto pwm_alloc_fail;
	}
	of_err |= of_property_read_u32_array(node, "active_pwm", pwm_data,
		(size_t) fan_data->active_steps);
	fan_data->fan_pwm = pwm_data;

	if (of_err) {
		err = -ENXIO;
		goto workqueue_alloc_fail;
	}

	mutex_init(&fan_data->fan_state_lock);
	fan_data->workqueue = alloc_workqueue(dev_name(&pdev->dev),
				WQ_HIGHPRI | WQ_UNBOUND, 1);
	if (!fan_data->workqueue) {
		err = -ENOMEM;
		goto workqueue_alloc_fail;
	}

	INIT_DELAYED_WORK(&(fan_data->fan_ramp_work), fan_ramping_work_func);

	fan_data->fan_cap_pwm = fan_data->fan_pwm[fan_data->fan_state_cap];
	fan_data->precision_multiplier =
			fan_data->pwm_period / fan_data->fan_pwm_max;
	dev_info(&pdev->dev, "cap state:%d, cap pwm:%d\n",
			fan_data->fan_state_cap, fan_data->fan_cap_pwm);

	fan_data->cdev =
		thermal_cooling_device_register("pwm-fan",
					fan_data, &pwm_fan_cooling_ops);

	if (IS_ERR_OR_NULL(fan_data->cdev)) {
		dev_err(&pdev->dev, "Failed to register cooling device\n");
		err = -EINVAL;
		goto cdev_register_fail;
	}

	fan_data->pwm_dev = pwm_request(fan_data->pwm_id, dev_name(&pdev->dev));
	if (IS_ERR_OR_NULL(fan_data->pwm_dev)) {
		dev_err(&pdev->dev, "unable to request PWM for fan\n");
		err = -ENODEV;
		goto pwm_req_fail;
	} else {
		dev_info(&pdev->dev, "got pwm for fan\n");
	}

	fan_data->tach_enabled = 0;
	gpio_free(fan_data->pwm_gpio);
	gpio_free_flag = 1;
	if (fan_data->tach_gpio != -1) {
		/* init fan tach */
		fan_data->tach_irq = gpio_to_irq(fan_data->tach_gpio);
		err = gpio_request(fan_data->tach_gpio, "pwm-fan-tach");
		if (err < 0) {
			dev_err(&pdev->dev, "fan tach gpio request failed\n");
			goto tach_gpio_request_fail;
		}

		gpio_free_flag = 0;
		err = gpio_direction_input(fan_data->tach_gpio);
		if (err < 0) {
			dev_err(&pdev->dev, "fan tach set gpio direction input failed\n");
			goto tach_request_irq_fail;
		}

		err = gpio_sysfs_set_active_low(fan_data->tach_gpio, 1);
		if (err < 0) {
			dev_err(&pdev->dev, "fan tach set gpio active low failed\n");
			goto tach_request_irq_fail;
		}

		err = request_irq(fan_data->tach_irq, fan_tach_isr,
			IRQF_TRIGGER_RISING,
			"pwm-fan-tach", NULL);
		if (err < 0) {
			dev_err(&pdev->dev, "fan request irq failed\n");
			goto tach_request_irq_fail;
		}
		dev_info(&pdev->dev, "fan tach request irq: %d. success\n",
				fan_data->tach_irq);
		disable_irq_nosync(fan_data->tach_irq);
	}

	of_err |= of_property_read_u32(data_node, "tach_period", &value);
	if (of_err < 0)
		dev_err(&pdev->dev, "parsing tach_period error: %d\n", of_err);
	else {
		fan_data->tach_period = (int) value;
		dev_info(&pdev->dev, "tach period: %d\n", fan_data->tach_period);

		/* init tach work related */
		fan_data->tach_workqueue = alloc_workqueue(fan_data->name,
				WQ_HIGHPRI | WQ_UNBOUND, 1);
		if (!fan_data->tach_workqueue) {
			err = -ENOMEM;
			goto tach_workqueue_alloc_fail;
		}
		INIT_DELAYED_WORK(&(fan_data->fan_tach_work),
				fan_tach_work_func);
		queue_delayed_work(fan_data->tach_workqueue,
				&(fan_data->fan_tach_work),
				msecs_to_jiffies(fan_data->tach_period));
	}
	/* init rpm related values */
	spin_lock_init(&irq_lock);
	irq_count = 0;
	fan_data->rpm_measured = 0;

	/*turn temp control on*/
	fan_data->fan_temp_control_flag = 1;
	set_pwm_duty_cycle(fan_data->fan_pwm[0], fan_data);

	platform_set_drvdata(pdev, fan_data);

	if (add_sysfs_entry(&pdev->dev) < 0) {
		dev_err(&pdev->dev, "FAN:Can't create syfs node");
		err = -ENOMEM;
		goto sysfs_fail;
	}

	if (pwm_fan_debug_init(fan_data) < 0) {
		dev_err(&pdev->dev, "FAN:Can't create debug fs nodes");
		/*Just continue without debug fs*/
	}

	/* print out initialized info */
	for (i = 0; i < fan_data->active_steps; i++) {
		dev_info(&pdev->dev,
			"index %d: pwm=%d, rpm=%d, rru=%d, rrd=%d, state:%d\n",
			i,
			fan_data->fan_pwm[i],
			fan_data->fan_rpm[i],
			fan_data->fan_rru[i],
			fan_data->fan_rrd[i],
			fan_data->fan_state_cap_lookup[i]);
	}

	return err;

sysfs_fail:
	destroy_workqueue(fan_data->tach_workqueue);
tach_workqueue_alloc_fail:
	free_irq(fan_data->tach_irq, NULL);
tach_request_irq_fail:
tach_gpio_request_fail:
	pwm_free(fan_data->pwm_dev);
pwm_req_fail:
	thermal_cooling_device_unregister(fan_data->cdev);
cdev_register_fail:
	destroy_workqueue(fan_data->workqueue);
workqueue_alloc_fail:
	devm_kfree(&pdev->dev, (void *)pwm_data);
pwm_alloc_fail:
	devm_kfree(&pdev->dev, (void *)lookup_data);
lookup_alloc_fail:
	devm_kfree(&pdev->dev, (void *)rrd_data);
rrd_alloc_fail:
	devm_kfree(&pdev->dev, (void *)rru_data);
rru_alloc_fail:
	devm_kfree(&pdev->dev, (void *)rpm_data);
rpm_alloc_fail:
	if (!gpio_free_flag)
		gpio_free(fan_data->pwm_gpio);
gpio_request_fail:
	devm_kfree(&pdev->dev, (void *)fan_data);
	if (err == -ENXIO)
		pr_err("FAN: of_property_read failed\n");
	else if (err == -ENOMEM)
		pr_err("FAN: memery allocation failed\n");
	return err;
}
Esempio n. 30
0
void ath10k_thermal_unregister(struct ath10k *ar)
{
	sysfs_remove_link(&ar->dev->kobj, "cooling_device");
	thermal_cooling_device_unregister(ar->thermal.cdev);
}