Commit 19785cf9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal

Pull thermal SoC updates from Zhang Rui:
 "Thermal SoC management updates:

   - imx thermal driver now supports i.MX7 thermal sensor (Anson Huang)

   - exynos thermal driver dropped support for exynos 5440 (Krzysztof
     Kozlowski)

   - rcar_thermal now supports r8a77995 (Yoshihiro Kaneko)

   - rcar_gen3_thermal now supports r8a77965 (Niklas Söderlund)

   - qcom-spmi-temp-alarm now supports GEN2 PMIC peripherals (David
     Collins)

   - uniphier thermal now supports UniPhier PXs3 (Kunihiko Hayashi)

   - mediatek thermal now supports MT7622 SoC (Sean Wang)

   - considerable refactoring of exynos driver (Bartlomiej
     Zolnierkiewicz)

   - small fixes all over the place on different drivers"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (50 commits)
  thermal: qcom: tsens: Allow number of sensors to come from DT
  thermal: tegra: soctherm: add const to struct thermal_cooling_device_ops
  thermal: exynos: Reduce severity of too early temperature read
  thermal: imx: Switch to SPDX identifier
  thermal: qcom-spmi-temp-alarm: add support for GEN2 PMIC peripherals
  thermal: ti-soc-thermal: fix incorrect entry in omap5430_adc_to_temp[]
  thermal: rcar_thermal: add r8a77995 support
  dt-bindings: thermal: rcar-thermal: add R8A77995 support
  thermal: mediatek: use of_device_get_match_data()
  thermal: exynos: remove trip reporting to user-space
  thermal: exynos: remove unused defines for Exynos5433
  thermal: exynos: cleanup code for enabling threshold interrupts
  thermal: exynos: check return values of ->get_trip_[temp, hyst] methods
  thermal: exynos: move trips setting to exynos_tmu_initialize()
  thermal: exynos: set trips in ascending order in exynos7_tmu_initialize()
  thermal: exynos: do not use trips structure directly in ->tmu_initialize
  thermal: exynos: add exynos*_tmu_set_[trip,hyst]() helpers
  thermal: exynos: move IRQs clearing to exynos_tmu_initialize()
  thermal: exynos: clear IRQs later in exynos4412_tmu_initialize()
  thermal: exynos: make ->tmu_initialize method void
  ...
