diff options
author | Johan Hovold <johan@kernel.org> | 2014-12-10 18:52:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 20:41:13 -0500 |
commit | 55ba953a35651988a3080bfbeb2496049fc39ee5 (patch) | |
tree | 670ab183f9f26e09a1e24682839df5a9f6cbd79a /drivers/rtc | |
parent | d17a82e212638dfb9268108053fde93345cb2e96 (diff) |
rtc: omap: add device abstraction
Add struct omap_rtc to hold previously global data as well as the
IP-block feature flags.
Also convert the register-access macros to proper inline helper functions.
Signed-off-by: Johan Hovold <johan@kernel.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Benot Cousson <bcousson@baylibre.com>
Cc: Lokesh Vutla <lokeshvutla@ti.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Keerthy J <j-keerthy@ti.com>
Tested-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-omap.c | 239 |
1 files changed, 133 insertions, 106 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index bdee29674589..1da610b8981f 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -118,26 +118,42 @@ | |||
118 | */ | 118 | */ |
119 | #define OMAP_RTC_HAS_32KCLK_EN BIT(2) | 119 | #define OMAP_RTC_HAS_32KCLK_EN BIT(2) |
120 | 120 | ||
121 | static void __iomem *rtc_base; | 121 | struct omap_rtc { |
122 | struct rtc_device *rtc; | ||
123 | void __iomem *base; | ||
124 | int irq_alarm; | ||
125 | int irq_timer; | ||
126 | u8 interrupts_reg; | ||
127 | unsigned long flags; | ||
128 | }; | ||
122 | 129 | ||
123 | #define rtc_read(addr) readb(rtc_base + (addr)) | 130 | static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg) |
124 | #define rtc_write(val, addr) writeb(val, rtc_base + (addr)) | 131 | { |
132 | return readb(rtc->base + reg); | ||
133 | } | ||
125 | 134 | ||
126 | #define rtc_writel(val, addr) writel(val, rtc_base + (addr)) | 135 | static inline void rtc_write(struct omap_rtc *rtc, unsigned int reg, u8 val) |
136 | { | ||
137 | writeb(val, rtc->base + reg); | ||
138 | } | ||
127 | 139 | ||
140 | static inline void rtc_writel(struct omap_rtc *rtc, unsigned int reg, u32 val) | ||
141 | { | ||
142 | writel(val, rtc->base + reg); | ||
143 | } | ||
128 | 144 | ||
129 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), | 145 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), |
130 | * so the only other requirement is that register accesses which | 146 | * so the only other requirement is that register accesses which |
131 | * require BUSY to be clear are made with IRQs locally disabled | 147 | * require BUSY to be clear are made with IRQs locally disabled |
132 | */ | 148 | */ |
133 | static void rtc_wait_not_busy(void) | 149 | static void rtc_wait_not_busy(struct omap_rtc *rtc) |
134 | { | 150 | { |
135 | int count = 0; | 151 | int count = 0; |
136 | u8 status; | 152 | u8 status; |
137 | 153 | ||
138 | /* BUSY may stay active for 1/32768 second (~30 usec) */ | 154 | /* BUSY may stay active for 1/32768 second (~30 usec) */ |
139 | for (count = 0; count < 50; count++) { | 155 | for (count = 0; count < 50; count++) { |
140 | status = rtc_read(OMAP_RTC_STATUS_REG); | 156 | status = rtc_read(rtc, OMAP_RTC_STATUS_REG); |
141 | if ((status & (u8)OMAP_RTC_STATUS_BUSY) == 0) | 157 | if ((status & (u8)OMAP_RTC_STATUS_BUSY) == 0) |
142 | break; | 158 | break; |
143 | udelay(1); | 159 | udelay(1); |
@@ -145,16 +161,17 @@ static void rtc_wait_not_busy(void) | |||
145 | /* now we have ~15 usec to read/write various registers */ | 161 | /* now we have ~15 usec to read/write various registers */ |
146 | } | 162 | } |
147 | 163 | ||
148 | static irqreturn_t rtc_irq(int irq, void *rtc) | 164 | static irqreturn_t rtc_irq(int irq, void *dev_id) |
149 | { | 165 | { |
166 | struct omap_rtc *rtc = dev_id; | ||
150 | unsigned long events = 0; | 167 | unsigned long events = 0; |
151 | u8 irq_data; | 168 | u8 irq_data; |
152 | 169 | ||
153 | irq_data = rtc_read(OMAP_RTC_STATUS_REG); | 170 | irq_data = rtc_read(rtc, OMAP_RTC_STATUS_REG); |
154 | 171 | ||
155 | /* alarm irq? */ | 172 | /* alarm irq? */ |
156 | if (irq_data & OMAP_RTC_STATUS_ALARM) { | 173 | if (irq_data & OMAP_RTC_STATUS_ALARM) { |
157 | rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); | 174 | rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); |
158 | events |= RTC_IRQF | RTC_AF; | 175 | events |= RTC_IRQF | RTC_AF; |
159 | } | 176 | } |
160 | 177 | ||
@@ -162,23 +179,21 @@ static irqreturn_t rtc_irq(int irq, void *rtc) | |||
162 | if (irq_data & OMAP_RTC_STATUS_1S_EVENT) | 179 | if (irq_data & OMAP_RTC_STATUS_1S_EVENT) |
163 | events |= RTC_IRQF | RTC_UF; | 180 | events |= RTC_IRQF | RTC_UF; |
164 | 181 | ||
165 | rtc_update_irq(rtc, 1, events); | 182 | rtc_update_irq(rtc->rtc, 1, events); |
166 | 183 | ||
167 | return IRQ_HANDLED; | 184 | return IRQ_HANDLED; |
168 | } | 185 | } |
169 | 186 | ||
170 | static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 187 | static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
171 | { | 188 | { |
189 | struct omap_rtc *rtc = dev_get_drvdata(dev); | ||
172 | u8 reg, irqwake_reg = 0; | 190 | u8 reg, irqwake_reg = 0; |
173 | struct platform_device *pdev = to_platform_device(dev); | ||
174 | const struct platform_device_id *id_entry = | ||
175 | platform_get_device_id(pdev); | ||
176 | 191 | ||
177 | local_irq_disable(); | 192 | local_irq_disable(); |
178 | rtc_wait_not_busy(); | 193 | rtc_wait_not_busy(rtc); |
179 | reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); | 194 | reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); |
180 | if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) | 195 | if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) |
181 | irqwake_reg = rtc_read(OMAP_RTC_IRQWAKEEN); | 196 | irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN); |
182 | 197 | ||
183 | if (enabled) { | 198 | if (enabled) { |
184 | reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; | 199 | reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; |
@@ -187,10 +202,10 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
187 | reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; | 202 | reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; |
188 | irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; | 203 | irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; |
189 | } | 204 | } |
190 | rtc_wait_not_busy(); | 205 | rtc_wait_not_busy(rtc); |
191 | rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); | 206 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); |
192 | if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) | 207 | if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) |
193 | rtc_write(irqwake_reg, OMAP_RTC_IRQWAKEEN); | 208 | rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); |
194 | local_irq_enable(); | 209 | local_irq_enable(); |
195 | 210 | ||
196 | return 0; | 211 | return 0; |
@@ -231,16 +246,18 @@ static void bcd2tm(struct rtc_time *tm) | |||
231 | 246 | ||
232 | static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm) | 247 | static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm) |
233 | { | 248 | { |
249 | struct omap_rtc *rtc = dev_get_drvdata(dev); | ||
250 | |||
234 | /* we don't report wday/yday/isdst ... */ | 251 | /* we don't report wday/yday/isdst ... */ |
235 | local_irq_disable(); | 252 | local_irq_disable(); |
236 | rtc_wait_not_busy(); | 253 | rtc_wait_not_busy(rtc); |
237 | 254 | ||
238 | tm->tm_sec = rtc_read(OMAP_RTC_SECONDS_REG); | 255 | tm->tm_sec = rtc_read(rtc, OMAP_RTC_SECONDS_REG); |
239 | tm->tm_min = rtc_read(OMAP_RTC_MINUTES_REG); | 256 | tm->tm_min = rtc_read(rtc, OMAP_RTC_MINUTES_REG); |
240 | tm->tm_hour = rtc_read(OMAP_RTC_HOURS_REG); | 257 | tm->tm_hour = rtc_read(rtc, OMAP_RTC_HOURS_REG); |
241 | tm->tm_mday = rtc_read(OMAP_RTC_DAYS_REG); | 258 | tm->tm_mday = rtc_read(rtc, OMAP_RTC_DAYS_REG); |
242 | tm->tm_mon = rtc_read(OMAP_RTC_MONTHS_REG); | 259 | tm->tm_mon = rtc_read(rtc, OMAP_RTC_MONTHS_REG); |
243 | tm->tm_year = rtc_read(OMAP_RTC_YEARS_REG); | 260 | tm->tm_year = rtc_read(rtc, OMAP_RTC_YEARS_REG); |
244 | 261 | ||
245 | local_irq_enable(); | 262 | local_irq_enable(); |
246 | 263 | ||
@@ -250,17 +267,19 @@ static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
250 | 267 | ||
251 | static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) | 268 | static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) |
252 | { | 269 | { |
270 | struct omap_rtc *rtc = dev_get_drvdata(dev); | ||
271 | |||
253 | if (tm2bcd(tm) < 0) | 272 | if (tm2bcd(tm) < 0) |
254 | return -EINVAL; | 273 | return -EINVAL; |
255 | local_irq_disable(); | 274 | local_irq_disable(); |
256 | rtc_wait_not_busy(); | 275 | rtc_wait_not_busy(rtc); |
257 | 276 | ||
258 | rtc_write(tm->tm_year, OMAP_RTC_YEARS_REG); | 277 | rtc_write(rtc, OMAP_RTC_YEARS_REG, tm->tm_year); |
259 | rtc_write(tm->tm_mon, OMAP_RTC_MONTHS_REG); | 278 | rtc_write(rtc, OMAP_RTC_MONTHS_REG, tm->tm_mon); |
260 | rtc_write(tm->tm_mday, OMAP_RTC_DAYS_REG); | 279 | rtc_write(rtc, OMAP_RTC_DAYS_REG, tm->tm_mday); |
261 | rtc_write(tm->tm_hour, OMAP_RTC_HOURS_REG); | 280 | rtc_write(rtc, OMAP_RTC_HOURS_REG, tm->tm_hour); |
262 | rtc_write(tm->tm_min, OMAP_RTC_MINUTES_REG); | 281 | rtc_write(rtc, OMAP_RTC_MINUTES_REG, tm->tm_min); |
263 | rtc_write(tm->tm_sec, OMAP_RTC_SECONDS_REG); | 282 | rtc_write(rtc, OMAP_RTC_SECONDS_REG, tm->tm_sec); |
264 | 283 | ||
265 | local_irq_enable(); | 284 | local_irq_enable(); |
266 | 285 | ||
@@ -269,20 +288,22 @@ static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
269 | 288 | ||
270 | static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | 289 | static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) |
271 | { | 290 | { |
291 | struct omap_rtc *rtc = dev_get_drvdata(dev); | ||
292 | |||
272 | local_irq_disable(); | 293 | local_irq_disable(); |
273 | rtc_wait_not_busy(); | 294 | rtc_wait_not_busy(rtc); |
274 | 295 | ||
275 | alm->time.tm_sec = rtc_read(OMAP_RTC_ALARM_SECONDS_REG); | 296 | alm->time.tm_sec = rtc_read(rtc, OMAP_RTC_ALARM_SECONDS_REG); |
276 | alm->time.tm_min = rtc_read(OMAP_RTC_ALARM_MINUTES_REG); | 297 | alm->time.tm_min = rtc_read(rtc, OMAP_RTC_ALARM_MINUTES_REG); |
277 | alm->time.tm_hour = rtc_read(OMAP_RTC_ALARM_HOURS_REG); | 298 | alm->time.tm_hour = rtc_read(rtc, OMAP_RTC_ALARM_HOURS_REG); |
278 | alm->time.tm_mday = rtc_read(OMAP_RTC_ALARM_DAYS_REG); | 299 | alm->time.tm_mday = rtc_read(rtc, OMAP_RTC_ALARM_DAYS_REG); |
279 | alm->time.tm_mon = rtc_read(OMAP_RTC_ALARM_MONTHS_REG); | 300 | alm->time.tm_mon = rtc_read(rtc, OMAP_RTC_ALARM_MONTHS_REG); |
280 | alm->time.tm_year = rtc_read(OMAP_RTC_ALARM_YEARS_REG); | 301 | alm->time.tm_year = rtc_read(rtc, OMAP_RTC_ALARM_YEARS_REG); |
281 | 302 | ||
282 | local_irq_enable(); | 303 | local_irq_enable(); |
283 | 304 | ||
284 | bcd2tm(&alm->time); | 305 | bcd2tm(&alm->time); |
285 | alm->enabled = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG) | 306 | alm->enabled = !!(rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG) |
286 | & OMAP_RTC_INTERRUPTS_IT_ALARM); | 307 | & OMAP_RTC_INTERRUPTS_IT_ALARM); |
287 | 308 | ||
288 | return 0; | 309 | return 0; |
@@ -290,27 +311,25 @@ static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
290 | 311 | ||
291 | static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | 312 | static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) |
292 | { | 313 | { |
314 | struct omap_rtc *rtc = dev_get_drvdata(dev); | ||
293 | u8 reg, irqwake_reg = 0; | 315 | u8 reg, irqwake_reg = 0; |
294 | struct platform_device *pdev = to_platform_device(dev); | ||
295 | const struct platform_device_id *id_entry = | ||
296 | platform_get_device_id(pdev); | ||
297 | 316 | ||
298 | if (tm2bcd(&alm->time) < 0) | 317 | if (tm2bcd(&alm->time) < 0) |
299 | return -EINVAL; | 318 | return -EINVAL; |
300 | 319 | ||
301 | local_irq_disable(); | 320 | local_irq_disable(); |
302 | rtc_wait_not_busy(); | 321 | rtc_wait_not_busy(rtc); |
303 | 322 | ||
304 | rtc_write(alm->time.tm_year, OMAP_RTC_ALARM_YEARS_REG); | 323 | rtc_write(rtc, OMAP_RTC_ALARM_YEARS_REG, alm->time.tm_year); |
305 | rtc_write(alm->time.tm_mon, OMAP_RTC_ALARM_MONTHS_REG); | 324 | rtc_write(rtc, OMAP_RTC_ALARM_MONTHS_REG, alm->time.tm_mon); |
306 | rtc_write(alm->time.tm_mday, OMAP_RTC_ALARM_DAYS_REG); | 325 | rtc_write(rtc, OMAP_RTC_ALARM_DAYS_REG, alm->time.tm_mday); |
307 | rtc_write(alm->time.tm_hour, OMAP_RTC_ALARM_HOURS_REG); | 326 | rtc_write(rtc, OMAP_RTC_ALARM_HOURS_REG, alm->time.tm_hour); |
308 | rtc_write(alm->time.tm_min, OMAP_RTC_ALARM_MINUTES_REG); | 327 | rtc_write(rtc, OMAP_RTC_ALARM_MINUTES_REG, alm->time.tm_min); |
309 | rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG); | 328 | rtc_write(rtc, OMAP_RTC_ALARM_SECONDS_REG, alm->time.tm_sec); |
310 | 329 | ||
311 | reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); | 330 | reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); |
312 | if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) | 331 | if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) |
313 | irqwake_reg = rtc_read(OMAP_RTC_IRQWAKEEN); | 332 | irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN); |
314 | 333 | ||
315 | if (alm->enabled) { | 334 | if (alm->enabled) { |
316 | reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; | 335 | reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; |
@@ -319,9 +338,9 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
319 | reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; | 338 | reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; |
320 | irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; | 339 | irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; |
321 | } | 340 | } |
322 | rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); | 341 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); |
323 | if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) | 342 | if (rtc->flags & OMAP_RTC_HAS_IRQWAKEEN) |
324 | rtc_write(irqwake_reg, OMAP_RTC_IRQWAKEEN); | 343 | rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); |
325 | 344 | ||
326 | local_irq_enable(); | 345 | local_irq_enable(); |
327 | 346 | ||
@@ -336,9 +355,6 @@ static struct rtc_class_ops omap_rtc_ops = { | |||
336 | .alarm_irq_enable = omap_rtc_alarm_irq_enable, | 355 | .alarm_irq_enable = omap_rtc_alarm_irq_enable, |
337 | }; | 356 | }; |
338 | 357 | ||
339 | static int omap_rtc_alarm; | ||
340 | static int omap_rtc_timer; | ||
341 | |||
342 | #define OMAP_RTC_DATA_AM3352_IDX 1 | 358 | #define OMAP_RTC_DATA_AM3352_IDX 1 |
343 | #define OMAP_RTC_DATA_DA830_IDX 2 | 359 | #define OMAP_RTC_DATA_DA830_IDX 2 |
344 | 360 | ||
@@ -372,13 +388,17 @@ MODULE_DEVICE_TABLE(of, omap_rtc_of_match); | |||
372 | 388 | ||
373 | static int __init omap_rtc_probe(struct platform_device *pdev) | 389 | static int __init omap_rtc_probe(struct platform_device *pdev) |
374 | { | 390 | { |
391 | struct omap_rtc *rtc; | ||
375 | struct resource *res; | 392 | struct resource *res; |
376 | struct rtc_device *rtc; | ||
377 | u8 reg, new_ctrl; | 393 | u8 reg, new_ctrl; |
378 | const struct platform_device_id *id_entry; | 394 | const struct platform_device_id *id_entry; |
379 | const struct of_device_id *of_id; | 395 | const struct of_device_id *of_id; |
380 | int ret; | 396 | int ret; |
381 | 397 | ||
398 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
399 | if (!rtc) | ||
400 | return -ENOMEM; | ||
401 | |||
382 | of_id = of_match_device(omap_rtc_of_match, &pdev->dev); | 402 | of_id = of_match_device(omap_rtc_of_match, &pdev->dev); |
383 | if (of_id) | 403 | if (of_id) |
384 | pdev->id_entry = of_id->data; | 404 | pdev->id_entry = of_id->data; |
@@ -389,26 +409,30 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
389 | return -ENODEV; | 409 | return -ENODEV; |
390 | } | 410 | } |
391 | 411 | ||
392 | omap_rtc_timer = platform_get_irq(pdev, 0); | 412 | rtc->flags = id_entry->driver_data; |
393 | if (omap_rtc_timer <= 0) | 413 | |
414 | rtc->irq_timer = platform_get_irq(pdev, 0); | ||
415 | if (rtc->irq_timer <= 0) | ||
394 | return -ENOENT; | 416 | return -ENOENT; |
395 | 417 | ||
396 | omap_rtc_alarm = platform_get_irq(pdev, 1); | 418 | rtc->irq_alarm = platform_get_irq(pdev, 1); |
397 | if (omap_rtc_alarm <= 0) | 419 | if (rtc->irq_alarm <= 0) |
398 | return -ENOENT; | 420 | return -ENOENT; |
399 | 421 | ||
400 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 422 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
401 | rtc_base = devm_ioremap_resource(&pdev->dev, res); | 423 | rtc->base = devm_ioremap_resource(&pdev->dev, res); |
402 | if (IS_ERR(rtc_base)) | 424 | if (IS_ERR(rtc->base)) |
403 | return PTR_ERR(rtc_base); | 425 | return PTR_ERR(rtc->base); |
426 | |||
427 | platform_set_drvdata(pdev, rtc); | ||
404 | 428 | ||
405 | /* Enable the clock/module so that we can access the registers */ | 429 | /* Enable the clock/module so that we can access the registers */ |
406 | pm_runtime_enable(&pdev->dev); | 430 | pm_runtime_enable(&pdev->dev); |
407 | pm_runtime_get_sync(&pdev->dev); | 431 | pm_runtime_get_sync(&pdev->dev); |
408 | 432 | ||
409 | if (id_entry->driver_data & OMAP_RTC_HAS_KICKER) { | 433 | if (rtc->flags & OMAP_RTC_HAS_KICKER) { |
410 | rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG); | 434 | rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); |
411 | rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG); | 435 | rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); |
412 | } | 436 | } |
413 | 437 | ||
414 | /* | 438 | /* |
@@ -416,25 +440,26 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
416 | * | 440 | * |
417 | * NOTE: ALARM2 is not cleared on AM3352 if rtc_write (writeb) is used | 441 | * NOTE: ALARM2 is not cleared on AM3352 if rtc_write (writeb) is used |
418 | */ | 442 | */ |
419 | rtc_writel(0, OMAP_RTC_INTERRUPTS_REG); | 443 | rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
420 | 444 | ||
421 | /* enable RTC functional clock */ | 445 | /* enable RTC functional clock */ |
422 | if (id_entry->driver_data & OMAP_RTC_HAS_32KCLK_EN) { | 446 | if (rtc->flags & OMAP_RTC_HAS_32KCLK_EN) { |
423 | reg = rtc_read(OMAP_RTC_OSC_REG); | 447 | reg = rtc_read(rtc, OMAP_RTC_OSC_REG); |
424 | rtc_writel(reg | OMAP_RTC_OSC_32KCLK_EN, OMAP_RTC_OSC_REG); | 448 | rtc_writel(rtc, OMAP_RTC_OSC_REG, |
449 | reg | OMAP_RTC_OSC_32KCLK_EN); | ||
425 | } | 450 | } |
426 | 451 | ||
427 | /* clear old status */ | 452 | /* clear old status */ |
428 | reg = rtc_read(OMAP_RTC_STATUS_REG); | 453 | reg = rtc_read(rtc, OMAP_RTC_STATUS_REG); |
429 | if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) { | 454 | if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) { |
430 | dev_info(&pdev->dev, "RTC power up reset detected\n"); | 455 | dev_info(&pdev->dev, "RTC power up reset detected\n"); |
431 | rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG); | 456 | rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_POWER_UP); |
432 | } | 457 | } |
433 | if (reg & (u8) OMAP_RTC_STATUS_ALARM) | 458 | if (reg & (u8) OMAP_RTC_STATUS_ALARM) |
434 | rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); | 459 | rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); |
435 | 460 | ||
436 | /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ | 461 | /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ |
437 | reg = rtc_read(OMAP_RTC_CTRL_REG); | 462 | reg = rtc_read(rtc, OMAP_RTC_CTRL_REG); |
438 | if (reg & (u8) OMAP_RTC_CTRL_STOP) | 463 | if (reg & (u8) OMAP_RTC_CTRL_STOP) |
439 | dev_info(&pdev->dev, "already running\n"); | 464 | dev_info(&pdev->dev, "already running\n"); |
440 | 465 | ||
@@ -460,27 +485,26 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
460 | dev_info(&pdev->dev, "split power mode\n"); | 485 | dev_info(&pdev->dev, "split power mode\n"); |
461 | 486 | ||
462 | if (reg != new_ctrl) | 487 | if (reg != new_ctrl) |
463 | rtc_write(new_ctrl, OMAP_RTC_CTRL_REG); | 488 | rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); |
464 | 489 | ||
465 | device_init_wakeup(&pdev->dev, true); | 490 | device_init_wakeup(&pdev->dev, true); |
466 | 491 | ||
467 | rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | 492 | rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, |
468 | &omap_rtc_ops, THIS_MODULE); | 493 | &omap_rtc_ops, THIS_MODULE); |
469 | if (IS_ERR(rtc)) { | 494 | if (IS_ERR(rtc->rtc)) { |
470 | ret = PTR_ERR(rtc); | 495 | ret = PTR_ERR(rtc->rtc); |
471 | goto err; | 496 | goto err; |
472 | } | 497 | } |
473 | platform_set_drvdata(pdev, rtc); | ||
474 | 498 | ||
475 | /* handle periodic and alarm irqs */ | 499 | /* handle periodic and alarm irqs */ |
476 | ret = devm_request_irq(&pdev->dev, omap_rtc_timer, rtc_irq, 0, | 500 | ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0, |
477 | dev_name(&rtc->dev), rtc); | 501 | dev_name(&rtc->rtc->dev), rtc); |
478 | if (ret) | 502 | if (ret) |
479 | goto err; | 503 | goto err; |
480 | 504 | ||
481 | if (omap_rtc_timer != omap_rtc_alarm) { | 505 | if (rtc->irq_timer != rtc->irq_alarm) { |
482 | ret = devm_request_irq(&pdev->dev, omap_rtc_alarm, rtc_irq, 0, | 506 | ret = devm_request_irq(&pdev->dev, rtc->irq_alarm, rtc_irq, 0, |
483 | dev_name(&rtc->dev), rtc); | 507 | dev_name(&rtc->rtc->dev), rtc); |
484 | if (ret) | 508 | if (ret) |
485 | goto err; | 509 | goto err; |
486 | } | 510 | } |
@@ -489,8 +513,8 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
489 | 513 | ||
490 | err: | 514 | err: |
491 | device_init_wakeup(&pdev->dev, false); | 515 | device_init_wakeup(&pdev->dev, false); |
492 | if (id_entry->driver_data & OMAP_RTC_HAS_KICKER) | 516 | if (rtc->flags & OMAP_RTC_HAS_KICKER) |
493 | rtc_writel(0, OMAP_RTC_KICK0_REG); | 517 | rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); |
494 | pm_runtime_put_sync(&pdev->dev); | 518 | pm_runtime_put_sync(&pdev->dev); |
495 | pm_runtime_disable(&pdev->dev); | 519 | pm_runtime_disable(&pdev->dev); |
496 | 520 | ||
@@ -499,16 +523,15 @@ err: | |||
499 | 523 | ||
500 | static int __exit omap_rtc_remove(struct platform_device *pdev) | 524 | static int __exit omap_rtc_remove(struct platform_device *pdev) |
501 | { | 525 | { |
502 | const struct platform_device_id *id_entry = | 526 | struct omap_rtc *rtc = platform_get_drvdata(pdev); |
503 | platform_get_device_id(pdev); | ||
504 | 527 | ||
505 | device_init_wakeup(&pdev->dev, 0); | 528 | device_init_wakeup(&pdev->dev, 0); |
506 | 529 | ||
507 | /* leave rtc running, but disable irqs */ | 530 | /* leave rtc running, but disable irqs */ |
508 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); | 531 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
509 | 532 | ||
510 | if (id_entry->driver_data & OMAP_RTC_HAS_KICKER) | 533 | if (rtc->flags & OMAP_RTC_HAS_KICKER) |
511 | rtc_writel(0, OMAP_RTC_KICK0_REG); | 534 | rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); |
512 | 535 | ||
513 | /* Disable the clock/module */ | 536 | /* Disable the clock/module */ |
514 | pm_runtime_put_sync(&pdev->dev); | 537 | pm_runtime_put_sync(&pdev->dev); |
@@ -518,20 +541,20 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
518 | } | 541 | } |
519 | 542 | ||
520 | #ifdef CONFIG_PM_SLEEP | 543 | #ifdef CONFIG_PM_SLEEP |
521 | static u8 irqstat; | ||
522 | |||
523 | static int omap_rtc_suspend(struct device *dev) | 544 | static int omap_rtc_suspend(struct device *dev) |
524 | { | 545 | { |
525 | irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); | 546 | struct omap_rtc *rtc = dev_get_drvdata(dev); |
547 | |||
548 | rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); | ||
526 | 549 | ||
527 | /* FIXME the RTC alarm is not currently acting as a wakeup event | 550 | /* FIXME the RTC alarm is not currently acting as a wakeup event |
528 | * source on some platforms, and in fact this enable() call is just | 551 | * source on some platforms, and in fact this enable() call is just |
529 | * saving a flag that's never used... | 552 | * saving a flag that's never used... |
530 | */ | 553 | */ |
531 | if (device_may_wakeup(dev)) | 554 | if (device_may_wakeup(dev)) |
532 | enable_irq_wake(omap_rtc_alarm); | 555 | enable_irq_wake(rtc->irq_alarm); |
533 | else | 556 | else |
534 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); | 557 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
535 | 558 | ||
536 | /* Disable the clock/module */ | 559 | /* Disable the clock/module */ |
537 | pm_runtime_put_sync(dev); | 560 | pm_runtime_put_sync(dev); |
@@ -541,13 +564,15 @@ static int omap_rtc_suspend(struct device *dev) | |||
541 | 564 | ||
542 | static int omap_rtc_resume(struct device *dev) | 565 | static int omap_rtc_resume(struct device *dev) |
543 | { | 566 | { |
567 | struct omap_rtc *rtc = dev_get_drvdata(dev); | ||
568 | |||
544 | /* Enable the clock/module so that we can access the registers */ | 569 | /* Enable the clock/module so that we can access the registers */ |
545 | pm_runtime_get_sync(dev); | 570 | pm_runtime_get_sync(dev); |
546 | 571 | ||
547 | if (device_may_wakeup(dev)) | 572 | if (device_may_wakeup(dev)) |
548 | disable_irq_wake(omap_rtc_alarm); | 573 | disable_irq_wake(rtc->irq_alarm); |
549 | else | 574 | else |
550 | rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG); | 575 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg); |
551 | 576 | ||
552 | return 0; | 577 | return 0; |
553 | } | 578 | } |
@@ -557,7 +582,9 @@ static SIMPLE_DEV_PM_OPS(omap_rtc_pm_ops, omap_rtc_suspend, omap_rtc_resume); | |||
557 | 582 | ||
558 | static void omap_rtc_shutdown(struct platform_device *pdev) | 583 | static void omap_rtc_shutdown(struct platform_device *pdev) |
559 | { | 584 | { |
560 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); | 585 | struct omap_rtc *rtc = platform_get_drvdata(pdev); |
586 | |||
587 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); | ||
561 | } | 588 | } |
562 | 589 | ||
563 | MODULE_ALIAS("platform:omap_rtc"); | 590 | MODULE_ALIAS("platform:omap_rtc"); |