diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c index 0f0e6f3af3cd..7c63a1b44a6b 100644 --- a/drivers/thermal/airoha_thermal.c +++ b/drivers/thermal/airoha_thermal.c @@ -245,6 +245,11 @@ enum airoha_thermal_chip_scu_field { AIROHA_THERMAL_FIELD_MAX, }; +struct airoha_thermal_zone { + struct airoha_thermal_priv *priv; + int sensor; +}; + struct airoha_thermal_priv { struct regmap *map; struct regmap *chip_scu; @@ -263,6 +268,9 @@ struct airoha_thermal_priv { struct airoha_thermal_soc_data { u32 pllrg_protect; + /* Sensor mux value per zone, NULL without a sensor mux */ + const int *sensors; + int num_sensors; const struct thermal_zone_device_ops *thdev_ops; int (*probe)(struct platform_device *pdev, @@ -348,7 +356,8 @@ static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv, static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); + struct airoha_thermal_zone *zone = thermal_zone_device_priv(tz); + struct airoha_thermal_priv *priv = zone->priv; int min_value, max_value, avg_value, value; int i; @@ -374,7 +383,8 @@ static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp) 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); + struct airoha_thermal_zone *zone = thermal_zone_device_priv(tz); + struct airoha_thermal_priv *priv = zone->priv; bool enable_monitor = false; if (high != INT_MAX) { @@ -642,8 +652,9 @@ static int an7583_thermal_read_diodes(struct airoha_thermal_priv *priv, static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); - int sensor_idx; + struct airoha_thermal_zone *zone = thermal_zone_device_priv(tz); + struct airoha_thermal_priv *priv = zone->priv; + int sensor_idx = zone->sensor; int delta_diode, delta_gain; int coeff, slope, offset; int tries = AIROHA_THERMAL_MUX_TRIES; @@ -651,9 +662,6 @@ static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp) int diode_zero, diode_d0, diode_d1; - /* Always read sensor AN7583_BGP_TEMP_SENSOR */ - sensor_idx = AN7583_BGP_TEMP_SENSOR; - coeff = an7583_thermal_coeff[sensor_idx]; slope = an7583_thermal_slope[sensor_idx]; offset = an7583_thermal_offset[sensor_idx]; @@ -717,7 +725,7 @@ static int airoha_thermal_probe(struct platform_device *pdev) const struct airoha_thermal_soc_data *soc_data; struct airoha_thermal_priv *priv; struct device *dev = &pdev->dev; - int ret; + int ret, i; soc_data = device_get_match_data(dev); @@ -739,11 +747,31 @@ static int airoha_thermal_probe(struct platform_device *pdev) return ret; /* register of thermal sensor and get info from DT */ - priv->tz = devm_thermal_of_zone_register(dev, 0, priv, - soc_data->thdev_ops); - if (IS_ERR(priv->tz)) { - dev_err(dev, "register thermal zone sensor failed\n"); - return PTR_ERR(priv->tz); + for (i = 0; i < soc_data->num_sensors; i++) { + struct airoha_thermal_zone *zone; + struct thermal_zone_device *tz; + + zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL); + if (!zone) + return -ENOMEM; + + zone->priv = priv; + zone->sensor = soc_data->sensors ? soc_data->sensors[i] : + AIROHA_THERMAL_NO_MUX_SENSOR; + + tz = devm_thermal_of_zone_register(dev, i, zone, + soc_data->thdev_ops); + if (IS_ERR(tz)) { + /* A DT may describe fewer zones than sensors */ + if (i && PTR_ERR(tz) == -ENODEV) + continue; + + dev_err(dev, "register thermal zone %d failed\n", i); + return PTR_ERR(tz); + } + + if (!i) + priv->tz = tz; } platform_set_drvdata(pdev, priv); @@ -751,7 +779,15 @@ static int airoha_thermal_probe(struct platform_device *pdev) return soc_data->post_probe ? soc_data->post_probe(pdev) : 0; } +/* The bandgap sensor stays zone 0 */ +static const int an7583_zone_sensors[AN7583_NUM_SENSOR] = { + AN7583_BGP_TEMP_SENSOR, + AN7583_GBE_TEMP_SENSOR, + AN7583_CPU_TEMP_SENSOR, +}; + static const struct airoha_thermal_soc_data en7581_data = { + .num_sensors = 1, .pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY, .thdev_ops = &en7581_thdev_ops, .probe = &en7581_thermal_probe, @@ -759,6 +795,8 @@ static const struct airoha_thermal_soc_data en7581_data = { }; static const struct airoha_thermal_soc_data an7583_data = { + .sensors = an7583_zone_sensors, + .num_sensors = AN7583_NUM_SENSOR, .pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY, .thdev_ops = &an7583_tz_ops, .probe = &an7583_thermal_probe,