コード例 #1
0
ファイル: rockchip_thermal.c プロジェクト: 383530895/linux
static int rockchip_thermal_remove(struct platform_device *pdev)
{
	struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) {
		struct rockchip_thermal_sensor *sensor = &thermal->sensors[i];

		rockchip_thermal_toggle_sensor(sensor, false);
		thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd);
	}

	thermal->chip->control(thermal->regs, false);

	clk_disable_unprepare(thermal->pclk);
	clk_disable_unprepare(thermal->clk);

	return 0;
}
コード例 #2
0
ファイル: tmp102.c プロジェクト: DenisLug/mptcp
static int tmp102_remove(struct i2c_client *client)
{
	struct tmp102 *tmp102 = i2c_get_clientdata(client);

	thermal_zone_of_sensor_unregister(tmp102->hwmon_dev, tmp102->tz);
	hwmon_device_unregister(tmp102->hwmon_dev);

	/* Stop monitoring if device was stopped originally */
	if (tmp102->config_orig & TMP102_CONF_SD) {
		int config;

		config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
		if (config >= 0)
			i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
						     config | TMP102_CONF_SD);
	}

	return 0;
}
コード例 #3
0
ファイル: hisi_thermal.c プロジェクト: guanhe0/kernel
static int hisi_thermal_remove(struct platform_device *pdev)
{
	struct hisi_thermal_data *data = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < HISI_MAX_SENSORS; i++) {
		struct hisi_thermal_sensor *sensor = &data->sensors[i];

		if (!sensor->tzd)
			continue;

		hisi_thermal_toggle_sensor(sensor, false);
		thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd);
	}

	hisi_thermal_disable_sensor(data);
	clk_disable_unprepare(data->clk);

	return 0;
}
コード例 #4
0
ファイル: rockchip_thermal.c プロジェクト: Abioy/ktsan
static int rockchip_thermal_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct rockchip_thermal_data *thermal;
	const struct of_device_id *match;
	struct resource *res;
	int irq;
	int i;
	int error;

	match = of_match_node(of_rockchip_thermal_match, np);
	if (!match)
		return -ENXIO;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no irq resource?\n");
		return -EINVAL;
	}

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

	thermal->pdev = pdev;

	thermal->chip = (const struct rockchip_tsadc_chip *)match->data;
	if (!thermal->chip)
		return -EINVAL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	thermal->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(thermal->regs))
		return PTR_ERR(thermal->regs);

	thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb");
	if (IS_ERR(thermal->reset)) {
		error = PTR_ERR(thermal->reset);
		dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error);
		return error;
	}

	thermal->clk = devm_clk_get(&pdev->dev, "tsadc");
	if (IS_ERR(thermal->clk)) {
		error = PTR_ERR(thermal->clk);
		dev_err(&pdev->dev, "failed to get tsadc clock: %d\n", error);
		return error;
	}

	thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
	if (IS_ERR(thermal->pclk)) {
		error = PTR_ERR(thermal->clk);
		dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n",
			error);
		return error;
	}

	error = clk_prepare_enable(thermal->clk);
	if (error) {
		dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
			error);
		return error;
	}

	error = clk_prepare_enable(thermal->pclk);
	if (error) {
		dev_err(&pdev->dev, "failed to enable pclk: %d\n", error);
		goto err_disable_clk;
	}

	rockchip_thermal_reset_controller(thermal->reset);

	error = rockchip_configure_from_dt(&pdev->dev, np, thermal);
	if (error) {
		dev_err(&pdev->dev, "failed to parse device tree data: %d\n",
			error);
		goto err_disable_pclk;
	}

	thermal->chip->initialize(thermal->regs, thermal->tshut_polarity);

	error = rockchip_thermal_register_sensor(pdev, thermal,
						 &thermal->sensors[0],
						 SENSOR_CPU);
	if (error) {
		dev_err(&pdev->dev,
			"failed to register CPU thermal sensor: %d\n", error);
		goto err_disable_pclk;
	}

	error = rockchip_thermal_register_sensor(pdev, thermal,
						 &thermal->sensors[1],
						 SENSOR_GPU);
	if (error) {
		dev_err(&pdev->dev,
			"failed to register GPU thermal sensor: %d\n", error);
		goto err_unregister_cpu_sensor;
	}

	error = devm_request_threaded_irq(&pdev->dev, irq, NULL,
					  &rockchip_thermal_alarm_irq_thread,
					  IRQF_ONESHOT,
					  "rockchip_thermal", thermal);
	if (error) {
		dev_err(&pdev->dev,
			"failed to request tsadc irq: %d\n", error);
		goto err_unregister_gpu_sensor;
	}

	thermal->chip->control(thermal->regs, true);

	for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++)
		rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);

	platform_set_drvdata(pdev, thermal);

	return 0;

