Commit 8e1279fcab1d03240ed150ff5d9113828766f0f0

Authored by Ye Li
1 parent 0f630e17a9

MLK-24157 ulp_wdog: Fix unaligned access to cs2 reg

Patch "MLK-22755 mx7ulp: wdog: Wait for WDOG unlock and
reconfiguration to complete",  added some flags checking
to WDOG driver. But the cs2 register access is wrong, should
use "readb" not "readl".

This is fine for some compilers (like gcc8.2, gcc9.2) which
adjusts the access to "ldrb" instruction. However for old
compilers (like gcc4.9), it won't fix the instruction and cause
data abort.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
(cherry picked from commit fd1f9177abdfab23ae124b8f41583c578cfe0b2e)

Showing 1 changed file with 4 additions and 4 deletions Inline Diff

drivers/watchdog/ulp_wdog.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright (C) 2016 Freescale Semiconductor, Inc. 3 * Copyright (C) 2016 Freescale Semiconductor, Inc.
4 */ 4 */
5 5
6 #include <common.h> 6 #include <common.h>
7 #include <cpu_func.h> 7 #include <cpu_func.h>
8 #include <asm/io.h> 8 #include <asm/io.h>
9 #include <asm/arch/imx-regs.h> 9 #include <asm/arch/imx-regs.h>
10 10
11 /* 11 /*
12 * MX7ULP WDOG Register Map 12 * MX7ULP WDOG Register Map
13 */ 13 */
14 struct wdog_regs { 14 struct wdog_regs {
15 u8 cs1; 15 u8 cs1;
16 u8 cs2; 16 u8 cs2;
17 u16 reserve0; 17 u16 reserve0;
18 u32 cnt; 18 u32 cnt;
19 u32 toval; 19 u32 toval;
20 u32 win; 20 u32 win;
21 }; 21 };
22 22
23 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS 23 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
24 #define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500 24 #define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500
25 #endif 25 #endif
26 26
27 #define REFRESH_WORD0 0xA602 /* 1st refresh word */ 27 #define REFRESH_WORD0 0xA602 /* 1st refresh word */
28 #define REFRESH_WORD1 0xB480 /* 2nd refresh word */ 28 #define REFRESH_WORD1 0xB480 /* 2nd refresh word */
29 29
30 #define UNLOCK_WORD0 0xC520 /* 1st unlock word */ 30 #define UNLOCK_WORD0 0xC520 /* 1st unlock word */
31 #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ 31 #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
32 32
33 #define WDGCS1_WDGE (1<<7) 33 #define WDGCS1_WDGE (1<<7)
34 #define WDGCS1_WDGUPDATE (1<<5) 34 #define WDGCS1_WDGUPDATE (1<<5)
35 35
36 #define WDGCS2_RCS (1<<2) 36 #define WDGCS2_RCS (1<<2)
37 #define WDGCS2_ULK (1<<3) 37 #define WDGCS2_ULK (1<<3)
38 #define WDGCS2_FLG (1<<6) 38 #define WDGCS2_FLG (1<<6)
39 39
40 #define WDG_BUS_CLK (0x0) 40 #define WDG_BUS_CLK (0x0)
41 #define WDG_LPO_CLK (0x1) 41 #define WDG_LPO_CLK (0x1)
42 #define WDG_32KHZ_CLK (0x2) 42 #define WDG_32KHZ_CLK (0x2)
43 #define WDG_EXT_CLK (0x3) 43 #define WDG_EXT_CLK (0x3)
44 44
45 void hw_watchdog_set_timeout(u16 val) 45 void hw_watchdog_set_timeout(u16 val)
46 { 46 {
47 /* setting timeout value */ 47 /* setting timeout value */
48 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 48 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
49 49
50 writel(val, &wdog->toval); 50 writel(val, &wdog->toval);
51 } 51 }
52 52
53 void hw_watchdog_reset(void) 53 void hw_watchdog_reset(void)
54 { 54 {
55 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 55 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
56 56
57 dmb(); 57 dmb();
58 __raw_writel(REFRESH_WORD0, &wdog->cnt); 58 __raw_writel(REFRESH_WORD0, &wdog->cnt);
59 __raw_writel(REFRESH_WORD1, &wdog->cnt); 59 __raw_writel(REFRESH_WORD1, &wdog->cnt);
60 dmb(); 60 dmb();
61 } 61 }
62 62
63 void hw_watchdog_init(void) 63 void hw_watchdog_init(void)
64 { 64 {
65 u8 val; 65 u8 val;
66 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 66 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
67 67
68 dmb(); 68 dmb();
69 __raw_writel(UNLOCK_WORD0, &wdog->cnt); 69 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
70 __raw_writel(UNLOCK_WORD1, &wdog->cnt); 70 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
71 dmb(); 71 dmb();
72 72
73 /* Wait WDOG Unlock */ 73 /* Wait WDOG Unlock */
74 while (!(readl(&wdog->cs2) & WDGCS2_ULK)); 74 while (!(readb(&wdog->cs2) & WDGCS2_ULK));
75 75
76 val = readb(&wdog->cs2); 76 val = readb(&wdog->cs2);
77 val |= WDGCS2_FLG; 77 val |= WDGCS2_FLG;
78 writeb(val, &wdog->cs2); 78 writeb(val, &wdog->cs2);
79 79
80 hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS); 80 hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
81 writel(0, &wdog->win); 81 writel(0, &wdog->win);
82 82
83 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ 83 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
84 writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */ 84 writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */
85 85
86 /* Wait WDOG reconfiguration */ 86 /* Wait WDOG reconfiguration */
87 while (!(readl(&wdog->cs2) & WDGCS2_RCS)); 87 while (!(readb(&wdog->cs2) & WDGCS2_RCS));
88 88
89 hw_watchdog_reset(); 89 hw_watchdog_reset();
90 } 90 }
91 91
92 void reset_cpu(ulong addr) 92 void reset_cpu(ulong addr)
93 { 93 {
94 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; 94 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
95 95
96 dmb(); 96 dmb();
97 __raw_writel(UNLOCK_WORD0, &wdog->cnt); 97 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
98 __raw_writel(UNLOCK_WORD1, &wdog->cnt); 98 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
99 dmb(); 99 dmb();
100 100
101 /* Wait WDOG Unlock */ 101 /* Wait WDOG Unlock */
102 while (!(readl(&wdog->cs2) & WDGCS2_ULK)); 102 while (!(readb(&wdog->cs2) & WDGCS2_ULK));
103 103
104 hw_watchdog_set_timeout(5); /* 5ms timeout */ 104 hw_watchdog_set_timeout(5); /* 5ms timeout */
105 writel(0, &wdog->win); 105 writel(0, &wdog->win);
106 106
107 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ 107 writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
108 writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */ 108 writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */
109 109
110 /* Wait WDOG reconfiguration */ 110 /* Wait WDOG reconfiguration */
111 while (!(readl(&wdog->cs2) & WDGCS2_RCS)); 111 while (!(readb(&wdog->cs2) & WDGCS2_RCS));
112 112
113 hw_watchdog_reset(); 113 hw_watchdog_reset();
114 114
115 while (1); 115 while (1);
116 } 116 }
117 117