Skip to content

Commit 975e4b2

Browse files
Kathiravan ThirumoorthyWim Van Sebroeck
authored andcommitted
watchdog: qcom: fine tune the max timeout value calculation
To determine the max_timeout value, the below calculation is used. max_timeout = 0x10000000 / clk_rate cat /sys/devices/platform/soc@0/b017000.watchdog/watchdog/watchdog0/max_timeout 8388 However, this is not valid for all the platforms. IPQ SoCs starting from IPQ40xx and recent Snapdragron SoCs also has the bark and bite time field length of 20bits, which can hold max up to 32 seconds if the clk_rate is 32KHz. If the user tries to configure the timeout more than 32s, then the value will be truncated and the actual value will not be reflected in the HW. To avoid this, lets add a variable called max_tick_count in the device data, which defines max counter value of the WDT controller. Using this, max-timeout will be calculated in runtime for various WDT contorllers. With this change, we get the proper max_timeout as below and restricts the user from configuring the timeout higher than this. cat /sys/devices/platform/soc@0/b017000.watchdog/watchdog/watchdog0/max_timeout 32 Signed-off-by: Kathiravan Thirumoorthy <quic_kathirav@quicinc.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Link: https://lore.kernel.org/r/20240116-wdt-v2-1-501c7694c3f0@quicinc.com Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
1 parent d2f656d commit 975e4b2

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

drivers/watchdog/qcom-wdt.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static const u32 reg_offset_data_kpss[] = {
4141
struct qcom_wdt_match_data {
4242
const u32 *offset;
4343
bool pretimeout;
44+
u32 max_tick_count;
4445
};
4546

4647
struct qcom_wdt {
@@ -177,11 +178,13 @@ static const struct watchdog_info qcom_wdt_pt_info = {
177178
static const struct qcom_wdt_match_data match_data_apcs_tmr = {
178179
.offset = reg_offset_data_apcs_tmr,
179180
.pretimeout = false,
181+
.max_tick_count = 0x10000000U,
180182
};
181183

182184
static const struct qcom_wdt_match_data match_data_kpss = {
183185
.offset = reg_offset_data_kpss,
184186
.pretimeout = true,
187+
.max_tick_count = 0xFFFFFU,
185188
};
186189

187190
static int qcom_wdt_probe(struct platform_device *pdev)
@@ -236,7 +239,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
236239
*/
237240
wdt->rate = clk_get_rate(clk);
238241
if (wdt->rate == 0 ||
239-
wdt->rate > 0x10000000U) {
242+
wdt->rate > data->max_tick_count) {
240243
dev_err(dev, "invalid clock rate\n");
241244
return -EINVAL;
242245
}
@@ -260,7 +263,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
260263

261264
wdt->wdd.ops = &qcom_wdt_ops;
262265
wdt->wdd.min_timeout = 1;
263-
wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
266+
wdt->wdd.max_timeout = data->max_tick_count / wdt->rate;
264267
wdt->wdd.parent = dev;
265268
wdt->layout = data->offset;
266269

0 commit comments

Comments
 (0)