|
40 | 40 | #define TMR1CTL_PRESCALE_MASK 0xf |
41 | 41 | #define TMR1CTL_PRESCALE_65536 0xf |
42 | 42 |
|
43 | | -static struct clk *rt288x_wdt_clk; |
44 | | -static unsigned long rt288x_wdt_freq; |
45 | | -static void __iomem *rt288x_wdt_base; |
46 | | -static struct reset_control *rt288x_wdt_reset; |
| 43 | +struct rt2880_wdt_data { |
| 44 | + void __iomem *base; |
| 45 | + unsigned long freq; |
| 46 | + struct clk *clk; |
| 47 | + struct reset_control *rst; |
| 48 | + struct watchdog_device wdt; |
| 49 | +}; |
47 | 50 |
|
48 | 51 | static bool nowayout = WATCHDOG_NOWAYOUT; |
49 | 52 | module_param(nowayout, bool, 0); |
50 | 53 | MODULE_PARM_DESC(nowayout, |
51 | 54 | "Watchdog cannot be stopped once started (default=" |
52 | 55 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
53 | 56 |
|
54 | | -static inline void rt_wdt_w32(unsigned reg, u32 val) |
| 57 | +static inline void rt_wdt_w32(void __iomem *base, unsigned reg, u32 val) |
55 | 58 | { |
56 | | - iowrite32(val, rt288x_wdt_base + reg); |
| 59 | + iowrite32(val, base + reg); |
57 | 60 | } |
58 | 61 |
|
59 | | -static inline u32 rt_wdt_r32(unsigned reg) |
| 62 | +static inline u32 rt_wdt_r32(void __iomem *base, unsigned reg) |
60 | 63 | { |
61 | | - return ioread32(rt288x_wdt_base + reg); |
| 64 | + return ioread32(base + reg); |
62 | 65 | } |
63 | 66 |
|
64 | 67 | static int rt288x_wdt_ping(struct watchdog_device *w) |
65 | 68 | { |
66 | | - rt_wdt_w32(TIMER_REG_TMR1LOAD, w->timeout * rt288x_wdt_freq); |
| 69 | + struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w); |
| 70 | + |
| 71 | + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1LOAD, w->timeout * drvdata->freq); |
67 | 72 |
|
68 | 73 | return 0; |
69 | 74 | } |
70 | 75 |
|
71 | 76 | static int rt288x_wdt_start(struct watchdog_device *w) |
72 | 77 | { |
| 78 | + struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w); |
73 | 79 | u32 t; |
74 | 80 |
|
75 | | - t = rt_wdt_r32(TIMER_REG_TMR1CTL); |
| 81 | + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); |
76 | 82 | t &= ~(TMR1CTL_MODE_MASK << TMR1CTL_MODE_SHIFT | |
77 | 83 | TMR1CTL_PRESCALE_MASK); |
78 | 84 | t |= (TMR1CTL_MODE_WDT << TMR1CTL_MODE_SHIFT | |
79 | 85 | TMR1CTL_PRESCALE_65536); |
80 | | - rt_wdt_w32(TIMER_REG_TMR1CTL, t); |
| 86 | + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); |
81 | 87 |
|
82 | 88 | rt288x_wdt_ping(w); |
83 | 89 |
|
84 | | - t = rt_wdt_r32(TIMER_REG_TMR1CTL); |
| 90 | + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); |
85 | 91 | t |= TMR1CTL_ENABLE; |
86 | | - rt_wdt_w32(TIMER_REG_TMR1CTL, t); |
| 92 | + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); |
87 | 93 |
|
88 | 94 | return 0; |
89 | 95 | } |
90 | 96 |
|
91 | 97 | static int rt288x_wdt_stop(struct watchdog_device *w) |
92 | 98 | { |
| 99 | + struct rt2880_wdt_data *drvdata = watchdog_get_drvdata(w); |
93 | 100 | u32 t; |
94 | 101 |
|
95 | 102 | rt288x_wdt_ping(w); |
96 | 103 |
|
97 | | - t = rt_wdt_r32(TIMER_REG_TMR1CTL); |
| 104 | + t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); |
98 | 105 | t &= ~TMR1CTL_ENABLE; |
99 | | - rt_wdt_w32(TIMER_REG_TMR1CTL, t); |
| 106 | + rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); |
100 | 107 |
|
101 | 108 | return 0; |
102 | 109 | } |
@@ -130,41 +137,45 @@ static const struct watchdog_ops rt288x_wdt_ops = { |
130 | 137 | .set_timeout = rt288x_wdt_set_timeout, |
131 | 138 | }; |
132 | 139 |
|
133 | | -static struct watchdog_device rt288x_wdt_dev = { |
134 | | - .info = &rt288x_wdt_info, |
135 | | - .ops = &rt288x_wdt_ops, |
136 | | - .min_timeout = 1, |
137 | | -}; |
138 | | - |
139 | 140 | static int rt288x_wdt_probe(struct platform_device *pdev) |
140 | 141 | { |
141 | 142 | struct device *dev = &pdev->dev; |
| 143 | + struct watchdog_device *wdt; |
| 144 | + struct rt2880_wdt_data *drvdata; |
142 | 145 | int ret; |
143 | 146 |
|
144 | | - rt288x_wdt_base = devm_platform_ioremap_resource(pdev, 0); |
145 | | - if (IS_ERR(rt288x_wdt_base)) |
146 | | - return PTR_ERR(rt288x_wdt_base); |
| 147 | + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); |
| 148 | + if (!drvdata) |
| 149 | + return -ENOMEM; |
| 150 | + |
| 151 | + drvdata->base = devm_platform_ioremap_resource(pdev, 0); |
| 152 | + if (IS_ERR(drvdata->base)) |
| 153 | + return PTR_ERR(drvdata->base); |
147 | 154 |
|
148 | | - rt288x_wdt_clk = devm_clk_get(dev, NULL); |
149 | | - if (IS_ERR(rt288x_wdt_clk)) |
150 | | - return PTR_ERR(rt288x_wdt_clk); |
| 155 | + drvdata->clk = devm_clk_get(dev, NULL); |
| 156 | + if (IS_ERR(drvdata->clk)) |
| 157 | + return PTR_ERR(drvdata->clk); |
151 | 158 |
|
152 | | - rt288x_wdt_reset = devm_reset_control_get_exclusive(dev, NULL); |
153 | | - if (!IS_ERR(rt288x_wdt_reset)) |
154 | | - reset_control_deassert(rt288x_wdt_reset); |
| 159 | + drvdata->rst = devm_reset_control_get_exclusive(dev, NULL); |
| 160 | + if (!IS_ERR(drvdata->rst)) |
| 161 | + reset_control_deassert(drvdata->rst); |
155 | 162 |
|
156 | | - rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE; |
| 163 | + drvdata->freq = clk_get_rate(drvdata->clk) / RALINK_WDT_PRESCALE; |
157 | 164 |
|
158 | | - rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); |
159 | | - rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); |
160 | | - rt288x_wdt_dev.parent = dev; |
| 165 | + wdt = &drvdata->wdt; |
| 166 | + wdt->info = &rt288x_wdt_info; |
| 167 | + wdt->ops = &rt288x_wdt_ops; |
| 168 | + wdt->min_timeout = 1; |
| 169 | + wdt->max_timeout = (0xfffful / drvdata->freq); |
| 170 | + wdt->parent = dev; |
| 171 | + wdt->bootstatus = rt288x_wdt_bootcause(); |
161 | 172 |
|
162 | | - watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout, |
163 | | - dev); |
164 | | - watchdog_set_nowayout(&rt288x_wdt_dev, nowayout); |
| 173 | + watchdog_init_timeout(wdt, wdt->max_timeout, dev); |
| 174 | + watchdog_set_nowayout(wdt, nowayout); |
| 175 | + watchdog_set_drvdata(wdt, drvdata); |
165 | 176 |
|
166 | | - watchdog_stop_on_reboot(&rt288x_wdt_dev); |
167 | | - ret = devm_watchdog_register_device(dev, &rt288x_wdt_dev); |
| 177 | + watchdog_stop_on_reboot(wdt); |
| 178 | + ret = devm_watchdog_register_device(dev, &drvdata->wdt); |
168 | 179 | if (!ret) |
169 | 180 | dev_info(dev, "Initialized\n"); |
170 | 181 |
|
|
0 commit comments