Message ID | 1507658570-32675-1-git-send-email-daniel.lezcano@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | [01/25] thermal/drivers/hisi: Fix missing interrupt enablement | expand |
Hi Daniel, On 2017/10/10 19:02, Daniel Lezcano wrote: > From: Kevin Wangtao <kevin.wangtao@linaro.org> > > Add binding for tsensor on H3660, this tsensor is used for > SoC thermal control, it supports alarm interrupt. > > Signed-off-by: Kevin Wangtao <kevin.wangtao@linaro.org> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- Applied this and 23rd into hisilicon dt tree. Thanks! BR, Wei > arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi > index c6a1961..d9c0cf3 100644 > --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi > +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi > @@ -848,5 +848,13 @@ > &sdio_cfg_func>; > status = "disabled"; > }; > + > + tsensor: tsensor@fff30000 { > + compatible = "hisilicon,hi3660-tsensor"; > + reg = <0x0 0xfff30000 0x0 0x1000>; > + interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; > + #thermal-sensor-cells = <1>; > + }; > + > }; > }; >
On Tue, Oct 10, 2017 at 08:02:33PM +0200, Daniel Lezcano wrote: > The TEMP0_CFG configuration register contains different field to set up the > temperature controller. However in the code, nothing prevents a setup to > overwrite the previous one: eg. writing the hdak value overwrites the sensor > selection, the sensor selection overwrites the hdak value. > > In order to prevent such thing, use a regmap-like mechanism by reading the > value before, set the corresponding bits and write the result. > > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > drivers/thermal/hisi_thermal.c | 34 +++++++++++++++++++++++++++++----- > 1 file changed, 29 insertions(+), 5 deletions(-) > > diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c > index 8e8a117..5688556 100644 > --- a/drivers/thermal/hisi_thermal.c > +++ b/drivers/thermal/hisi_thermal.c > @@ -30,6 +30,8 @@ > #define TEMP0_TH (0x4) > #define TEMP0_RST_TH (0x8) > #define TEMP0_CFG (0xC) > +#define TEMP0_CFG_SS_MSK (0xF000) > +#define TEMP0_CFG_HDAK_MSK (0x30) > #define TEMP0_EN (0x10) > #define TEMP0_INT_EN (0x14) > #define TEMP0_INT_CLR (0x18) > @@ -132,19 +134,41 @@ static inline void hisi_thermal_enable(void __iomem *addr, int value) > writel(value, addr + TEMP0_EN); > } > > -static inline void hisi_thermal_sensor_select(void __iomem *addr, int sensor) > +static inline int hisi_thermal_get_temperature(void __iomem *addr) > { > - writel((sensor << 12), addr + TEMP0_CFG); > + return hisi_thermal_step_to_temp(readl(addr + TEMP0_VALUE)); > } > > -static inline int hisi_thermal_get_temperature(void __iomem *addr) > +/* > + * Temperature configuration register - Sensor selection > + * > + * Bits [19:12] > + * > + * 0x0: local sensor (default) > + * 0x1: remote sensor 1 (ACPU cluster 1) > + * 0x2: remote sensor 2 (ACPU cluster 0) > + * 0x3: remote sensor 3 (G3D) > + */ > +static inline void hisi_thermal_sensor_select(void __iomem *addr, int sensor) > { > - return hisi_thermal_step_to_temp(readl(addr + TEMP0_VALUE)); > + writel((readl(addr + TEMP0_CFG) & ~TEMP0_CFG_SS_MSK ) | ERROR: space prohibited before that close parenthesis ')' #135: FILE: drivers/thermal/hisi_thermal.c:154: + writel((readl(addr + TEMP0_CFG) & ~TEMP0_CFG_SS_MSK ) | > + (sensor << 12), addr + TEMP0_CFG); > } > > +/* > + * Temperature configuration register - Hdak conversion polling interval > + * > + * Bits [5:4] > + * > + * 0x0 : 0.768 ms > + * 0x1 : 6.144 ms > + * 0x2 : 49.152 ms > + * 0x3 : 393.216 ms > + */ > static inline void hisi_thermal_hdak_set(void __iomem *addr, int value) > { > - writel(value, addr + TEMP0_CFG); > + writel((readl(addr + TEMP0_CFG) & ~TEMP0_CFG_HDAK_MSK) | > + (value << 4), addr + TEMP0_CFG); > } > > static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data, > -- > 2.7.4 >
On Tue, Oct 10, 2017 at 08:02:46PM +0200, Daniel Lezcano wrote: > From: Kevin Wangtao <kevin.wangtao@linaro.org> > > For platform compatibility, add the tsensor ops to a thermal data structure. > Each platform has its own probe function to register proper tsensor ops > function to the pointer, platform related resource request are also implemented > in the platform probe function. Please fix minor check patch issues like: CHECK: Please don't use multiple blank lines #142: FILE: drivers/thermal/hisi_thermal.c:67: + CHECK: Please don't use multiple blank lines #218: FILE: drivers/thermal/hisi_thermal.c:297: + + CHECK: Alignment should match open parenthesis #335: FILE: drivers/thermal/hisi_thermal.c:424: + ret = devm_request_threaded_irq(dev, data->irq, NULL, + hisi_thermal_alarm_irq_thread, > > Signed-off-by: Kevin Wangtao <kevin.wangtao@linaro.org> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > drivers/thermal/hisi_thermal.c | 135 +++++++++++++++++++++++++++-------------- > 1 file changed, 89 insertions(+), 46 deletions(-) > > diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c > index 8a70ab7..b5a7159 100644 > --- a/drivers/thermal/hisi_thermal.c > +++ b/drivers/thermal/hisi_thermal.c > @@ -23,6 +23,7 @@ > #include <linux/module.h> > #include <linux/platform_device.h> > #include <linux/io.h> > +#include <linux/of_device.h> > > #include "thermal_core.h" > > @@ -30,7 +31,7 @@ > #define HI6220_TEMP0_TH (0x4) > #define HI6220_TEMP0_RST_TH (0x8) > #define HI6220_TEMP0_CFG (0xC) > -#define HI6220_TEMP0_CFG_SS_MSK (0xF000) > +#define HI6220_TEMP0_CFG_SS_MSK (0xF000) > #define HI6220_TEMP0_CFG_HDAK_MSK (0x30) > #define HI6220_TEMP0_EN (0x10) > #define HI6220_TEMP0_INT_EN (0x14) > @@ -41,7 +42,7 @@ > #define HI6220_TEMP_BASE (-60000) > #define HI6220_TEMP_RESET (100000) > #define HI6220_TEMP_STEP (785) > -#define HI6220_TEMP_LAG (3500) > +#define HI6220_TEMP_LAG (3500) > > #define HI6220_DEFAULT_SENSOR 2 > > @@ -52,6 +53,10 @@ struct hisi_thermal_sensor { > }; > > struct hisi_thermal_data { > + int (*get_temp)(struct hisi_thermal_data *data); > + int (*enable_sensor)(struct hisi_thermal_data *data); > + int (*disable_sensor)(struct hisi_thermal_data *data); > + int (*irq_handler)(struct hisi_thermal_data *data); > struct platform_device *pdev; > struct clk *clk; > struct hisi_thermal_sensor sensor; > @@ -59,6 +64,7 @@ struct hisi_thermal_data { > int irq; > }; > > + > /* > * The temperature computation on the tsensor is as follow: > * Unit: millidegree Celsius > @@ -192,7 +198,18 @@ static inline void hi6220_thermal_hdak_set(void __iomem *addr, int value) > (value << 4), addr + HI6220_TEMP0_CFG); > } > > -static void hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) > +static int hi6220_thermal_irq_handler(struct hisi_thermal_data *data) > +{ > + hi6220_thermal_alarm_clear(data->regs, 1); > + return 0; > +} > + > +static int hi6220_thermal_get_temp(struct hisi_thermal_data *data) > +{ > + return hi6220_thermal_get_temperature(data->regs); > +} > + > +static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) > { > /* disable sensor module */ > hi6220_thermal_enable(data->regs, 0); > @@ -200,9 +217,9 @@ static void hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) > hi6220_thermal_reset_enable(data->regs, 0); > > clk_disable_unprepare(data->clk); > + return 0; > } > > - > static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) > { > struct hisi_thermal_sensor *sensor = &data->sensor; > @@ -240,12 +257,50 @@ static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) > > return 0; > } > + > +static int hi6220_thermal_probe(struct hisi_thermal_data *data) > +{ > + struct platform_device *pdev = data->pdev; > + struct device *dev = &pdev->dev; > + struct resource *res; > + int ret; > + > + data->get_temp = hi6220_thermal_get_temp; > + data->enable_sensor = hi6220_thermal_enable_sensor; > + data->disable_sensor = hi6220_thermal_disable_sensor; > + data->irq_handler = hi6220_thermal_irq_handler; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + data->regs = devm_ioremap_resource(dev, res); > + if (IS_ERR(data->regs)) { > + dev_err(dev, "failed to get io address\n"); > + return PTR_ERR(data->regs); > + } > + > + data->clk = devm_clk_get(dev, "thermal_clk"); > + if (IS_ERR(data->clk)) { > + ret = PTR_ERR(data->clk); > + if (ret != -EPROBE_DEFER) > + dev_err(dev, "failed to get thermal clk: %d\n", ret); > + return ret; > + } > + > + data->irq = platform_get_irq(pdev, 0); > + if (data->irq < 0) > + return data->irq; > + > + data->sensor.id = HI6220_DEFAULT_SENSOR; > + > + return 0; > +} > + > + > static int hisi_thermal_get_temp(void *__data, int *temp) > { > struct hisi_thermal_data *data = __data; > struct hisi_thermal_sensor *sensor = &data->sensor; > > - *temp = hi6220_thermal_get_temperature(data->regs); > + *temp = data->get_temp(data); > > dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n", > sensor->id, *temp, sensor->thres_temp); > @@ -263,7 +318,7 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) > struct hisi_thermal_sensor *sensor = &data->sensor; > int temp = 0; > > - hi6220_thermal_alarm_clear(data->regs, 1); > + data->irq_handler(data); > > hisi_thermal_get_temp(data, &temp); > > @@ -284,14 +339,11 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) > > static int hisi_thermal_register_sensor(struct platform_device *pdev, > struct hisi_thermal_data *data, > - struct hisi_thermal_sensor *sensor, > - int index) > + struct hisi_thermal_sensor *sensor) > { > int ret, i; > const struct thermal_trip *trip; > > - sensor->id = index; > - > sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, > sensor->id, data, > &hisi_of_thermal_ops); > @@ -316,7 +368,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, > } > > static const struct of_device_id of_hisi_thermal_match[] = { > - { .compatible = "hisilicon,tsensor" }, > + { .compatible = "hisilicon,tsensor", .data = hi6220_thermal_probe }, > { /* end */ } > }; > MODULE_DEVICE_TABLE(of, of_hisi_thermal_match); > @@ -333,58 +385,48 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor, > static int hisi_thermal_probe(struct platform_device *pdev) > { > struct hisi_thermal_data *data; > - struct resource *res; > + int (*platform_probe)(struct hisi_thermal_data *); > + struct device *dev = &pdev->dev; > int ret; > > - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); > + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); > if (!data) > return -ENOMEM; > > data->pdev = pdev; > + platform_set_drvdata(pdev, data); > > - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > - data->regs = devm_ioremap_resource(&pdev->dev, res); > - if (IS_ERR(data->regs)) { > - dev_err(&pdev->dev, "failed to get io address\n"); > - return PTR_ERR(data->regs); > + platform_probe = of_device_get_match_data(dev); I get the compilation warn below: CHECK drivers/thermal/hisi_thermal.c drivers/thermal/hisi_thermal.c:399:24: warning: incorrect type in assignment (different modifiers) drivers/thermal/hisi_thermal.c:399:24: expected int ( *platform_probe )( ... ) drivers/thermal/hisi_thermal.c:399:24: got void const * CC [M] drivers/thermal/hisi_thermal.o Please fix it. > + if (!platform_probe) { > + dev_err(dev, "failed to get probe func\n"); > + return -EINVAL; > } > > - data->irq = platform_get_irq(pdev, 0); > - if (data->irq < 0) > - return data->irq; > - > - platform_set_drvdata(pdev, data); > - > - data->clk = devm_clk_get(&pdev->dev, "thermal_clk"); > - if (IS_ERR(data->clk)) { > - ret = PTR_ERR(data->clk); > - if (ret != -EPROBE_DEFER) > - dev_err(&pdev->dev, > - "failed to get thermal clk: %d\n", ret); > + ret = platform_probe(data); > + if (ret) > return ret; > - } > > ret = hisi_thermal_register_sensor(pdev, data, > - &data->sensor, > - HI6220_DEFAULT_SENSOR); > + &data->sensor); > if (ret) { > - dev_err(&pdev->dev, "failed to register thermal sensor: %d\n", > - ret); > + dev_err(dev, "failed to register thermal sensor: %d\n", ret); > return ret; > } > > - ret = hi6220_thermal_enable_sensor(data); > + ret = data->enable_sensor(data); > if (ret) { > - dev_err(&pdev->dev, "Failed to setup the sensor: %d\n", ret); > + dev_err(dev, "Failed to setup the sensor: %d\n", ret); > return ret; > } > > - ret = devm_request_threaded_irq(&pdev->dev, data->irq, NULL, > - hisi_thermal_alarm_irq_thread, > - IRQF_ONESHOT, "hisi_thermal", data); > - if (ret < 0) { > - dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); > - return ret; > + if (data->irq) { > + ret = devm_request_threaded_irq(dev, data->irq, NULL, > + hisi_thermal_alarm_irq_thread, > + IRQF_ONESHOT, "hisi_thermal", data); > + if (ret < 0) { > + dev_err(dev, "failed to request alarm irq: %d\n", ret); > + return ret; > + } > } > > hisi_thermal_toggle_sensor(&data->sensor, true); > @@ -398,7 +440,8 @@ static int hisi_thermal_remove(struct platform_device *pdev) > struct hisi_thermal_sensor *sensor = &data->sensor; > > hisi_thermal_toggle_sensor(sensor, false); > - hi6220_thermal_disable_sensor(data); > + > + data->disable_sensor(data); > > return 0; > } > @@ -408,7 +451,7 @@ static int hisi_thermal_suspend(struct device *dev) > { > struct hisi_thermal_data *data = dev_get_drvdata(dev); > > - hi6220_thermal_disable_sensor(data); > + data->disable_sensor(data); > > return 0; > } > @@ -417,7 +460,7 @@ static int hisi_thermal_resume(struct device *dev) > { > struct hisi_thermal_data *data = dev_get_drvdata(dev); > > - return hi6220_thermal_enable_sensor(data); > + return data->enable_sensor(data); > } > #endif > > -- > 2.7.4 >
On Tue, Oct 10, 2017 at 08:02:45PM +0200, Daniel Lezcano wrote: > From: Kevin Wangtao <kevin.wangtao@linaro.org> > > As the next patches will provide support for the hikey3660's sensor, several > functions with the same purpose but for different platforms will be introduced. > In order to make a clear distinction between them, let's prefix the function > names with the platform name. > > This patch has no functional changes. CHECK: Alignment should match open parenthesis #188: FILE: drivers/thermal/hisi_thermal.c:124: + writel(DIV_ROUND_UP(value, HI6220_TEMP_STEP) & 0x1F, + addr + HI6220_TEMP0_LAG); CHECK: Alignment should match open parenthesis #210: FILE: drivers/thermal/hisi_thermal.c:140: + writel(hi6220_thermal_temp_to_step(temp) | 0x0FFFFFF00, + addr + HI6220_TEMP0_TH); total: 0 errors, 1 warnings, 2 checks, 286 lines checked > > Signed-off-by: Kevin Wangtao <kevin.wangtao@linaro.org> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > drivers/thermal/hisi_thermal.c | 145 +++++++++++++++++++++-------------------- > 1 file changed, 73 insertions(+), 72 deletions(-) > > diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c > index ff9055a..8a70ab7 100644 > --- a/drivers/thermal/hisi_thermal.c > +++ b/drivers/thermal/hisi_thermal.c > @@ -26,25 +26,24 @@ > > #include "thermal_core.h" > > -#define TEMP0_LAG (0x0) > -#define TEMP0_TH (0x4) > -#define TEMP0_RST_TH (0x8) > -#define TEMP0_CFG (0xC) > -#define TEMP0_CFG_SS_MSK (0xF000) > -#define TEMP0_CFG_HDAK_MSK (0x30) > -#define TEMP0_EN (0x10) > -#define TEMP0_INT_EN (0x14) > -#define TEMP0_INT_CLR (0x18) > -#define TEMP0_RST_MSK (0x1C) > -#define TEMP0_VALUE (0x28) > - > -#define HISI_TEMP_BASE (-60000) > -#define HISI_TEMP_RESET (100000) > -#define HISI_TEMP_STEP (785) > -#define HISI_TEMP_LAG (3500) > - > -#define HISI_MAX_SENSORS 4 > -#define HISI_DEFAULT_SENSOR 2 > +#define HI6220_TEMP0_LAG (0x0) > +#define HI6220_TEMP0_TH (0x4) > +#define HI6220_TEMP0_RST_TH (0x8) > +#define HI6220_TEMP0_CFG (0xC) > +#define HI6220_TEMP0_CFG_SS_MSK (0xF000) > +#define HI6220_TEMP0_CFG_HDAK_MSK (0x30) > +#define HI6220_TEMP0_EN (0x10) > +#define HI6220_TEMP0_INT_EN (0x14) > +#define HI6220_TEMP0_INT_CLR (0x18) > +#define HI6220_TEMP0_RST_MSK (0x1C) > +#define HI6220_TEMP0_VALUE (0x28) > + > +#define HI6220_TEMP_BASE (-60000) > +#define HI6220_TEMP_RESET (100000) > +#define HI6220_TEMP_STEP (785) > +#define HI6220_TEMP_LAG (3500) > + > +#define HI6220_DEFAULT_SENSOR 2 > > struct hisi_thermal_sensor { > struct thermal_zone_device *tzd; > @@ -78,14 +77,14 @@ struct hisi_thermal_data { > * steps = (Temp - TempBase) / 785 > * > */ > -static inline int hisi_thermal_step_to_temp(int step) > +static inline int hi6220_thermal_step_to_temp(int step) > { > - return HISI_TEMP_BASE + (step * HISI_TEMP_STEP); > + return HI6220_TEMP_BASE + (step * HI6220_TEMP_STEP); > } > > -static inline int hisi_thermal_temp_to_step(int temp) > +static inline int hi6220_thermal_temp_to_step(int temp) > { > - return DIV_ROUND_UP(temp - HISI_TEMP_BASE, HISI_TEMP_STEP); > + return DIV_ROUND_UP(temp - HI6220_TEMP_BASE, HI6220_TEMP_STEP); > } > > /* > @@ -112,51 +111,53 @@ static inline int hisi_thermal_temp_to_step(int temp) > * > * [0:4] : lag register > * > - * The temperature is coded in steps, cf. HISI_TEMP_STEP. > + * The temperature is coded in steps, cf. HI6220_TEMP_STEP. > * > * Min : 0x00 : 0.0 °C > * Max : 0x1F : 24.3 °C > * > * The 'value' parameter is in milliCelsius. > */ > -static inline void hisi_thermal_set_lag(void __iomem *addr, int value) > +static inline void hi6220_thermal_set_lag(void __iomem *addr, int value) > { > - writel(DIV_ROUND_UP(value, HISI_TEMP_STEP) & 0x1F, addr + TEMP0_LAG); > + writel(DIV_ROUND_UP(value, HI6220_TEMP_STEP) & 0x1F, > + addr + HI6220_TEMP0_LAG); > } > > -static inline void hisi_thermal_alarm_clear(void __iomem *addr, int value) > +static inline void hi6220_thermal_alarm_clear(void __iomem *addr, int value) > { > - writel(value, addr + TEMP0_INT_CLR); > + writel(value, addr + HI6220_TEMP0_INT_CLR); > } > > -static inline void hisi_thermal_alarm_enable(void __iomem *addr, int value) > +static inline void hi6220_thermal_alarm_enable(void __iomem *addr, int value) > { > - writel(value, addr + TEMP0_INT_EN); > + writel(value, addr + HI6220_TEMP0_INT_EN); > } > > -static inline void hisi_thermal_alarm_set(void __iomem *addr, int temp) > +static inline void hi6220_thermal_alarm_set(void __iomem *addr, int temp) > { > - writel(hisi_thermal_temp_to_step(temp) | 0x0FFFFFF00, addr + TEMP0_TH); > + writel(hi6220_thermal_temp_to_step(temp) | 0x0FFFFFF00, > + addr + HI6220_TEMP0_TH); > } > > -static inline void hisi_thermal_reset_set(void __iomem *addr, int temp) > +static inline void hi6220_thermal_reset_set(void __iomem *addr, int temp) > { > - writel(hisi_thermal_temp_to_step(temp), addr + TEMP0_RST_TH); > + writel(hi6220_thermal_temp_to_step(temp), addr + HI6220_TEMP0_RST_TH); > } > > -static inline void hisi_thermal_reset_enable(void __iomem *addr, int value) > +static inline void hi6220_thermal_reset_enable(void __iomem *addr, int value) > { > - writel(value, addr + TEMP0_RST_MSK); > + writel(value, addr + HI6220_TEMP0_RST_MSK); > } > > -static inline void hisi_thermal_enable(void __iomem *addr, int value) > +static inline void hi6220_thermal_enable(void __iomem *addr, int value) > { > - writel(value, addr + TEMP0_EN); > + writel(value, addr + HI6220_TEMP0_EN); > } > > -static inline int hisi_thermal_get_temperature(void __iomem *addr) > +static inline int hi6220_thermal_get_temperature(void __iomem *addr) > { > - return hisi_thermal_step_to_temp(readl(addr + TEMP0_VALUE)); > + return hi6220_thermal_step_to_temp(readl(addr + HI6220_TEMP0_VALUE)); > } > > /* > @@ -169,10 +170,10 @@ static inline int hisi_thermal_get_temperature(void __iomem *addr) > * 0x2: remote sensor 2 (ACPU cluster 0) > * 0x3: remote sensor 3 (G3D) > */ > -static inline void hisi_thermal_sensor_select(void __iomem *addr, int sensor) > +static inline void hi6220_thermal_sensor_select(void __iomem *addr, int sensor) > { > - writel((readl(addr + TEMP0_CFG) & ~TEMP0_CFG_SS_MSK ) | > - (sensor << 12), addr + TEMP0_CFG); > + writel((readl(addr + HI6220_TEMP0_CFG) & ~HI6220_TEMP0_CFG_SS_MSK) | > + (sensor << 12), addr + HI6220_TEMP0_CFG); > } > > /* > @@ -185,24 +186,24 @@ static inline void hisi_thermal_sensor_select(void __iomem *addr, int sensor) > * 0x2 : 49.152 ms > * 0x3 : 393.216 ms > */ > -static inline void hisi_thermal_hdak_set(void __iomem *addr, int value) > +static inline void hi6220_thermal_hdak_set(void __iomem *addr, int value) > { > - writel((readl(addr + TEMP0_CFG) & ~TEMP0_CFG_HDAK_MSK) | > - (value << 4), addr + TEMP0_CFG); > + writel((readl(addr + HI6220_TEMP0_CFG) & ~HI6220_TEMP0_CFG_HDAK_MSK) | > + (value << 4), addr + HI6220_TEMP0_CFG); > } > > -static void hisi_thermal_disable_sensor(struct hisi_thermal_data *data) > +static void hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) > { > /* disable sensor module */ > - hisi_thermal_enable(data->regs, 0); > - hisi_thermal_alarm_enable(data->regs, 0); > - hisi_thermal_reset_enable(data->regs, 0); > + hi6220_thermal_enable(data->regs, 0); > + hi6220_thermal_alarm_enable(data->regs, 0); > + hi6220_thermal_reset_enable(data->regs, 0); > > clk_disable_unprepare(data->clk); > } > > > -static int hisi_thermal_setup(struct hisi_thermal_data *data) > +static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) > { > struct hisi_thermal_sensor *sensor = &data->sensor; > int ret; > @@ -213,29 +214,29 @@ static int hisi_thermal_setup(struct hisi_thermal_data *data) > return ret; > > /* disable module firstly */ > - hisi_thermal_reset_enable(data->regs, 0); > - hisi_thermal_enable(data->regs, 0); > + hi6220_thermal_reset_enable(data->regs, 0); > + hi6220_thermal_enable(data->regs, 0); > > /* select sensor id */ > - hisi_thermal_sensor_select(data->regs, sensor->id); > + hi6220_thermal_sensor_select(data->regs, sensor->id); > > /* setting the hdak time */ > - hisi_thermal_hdak_set(data->regs, 0); > + hi6220_thermal_hdak_set(data->regs, 0); > > /* setting lag value between current temp and the threshold */ > - hisi_thermal_set_lag(data->regs, HISI_TEMP_LAG); > + hi6220_thermal_set_lag(data->regs, HI6220_TEMP_LAG); > > /* enable for interrupt */ > - hisi_thermal_alarm_set(data->regs, sensor->thres_temp); > + hi6220_thermal_alarm_set(data->regs, sensor->thres_temp); > > - hisi_thermal_reset_set(data->regs, HISI_TEMP_RESET); > + hi6220_thermal_reset_set(data->regs, HI6220_TEMP_RESET); > > /* enable module */ > - hisi_thermal_reset_enable(data->regs, 1); > - hisi_thermal_enable(data->regs, 1); > + hi6220_thermal_reset_enable(data->regs, 1); > + hi6220_thermal_enable(data->regs, 1); > > - hisi_thermal_alarm_clear(data->regs, 0); > - hisi_thermal_alarm_enable(data->regs, 1); > + hi6220_thermal_alarm_clear(data->regs, 0); > + hi6220_thermal_alarm_enable(data->regs, 1); > > return 0; > } > @@ -244,7 +245,7 @@ static int hisi_thermal_get_temp(void *__data, int *temp) > struct hisi_thermal_data *data = __data; > struct hisi_thermal_sensor *sensor = &data->sensor; > > - *temp = hisi_thermal_get_temperature(data->regs); > + *temp = hi6220_thermal_get_temperature(data->regs); > > dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n", > sensor->id, *temp, sensor->thres_temp); > @@ -260,11 +261,11 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) > { > struct hisi_thermal_data *data = dev; > struct hisi_thermal_sensor *sensor = &data->sensor; > - int temp; > + int temp = 0; > > - hisi_thermal_alarm_clear(data->regs, 1); > + hi6220_thermal_alarm_clear(data->regs, 1); > > - temp = hisi_thermal_get_temperature(data->regs); > + hisi_thermal_get_temp(data, &temp); > > if (temp >= sensor->thres_temp) { > dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n", > @@ -273,7 +274,7 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) > thermal_zone_device_update(data->sensor.tzd, > THERMAL_EVENT_UNSPECIFIED); > > - } else if (temp < sensor->thres_temp) { > + } else { > dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n", > temp, sensor->thres_temp); > } > @@ -365,14 +366,14 @@ static int hisi_thermal_probe(struct platform_device *pdev) > > ret = hisi_thermal_register_sensor(pdev, data, > &data->sensor, > - HISI_DEFAULT_SENSOR); > + HI6220_DEFAULT_SENSOR); > if (ret) { > dev_err(&pdev->dev, "failed to register thermal sensor: %d\n", > ret); > return ret; > } > > - ret = hisi_thermal_setup(data); > + ret = hi6220_thermal_enable_sensor(data); > if (ret) { > dev_err(&pdev->dev, "Failed to setup the sensor: %d\n", ret); > return ret; > @@ -397,7 +398,7 @@ static int hisi_thermal_remove(struct platform_device *pdev) > struct hisi_thermal_sensor *sensor = &data->sensor; > > hisi_thermal_toggle_sensor(sensor, false); > - hisi_thermal_disable_sensor(data); > + hi6220_thermal_disable_sensor(data); > > return 0; > } > @@ -407,7 +408,7 @@ static int hisi_thermal_suspend(struct device *dev) > { > struct hisi_thermal_data *data = dev_get_drvdata(dev); > > - hisi_thermal_disable_sensor(data); > + hi6220_thermal_disable_sensor(data); > > return 0; > } > @@ -416,7 +417,7 @@ static int hisi_thermal_resume(struct device *dev) > { > struct hisi_thermal_data *data = dev_get_drvdata(dev); > > - return hisi_thermal_setup(data); > + return hi6220_thermal_enable_sensor(data); > } > #endif > > -- > 2.7.4 >
On Tue, Oct 10, 2017 at 08:02:44PM +0200, Daniel Lezcano wrote: > From: Kevin Wangtao <kevin.wangtao@linaro.org> > > Reorganize the code for next patches by moving the functions upper in > the file which will prevent a forward declaration. There is no functional > change here. > CHECK: Please don't use multiple blank lines #104: FILE: drivers/thermal/hisi_thermal.c:204: + total: 0 errors, 0 warnings, 1 checks, 88 lines checked > Signed-off-by: Kevin Wangtao <kevin.wangtao@linaro.org> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > drivers/thermal/hisi_thermal.c | 76 +++++++++++++++++++++--------------------- > 1 file changed, 38 insertions(+), 38 deletions(-) > > diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c > index befdb28..ff9055a 100644 > --- a/drivers/thermal/hisi_thermal.c > +++ b/drivers/thermal/hisi_thermal.c > @@ -201,6 +201,44 @@ static void hisi_thermal_disable_sensor(struct hisi_thermal_data *data) > clk_disable_unprepare(data->clk); > } > > + > +static int hisi_thermal_setup(struct hisi_thermal_data *data) > +{ > + struct hisi_thermal_sensor *sensor = &data->sensor; > + int ret; > + > + /* enable clock for tsensor */ > + ret = clk_prepare_enable(data->clk); > + if (ret) > + return ret; > + > + /* disable module firstly */ > + hisi_thermal_reset_enable(data->regs, 0); > + hisi_thermal_enable(data->regs, 0); > + > + /* select sensor id */ > + hisi_thermal_sensor_select(data->regs, sensor->id); > + > + /* setting the hdak time */ > + hisi_thermal_hdak_set(data->regs, 0); > + > + /* setting lag value between current temp and the threshold */ > + hisi_thermal_set_lag(data->regs, HISI_TEMP_LAG); > + > + /* enable for interrupt */ > + hisi_thermal_alarm_set(data->regs, sensor->thres_temp); > + > + hisi_thermal_reset_set(data->regs, HISI_TEMP_RESET); > + > + /* enable module */ > + hisi_thermal_reset_enable(data->regs, 1); > + hisi_thermal_enable(data->regs, 1); > + > + hisi_thermal_alarm_clear(data->regs, 0); > + hisi_thermal_alarm_enable(data->regs, 1); > + > + return 0; > +} > static int hisi_thermal_get_temp(void *__data, int *temp) > { > struct hisi_thermal_data *data = __data; > @@ -291,44 +329,6 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor, > on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED); > } > > -static int hisi_thermal_setup(struct hisi_thermal_data *data) > -{ > - struct hisi_thermal_sensor *sensor = &data->sensor; > - int ret; > - > - /* enable clock for tsensor */ > - ret = clk_prepare_enable(data->clk); > - if (ret) > - return ret; > - > - /* disable module firstly */ > - hisi_thermal_reset_enable(data->regs, 0); > - hisi_thermal_enable(data->regs, 0); > - > - /* select sensor id */ > - hisi_thermal_sensor_select(data->regs, sensor->id); > - > - /* setting the hdak time */ > - hisi_thermal_hdak_set(data->regs, 0); > - > - /* setting lag value between current temp and the threshold */ > - hisi_thermal_set_lag(data->regs, HISI_TEMP_LAG); > - > - /* enable for interrupt */ > - hisi_thermal_alarm_set(data->regs, sensor->thres_temp); > - > - hisi_thermal_reset_set(data->regs, HISI_TEMP_RESET); > - > - /* enable module */ > - hisi_thermal_reset_enable(data->regs, 1); > - hisi_thermal_enable(data->regs, 1); > - > - hisi_thermal_alarm_clear(data->regs, 0); > - hisi_thermal_alarm_enable(data->regs, 1); > - > - return 0; > -} > - > static int hisi_thermal_probe(struct platform_device *pdev) > { > struct hisi_thermal_data *data; > -- > 2.7.4 >
On Tue, Oct 10, 2017 at 08:02:47PM +0200, Daniel Lezcano wrote: > From: Kevin Wangtao <kevin.wangtao@linaro.org> > > The next patches will provide the support for the hi3660 where the temperature > sensor can have multiple alarm levels. In order to set the scene to support it, > we have to convert the current code to be able to support multiple threshold > values. > > [Daniel Lezcano: Restated the log] CHECK: Prefer kernel type 'u32' over 'uint32_t' #113: FILE: drivers/thermal/hisi_thermal.c:54: + uint32_t thres_temp[MAX_THRES_NUM]; total: 0 errors, 1 warnings, 1 checks, 67 lines checked > > Signed-off-by: Kevin Wangtao <kevin.wangtao@linaro.org> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > drivers/thermal/hisi_thermal.c | 21 ++++++++++++--------- > 1 file changed, 12 insertions(+), 9 deletions(-) > > diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c > index b5a7159..e87ca6c 100644 > --- a/drivers/thermal/hisi_thermal.c > +++ b/drivers/thermal/hisi_thermal.c > @@ -46,10 +46,12 @@ > > #define HI6220_DEFAULT_SENSOR 2 > > +#define MAX_THRES_NUM 2 > + > struct hisi_thermal_sensor { > struct thermal_zone_device *tzd; > uint32_t id; > - uint32_t thres_temp; > + uint32_t thres_temp[MAX_THRES_NUM]; > }; > > struct hisi_thermal_data { > @@ -244,7 +246,7 @@ static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) > hi6220_thermal_set_lag(data->regs, HI6220_TEMP_LAG); > > /* enable for interrupt */ > - hi6220_thermal_alarm_set(data->regs, sensor->thres_temp); > + hi6220_thermal_alarm_set(data->regs, sensor->thres_temp[0]); > > hi6220_thermal_reset_set(data->regs, HI6220_TEMP_RESET); > > @@ -303,7 +305,7 @@ static int hisi_thermal_get_temp(void *__data, int *temp) > *temp = data->get_temp(data); > > dev_dbg(&data->pdev->dev, "id=%d, temp=%d, thres=%d\n", > - sensor->id, *temp, sensor->thres_temp); > + sensor->id, *temp, sensor->thres_temp[0]); > > return 0; > } > @@ -322,16 +324,16 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev) > > hisi_thermal_get_temp(data, &temp); > > - if (temp >= sensor->thres_temp) { > + if (temp >= sensor->thres_temp[0]) { > dev_crit(&data->pdev->dev, "THERMAL ALARM: %d > %d\n", > - temp, sensor->thres_temp); > + temp, sensor->thres_temp[0]); > > thermal_zone_device_update(data->sensor.tzd, > THERMAL_EVENT_UNSPECIFIED); > > } else { > dev_crit(&data->pdev->dev, "THERMAL ALARM stopped: %d < %d\n", > - temp, sensor->thres_temp); > + temp, sensor->thres_temp[0]); > } > > return IRQ_HANDLED; > @@ -341,7 +343,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, > struct hisi_thermal_data *data, > struct hisi_thermal_sensor *sensor) > { > - int ret, i; > + int ret, i, thres_idx = 0; > const struct thermal_trip *trip; > > sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, > @@ -359,8 +361,9 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, > > for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) { > if (trip[i].type == THERMAL_TRIP_PASSIVE) { > - sensor->thres_temp = trip[i].temperature; > - break; > + sensor->thres_temp[thres_idx++] = trip[i].temperature; > + if (thres_idx >= MAX_THRES_NUM) > + break; > } > } > > -- > 2.7.4 >
On Tue, Oct 10, 2017 at 08:02:49PM +0200, Daniel Lezcano wrote: > From: Kevin Wangtao <kevin.wangtao@linaro.org> > > This patch adds the support for thermal sensor on the Hi3660 SoC. > Hi3660 tsensor support alarm interrupt and have three configurable > alarm thresholds, it also has a configurable hysteresis interval, > interrupt will be triggered when temperature rise above the alarm > threshold or fall below the hysteresis threshold. Minor: CHECK: Alignment should match open parenthesis #173: FILE: drivers/thermal/hisi_thermal.c:214: + writel(DIV_ROUND_UP(value, HI3660_TEMP_STEP) & 0x7F, + addr + HI3660_LAG(id)); total: 0 errors, 0 warnings, 1 checks, 205 lines checked > > Signed-off-by: Kevin Wangtao <kevin.wangtao@linaro.org> > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > drivers/thermal/hisi_thermal.c | 146 ++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 145 insertions(+), 1 deletion(-) > > diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c > index e87ca6c..10276f0 100644 > --- a/drivers/thermal/hisi_thermal.c > +++ b/drivers/thermal/hisi_thermal.c > @@ -39,12 +39,24 @@ > #define HI6220_TEMP0_RST_MSK (0x1C) > #define HI6220_TEMP0_VALUE (0x28) > > +#define HI3660_OFFSET(chan) ((chan) * 0x40) > +#define HI3660_TEMP(chan) (HI3660_OFFSET(chan) + 0x1C) > +#define HI3660_TH(chan) (HI3660_OFFSET(chan) + 0x20) > +#define HI3660_LAG(chan) (HI3660_OFFSET(chan) + 0x28) > +#define HI3660_INT_EN(chan) (HI3660_OFFSET(chan) + 0x2C) > +#define HI3660_INT_CLR(chan) (HI3660_OFFSET(chan) + 0x30) > + > #define HI6220_TEMP_BASE (-60000) > #define HI6220_TEMP_RESET (100000) > #define HI6220_TEMP_STEP (785) > #define HI6220_TEMP_LAG (3500) > > +#define HI3660_TEMP_BASE (-63780) > +#define HI3660_TEMP_STEP (205) > +#define HI3660_TEMP_LAG (4000) > + > #define HI6220_DEFAULT_SENSOR 2 > +#define HI3660_DEFAULT_SENSOR 1 > > #define MAX_THRES_NUM 2 > > @@ -96,6 +108,24 @@ static inline int hi6220_thermal_temp_to_step(int temp) > } > > /* > + * for Hi3660, > + * Step: 189/922 (0.205) > + * Temperature base: -63.780°C > + * > + * The register is programmed in temperature steps, every step is 205 > + * millidegree and begins at -63 780 m°C > + */ > +static inline int hi3660_thermal_step_to_temp(int step) > +{ > + return HI3660_TEMP_BASE + step * HI3660_TEMP_STEP; > +} > + > +static inline int hi3660_thermal_temp_to_step(int temp) > +{ > + return DIV_ROUND_UP(temp - HI3660_TEMP_BASE, HI3660_TEMP_STEP); > +} > + > +/* > * The lag register contains 5 bits encoding the temperature in steps. > * > * Each time the temperature crosses the threshold boundary, an > @@ -169,6 +199,45 @@ static inline int hi6220_thermal_get_temperature(void __iomem *addr) > } > > /* > + * [0:6] lag register > + * > + * The temperature is coded in steps, cf. HI3660_TEMP_STEP. > + * > + * Min : 0x00 : 0.0 °C > + * Max : 0x7F : 26.0 °C > + * > + */ > +static inline void hi3660_thermal_set_lag(void __iomem *addr, > + int id, int value) > +{ > + writel(DIV_ROUND_UP(value, HI3660_TEMP_STEP) & 0x7F, > + addr + HI3660_LAG(id)); > +} > + > +static inline void hi3660_thermal_alarm_clear(void __iomem *addr, > + int id, int value) > +{ > + writel(value, addr + HI3660_INT_CLR(id)); > +} > + > +static inline void hi3660_thermal_alarm_enable(void __iomem *addr, > + int id, int value) > +{ > + writel(value, addr + HI3660_INT_EN(id)); > +} > + > +static inline void hi3660_thermal_alarm_set(void __iomem *addr, > + int id, int value) > +{ > + writel(value, addr + HI3660_TH(id)); > +} > + > +static inline int hi3660_thermal_get_temperature(void __iomem *addr, int id) > +{ > + return hi3660_thermal_step_to_temp(readl(addr + HI3660_TEMP(id))); > +} > + > +/* > * Temperature configuration register - Sensor selection > * > * Bits [19:12] > @@ -206,11 +275,22 @@ static int hi6220_thermal_irq_handler(struct hisi_thermal_data *data) > return 0; > } > > +static int hi3660_thermal_irq_handler(struct hisi_thermal_data *data) > +{ > + hi3660_thermal_alarm_clear(data->regs, data->sensor.id, 1); > + return 0; > +} > + > static int hi6220_thermal_get_temp(struct hisi_thermal_data *data) > { > return hi6220_thermal_get_temperature(data->regs); > } > > +static int hi3660_thermal_get_temp(struct hisi_thermal_data *data) > +{ > + return hi3660_thermal_get_temperature(data->regs, data->sensor.id); > +} > + > static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) > { > /* disable sensor module */ > @@ -222,6 +302,13 @@ static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) > return 0; > } > > +static int hi3660_thermal_disable_sensor(struct hisi_thermal_data *data) > +{ > + /* disable sensor module */ > + hi3660_thermal_alarm_enable(data->regs, data->sensor.id, 0); > + return 0; > +} > + > static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) > { > struct hisi_thermal_sensor *sensor = &data->sensor; > @@ -260,6 +347,29 @@ static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) > return 0; > } > > +static int hi3660_thermal_enable_sensor(struct hisi_thermal_data *data) > +{ > + unsigned int value; > + struct hisi_thermal_sensor *sensor = &data->sensor; > + > + /* disable interrupt */ > + hi3660_thermal_alarm_enable(data->regs, sensor->id, 0); > + > + /* setting lag value between current temp and the threshold */ > + hi3660_thermal_set_lag(data->regs, sensor->id, HI3660_TEMP_LAG); > + > + /* set interrupt threshold */ > + value = hi3660_thermal_temp_to_step(sensor->thres_temp[0]); > + value |= hi3660_thermal_temp_to_step(sensor->thres_temp[1]) << 10; > + hi3660_thermal_alarm_set(data->regs, sensor->id, value); > + > + /* enable interrupt */ > + hi3660_thermal_alarm_clear(data->regs, sensor->id, 1); > + hi3660_thermal_alarm_enable(data->regs, sensor->id, 1); > + > + return 0; > +} > + > static int hi6220_thermal_probe(struct hisi_thermal_data *data) > { > struct platform_device *pdev = data->pdev; > @@ -296,6 +406,33 @@ static int hi6220_thermal_probe(struct hisi_thermal_data *data) > return 0; > } > > +static int hi3660_thermal_probe(struct hisi_thermal_data *data) > +{ > + struct platform_device *pdev = data->pdev; > + struct device *dev = &pdev->dev; > + struct resource *res; > + > + data->get_temp = hi3660_thermal_get_temp; > + data->enable_sensor = hi3660_thermal_enable_sensor; > + data->disable_sensor = hi3660_thermal_disable_sensor; > + data->irq_handler = hi3660_thermal_irq_handler; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + data->regs = devm_ioremap_resource(dev, res); > + if (IS_ERR(data->regs)) { > + dev_err(dev, "failed to get io address\n"); > + return PTR_ERR(data->regs); > + } > + > + data->irq = platform_get_irq(pdev, 0); > + if (data->irq < 0) > + return data->irq; > + > + data->sensor.id = HI3660_DEFAULT_SENSOR; > + > + return 0; > +} > + > > static int hisi_thermal_get_temp(void *__data, int *temp) > { > @@ -371,7 +508,14 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, > } > > static const struct of_device_id of_hisi_thermal_match[] = { > - { .compatible = "hisilicon,tsensor", .data = hi6220_thermal_probe }, > + { > + .compatible = "hisilicon,tsensor", > + .data = hi6220_thermal_probe > + }, > + { > + .compatible = "hisilicon,hi3660-tsensor", > + .data = hi3660_thermal_probe > + }, > { /* end */ } > }; > MODULE_DEVICE_TABLE(of, of_hisi_thermal_match); > -- > 2.7.4 >
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index 9c3ce34..f3b50b0 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -345,8 +345,7 @@ static int hisi_thermal_probe(struct platform_device *pdev) } hisi_thermal_enable_bind_irq_sensor(data); - irq_get_irqchip_state(data->irq, IRQCHIP_STATE_MASKED, - &data->irq_enabled); + data->irq_enabled = true; for (i = 0; i < HISI_MAX_SENSORS; ++i) { ret = hisi_thermal_register_sensor(pdev, data, @@ -358,6 +357,8 @@ static int hisi_thermal_probe(struct platform_device *pdev) hisi_thermal_toggle_sensor(&data->sensors[i], true); } + enable_irq(data->irq); + return 0; }