diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-26 14:21:30 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-26 14:21:30 -0700 |
| commit | b81e34131907d2c243c51117a4aff8dbe22ccc9c (patch) | |
| tree | 3ca8f72beba189f5d6e78e0b699a0ce581d359b1 | |
| parent | 85671b807f82dae7a88ccfc74e33a8374219841c (diff) | |
| parent | 79a57e48822a88f082a4dadb366abaf3c0988b5d (diff) | |
Merge tag 'thermal-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more thermal control updates from Rafael Wysocki:
"This mostly consists of assorted updates of thermal drivers, including
new hardware support (Airoha AN7583, Qualcomm Master BandGap thermal
monitor, QCom PMIC5 Gen3 ADC), but it also includes two reverts of
recent cosmetic thermal core updates that went against driver core
plans to eliminate class_create():
- Fix missing bitfield include headers in Armada and QCom SPM BMG
drivers (Daniel Lezcano)
- Fix missed file when manually applying a change after a conflict
resolution for the QCom SPMI ADC TM5 Gen3 (Daniel Lezcano)
- Move thermal_zone_device_enable() to the right place in order to
prevent calling it if the thermal zone registration failed (Dan
Carpenter)
- Improve bitfield manipulations on Armada (Bryan B. Lima)
- Remove unneeded 'fast_io' on Sun8i and Armada (Wolfram Sang)
- Fix wrong boundary when clamping the low values in the set_trips()
callback and fix wrong mask when setting the temperature interval
on Airoha (Christian Marangi)
- Make use of the regmap API to support Airoha AN7583 (Christian
Marangi)
- Fix adc_tm5_get_temp() return check value on the QCom SPMI ADC
sensor (Rakesh Kota)
- Fix unbalanced clock enablement when the resume fails on the iMX
driver (Can Peng)
- Add Qualcomm Master BandGap thermal monitor support (Satya Priya
Kakitapalli)
- Add Maili Temperature bindings compatible (Haritha S K)
- Add a devm action to clean hardware interrupts, sampling, and
control registers on Spacemit K1 (Pei Xiao)
- Fix trivial typo in a thermal OF code comment (Marek Vasut)
- Remove unnecessary print on Qcom SPMI ADC driver when a call to
devm_request_threaded_irq() fails as this one already prints a
message (Jishnu Prakash)
- Add support for QCom PMIC5 Gen3 ADC by using auxiliary driver and
shared interrupt with the IIO driver (Jishnu Prakash)
- Make resets optional on MT8196 and add the corresponding property
in the DT bindings (AngeloGioacchino Del Regno)
- Fix clock staying enabled on failing resume operation on Qoriq (Can
Peng)
- Fix wrong closing brace position in thermal library header (Andreas
Haufler)
- Fix low and high trip point validation by moving the check after
the clamp on the spacemit driver (surendra)
- Remove redundant error messages on IRQ request failure (Pan Chuang)
- Add IIO_CONSUMER namespace import to the qcom-spmi-mbg-tm thermal
driver to avoid modpost warnings that would appear after merging
the iio tree against the thermal updates (Nathan Chancellor)
- Revert two recent cosmetic updates of the thermal core conflicting
with driver core plans to eliminate class_create() (Rafael
Wysocki)"
* tag 'thermal-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (32 commits)
thermal/drivers/qcom-spmi-mbg-tm: Add module namespace import for IIO_CONSUMER
Revert "thermal/core: Allocate the thermal class dynamically"
Revert "thermal/core: Use the thermal class pointer as init guard"
thermal/drivers/armada: Fix missing bitfields include
thermal/drivers/qcom/spm mbg tm: Fix missing bitfield header
thermal/drivers/qcom: Fix missing spmi adc tm5 gen3 file
thermal/drivers: Remove redundant error messages on IRQ request failure
thermal/drivers/spacemit: Validate clamped trip thresholds
tools/lib/thermal: Fix misplaced extern "C" closing brace
thermal/drivers/qoriq: Disable clock on resume failure
thermal/drivers/mediatek/lvts_thermal: Make reset optional for MT8196
dt-bindings: thermal: mediatek: Make resets optional for MT8196
thermal/drivers/qcom: add support for PMIC5 Gen3 ADC thermal monitoring
iio: adc: qcom-spmi-adc5-gen3: Share SDAM0 IRQ with ADC_TM auxiliary driver
iio: adc: qcom-spmi-adc5-gen3: Remove an unnecessary print
thermal/of: Fix trivial enabled typo
thermal/drivers/spacemit/k1: Add shutdown action and reorder registration order
dt-bindings: thermal: qcom-tsens: Document the Maili Temperature Sensor
thermal/drivers/qcom: Add support for Qualcomm MBG thermal monitoring
dt-bindings: thermal: Add Qualcomm MBG thermal monitor support
...
40 files changed, 1442 insertions, 288 deletions
diff --git a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml index 67c449d804c2..cc564dc7b414 100644 --- a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml +++ b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml @@ -19,15 +19,29 @@ properties: items: - enum: - airoha,en7581-chip-scu + - airoha,an7583-chip-scu - const: syscon reg: maxItems: 1 + '#thermal-sensor-cells': + const: 0 + required: - compatible - reg +if: + properties: + compatible: + contains: + const: airoha,en7581-chip-scu + +then: + properties: + '#thermal-sensor-cells': false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 644c42b5e2e5..11db2b3f9a6b 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -193,6 +193,10 @@ patternProperties: type: object $ref: /schemas/thermal/qcom,spmi-temp-alarm.yaml# + "^temperature-sensor@[0-9a-f]+$": + type: object + $ref: /schemas/thermal/qcom,pm8775-mbg-tm.yaml# + "^typec@[0-9a-f]+$": type: object $ref: /schemas/usb/qcom,pmic-typec.yaml# diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml index 975235130670..29f431fcdcd5 100644 --- a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml @@ -94,12 +94,23 @@ allOf: nvmem-cell-names: minItems: 2 + - if: + properties: + compatible: + not: + contains: + enum: + - mediatek,mt8196-lvts-ap + - mediatek,mt8196-lvts-mcu + then: + required: + - resets + required: - compatible - reg - interrupts - clocks - - resets - nvmem-cells - nvmem-cell-names diff --git a/Documentation/devicetree/bindings/thermal/qcom,pm8775-mbg-tm.yaml b/Documentation/devicetree/bindings/thermal/qcom,pm8775-mbg-tm.yaml new file mode 100644 index 000000000000..2e084d040625 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/qcom,pm8775-mbg-tm.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/qcom,pm8775-mbg-tm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm's SPMI PMIC MBG Thermal Monitoring + +maintainers: + - Jishnu Prakash <jishnu.prakash@oss.qualcomm.com> + - Kamal Wadhwa <kamal.wadhwa@oss.qualcomm.com> + +description: + Qualcomm's MBG(Master Bandgap) temperature alarm monitors the die + temperature and generates an interrupt if the PMIC die temperature is + over a set of programmable temperature thresholds. It allows monitoring + for both hot and cold, LVL1 and LVL2 thresholds, which makes it different + from the existing temp alarm peripheral. The interrupt comes over SPMI + and the MBG's fault status register gives details to understand whether + it is a hot/cold and LVL1/LVL2 violation. + +properties: + compatible: + const: qcom,pm8775-mbg-tm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + io-channels: + items: + - description: ADC channel, which reports chip die temperature. + + io-channel-names: + items: + - const: thermal + + '#thermal-sensor-cells': + const: 0 + +required: + - compatible + - reg + - interrupts + - io-channels + - io-channel-names + +allOf: + - $ref: thermal-sensor.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + + pmic { + #address-cells = <1>; + #size-cells = <0>; + + temperature-sensor@d700 { + compatible = "qcom,pm8775-mbg-tm"; + reg = <0xd700>; + interrupts = <0x1 0xd7 0x0 IRQ_TYPE_EDGE_RISING>; + io-channels = <&pm8775_adc 0x3>; + io-channel-names = "thermal"; + #thermal-sensor-cells = <0>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index f0efaa8349ee..5a8f7673e730 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -58,6 +58,7 @@ properties: - qcom,glymur-tsens - qcom,hawi-tsens - qcom,kaanapali-tsens + - qcom,maili-tsens - qcom,milos-tsens - qcom,nord-tsens - qcom,msm8953-tsens diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index c56b650fd8c0..c68c6c5f6aca 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -55,9 +55,6 @@ struct adc5_channel_prop { * requests from multiple clients. * @data: software configuration data. * @n_tm_channels: number of ADC channels used for TM measurements. - * @handler: TM callback to be called for threshold violation interrupt - * on first SDAM. - * @tm_aux: pointer to auxiliary TM device. */ struct adc5_chip { struct device *dev; @@ -69,8 +66,6 @@ struct adc5_chip { struct mutex lock; const struct adc5_data *data; unsigned int n_tm_channels; - void (*handler)(struct auxiliary_device *tm_aux); - struct auxiliary_device *tm_aux; }; int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index, @@ -286,23 +281,21 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) { struct adc5_chip *adc = dev_id; struct device *dev = adc->dev; - struct auxiliary_device *adev; u8 status, eoc_status, val; - u8 tm_status[2]; int ret; ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_STATUS1, &status, sizeof(status)); if (ret) { dev_err(dev, "adc read status1 failed with %d\n", ret); - return IRQ_HANDLED; + return IRQ_NONE; } ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_EOC_STS, &eoc_status, sizeof(eoc_status)); if (ret) { dev_err(dev, "adc read eoc status failed with %d\n", ret); - return IRQ_HANDLED; + return IRQ_NONE; } if (status & ADC5_GEN3_STATUS1_CONV_FAULT) { @@ -315,30 +308,13 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) return IRQ_HANDLED; } - /* CHAN0 is the preconfigured channel for immediate conversion */ - if (eoc_status & ADC5_GEN3_EOC_CHAN_0) - complete(&adc->complete); - - ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, - ADC5_GEN3_TM_HIGH_STS, tm_status, sizeof(tm_status)); - if (ret) { - dev_err(dev, "adc read TM status failed with %d\n", ret); - return IRQ_HANDLED; - } - - dev_dbg(dev, "Interrupt status:%#x, EOC status:%#x, high:%#x, low:%#x\n", - status, eoc_status, tm_status[0], tm_status[1]); + dev_dbg(dev, "Interrupt status:%#x, EOC status:%#x\n", status, eoc_status); - if (tm_status[0] || tm_status[1]) { - adev = adc->tm_aux; - if (!adev || !adev->dev.driver) { - dev_err(dev, "adc_tm auxiliary device not initialized\n"); - return IRQ_HANDLED; - } - - adc->handler(adev); - } + /* CHAN0 is the preconfigured channel for immediate conversion */ + if (!(eoc_status & ADC5_GEN3_EOC_CHAN_0)) + return IRQ_NONE; + complete(&adc->complete); return IRQ_HANDLED; } @@ -683,8 +659,6 @@ static int adc5_gen3_add_aux_tm_device(struct adc5_chip *adc) if (ret) return ret; - adc->tm_aux = &aux_device->aux_dev; - return 0; } @@ -740,16 +714,6 @@ int adc5_gen3_therm_code_to_temp(struct device *dev, } EXPORT_SYMBOL_NS_GPL(adc5_gen3_therm_code_to_temp, "QCOM_SPMI_ADC5_GEN3"); -void adc5_gen3_register_tm_event_notifier(struct device *dev, - void (*handler)(struct auxiliary_device *)) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); - struct adc5_chip *adc = iio_priv(indio_dev); - - adc->handler = handler; -} -EXPORT_SYMBOL_NS_GPL(adc5_gen3_register_tm_event_notifier, "QCOM_SPMI_ADC5_GEN3"); - static int adc5_gen3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -816,14 +780,19 @@ static int adc5_gen3_probe(struct platform_device *pdev) return -ENOMEM; } - ret = devm_request_irq(dev, adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq, - adc5_gen3_isr, 0, - adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq_name, - adc); + /* + * This interrupt is shared with the ADC_TM auxiliary driver, which + * is threaded and uses IRQF_ONESHOT. Since shared interrupts need + * to agree on IRQF_ONESHOT configuration and there is a kernel + * warning for using IRQF_ONESHOT with non-threaded interrupts, + * make this also a threaded IRQ. + */ + ret = devm_request_threaded_irq(dev, adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq, + NULL, adc5_gen3_isr, IRQF_ONESHOT | IRQF_SHARED, + adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq_name, + adc); if (ret) - return dev_err_probe(dev, ret, - "Failed to request SDAM%d irq\n", - ADC5_GEN3_VADC_SDAM); + return ret; ret = adc5_get_fw_data(adc); if (ret) diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c index b9fd6bfc88e5..77b3a1af271f 100644 --- a/drivers/thermal/airoha_thermal.c +++ b/drivers/thermal/airoha_thermal.c @@ -18,6 +18,12 @@ #define EN7581_DOUT_TADC 0x2f8 #define EN7581_DOUT_TADC_MASK GENMASK(15, 0) +#define AN7583_MUX_SENSOR 0x2a0 +#define AN7583_LOAD_ADJ GENMASK(3, 2) +#define AN7583_MUX_TADC 0x2e4 +#define AN7583_MUX_TADC_MASK GENMASK(3, 1) +#define AN7583_DOUT_TADC 0x2f0 + /* PTP_THERMAL regs */ #define EN7581_TEMPMONCTL0 0x800 #define EN7581_SENSE3_EN BIT(3) @@ -181,6 +187,11 @@ #define EN7581_SCU_THERMAL_PROTECT_KEY 0x12 #define EN7581_SCU_THERMAL_MUX_DIODE1 0x7 +#define AN7583_SCU_THERMAL_PROTECT_KEY 0x80 +#define AN7583_NUM_SENSOR 3 + +#define AIROHA_THERMAL_NO_MUX_SENSOR -1 + /* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */ #define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \ (priv)->default_slope) / 1000) + \ @@ -193,42 +204,131 @@ #define AIROHA_MAX_SAMPLES 6 +/* + * AN7583 supports all these ADC mux but the original driver + * always checked temp with the AN7583_BGP_TEMP_SENSOR. + * Assume using the other sensor temperature is invalid and + * always read from AN7583_BGP_TEMP_SENSOR. + * + * On top of this it's defined that AN7583 supports 3 + * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR, + * AN7583_CPU_TEMP_SENSOR. + * + * Provide the ADC mux for reference. + */ +enum an7583_thermal_adc_mux { + AN7583_BGP_TEMP_SENSOR, + AN7583_PAD_AVS, + AN7583_CORE_POWER, + AN7583_AVSDAC_OUT, + AN7583_VCM, + AN7583_GBE_TEMP_SENSOR, + AN7583_CPU_TEMP_SENSOR, + + AN7583_ADC_MUX_MAX, +}; + +enum an7583_thermal_diode_mux { + AN7583_D0_TADC, + AN7583_ZERO_TADC, + AN7583_D1_TADC, +}; + +enum airoha_thermal_chip_scu_field { + AIROHA_THERMAL_DOUT_TADC, + AIROHA_THERMAL_MUX_SENSOR, + AIROHA_THERMAL_MUX_TADC, + + /* keep last */ + AIROHA_THERMAL_FIELD_MAX, +}; + struct airoha_thermal_priv { - void __iomem *base; + struct regmap *map; struct regmap *chip_scu; + struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX]; struct resource scu_adc_res; + u32 pllrg_protect; + int current_adc; + struct thermal_zone_device *tz; int init_temp; int default_slope; int default_offset; }; +struct airoha_thermal_soc_data { + u32 pllrg_protect; + + const struct thermal_zone_device_ops *thdev_ops; + int (*probe)(struct platform_device *pdev, + struct airoha_thermal_priv *priv); + int (*post_probe)(struct platform_device *pdev); +}; + +static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = { + [AN7583_BGP_TEMP_SENSOR] = 973, + [AN7583_GBE_TEMP_SENSOR] = 995, + [AN7583_CPU_TEMP_SENSOR] = 1035, +}; + +static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = { + [AN7583_BGP_TEMP_SENSOR] = 7440, + [AN7583_GBE_TEMP_SENSOR] = 7620, + [AN7583_CPU_TEMP_SENSOR] = 8390, +}; + +static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = { + [AN7583_BGP_TEMP_SENSOR] = 294, + [AN7583_GBE_TEMP_SENSOR] = 298, + [AN7583_CPU_TEMP_SENSOR] = 344, +}; + static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv) { u32 val; - regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val); - return FIELD_GET(EN7581_DOUT_TADC_MASK, val); + regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC], + &val); + return val; } -static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv) +static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv, + int tdac_idx, int sensor_idx) { - u32 adc_mux, pllrg; + u32 pllrg; /* Save PLLRG current value */ regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg); - /* Give access to thermal regs */ - regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY); - adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1); - regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux); + /* Give access to Thermal regs */ + regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, + priv->pllrg_protect); + + /* + * Configure Thermal Sensor mux to sensor_idx. + * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR) + */ + if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR) + regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR], + sensor_idx); + + /* Configure Thermal ADC mux to tdac_idx */ + if (priv->current_adc != tdac_idx) { + regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC], + tdac_idx); + priv->current_adc = tdac_idx; + } /* Restore PLLRG value on exit */ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg); + + /* Sleep 10 ms for Thermal ADC to enable */ + usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); } -static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp) +static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); int min_value, max_value, avg_value, value; @@ -253,7 +353,7 @@ static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp) return 0; } -static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low, +static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) { struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); @@ -265,44 +365,44 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low, RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); /* We offset the high temp of 1°C to trigger correct event */ - writel(TEMP_TO_RAW(priv, high) >> 4, - priv->base + EN7581_TEMPOFFSETH); + regmap_write(priv->map, EN7581_TEMPOFFSETH, + TEMP_TO_RAW(priv, high) >> 4); enable_monitor = true; } if (low != -INT_MAX) { /* Validate low and clamp it to a supported value */ - low = clamp_t(int, high, RAW_TO_TEMP(priv, 0), + low = clamp_t(int, low, RAW_TO_TEMP(priv, 0), RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); /* We offset the low temp of 1°C to trigger correct event */ - writel(TEMP_TO_RAW(priv, low) >> 4, - priv->base + EN7581_TEMPOFFSETL); + regmap_write(priv->map, EN7581_TEMPOFFSETL, + TEMP_TO_RAW(priv, low) >> 4); enable_monitor = true; } /* Enable sensor 0 monitor after trip are set */ if (enable_monitor) - writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0); + regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN); return 0; } -static const struct thermal_zone_device_ops thdev_ops = { - .get_temp = airoha_thermal_get_temp, - .set_trips = airoha_thermal_set_trips, +static const struct thermal_zone_device_ops en7581_thdev_ops = { + .get_temp = en7581_thermal_get_temp, + .set_trips = en7581_thermal_set_trips, }; -static irqreturn_t airoha_thermal_irq(int irq, void *data) +static irqreturn_t en7581_thermal_irq(int irq, void *data) { struct airoha_thermal_priv *priv = data; enum thermal_notify_event event; bool update = false; - u32 status; + u32 status = 0; - status = readl(priv->base + EN7581_TEMPMONINTSTS); + regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status); switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) { case EN7581_HOFSINTSTS0: event = THERMAL_TRIP_VIOLATED; @@ -318,7 +418,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data) } /* Reset Interrupt */ - writel(status, priv->base + EN7581_TEMPMONINTSTS); + regmap_write(priv->map, EN7581_TEMPMONINTSTS, status); if (update) thermal_zone_device_update(priv->tz, event); @@ -326,21 +426,21 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data) return IRQ_HANDLED; } -static void airoha_thermal_setup_adc_val(struct device *dev, +static void en7581_thermal_setup_adc_val(struct device *dev, struct airoha_thermal_priv *priv) { - u32 efuse_calib_info, cpu_sensor; + u32 efuse_calib_info = 0; + u32 cpu_sensor = 0; - /* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */ - airoha_init_thermal_ADC_mode(priv); - /* sleep 10 ms for ADC to enable */ - usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); + /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */ + airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1, + AIROHA_THERMAL_NO_MUX_SENSOR); - efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG); + regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info); if (efuse_calib_info) { priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info); /* Different slope are applied if the sensor is used for CPU or for package */ - cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG); + regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor); if (cpu_sensor) { priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT; priv->init_temp = EN7581_INIT_TEMP_FTK_X10; @@ -356,11 +456,11 @@ static void airoha_thermal_setup_adc_val(struct device *dev, } } -static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) +static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv) { /* Set measure mode */ - writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4), - priv->base + EN7581_TEMPMSRCTL0); + regmap_write(priv->map, EN7581_TEMPMSRCTL0, + FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4)); /* * Configure ADC valid reading addr @@ -375,15 +475,15 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) * We set valid instead of volt as we don't enable valid/volt * split reading and AHB read valid addr in such case. */ - writel(priv->scu_adc_res.start + EN7581_DOUT_TADC, - priv->base + EN7581_TEMPADCVALIDADDR); + regmap_write(priv->map, EN7581_TEMPADCVALIDADDR, + priv->scu_adc_res.start + EN7581_DOUT_TADC); /* * Configure valid bit on a fake value of bit 16. The ADC outputs * max of 2 bytes for voltage. */ - writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16), - priv->base + EN7581_TEMPADCVALIDMASK); + regmap_write(priv->map, EN7581_TEMPADCVALIDMASK, + FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16)); /* * AHB supports max 12 bytes for ADC voltage. Shift the read @@ -391,40 +491,53 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) * in the order of half a °C and is acceptable in the context * of triggering interrupt in critical condition. */ - writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4), - priv->base + EN7581_TEMPADCVOLTAGESHIFT); + regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT, + FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4)); /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */ - writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3), - priv->base + EN7581_TEMPMONCTL1); + regmap_write(priv->map, EN7581_TEMPMONCTL1, + FIELD_PREP(EN7581_PERIOD_UNIT, 3)); /* * filt interval is 1 * 52.715us = 52.715us, * sen interval is 379 * 52.715us = 19.97ms */ - writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) | - FIELD_PREP(EN7581_FILT_INTERVAL, 379), - priv->base + EN7581_TEMPMONCTL2); + regmap_write(priv->map, EN7581_TEMPMONCTL2, + FIELD_PREP(EN7581_FILT_INTERVAL, 1) | + FIELD_PREP(EN7581_SEN_INTERVAL, 379)); /* AHB poll is set to 146 * 68 |
