On Mon, Apr 22, 2024 at 6:42 PM Daniel Lezcano <daniel.lezcano@xxxxxxxxxx> wrote: > > On 20/04/2024 03:46, Binbin Zhou wrote: > > The Loongson-2K2000 and Loongson-2K1000 have similar thermal sensors, > > except that the temperature is read differently. > > > > In particular, the temperature output registers of the Loongson-2K2000 > > are defined in the chip configuration domain and are read in a different > > way. > > > > Signed-off-by: Binbin Zhou <zhoubinbin@xxxxxxxxxxx> > > Acked-by: Huacai Chen <chenhuacai@xxxxxxxxxxx> > > --- > > drivers/thermal/loongson2_thermal.c | 50 +++++++++++++++++++++++------ > > 1 file changed, 40 insertions(+), 10 deletions(-) > > > > diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c > > index 7de01fbea801..8ecd8ed465ec 100644 > > --- a/drivers/thermal/loongson2_thermal.c > > +++ b/drivers/thermal/loongson2_thermal.c > > @@ -30,12 +30,20 @@ > > LOONGSON2_THSENS_INT_HIGH) > > #define LOONGSON2_THSENS_OUT_MASK 0xFF > > > > +/* > > + * This flag is used to indicate the temperature reading > > + * method of the Loongson-2K2000 > > + */ > > +#define LS2K2000_THSENS_OUT_FLAG BIT(0) > > + > > struct loongson2_thermal_chip_data { > > unsigned int thermal_sensor_sel; > > + unsigned int flags; > > }; > > > > struct loongson2_thermal_data { > > - void __iomem *regs; > > + void __iomem *ctrl_reg; > > + void __iomem *temp_reg; > > const struct loongson2_thermal_chip_data *chip_data; > > }; > > > > @@ -48,7 +56,7 @@ static void loongson2_set_ctrl_regs(struct loongson2_thermal_data *data, > > > > reg_ctrl = ctrl_data + HECTO; > > reg_ctrl |= enable ? 0x100 : 0; > > - writew(reg_ctrl, data->regs + ctrl_reg + reg_off); > > + writew(reg_ctrl, data->ctrl_reg + ctrl_reg + reg_off); > > } > > > > static int loongson2_thermal_set(struct loongson2_thermal_data *data, > > @@ -65,11 +73,16 @@ static int loongson2_thermal_set(struct loongson2_thermal_data *data, > > > > static int loongson2_thermal_get_temp(struct thermal_zone_device *tz, int *temp) > > { > > - u32 reg_val; > > + int val; > > struct loongson2_thermal_data *data = thermal_zone_device_priv(tz); > > > > - reg_val = readl(data->regs + LOONGSON2_THSENS_OUT_REG); > > - *temp = ((reg_val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO; > > + if (data->chip_data->flags) { > > + val = readl(data->temp_reg); > > + *temp = ((val & 0xffff) * 820 / 0x4000 - 311) * KILO; > > + } else { > > + val = readl(data->ctrl_reg + LOONGSON2_THSENS_OUT_REG); > > + *temp = ((val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO; > > + } > > Why not use a different ops. That will keep the code cleaner for the > next sensor versions. > > For example: > > static int loongson2_2k2000_get_temp(...) > { > } > > static int loongson2_2k1000_get_temp(...) > { > } > > static struct thermal_zone_device_ops loongson2_of_thermal_ops = { > .get_temp = loongson2_2k1000_get_temp, > .set_trips = loongson2_thermal_set_trips, > }; > > > loongson2_thermal_probe > { > ... > > if (data->chip_data->flags & LS2K2000_THSENS_OUT_FLAG) > loongson2_of_thermal_ops.get_temp = loongson2_2k2000_get_temp; > ... > > } Hi Daniel: Thanks for your advice. I'll use a different ops to keep the code cleaner in the next version, Thanks. Binbin > > > return 0; > > } > > @@ -79,7 +92,7 @@ static irqreturn_t loongson2_thermal_irq_thread(int irq, void *dev) > > struct thermal_zone_device *tzd = dev; > > struct loongson2_thermal_data *data = thermal_zone_device_priv(tzd); > > > > - writeb(LOONGSON2_THSENS_INT_EN, data->regs + LOONGSON2_THSENS_STATUS_REG); > > + writeb(LOONGSON2_THSENS_INT_EN, data->ctrl_reg + LOONGSON2_THSENS_STATUS_REG); > > > > thermal_zone_device_update(tzd, THERMAL_EVENT_UNSPECIFIED); > > > > @@ -111,15 +124,22 @@ static int loongson2_thermal_probe(struct platform_device *pdev) > > > > data->chip_data = device_get_match_data(dev); > > > > - data->regs = devm_platform_ioremap_resource(pdev, 0); > > - if (IS_ERR(data->regs)) > > - return PTR_ERR(data->regs); > > + data->ctrl_reg = devm_platform_ioremap_resource(pdev, 0); > > + if (IS_ERR(data->ctrl_reg)) > > + return PTR_ERR(data->ctrl_reg); > > + > > + /* The temperature output register is separate for Loongson-2K2000 */ > > + if (data->chip_data->flags) { > > + data->temp_reg = devm_platform_ioremap_resource(pdev, 1); > > + if (IS_ERR(data->temp_reg)) > > + return PTR_ERR(data->temp_reg); > > + } > > > > irq = platform_get_irq(pdev, 0); > > if (irq < 0) > > return irq; > > > > - writeb(LOONGSON2_THSENS_INT_EN, data->regs + LOONGSON2_THSENS_STATUS_REG); > > + writeb(LOONGSON2_THSENS_INT_EN, data->ctrl_reg + LOONGSON2_THSENS_STATUS_REG); > > > > loongson2_thermal_set(data, 0, 0, false); > > > > @@ -146,6 +166,12 @@ static int loongson2_thermal_probe(struct platform_device *pdev) > > > > static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = { > > .thermal_sensor_sel = 0, > > + .flags = 0, > > +}; > > + > > +static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k2000_data = { > > + .thermal_sensor_sel = 0, > > + .flags = LS2K2000_THSENS_OUT_FLAG, > > }; > > > > static const struct of_device_id of_loongson2_thermal_match[] = { > > @@ -153,6 +179,10 @@ static const struct of_device_id of_loongson2_thermal_match[] = { > > .compatible = "loongson,ls2k1000-thermal", > > .data = &loongson2_thermal_ls2k1000_data, > > }, > > + { > > + .compatible = "loongson,ls2k2000-thermal", > > + .data = &loongson2_thermal_ls2k2000_data, > > + }, > > { /* end */ } > > }; > > MODULE_DEVICE_TABLE(of, of_loongson2_thermal_match); > > -- > <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs > > Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | > <http://twitter.com/#!/linaroorg> Twitter | > <http://www.linaro.org/linaro-blog/> Blog >