err_unregister_gpu_sensor:
	thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[1].tzd);
err_unregister_cpu_sensor:
	thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[0].tzd);
err_disable_pclk:
	clk_disable_unprepare(thermal->pclk);
err_disable_clk:
	clk_disable_unprepare(thermal->clk);

	return error;
}
コード例 #5
0
ファイル: bcm2835_thermal.c プロジェクト: mdamt/linux
static int bcm2835_thermal_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	struct thermal_zone_device *tz;
	struct bcm2835_thermal_data *data;
	struct resource *res;
	int err = 0;
	u32 val;
	unsigned long rate;

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

	match = of_match_device(bcm2835_thermal_of_match_table,
				&pdev->dev);
	if (!match)
		return -EINVAL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	data->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(data->regs)) {
		err = PTR_ERR(data->regs);
		dev_err(&pdev->dev, "Could not get registers: %d\n", err);
		return err;
	}

	data->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(data->clk)) {
		err = PTR_ERR(data->clk);
		if (err != -EPROBE_DEFER)
			dev_err(&pdev->dev, "Could not get clk: %d\n", err);
		return err;
	}

	err = clk_prepare_enable(data->clk);
	if (err)
		return err;

	rate = clk_get_rate(data->clk);
	if ((rate < 1920000) || (rate > 5000000))
		dev_warn(&pdev->dev,
			 "Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n",
			 data->clk, data->clk);

	/* register of thermal sensor and get info from DT */
	tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
					     &bcm2835_thermal_ops);
	if (IS_ERR(tz)) {
		err = PTR_ERR(tz);
		dev_err(&pdev->dev,
			"Failed to register the thermal device: %d\n",
			err);
		goto err_clk;
	}

	/*
	 * right now the FW does set up the HW-block, so we are not
	 * touching the configuration registers.
	 * But if the HW is not enabled, then set it up
	 * using "sane" values used by the firmware right now.
	 */
	val = readl(data->regs + BCM2835_TS_TSENSCTL);
	if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
		int trip_temp, offset, slope;

		slope = thermal_zone_get_slope(tz);
		offset = thermal_zone_get_offset(tz);
		/*
		 * For now we deal only with critical, otherwise
		 * would need to iterate
		 */
		err = tz->ops->get_trip_temp(tz, 0, &trip_temp);
		if (err < 0) {
			dev_err(&pdev->dev,
				"Not able to read trip_temp: %d\n",
				err);
			goto err_tz;
		}

		/* set bandgap reference voltage and enable voltage regulator */
		val = (BCM2835_TS_TSENSCTL_CTRL_DEFAULT <<
		       BCM2835_TS_TSENSCTL_CTRL_SHIFT) |
		      BCM2835_TS_TSENSCTL_REGULEN;

		/* use the recommended reset duration */
		val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);

		/*  trip_adc value from info */
		val |= bcm2835_thermal_temp2adc(trip_temp,
						offset,
						slope)
			<< BCM2835_TS_TSENSCTL_THOLD_SHIFT;

		/* write the value back to the register as 2 steps */
		writel(val, data->regs + BCM2835_TS_TSENSCTL);
		val |= BCM2835_TS_TSENSCTL_RSTB;
		writel(val, data->regs + BCM2835_TS_TSENSCTL);
	}

	data->tz = tz;

	platform_set_drvdata(pdev, tz);

	bcm2835_thermal_debugfs(pdev);

	return 0;
err_tz:
	thermal_zone_of_sensor_unregister(&pdev->dev, tz);
err_clk:
	clk_disable_unprepare(data->clk);

	return err;
}
コード例 #6
0
ファイル: of-thermal.c プロジェクト: Lyude/linux
static void devm_thermal_zone_of_sensor_release(struct device *dev, void *res)
{
	thermal_zone_of_sensor_unregister(dev,
					  *(struct thermal_zone_device **)res);
}