parents 98db5e55 6d7c70d1
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
"samsung,exynos5420-tmu-ext-triminfo" for TMU channels 2, 3 and 4 "samsung,exynos5420-tmu-ext-triminfo" for TMU channels 2, 3 and 4
Exynos5420 (Must pass triminfo base and triminfo clock) Exynos5420 (Must pass triminfo base and triminfo clock)
"samsung,exynos5433-tmu" "samsung,exynos5433-tmu"
"samsung,exynos5440-tmu"
"samsung,exynos7-tmu" "samsung,exynos7-tmu"
- interrupt-parent : The phandle for the interrupt controller - interrupt-parent : The phandle for the interrupt controller
- reg : Address range of the thermal registers. For soc's which has multiple - reg : Address range of the thermal registers. For soc's which has multiple
...@@ -68,18 +67,7 @@ Example 1): ...@@ -68,18 +67,7 @@ Example 1):
#thermal-sensor-cells = <0>; #thermal-sensor-cells = <0>;
}; };
Example 2): Example 2): (In case of Exynos5420 "with misplaced TRIMINFO register")
tmuctrl_0: tmuctrl@160118 {
compatible = "samsung,exynos5440-tmu";
reg = <0x160118 0x230>, <0x160368 0x10>;
interrupts = <0 58 0>;
clocks = <&clock 21>;
clock-names = "tmu_apbif";
#thermal-sensor-cells = <0>;
};
Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
tmu_cpu2: tmu@10068000 { tmu_cpu2: tmu@10068000 {
compatible = "samsung,exynos5420-tmu-ext-triminfo"; compatible = "samsung,exynos5420-tmu-ext-triminfo";
reg = <0x10068000 0x100>, <0x1006c000 0x4>; reg = <0x10068000 0x100>, <0x1006c000 0x4>;
......
* Temperature Monitor (TEMPMON) on Freescale i.MX SoCs * Temperature Monitor (TEMPMON) on Freescale i.MX SoCs
Required properties: Required properties:
- compatible : "fsl,imx6q-tempmon" for i.MX6Q, "fsl,imx6sx-tempmon" for i.MX6SX. - compatible : must be one of following:
i.MX6SX has two more IRQs than i.MX6Q, one is IRQ_LOW and the other is IRQ_PANIC, - "fsl,imx6q-tempmon" for i.MX6Q,
- "fsl,imx6sx-tempmon" for i.MX6SX,
- "fsl,imx7d-tempmon" for i.MX7S/D.
- interrupts : the interrupt output of the controller:
i.MX6Q has one IRQ which will be triggered when temperature is higher than high threshold,
i.MX6SX and i.MX7S/D have two more IRQs than i.MX6Q, one is IRQ_LOW and the other is IRQ_PANIC,
when temperature is below than low threshold, IRQ_LOW will be triggered, when temperature when temperature is below than low threshold, IRQ_LOW will be triggered, when temperature
is higher than panic threshold, system will auto reboot by SRC module. is higher than panic threshold, system will auto reboot by SRC module.
- fsl,tempmon : phandle pointer to system controller that contains TEMPMON - fsl,tempmon : phandle pointer to system controller that contains TEMPMON
......
...@@ -12,6 +12,7 @@ Required properties: ...@@ -12,6 +12,7 @@ Required properties:
- "mediatek,mt8173-thermal" : For MT8173 family of SoCs - "mediatek,mt8173-thermal" : For MT8173 family of SoCs
- "mediatek,mt2701-thermal" : For MT2701 family of SoCs - "mediatek,mt2701-thermal" : For MT2701 family of SoCs
- "mediatek,mt2712-thermal" : For MT2712 family of SoCs - "mediatek,mt2712-thermal" : For MT2712 family of SoCs
- "mediatek,mt7622-thermal" : For MT7622 SoC
- reg: Address range of the thermal controller - reg: Address range of the thermal controller
- interrupts: IRQ for the thermal controller - interrupts: IRQ for the thermal controller
- clocks, clock-names: Clocks needed for the thermal controller. required - clocks, clock-names: Clocks needed for the thermal controller. required
......
...@@ -8,6 +8,7 @@ Required properties: ...@@ -8,6 +8,7 @@ Required properties:
- reg: Address range of the thermal registers - reg: Address range of the thermal registers
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. - #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
- #qcom,sensors: Number of sensors in tsens block
- Refer to Documentation/devicetree/bindings/nvmem/nvmem.txt to know how to specify - Refer to Documentation/devicetree/bindings/nvmem/nvmem.txt to know how to specify
nvmem cells nvmem cells
......
...@@ -9,6 +9,7 @@ Required properties: ...@@ -9,6 +9,7 @@ Required properties:
Examples with soctypes are: Examples with soctypes are:
- "renesas,r8a7795-thermal" (R-Car H3) - "renesas,r8a7795-thermal" (R-Car H3)
- "renesas,r8a7796-thermal" (R-Car M3-W) - "renesas,r8a7796-thermal" (R-Car M3-W)
- "renesas,r8a77965-thermal" (R-Car M3-N)
- reg : Address ranges of the thermal registers. Each sensor - reg : Address ranges of the thermal registers. Each sensor
needs one address range. Sorting must be done in needs one address range. Sorting must be done in
increasing order according to datasheet, i.e. increasing order according to datasheet, i.e.
...@@ -18,7 +19,7 @@ Required properties: ...@@ -18,7 +19,7 @@ Required properties:
Optional properties: Optional properties:
- interrupts : interrupts routed to the TSC (3 for H3 and M3-W) - interrupts : interrupts routed to the TSC (3 for H3, M3-W and M3-N)
- power-domain : Must contain a reference to the power domain. This - power-domain : Must contain a reference to the power domain. This
property is mandatory if the thermal sensor instance property is mandatory if the thermal sensor instance
is part of a controllable power domain. is part of a controllable power domain.
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
Required properties: Required properties:
- compatible : "renesas,thermal-<soctype>", - compatible : "renesas,thermal-<soctype>",
"renesas,rcar-gen2-thermal" (with thermal-zone) or "renesas,rcar-gen2-thermal" (with thermal-zone) or
"renesas,rcar-thermal" (without thermal-zone) as fallback. "renesas,rcar-thermal" (without thermal-zone) as
fallback except R-Car D3.
Examples with soctypes are: Examples with soctypes are:
- "renesas,thermal-r8a73a4" (R-Mobile APE6) - "renesas,thermal-r8a73a4" (R-Mobile APE6)
- "renesas,thermal-r8a7743" (RZ/G1M) - "renesas,thermal-r8a7743" (RZ/G1M)
...@@ -12,13 +13,15 @@ Required properties: ...@@ -12,13 +13,15 @@ Required properties:
- "renesas,thermal-r8a7791" (R-Car M2-W) - "renesas,thermal-r8a7791" (R-Car M2-W)
- "renesas,thermal-r8a7792" (R-Car V2H) - "renesas,thermal-r8a7792" (R-Car V2H)
- "renesas,thermal-r8a7793" (R-Car M2-N) - "renesas,thermal-r8a7793" (R-Car M2-N)
- "renesas,thermal-r8a77995" (R-Car D3)
- reg : Address range of the thermal registers. - reg : Address range of the thermal registers.
The 1st reg will be recognized as common register The 1st reg will be recognized as common register
if it has "interrupts". if it has "interrupts".
Option properties: Option properties:
- interrupts : use interrupt - interrupts : If present should contain 3 interrupts for
R-Car D3 or 1 interrupt otherwise.
Example (non interrupt support): Example (non interrupt support):
......
...@@ -8,6 +8,7 @@ Required properties: ...@@ -8,6 +8,7 @@ Required properties:
- compatible : - compatible :
- "socionext,uniphier-pxs2-thermal" : For UniPhier PXs2 SoC - "socionext,uniphier-pxs2-thermal" : For UniPhier PXs2 SoC
- "socionext,uniphier-ld20-thermal" : For UniPhier LD20 SoC - "socionext,uniphier-ld20-thermal" : For UniPhier LD20 SoC
- "socionext,uniphier-pxs3-thermal" : For UniPhier PXs3 SoC
- interrupts : IRQ for the temperature alarm - interrupts : IRQ for the temperature alarm
- #thermal-sensor-cells : Should be 0. See ./thermal.txt for details. - #thermal-sensor-cells : Should be 0. See ./thermal.txt for details.
......
This diff is collapsed.
...@@ -153,6 +153,12 @@ ...@@ -153,6 +153,12 @@
/* The number of sensing points per bank */ /* The number of sensing points per bank */
#define MT2712_NUM_SENSORS_PER_ZONE 4 #define MT2712_NUM_SENSORS_PER_ZONE 4
#define MT7622_TEMP_AUXADC_CHANNEL 11
#define MT7622_NUM_SENSORS 1
#define MT7622_NUM_ZONES 1
#define MT7622_NUM_SENSORS_PER_ZONE 1
#define MT7622_TS1 0
struct mtk_thermal; struct mtk_thermal;
struct thermal_bank_cfg { struct thermal_bank_cfg {
...@@ -242,6 +248,12 @@ static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = { ...@@ -242,6 +248,12 @@ static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 }; static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
/* MT7622 thermal sensor data */
static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
/** /**
* The MT8173 thermal controller has four banks. Each bank can read up to * The MT8173 thermal controller has four banks. Each bank can read up to
* four temperature sensors simultaneously. The MT8173 has a total of 5 * four temperature sensors simultaneously. The MT8173 has a total of 5
...@@ -329,6 +341,25 @@ static const struct mtk_thermal_data mt2712_thermal_data = { ...@@ -329,6 +341,25 @@ static const struct mtk_thermal_data mt2712_thermal_data = {
.sensor_mux_values = mt2712_mux_values, .sensor_mux_values = mt2712_mux_values,
}; };
/*
* MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
* access.
*/
static const struct mtk_thermal_data mt7622_thermal_data = {
.auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
.num_banks = MT7622_NUM_ZONES,
.num_sensors = MT7622_NUM_SENSORS,
.bank_data = {
{
.num_sensors = 1,
.sensors = mt7622_bank_data,
},
},
.msr = mt7622_msr,
.adcpnp = mt7622_adcpnp,
.sensor_mux_values = mt7622_mux_values,
};
/** /**
* raw_to_mcelsius - convert a raw ADC value to mcelsius * raw_to_mcelsius - convert a raw ADC value to mcelsius
* @mt: The thermal controller * @mt: The thermal controller
...@@ -631,6 +662,10 @@ static const struct of_device_id mtk_thermal_of_match[] = { ...@@ -631,6 +662,10 @@ static const struct of_device_id mtk_thermal_of_match[] = {
{ {
.compatible = "mediatek,mt2712-thermal", .compatible = "mediatek,mt2712-thermal",
.data = (void *)&mt2712_thermal_data, .data = (void *)&mt2712_thermal_data,
},
{
.compatible = "mediatek,mt7622-thermal",
.data = (void *)&mt7622_thermal_data,
}, { }, {
}, },
}; };
...@@ -642,7 +677,6 @@ static int mtk_thermal_probe(struct platform_device *pdev) ...@@ -642,7 +677,6 @@ static int mtk_thermal_probe(struct platform_device *pdev)
struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node; struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
struct mtk_thermal *mt; struct mtk_thermal *mt;
struct resource *res; struct resource *res;
const struct of_device_id *of_id;
u64 auxadc_phys_base, apmixed_phys_base; u64 auxadc_phys_base, apmixed_phys_base;
struct thermal_zone_device *tzdev; struct thermal_zone_device *tzdev;
...@@ -650,9 +684,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) ...@@ -650,9 +684,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
if (!mt) if (!mt)
return -ENOMEM; return -ENOMEM;
of_id = of_match_device(mtk_thermal_of_match, &pdev->dev); mt->conf = of_device_get_match_data(&pdev->dev);
if (of_id)
mt->conf = (const struct mtk_thermal_data *)of_id->data;
mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm"); mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
if (IS_ERR(mt->clk_peri_therm)) if (IS_ERR(mt->clk_peri_therm))
......
/* /*
* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/bitops.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/iio/consumer.h> #include <linux/iio/consumer.h>
...@@ -29,13 +30,17 @@ ...@@ -29,13 +30,17 @@
#define QPNP_TM_REG_ALARM_CTRL 0x46 #define QPNP_TM_REG_ALARM_CTRL 0x46
#define QPNP_TM_TYPE 0x09 #define QPNP_TM_TYPE 0x09
#define QPNP_TM_SUBTYPE 0x08 #define QPNP_TM_SUBTYPE_GEN1 0x08
#define QPNP_TM_SUBTYPE_GEN2 0x09
#define STATUS_STAGE_MASK 0x03 #define STATUS_GEN1_STAGE_MASK GENMASK(1, 0)
#define STATUS_GEN2_STATE_MASK GENMASK(6, 4)
#define STATUS_GEN2_STATE_SHIFT 4
#define SHUTDOWN_CTRL1_THRESHOLD_MASK 0x03 #define SHUTDOWN_CTRL1_OVERRIDE_MASK GENMASK(7, 6)
#define SHUTDOWN_CTRL1_THRESHOLD_MASK GENMASK(1, 0)
#define ALARM_CTRL_FORCE_ENABLE 0x80 #define ALARM_CTRL_FORCE_ENABLE BIT(7)
/* /*
* Trip point values based on threshold control * Trip point values based on threshold control
...@@ -58,6 +63,7 @@ ...@@ -58,6 +63,7 @@
struct qpnp_tm_chip { struct qpnp_tm_chip {
struct regmap *map; struct regmap *map;
struct thermal_zone_device *tz_dev; struct thermal_zone_device *tz_dev;
unsigned int subtype;
long temp; long temp;
unsigned int thresh; unsigned int thresh;
unsigned int stage; unsigned int stage;
...@@ -66,6 +72,9 @@ struct qpnp_tm_chip { ...@@ -66,6 +72,9 @@ struct qpnp_tm_chip {
struct iio_channel *adc; struct iio_channel *adc;
}; };
/* This array maps from GEN2 alarm state to GEN1 alarm stage */
static const unsigned int alarm_state_map[8] = {0, 1, 1, 2, 2, 3, 3, 3};
static int qpnp_tm_read(struct qpnp_tm_chip *chip, u16 addr, u8 *data) static int qpnp_tm_read(struct qpnp_tm_chip *chip, u16 addr, u8 *data)
{ {
unsigned int val; unsigned int val;
...@@ -84,30 +93,59 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data) ...@@ -84,30 +93,59 @@ static int qpnp_tm_write(struct qpnp_tm_chip *chip, u16 addr, u8 data)
return regmap_write(chip->map, chip->base + addr, data); return regmap_write(chip->map, chip->base + addr, data);
} }
/**
* qpnp_tm_get_temp_stage() - return over-temperature stage
* @chip: Pointer to the qpnp_tm chip
*
* Return: stage (GEN1) or state (GEN2) on success, or errno on failure.
*/
static int qpnp_tm_get_temp_stage(struct qpnp_tm_chip *chip)
{
int ret;
u8 reg = 0;
ret = qpnp_tm_read(chip, QPNP_TM_REG_STATUS, &reg);
if (ret < 0)
return ret;
if (chip->subtype == QPNP_TM_SUBTYPE_GEN1)
ret = reg & STATUS_GEN1_STAGE_MASK;
else
ret = (reg & STATUS_GEN2_STATE_MASK) >> STATUS_GEN2_STATE_SHIFT;
return ret;
}
/* /*
* This function updates the internal temp value based on the * This function updates the internal temp value based on the
* current thermal stage and threshold as well as the previous stage * current thermal stage and threshold as well as the previous stage
*/ */
static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip)
{ {
unsigned int stage; unsigned int stage, stage_new, stage_old;
int ret; int ret;
u8 reg = 0;
ret = qpnp_tm_read(chip, QPNP_TM_REG_STATUS, &reg); ret = qpnp_tm_get_temp_stage(chip);
if (ret < 0) if (ret < 0)
return ret; return ret;
stage = ret;
stage = reg & STATUS_STAGE_MASK; if (chip->subtype == QPNP_TM_SUBTYPE_GEN1) {
stage_new = stage;
stage_old = chip->stage;
} else {
stage_new = alarm_state_map[stage];
stage_old = alarm_state_map[chip->stage];
}
if (stage > chip->stage) { if (stage_new > stage_old) {
/* increasing stage, use lower bound */ /* increasing stage, use lower bound */
chip->temp = (stage - 1) * TEMP_STAGE_STEP + chip->temp = (stage_new - 1) * TEMP_STAGE_STEP +
chip->thresh * TEMP_THRESH_STEP + chip->thresh * TEMP_THRESH_STEP +
TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
} else if (stage < chip->stage) { } else if (stage_new < stage_old) {
/* decreasing stage, use upper bound */ /* decreasing stage, use upper bound */
chip->temp = stage * TEMP_STAGE_STEP + chip->temp = stage_new * TEMP_STAGE_STEP +
chip->thresh * TEMP_THRESH_STEP - chip->thresh * TEMP_THRESH_STEP -
TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN; TEMP_STAGE_HYSTERESIS + TEMP_THRESH_MIN;
} }
...@@ -162,28 +200,37 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data) ...@@ -162,28 +200,37 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data)
*/ */
static int qpnp_tm_init(struct qpnp_tm_chip *chip) static int qpnp_tm_init(struct qpnp_tm_chip *chip)
{ {
unsigned int stage;
int ret; int ret;
u8 reg; u8 reg = 0;
chip->thresh = THRESH_MIN; ret = qpnp_tm_read(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, &reg);
if (ret < 0)
return ret;
chip->thresh = reg & SHUTDOWN_CTRL1_THRESHOLD_MASK;
chip->temp = DEFAULT_TEMP; chip->temp = DEFAULT_TEMP;
ret = qpnp_tm_read(chip, QPNP_TM_REG_STATUS, &reg); ret = qpnp_tm_get_temp_stage(chip);
if (ret < 0) if (ret < 0)
return ret; return ret;
chip->stage = ret;
chip->stage = reg & STATUS_STAGE_MASK; stage = chip->subtype == QPNP_TM_SUBTYPE_GEN1
? chip->stage : alarm_state_map[chip->stage];
if (chip->stage) if (stage)
chip->temp = chip->thresh * TEMP_THRESH_STEP + chip->temp = chip->thresh * TEMP_THRESH_STEP +
(chip->stage - 1) * TEMP_STAGE_STEP + (stage - 1) * TEMP_STAGE_STEP +
TEMP_THRESH_MIN; TEMP_THRESH_MIN;
/* /*
* Set threshold and disable software override of stage 2 and 3 * Set threshold and disable software override of stage 2 and 3
* shutdowns. * shutdowns.
*/ */
reg = chip->thresh & SHUTDOWN_CTRL1_THRESHOLD_MASK; chip->thresh = THRESH_MIN;
reg &= ~(SHUTDOWN_CTRL1_OVERRIDE_MASK | SHUTDOWN_CTRL1_THRESHOLD_MASK);
reg |= chip->thresh & SHUTDOWN_CTRL1_THRESHOLD_MASK;
ret = qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); ret = qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -246,12 +293,15 @@ static int qpnp_tm_probe(struct platform_device *pdev) ...@@ -246,12 +293,15 @@ static int qpnp_tm_probe(struct platform_device *pdev)
return ret; return ret;
} }
if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) { if (type != QPNP_TM_TYPE || (subtype != QPNP_TM_SUBTYPE_GEN1
&& subtype != QPNP_TM_SUBTYPE_GEN2)) {
dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n", dev_err(&pdev->dev, "invalid type 0x%02x or subtype 0x%02x\n",
type, subtype); type, subtype);
return -ENODEV; return -ENODEV;
} }
chip->subtype = subtype;
ret = qpnp_tm_init(chip); ret = qpnp_tm_init(chip);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "init failed\n"); dev_err(&pdev->dev, "init failed\n");
......
...@@ -115,6 +115,7 @@ static int tsens_probe(struct platform_device *pdev) ...@@ -115,6 +115,7 @@ static int tsens_probe(struct platform_device *pdev)
struct tsens_device *tmdev; struct tsens_device *tmdev;
const struct tsens_data *data; const struct tsens_data *data;
const struct of_device_id *id; const struct of_device_id *id;
u32 num_sensors;
if (pdev->dev.of_node) if (pdev->dev.of_node)
dev = &pdev->dev; dev = &pdev->dev;
...@@ -129,19 +130,24 @@ static int tsens_probe(struct platform_device *pdev) ...@@ -129,19 +130,24 @@ static int tsens_probe(struct platform_device *pdev)
else else
data = &data_8960; data = &data_8960;
if (data->num_sensors <= 0) { num_sensors = data->num_sensors;
if (np)
of_property_read_u32(np, "#qcom,sensors", &num_sensors);
if (num_sensors <= 0) {
dev_err(dev, "invalid number of sensors\n"); dev_err(dev, "invalid number of sensors\n");
return -EINVAL; return -EINVAL;
} }
tmdev = devm_kzalloc(dev, tmdev = devm_kzalloc(dev,
struct_size(tmdev, sensor, data->num_sensors), struct_size(tmdev, sensor, num_sensors),
GFP_KERNEL); GFP_KERNEL);
if (!tmdev) if (!tmdev)
return -ENOMEM; return -ENOMEM;
tmdev->dev = dev; tmdev->dev = dev;
tmdev->num_sensors = data->num_sensors; tmdev->num_sensors = num_sensors;
tmdev->ops = data->ops; tmdev->ops = data->ops;
for (i = 0; i < tmdev->num_sensors; i++) { for (i = 0; i < tmdev->num_sensors; i++) {
if (data->hw_ids) if (data->hw_ids)
......
...@@ -132,7 +132,7 @@ static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc, ...@@ -132,7 +132,7 @@ static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
#define RCAR3_THERMAL_GRAN 500 /* mili Celsius */ #define RCAR3_THERMAL_GRAN 500 /* mili Celsius */
/* no idea where these constants come from */ /* no idea where these constants come from */
#define TJ_1 96 #define TJ_1 116
#define TJ_3 -41 #define TJ_3 -41
static void rcar_gen3_thermal_calc_coefs(struct equation_coefs *coef, static void rcar_gen3_thermal_calc_coefs(struct equation_coefs *coef,
...@@ -146,7 +146,7 @@ static void rcar_gen3_thermal_calc_coefs(struct equation_coefs *coef, ...@@ -146,7 +146,7 @@ static void rcar_gen3_thermal_calc_coefs(struct equation_coefs *coef,
* Division is not scaled in BSP and if scaled it might overflow * Division is not scaled in BSP and if scaled it might overflow
* the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled * the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled
*/ */
tj_2 = (FIXPT_INT((ptat[1] - ptat[2]) * 137) tj_2 = (FIXPT_INT((ptat[1] - ptat[2]) * 157)
/ (ptat[0] - ptat[2])) - FIXPT_INT(41); / (ptat[0] - ptat[2])) - FIXPT_INT(41);
coef->a1 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[2]), coef->a1 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[2]),
...@@ -207,8 +207,8 @@ static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high) ...@@ -207,8 +207,8 @@ static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high)
{ {
struct rcar_gen3_thermal_tsc *tsc = devdata; struct rcar_gen3_thermal_tsc *tsc = devdata;
low = clamp_val(low, -40000, 125000); low = clamp_val(low, -40000, 120000);
high = clamp_val(high, -40000, 125000); high = clamp_val(high, -40000, 120000);
rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1, rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1,
rcar_gen3_thermal_mcelsius_to_temp(tsc, low)); rcar_gen3_thermal_mcelsius_to_temp(tsc, low));
...@@ -329,6 +329,7 @@ static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc) ...@@ -329,6 +329,7 @@ static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
{ .compatible = "renesas,r8a7795-thermal", }, { .compatible = "renesas,r8a7795-thermal", },
{ .compatible = "renesas,r8a7796-thermal", }, { .compatible = "renesas,r8a7796-thermal", },
{ .compatible = "renesas,r8a77965-thermal", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids); MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
...@@ -354,11 +355,11 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) ...@@ -354,11 +355,11 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
/* default values if FUSEs are missing */ /* default values if FUSEs are missing */
/* TODO: Read values from hardware on supported platforms */ /* TODO: Read values from hardware on supported platforms */
int ptat[3] = { 2351, 1509, 435 }; int ptat[3] = { 2631, 1509, 435 };
int thcode[TSC_MAX_NUM][3] = { int thcode[TSC_MAX_NUM][3] = {
{ 3248, 2800, 2221 }, { 3397, 2800, 2221 },
{ 3245, 2795, 2216 }, { 3393, 2795, 2216 },
{ 3250, 2805, 2237 }, { 3389, 2805, 2237 },
}; };
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
......
...@@ -58,10 +58,47 @@ struct rcar_thermal_common { ...@@ -58,10 +58,47 @@ struct rcar_thermal_common {
spinlock_t lock; spinlock_t lock;
}; };
struct rcar_thermal_chip {
unsigned int use_of_thermal : 1;
unsigned int has_filonoff : 1;
unsigned int irq_per_ch : 1;
unsigned int needs_suspend_resume : 1;
unsigned int nirqs;
};
static const struct rcar_thermal_chip rcar_thermal = {
.use_of_thermal = 0,
.has_filonoff = 1,
.irq_per_ch = 0,
.needs_suspend_resume = 0,
.nirqs = 1,
};
static const struct rcar_thermal_chip rcar_gen2_thermal = {
.use_of_thermal = 1,
.has_filonoff = 1,
.irq_per_ch = 0,
.needs_suspend_resume = 0,
.nirqs = 1,
};
static const struct rcar_thermal_chip rcar_gen3_thermal = {
.use_of_thermal = 1,
.has_filonoff = 0,
.irq_per_ch = 1,
.needs_suspend_resume = 1,
/*
* The Gen3 chip has 3 interrupts, but this driver uses only 2
* interrupts to detect a temperature change, rise or fall.
*/
.nirqs = 2,
};
struct rcar_thermal_priv { struct rcar_thermal_priv {
void __iomem *base; void __iomem *base;
struct rcar_thermal_common *common; struct rcar_thermal_common *common;
struct thermal_zone_device *zone; struct thermal_zone_device *zone;
const struct rcar_thermal_chip *chip;
struct delayed_work work; struct delayed_work work;
struct mutex lock; struct mutex lock;
struct list_head list; struct list_head list;
...@@ -77,13 +114,20 @@ struct rcar_thermal_priv { ...@@ -77,13 +114,20 @@ struct rcar_thermal_priv {
#define rcar_priv_to_dev(priv) ((priv)->common->dev) #define rcar_priv_to_dev(priv) ((priv)->common->dev)
#define rcar_has_irq_support(priv) ((priv)->common->base) #define rcar_has_irq_support(priv) ((priv)->common->base)
#define rcar_id_to_shift(priv) ((priv)->id * 8) #define rcar_id_to_shift(priv) ((priv)->id * 8)
#define rcar_of_data(dev) ((unsigned long)of_device_get_match_data(dev))
#define rcar_use_of_thermal(dev) (rcar_of_data(dev) == USE_OF_THERMAL)
#define USE_OF_THERMAL 1
static const struct of_device_id rcar_thermal_dt_ids[] = { static const struct of_device_id rcar_thermal_dt_ids[] = {
{ .compatible = "renesas,rcar-thermal", }, {
{ .compatible = "renesas,rcar-gen2-thermal", .data = (void *)USE_OF_THERMAL }, .compatible = "renesas,rcar-thermal",
.data = &rcar_thermal,
},
{
.compatible = "renesas,rcar-gen2-thermal",
.data = &rcar_gen2_thermal,
},
{
.compatible = "renesas,thermal-r8a77995",
.data = &rcar_gen3_thermal,
},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
...@@ -190,7 +234,8 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) ...@@ -190,7 +234,8 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
* enable IRQ * enable IRQ
*/ */
if (rcar_has_irq_support(priv)) { if (rcar_has_irq_support(priv)) {
rcar_thermal_write(priv, FILONOFF, 0); if (priv->chip->has_filonoff)
rcar_thermal_write(priv, FILONOFF, 0);
/* enable Rising/Falling edge interrupt */ /* enable Rising/Falling edge interrupt */
rcar_thermal_write(priv, POSNEG, 0x1); rcar_thermal_write(priv, POSNEG, 0x1);
...@@ -420,7 +465,7 @@ static int rcar_thermal_remove(struct platform_device *pdev) ...@@ -420,7 +465,7 @@ static int rcar_thermal_remove(struct platform_device *pdev)
rcar_thermal_for_each_priv(priv, common) { rcar_thermal_for_each_priv(priv, common) {
rcar_thermal_irq_disable(priv); rcar_thermal_irq_disable(priv);
if (rcar_use_of_thermal(dev)) if (priv->chip->use_of_thermal)
thermal_remove_hwmon_sysfs(priv->zone); thermal_remove_hwmon_sysfs(priv->zone);
else else
thermal_zone_device_unregister(priv->zone); thermal_zone_device_unregister(priv->zone);
...@@ -438,6 +483,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -438,6 +483,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
struct rcar_thermal_priv *priv; struct rcar_thermal_priv *priv;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res, *irq; struct resource *res, *irq;
const struct rcar_thermal_chip *chip = of_device_get_match_data(dev);
int mres = 0; int mres = 0;
int i; int i;
int ret = -ENODEV; int ret = -ENODEV;
...@@ -457,19 +503,35 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -457,19 +503,35 @@ static int rcar_thermal_probe(struct platform_device *pdev)
pm_runtime_enable(dev); pm_runtime_enable(dev);
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); for (i = 0; i < chip->nirqs; i++) {
if (irq) { irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
/* if (!irq)
* platform has IRQ support. continue;
* Then, driver uses common registers if (!common->base) {
* rcar_has_irq_support() will be enabled /*
*/ * platform has IRQ support.
res = platform_get_resource(pdev, IORESOURCE_MEM, mres++); * Then, driver uses common registers
common->base = devm_ioremap_resource(dev, res); * rcar_has_irq_support() will be enabled
if (IS_ERR(common->base)) */
return PTR_ERR(common->base); res = platform_get_resource(pdev, IORESOURCE_MEM,
mres++);
common->base = devm_ioremap_resource(dev, res);
if (IS_ERR(common->base))
return PTR_ERR(common->base);
idle = 0; /* polling delay is not needed */
}
idle = 0; /* polling delay is not needed */ ret = devm_request_irq(dev, irq->start, rcar_thermal_irq,
IRQF_SHARED, dev_name(dev), common);
if (ret) {
dev_err(dev, "irq request failed\n ");
goto error_unregister;
}
/* update ENR bits */
if (chip->irq_per_ch)
enr_bits |= 1 << i;
} }
for (i = 0;; i++) { for (i = 0;; i++) {
...@@ -491,6 +553,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -491,6 +553,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
priv->common = common; priv->common = common;
priv->id = i; priv->id = i;
priv->chip = chip;
mutex_init(&priv->lock); mutex_init(&priv->lock);
INIT_LIST_HEAD(&priv->list); INIT_LIST_HEAD(&priv->list);
INIT_DELAYED_WORK(&priv->work, rcar_thermal_work); INIT_DELAYED_WORK(&priv->work, rcar_thermal_work);
...@@ -498,7 +561,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -498,7 +561,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto error_unregister; goto error_unregister;
if (rcar_use_of_thermal(dev)) if (chip->use_of_thermal)
priv->zone = devm_thermal_zone_of_sensor_register( priv->zone = devm_thermal_zone_of_sensor_register(
dev, i, priv, dev, i, priv,
&rcar_thermal_zone_of_ops); &rcar_thermal_zone_of_ops);
...@@ -515,7 +578,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -515,7 +578,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
goto error_unregister; goto error_unregister;
} }
if (rcar_use_of_thermal(dev)) { if (chip->use_of_thermal) {
/* /*
* thermal_zone doesn't enable hwmon as default, * thermal_zone doesn't enable hwmon as default,
* but, enable it here to keep compatible * but, enable it here to keep compatible
...@@ -531,20 +594,12 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -531,20 +594,12 @@ static int rcar_thermal_probe(struct platform_device *pdev)
list_move_tail(&priv->list, &common->head); list_move_tail(&priv->list, &common->head);
/* update ENR bits */ /* update ENR bits */
enr_bits |= 3 << (i * 8); if (!chip->irq_per_ch)
enr_bits |= 3 << (i * 8);
} }
/* enable temperature comparation */ if (enr_bits)
if (irq) {
ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0,
dev_name(dev), common);
if (ret) {
dev_err(dev, "irq request failed\n ");
goto error_unregister;
}
rcar_thermal_common_write(common, ENR, enr_bits); rcar_thermal_common_write(common, ENR, enr_bits);
}
dev_info(dev, "%d sensor probed\n", i); dev_info(dev, "%d sensor probed\n", i);
...@@ -556,9 +611,48 @@ static int rcar_thermal_probe(struct platform_device *pdev) ...@@ -556,9 +611,48 @@ static int rcar_thermal_probe(struct platform_device *pdev)
return ret; return ret;
} }
#ifdef CONFIG_PM_SLEEP
static int rcar_thermal_suspend(struct device *dev)
{
struct rcar_thermal_common *common = dev_get_drvdata(dev);
struct rcar_thermal_priv *priv = list_first_entry(&common->head,
typeof(*priv), list);
if (priv->chip->needs_suspend_resume) {
rcar_thermal_common_write(common, ENR, 0);
rcar_thermal_irq_disable(priv);
rcar_thermal_bset(priv, THSCR, CPCTL, 0);
}
return 0;
}
static int rcar_thermal_resume(struct device *dev)
{
struct rcar_thermal_common *common = dev_get_drvdata(dev);
struct rcar_thermal_priv *priv = list_first_entry(&common->head,
typeof(*priv), list);
int ret;
if (priv->chip->needs_suspend_resume) {
ret = rcar_thermal_update_temp(priv);
if (ret < 0)
return ret;
rcar_thermal_irq_enable(priv);
rcar_thermal_common_write(common, ENR, 0x03);
}
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(rcar_thermal_pm_ops, rcar_thermal_suspend,
rcar_thermal_resume);
static struct platform_driver rcar_thermal_driver = { static struct platform_driver rcar_thermal_driver = {
.driver = { .driver = {
.name = "rcar_thermal", .name = "rcar_thermal",
.pm = &rcar_thermal_pm_ops,
.of_match_table = rcar_thermal_dt_ids, .of_match_table = rcar_thermal_dt_ids,
}, },
.probe = rcar_thermal_probe, .probe = rcar_thermal_probe,
......
This diff is collapsed.
/*
* exynos_tmu.h - Samsung EXYNOS TMU (Thermal Management Unit)
*
* Copyright (C) 2011 Samsung Electronics
* Donggeun Kim <dg77.kim@samsung.com>
* Amit Daniel Kachhap <amit.daniel@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _EXYNOS_TMU_H
#define _EXYNOS_TMU_H
#include <linux/cpu_cooling.h>
#include <dt-bindings/thermal/thermal_exynos.h>
enum soc_type {
SOC_ARCH_EXYNOS3250 = 1,
SOC_ARCH_EXYNOS4210,
SOC_ARCH_EXYNOS4412,
SOC_ARCH_EXYNOS5250,
SOC_ARCH_EXYNOS5260,
SOC_ARCH_EXYNOS5420,
SOC_ARCH_EXYNOS5420_TRIMINFO,
SOC_ARCH_EXYNOS5433,
SOC_ARCH_EXYNOS5440,
SOC_ARCH_EXYNOS7,
};
/**
* struct exynos_tmu_platform_data
* @gain: gain of amplifier in the positive-TC generator block
* 0 < gain <= 15
* @reference_voltage: reference voltage of amplifier
* in the positive-TC generator block
* 0 < reference_voltage <= 31
* @noise_cancel_mode: noise cancellation mode
* 000, 100, 101, 110 and 111 can be different modes
* @type: determines the type of SOC
* @efuse_value: platform defined fuse value
* @min_efuse_value: minimum valid trimming data
* @max_efuse_value: maximum valid trimming data
* @default_temp_offset: default temperature offset in case of no trimming
* @cal_type: calibration type for temperature
*
* This structure is required for configuration of exynos_tmu driver.
*/
struct exynos_tmu_platform_data {
u8 gain;
u8 reference_voltage;
u8 noise_cancel_mode;
u32 efuse_value;
u32 min_efuse_value;
u32 max_efuse_value;
u8 first_point_trim;
u8 second_point_trim;
u8 default_temp_offset;
enum soc_type type;
u32 cal_type;
};
#endif /* _EXYNOS_TMU_H */
...@@ -240,31 +240,6 @@ struct tegra_soctherm { ...@@ -240,31 +240,6 @@ struct tegra_soctherm {
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
}; };
/**
* clk_writel() - writes a value to a CAR register
* @ts: pointer to a struct tegra_soctherm
* @v: the value to write
* @reg: the register offset
*
* Writes @v to @reg. No return value.
*/
static inline void clk_writel(struct tegra_soctherm *ts, u32 value, u32 reg)
{
writel(value, (ts->clk_regs + reg));
}
/**
* clk_readl() - reads specified register from CAR IP block
* @ts: pointer to a struct tegra_soctherm
* @reg: register address to be read
*
* Return: the value of the register
*/
static inline u32 clk_readl(struct tegra_soctherm *ts, u32 reg)
{
return readl(ts->clk_regs + reg);
}
/** /**
* ccroc_writel() - writes a value to a CCROC register * ccroc_writel() - writes a value to a CCROC register
* @ts: pointer to a struct tegra_soctherm * @ts: pointer to a struct tegra_soctherm
...@@ -926,7 +901,7 @@ static int throt_set_cdev_state(struct thermal_cooling_device *cdev, ...@@ -926,7 +901,7 @@ static int throt_set_cdev_state(struct thermal_cooling_device *cdev,
return 0; return 0;
} }
static struct thermal_cooling_device_ops throt_cooling_ops = { static const struct thermal_cooling_device_ops throt_cooling_ops = {
.get_max_state = throt_get_cdev_max_state, .get_max_state = throt_get_cdev_max_state,
.get_cur_state = throt_get_cdev_cur_state, .get_cur_state = throt_get_cdev_cur_state,
.set_cur_state = throt_set_cdev_state, .set_cur_state = throt_set_cdev_state,
...@@ -1207,9 +1182,9 @@ static void tegra_soctherm_throttle(struct device *dev) ...@@ -1207,9 +1182,9 @@ static void tegra_soctherm_throttle(struct device *dev)
} else { } else {
writel(v, ts->regs + THROT_GLOBAL_CFG); writel(v, ts->regs + THROT_GLOBAL_CFG);
v = clk_readl(ts, CAR_SUPER_CCLKG_DIVIDER); v = readl(ts->clk_regs + CAR_SUPER_CCLKG_DIVIDER);
v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1); v = REG_SET_MASK(v, CDIVG_USE_THERM_CONTROLS_MASK, 1);
clk_writel(ts, v, CAR_SUPER_CCLKG_DIVIDER); writel(v, ts->clk_regs + CAR_SUPER_CCLKG_DIVIDER);
} }
/* initialize stats collection */ /* initialize stats collection */
......
...@@ -310,7 +310,7 @@ omap5430_adc_to_temp[ ...@@ -310,7 +310,7 @@ omap5430_adc_to_temp[
119800, 120200, 120600, 121000, 121400, 121800, 122400, 122600, 123000, 119800, 120200, 120600, 121000, 121400, 121800, 122400, 122600, 123000,
123400, 123400,
/* Index 940 - 945 */ /* Index 940 - 945 */
123800, 1242000, 124600, 124900, 125000, 125000, 123800, 124200, 124600, 124900, 125000, 125000,
}; };
/* OMAP54xx ES2.0 data */ /* OMAP54xx ES2.0 data */
......
...@@ -365,6 +365,10 @@ static const struct of_device_id uniphier_tm_dt_ids[] = { ...@@ -365,6 +365,10 @@ static const struct of_device_id uniphier_tm_dt_ids[] = {
.compatible = "socionext,uniphier-ld20-thermal", .compatible = "socionext,uniphier-ld20-thermal",
.data = &uniphier_ld20_tm_data, .data = &uniphier_ld20_tm_data,
}, },
{
.compatible = "socionext,uniphier-pxs3-thermal",
.data = &uniphier_ld20_tm_data,
},
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, uniphier_tm_dt_ids); MODULE_DEVICE_TABLE(of, uniphier_tm_dt_ids);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment