.. | .. |
---|
107 | 107 | .get_timeleft = bcm7038_wdt_get_timeleft, |
---|
108 | 108 | }; |
---|
109 | 109 | |
---|
| 110 | +static void bcm7038_clk_disable_unprepare(void *data) |
---|
| 111 | +{ |
---|
| 112 | + clk_disable_unprepare(data); |
---|
| 113 | +} |
---|
| 114 | + |
---|
110 | 115 | static int bcm7038_wdt_probe(struct platform_device *pdev) |
---|
111 | 116 | { |
---|
112 | 117 | struct device *dev = &pdev->dev; |
---|
113 | 118 | struct bcm7038_watchdog *wdt; |
---|
114 | | - struct resource *res; |
---|
115 | 119 | int err; |
---|
116 | 120 | |
---|
117 | 121 | wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); |
---|
.. | .. |
---|
120 | 124 | |
---|
121 | 125 | platform_set_drvdata(pdev, wdt); |
---|
122 | 126 | |
---|
123 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
124 | | - wdt->base = devm_ioremap_resource(dev, res); |
---|
| 127 | + wdt->base = devm_platform_ioremap_resource(pdev, 0); |
---|
125 | 128 | if (IS_ERR(wdt->base)) |
---|
126 | 129 | return PTR_ERR(wdt->base); |
---|
127 | 130 | |
---|
.. | .. |
---|
129 | 132 | /* If unable to get clock, use default frequency */ |
---|
130 | 133 | if (!IS_ERR(wdt->clk)) { |
---|
131 | 134 | err = clk_prepare_enable(wdt->clk); |
---|
| 135 | + if (err) |
---|
| 136 | + return err; |
---|
| 137 | + err = devm_add_action_or_reset(dev, |
---|
| 138 | + bcm7038_clk_disable_unprepare, |
---|
| 139 | + wdt->clk); |
---|
132 | 140 | if (err) |
---|
133 | 141 | return err; |
---|
134 | 142 | wdt->rate = clk_get_rate(wdt->clk); |
---|
.. | .. |
---|
148 | 156 | wdt->wdd.parent = dev; |
---|
149 | 157 | watchdog_set_drvdata(&wdt->wdd, wdt); |
---|
150 | 158 | |
---|
151 | | - err = watchdog_register_device(&wdt->wdd); |
---|
152 | | - if (err) { |
---|
153 | | - dev_err(dev, "Failed to register watchdog device\n"); |
---|
154 | | - clk_disable_unprepare(wdt->clk); |
---|
| 159 | + watchdog_stop_on_reboot(&wdt->wdd); |
---|
| 160 | + watchdog_stop_on_unregister(&wdt->wdd); |
---|
| 161 | + err = devm_watchdog_register_device(dev, &wdt->wdd); |
---|
| 162 | + if (err) |
---|
155 | 163 | return err; |
---|
156 | | - } |
---|
157 | 164 | |
---|
158 | 165 | dev_info(dev, "Registered BCM7038 Watchdog\n"); |
---|
159 | | - |
---|
160 | | - return 0; |
---|
161 | | -} |
---|
162 | | - |
---|
163 | | -static int bcm7038_wdt_remove(struct platform_device *pdev) |
---|
164 | | -{ |
---|
165 | | - struct bcm7038_watchdog *wdt = platform_get_drvdata(pdev); |
---|
166 | | - |
---|
167 | | - if (!nowayout) |
---|
168 | | - bcm7038_wdt_stop(&wdt->wdd); |
---|
169 | | - |
---|
170 | | - watchdog_unregister_device(&wdt->wdd); |
---|
171 | | - clk_disable_unprepare(wdt->clk); |
---|
172 | 166 | |
---|
173 | 167 | return 0; |
---|
174 | 168 | } |
---|
.. | .. |
---|
198 | 192 | static SIMPLE_DEV_PM_OPS(bcm7038_wdt_pm_ops, bcm7038_wdt_suspend, |
---|
199 | 193 | bcm7038_wdt_resume); |
---|
200 | 194 | |
---|
201 | | -static void bcm7038_wdt_shutdown(struct platform_device *pdev) |
---|
202 | | -{ |
---|
203 | | - struct bcm7038_watchdog *wdt = platform_get_drvdata(pdev); |
---|
204 | | - |
---|
205 | | - if (watchdog_active(&wdt->wdd)) |
---|
206 | | - bcm7038_wdt_stop(&wdt->wdd); |
---|
207 | | -} |
---|
208 | | - |
---|
209 | 195 | static const struct of_device_id bcm7038_wdt_match[] = { |
---|
210 | 196 | { .compatible = "brcm,bcm7038-wdt" }, |
---|
211 | 197 | {}, |
---|
.. | .. |
---|
214 | 200 | |
---|
215 | 201 | static struct platform_driver bcm7038_wdt_driver = { |
---|
216 | 202 | .probe = bcm7038_wdt_probe, |
---|
217 | | - .remove = bcm7038_wdt_remove, |
---|
218 | | - .shutdown = bcm7038_wdt_shutdown, |
---|
219 | 203 | .driver = { |
---|
220 | 204 | .name = "bcm7038-wdt", |
---|
221 | 205 | .of_match_table = bcm7038_wdt_match, |
---|