| 1 | |
| 2 | |
| 3 | * SuperH On-Chip RTC Support
|
| 4 | *
|
| 5 | * Copyright (C) 2006 - 2009 Paul Mundt
|
| 6 | * Copyright (C) 2006 Jamie Lenehan
|
| 7 | * Copyright (C) 2008 Angelo Castello
|
| 8 | * Copyright (C) 2025 Wolfram Sang, Renesas Electronics Corporation
|
| 9 | *
|
| 10 | * Based on the old arch/sh/kernel/cpu/rtc.c by:
|
| 11 | *
|
| 12 | * Copyright (C) 2000 Philipp Rumpf <[email protected]>
|
| 13 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
|
| 14 |
|
| 15 | #include <linux/module.h>
|
| 16 | #include <linux/kernel.h>
|
| 17 | #include <linux/bcd.h>
|
| 18 | #include <linux/rtc.h>
|
| 19 | #include <linux/init.h>
|
| 20 | #include <linux/platform_device.h>
|
| 21 | #include <linux/seq_file.h>
|
| 22 | #include <linux/interrupt.h>
|
| 23 | #include <linux/spinlock.h>
|
| 24 | #include <linux/io.h>
|
| 25 | #include <linux/log2.h>
|
| 26 | #include <linux/clk.h>
|
| 27 | #include <linux/slab.h>
|
| 28 | #ifdef CONFIG_SUPERH
|
| 29 | #include <asm/rtc.h>
|
| 30 | #else
|
| 31 |
|
| 32 | #define rtc_reg_size sizeof(u16)
|
| 33 | #define RTC_BIT_INVERTED 0
|
| 34 | #define RTC_CAP_4_DIGIT_YEAR BIT(0)
|
| 35 | #define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR
|
| 36 | #endif
|
| 37 |
|
| 38 | #define DRV_NAME "sh-rtc"
|
| 39 |
|
| 40 | #define RTC_REG(r) ((r) * rtc_reg_size)
|
| 41 |
|
| 42 | #define R64CNT RTC_REG(0)
|
| 43 |
|
| 44 | #define RSECCNT RTC_REG(1)
|
| 45 | #define RMINCNT RTC_REG(2)
|
| 46 | #define RHRCNT RTC_REG(3)
|
| 47 | #define RWKCNT RTC_REG(4)
|
| 48 | #define RDAYCNT RTC_REG(5)
|
| 49 | #define RMONCNT RTC_REG(6)
|
| 50 | #define RYRCNT RTC_REG(7)
|
| 51 | #define RSECAR RTC_REG(8)
|
| 52 | #define RMINAR RTC_REG(9)
|
| 53 | #define RHRAR RTC_REG(10)
|
| 54 | #define RWKAR RTC_REG(11)
|
| 55 | #define RDAYAR RTC_REG(12)
|
| 56 | #define RMONAR RTC_REG(13)
|
| 57 | #define RCR1 RTC_REG(14)
|
| 58 | #define RCR2 RTC_REG(15)
|
| 59 |
|
| 60 | |
| 61 | * Note on RYRAR and RCR3: Up until this point most of the register
|
| 62 | * definitions are consistent across all of the available parts. However,
|
| 63 | * the placement of the optional RYRAR and RCR3 (the RYRAR control
|
| 64 | * register used to control RYRCNT/RYRAR compare) varies considerably
|
| 65 | * across various parts, occasionally being mapped in to a completely
|
| 66 | * unrelated address space. For proper RYRAR support a separate resource
|
| 67 | * would have to be handed off, but as this is purely optional in
|
| 68 | * practice, we simply opt not to support it, thereby keeping the code
|
| 69 | * quite a bit more simplified.
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 | #define AR_ENB BIT(7)
|
| 74 |
|
| 75 |
|
| 76 | #define RCR1_CF BIT(7)
|
| 77 | #define RCR1_CIE BIT(4)
|
| 78 | #define RCR1_AIE BIT(3)
|
| 79 | #define RCR1_AF BIT(0)
|
| 80 |
|
| 81 |
|
| 82 | #define RCR2_RTCEN BIT(3)
|
| 83 | #define RCR2_ADJ BIT(2)
|
| 84 | #define RCR2_RESET BIT(1)
|
| 85 | #define RCR2_START BIT(0)
|
| 86 |
|
| 87 | struct sh_rtc {
|
| 88 | void __iomem *regbase;
|
| 89 | int alarm_irq;
|
| 90 | struct clk *clk;
|
| 91 | struct rtc_device *rtc_dev;
|
| 92 | spinlock_t lock;
|
| 93 | unsigned long capabilities;
|
| 94 | };
|
| 95 |
|
| 96 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
|
| 97 | {
|
| 98 | struct sh_rtc *rtc = dev_id;
|
| 99 | unsigned int tmp, pending;
|
| 100 |
|
| 101 | spin_lock(&rtc->lock);
|
| 102 |
|
| 103 | tmp = readb(rtc->regbase + RCR1);
|
| 104 | pending = tmp & RCR1_AF;
|
| 105 | tmp &= ~(RCR1_AF | RCR1_AIE);
|
| 106 | writeb(tmp, rtc->regbase + RCR1);
|
| 107 |
|
| 108 | if (pending)
|
| 109 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
|
| 110 |
|
| 111 | spin_unlock(&rtc->lock);
|
| 112 |
|
| 113 | return IRQ_RETVAL(pending);
|
| 114 | }
|
| 115 |
|
| 116 | static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
|
| 117 | {
|
| 118 | struct sh_rtc *rtc = dev_get_drvdata(dev);
|
| 119 | unsigned int tmp;
|
| 120 |
|
| 121 | spin_lock_irq(&rtc->lock);
|
| 122 |
|
| 123 | tmp = readb(rtc->regbase + RCR1);
|
| 124 |
|
| 125 | if (enable)
|
| 126 | tmp |= RCR1_AIE;
|
| 127 | else
|
| 128 | tmp &= ~RCR1_AIE;
|
| 129 |
|
| 130 | writeb(tmp, rtc->regbase + RCR1);
|
| 131 |
|
| 132 | spin_unlock_irq(&rtc->lock);
|
| 133 |
|
| 134 | return 0;
|
| 135 | }
|
| 136 |
|
| 137 | static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
| 138 | {
|
| 139 | struct sh_rtc *rtc = dev_get_drvdata(dev);
|
| 140 | unsigned int sec128, sec2, yr, yr100, cf_bit;
|
| 141 |
|
| 142 | if (!(readb(rtc->regbase + RCR2) & RCR2_RTCEN))
|
| 143 | return -EINVAL;
|
| 144 |
|
| 145 | do {
|
| 146 | unsigned int tmp;
|
| 147 |
|
| 148 | spin_lock_irq(&rtc->lock);
|
| 149 |
|
| 150 | tmp = readb(rtc->regbase + RCR1);
|
| 151 | tmp &= ~RCR1_CF;
|
| 152 | tmp |= RCR1_CIE;
|
| 153 | writeb(tmp, rtc->regbase + RCR1);
|
| 154 |
|
| 155 | sec128 = readb(rtc->regbase + R64CNT);
|
| 156 |
|
| 157 | tm->tm_sec = bcd2bin(readb(rtc->regbase + RSECCNT));
|
| 158 | tm->tm_min = bcd2bin(readb(rtc->regbase + RMINCNT));
|
| 159 | tm->tm_hour = bcd2bin(readb(rtc->regbase + RHRCNT));
|
| 160 | tm->tm_wday = bcd2bin(readb(rtc->regbase + RWKCNT));
|
| 161 | tm->tm_mday = bcd2bin(readb(rtc->regbase + RDAYCNT));
|
| 162 | tm->tm_mon = bcd2bin(readb(rtc->regbase + RMONCNT)) - 1;
|
| 163 |
|
| 164 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
|
| 165 | yr = readw(rtc->regbase + RYRCNT);
|
| 166 | yr100 = bcd2bin(yr >> 8);
|
| 167 | yr &= 0xff;
|
| 168 | } else {
|
| 169 | yr = readb(rtc->regbase + RYRCNT);
|
| 170 | yr100 = bcd2bin((yr == 0x99) ? 0x19 : 0x20);
|
| 171 | }
|
| 172 |
|
| 173 | tm->tm_year = (yr100 * 100 + bcd2bin(yr)) - 1900;
|
| 174 |
|
| 175 | sec2 = readb(rtc->regbase + R64CNT);
|
| 176 | cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF;
|
| 177 |
|
| 178 | spin_unlock_irq(&rtc->lock);
|
| 179 | } while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);
|
| 180 |
|
| 181 | #if RTC_BIT_INVERTED != 0
|
| 182 | if ((sec128 & RTC_BIT_INVERTED))
|
| 183 | tm->tm_sec--;
|
| 184 | #endif
|
| 185 |
|
| 186 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
|
| 187 | __func__, tm->tm_sec, tm->tm_min, tm->tm_hour,
|
| 188 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
|
| 189 |
|
| 190 | return 0;
|
| 191 | }
|
| 192 |
|
| 193 | static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
| 194 | {
|
| 195 | struct sh_rtc *rtc = dev_get_drvdata(dev);
|
| 196 | unsigned int tmp;
|
| 197 | int year;
|
| 198 |
|
| 199 | spin_lock_irq(&rtc->lock);
|
| 200 |
|
| 201 |
|
| 202 | tmp = readb(rtc->regbase + RCR2);
|
| 203 | tmp |= RCR2_RESET;
|
| 204 | tmp &= ~RCR2_START;
|
| 205 | writeb(tmp, rtc->regbase + RCR2);
|
| 206 |
|
| 207 | writeb(bin2bcd(tm->tm_sec), rtc->regbase + RSECCNT);
|
| 208 | writeb(bin2bcd(tm->tm_min), rtc->regbase + RMINCNT);
|
| 209 | writeb(bin2bcd(tm->tm_hour), rtc->regbase + RHRCNT);
|
| 210 | writeb(bin2bcd(tm->tm_wday), rtc->regbase + RWKCNT);
|
| 211 | writeb(bin2bcd(tm->tm_mday), rtc->regbase + RDAYCNT);
|
| 212 | writeb(bin2bcd(tm->tm_mon + 1), rtc->regbase + RMONCNT);
|
| 213 |
|
| 214 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
|
| 215 | year = (bin2bcd((tm->tm_year + 1900) / 100) << 8) |
|
| 216 | bin2bcd(tm->tm_year % 100);
|
| 217 | writew(year, rtc->regbase + RYRCNT);
|
| 218 | } else {
|
| 219 | year = tm->tm_year % 100;
|
| 220 | writeb(bin2bcd(year), rtc->regbase + RYRCNT);
|
| 221 | }
|
| 222 |
|
| 223 |
|
| 224 | tmp = readb(rtc->regbase + RCR2);
|
| 225 | tmp &= ~RCR2_RESET;
|
| 226 | tmp |= RCR2_RTCEN | RCR2_START;
|
| 227 | writeb(tmp, rtc->regbase + RCR2);
|
| 228 |
|
| 229 | spin_unlock_irq(&rtc->lock);
|
| 230 |
|
| 231 | return 0;
|
| 232 | }
|
| 233 |
|
| 234 | static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off)
|
| 235 | {
|
| 236 | unsigned int byte;
|
| 237 | int value = -1;
|
| 238 |
|
| 239 | byte = readb(rtc->regbase + reg_off);
|
| 240 | if (byte & AR_ENB) {
|
| 241 | byte &= ~AR_ENB;
|
| 242 | value = bcd2bin(byte);
|
| 243 | }
|
| 244 |
|
| 245 | return value;
|
| 246 | }
|
| 247 |
|
| 248 | static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
|
| 249 | {
|
| 250 | struct sh_rtc *rtc = dev_get_drvdata(dev);
|
| 251 | struct rtc_time *tm = &wkalrm->time;
|
| 252 |
|
| 253 | spin_lock_irq(&rtc->lock);
|
| 254 |
|
| 255 | tm->tm_sec = sh_rtc_read_alarm_value(rtc, RSECAR);
|
| 256 | tm->tm_min = sh_rtc_read_alarm_value(rtc, RMINAR);
|
| 257 | tm->tm_hour = sh_rtc_read_alarm_value(rtc, RHRAR);
|
| 258 | tm->tm_wday = sh_rtc_read_alarm_value(rtc, RWKAR);
|
| 259 | tm->tm_mday = sh_rtc_read_alarm_value(rtc, RDAYAR);
|
| 260 | tm->tm_mon = sh_rtc_read_alarm_value(rtc, RMONAR);
|
| 261 | if (tm->tm_mon > 0)
|
| 262 | tm->tm_mon -= 1;
|
| 263 |
|
| 264 | wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0;
|
| 265 |
|
| 266 | spin_unlock_irq(&rtc->lock);
|
| 267 |
|
| 268 | return 0;
|
| 269 | }
|
| 270 |
|
| 271 | static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc,
|
| 272 | int value, int reg_off)
|
| 273 | {
|
| 274 |
|
| 275 | if (value < 0)
|
| 276 | writeb(0, rtc->regbase + reg_off);
|
| 277 | else
|
| 278 | writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off);
|
| 279 | }
|
| 280 |
|
| 281 | static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
|
| 282 | {
|
| 283 | struct sh_rtc *rtc = dev_get_drvdata(dev);
|
| 284 | unsigned int rcr1;
|
| 285 | struct rtc_time *tm = &wkalrm->time;
|
| 286 | int mon;
|
| 287 |
|
| 288 | spin_lock_irq(&rtc->lock);
|
| 289 |
|
| 290 |
|
| 291 | rcr1 = readb(rtc->regbase + RCR1);
|
| 292 | rcr1 &= ~(RCR1_AF | RCR1_AIE);
|
| 293 | writeb(rcr1, rtc->regbase + RCR1);
|
| 294 |
|
| 295 |
|
| 296 | sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR);
|
| 297 | sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR);
|
| 298 | sh_rtc_write_alarm_value(rtc, tm->tm_hour, RHRAR);
|
| 299 | sh_rtc_write_alarm_value(rtc, tm->tm_wday, RWKAR);
|
| 300 | sh_rtc_write_alarm_value(rtc, tm->tm_mday, RDAYAR);
|
| 301 | mon = tm->tm_mon;
|
| 302 | if (mon >= 0)
|
| 303 | mon += 1;
|
| 304 | sh_rtc_write_alarm_value(rtc, mon, RMONAR);
|
| 305 |
|
| 306 | if (wkalrm->enabled) {
|
| 307 | rcr1 |= RCR1_AIE;
|
| 308 | writeb(rcr1, rtc->regbase + RCR1);
|
| 309 | }
|
| 310 |
|
| 311 | spin_unlock_irq(&rtc->lock);
|
| 312 |
|
| 313 | return 0;
|
| 314 | }
|
| 315 |
|
| 316 | static const struct rtc_class_ops sh_rtc_ops = {
|
| 317 | .read_time = sh_rtc_read_time,
|
| 318 | .set_time = sh_rtc_set_time,
|
| 319 | .read_alarm = sh_rtc_read_alarm,
|
| 320 | .set_alarm = sh_rtc_set_alarm,
|
| 321 | .alarm_irq_enable = sh_rtc_alarm_irq_enable,
|
| 322 | };
|
| 323 |
|
| 324 | static int __init sh_rtc_probe(struct platform_device *pdev)
|
| 325 | {
|
| 326 | struct sh_rtc *rtc;
|
| 327 | struct resource *res, *req_res;
|
| 328 | char clk_name[14];
|
| 329 | int clk_id, ret;
|
| 330 | unsigned int tmp;
|
| 331 | resource_size_t regsize;
|
| 332 |
|
| 333 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
|
| 334 | if (unlikely(!rtc))
|
| 335 | return -ENOMEM;
|
| 336 |
|
| 337 | spin_lock_init(&rtc->lock);
|
| 338 |
|
| 339 | ret = platform_get_irq(pdev, 0);
|
| 340 | if (unlikely(ret <= 0)) {
|
| 341 | dev_err(&pdev->dev, "No IRQ resource\n");
|
| 342 | return -ENOENT;
|
| 343 | }
|
| 344 |
|
| 345 | if (!pdev->dev.of_node)
|
| 346 | rtc->alarm_irq = platform_get_irq(pdev, 2);
|
| 347 | else
|
| 348 | rtc->alarm_irq = ret;
|
| 349 |
|
| 350 | res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
| 351 | if (!res)
|
| 352 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
| 353 | if (!res) {
|
| 354 | dev_err(&pdev->dev, "No IO resource\n");
|
| 355 | return -ENOENT;
|
| 356 | }
|
| 357 |
|
| 358 | regsize = resource_size(res);
|
| 359 | req_res = devm_request_mem_region(&pdev->dev, res->start, regsize, pdev->name);
|
| 360 | if (!req_res)
|
| 361 | return -EBUSY;
|
| 362 |
|
| 363 | rtc->regbase = devm_ioremap(&pdev->dev, req_res->start, regsize);
|
| 364 | if (!rtc->regbase)
|
| 365 | return -EINVAL;
|
| 366 |
|
| 367 | if (!pdev->dev.of_node) {
|
| 368 | clk_id = pdev->id;
|
| 369 |
|
| 370 | if (clk_id < 0)
|
| 371 | clk_id = 0;
|
| 372 |
|
| 373 | snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id);
|
| 374 | } else {
|
| 375 | snprintf(clk_name, sizeof(clk_name), "fck");
|
| 376 | }
|
| 377 |
|
| 378 | rtc->clk = devm_clk_get(&pdev->dev, clk_name);
|
| 379 | if (IS_ERR(rtc->clk)) {
|
| 380 | |
| 381 | * No error handling for rtc->clk intentionally, not all
|
| 382 | * platforms will have a unique clock for the RTC, and
|
| 383 | * the clk API can handle the struct clk pointer being
|
| 384 | * NULL.
|
| 385 |
|
| 386 | rtc->clk = NULL;
|
| 387 | }
|
| 388 |
|
| 389 | rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
|
| 390 | if (IS_ERR(rtc->rtc_dev))
|
| 391 | return PTR_ERR(rtc->rtc_dev);
|
| 392 |
|
| 393 | clk_enable(rtc->clk);
|
| 394 |
|
| 395 | rtc->capabilities = RTC_DEF_CAPABILITIES;
|
| 396 |
|
| 397 | #ifdef CONFIG_SUPERH
|
| 398 | if (dev_get_platdata(&pdev->dev)) {
|
| 399 | struct sh_rtc_platform_info *pinfo =
|
| 400 | dev_get_platdata(&pdev->dev);
|
| 401 |
|
| 402 | |
| 403 | * Some CPUs have special capabilities in addition to the
|
| 404 | * default set. Add those in here.
|
| 405 |
|
| 406 | rtc->capabilities |= pinfo->capabilities;
|
| 407 | }
|
| 408 | #endif
|
| 409 |
|
| 410 | ret = devm_request_irq(&pdev->dev, rtc->alarm_irq, sh_rtc_alarm, 0, "sh-rtc", rtc);
|
| 411 | if (ret) {
|
| 412 | dev_err(&pdev->dev, "request alarm IRQ failed with %d, IRQ %d\n",
|
| 413 | ret, rtc->alarm_irq);
|
| 414 | goto err_unmap;
|
| 415 | }
|
| 416 |
|
| 417 | platform_set_drvdata(pdev, rtc);
|
| 418 |
|
| 419 |
|
| 420 | tmp = readb(rtc->regbase + RCR1);
|
| 421 | tmp &= ~(RCR1_CIE | RCR1_AIE);
|
| 422 | writeb(tmp, rtc->regbase + RCR1);
|
| 423 |
|
| 424 | rtc->rtc_dev->ops = &sh_rtc_ops;
|
| 425 |
|
| 426 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
|
| 427 | rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900;
|
| 428 | rtc->rtc_dev->range_max = RTC_TIMESTAMP_END_9999;
|
| 429 | } else {
|
| 430 | rtc->rtc_dev->range_min = mktime64(1999, 1, 1, 0, 0, 0);
|
| 431 | rtc->rtc_dev->range_max = mktime64(2098, 12, 31, 23, 59, 59);
|
| 432 | }
|
| 433 |
|
| 434 | ret = devm_rtc_register_device(rtc->rtc_dev);
|
| 435 | if (ret)
|
| 436 | goto err_unmap;
|
| 437 |
|
| 438 | device_init_wakeup(&pdev->dev, true);
|
| 439 | return 0;
|
| 440 |
|
| 441 | err_unmap:
|
| 442 | clk_disable(rtc->clk);
|
| 443 |
|
| 444 | return ret;
|
| 445 | }
|
| 446 |
|
| 447 | static void __exit sh_rtc_remove(struct platform_device *pdev)
|
| 448 | {
|
| 449 | struct sh_rtc *rtc = platform_get_drvdata(pdev);
|
| 450 |
|
| 451 | sh_rtc_alarm_irq_enable(&pdev->dev, 0);
|
| 452 |
|
| 453 | clk_disable(rtc->clk);
|
| 454 | }
|
| 455 |
|
| 456 | static int sh_rtc_suspend(struct device *dev)
|
| 457 | {
|
| 458 | struct sh_rtc *rtc = dev_get_drvdata(dev);
|
| 459 |
|
| 460 | if (device_may_wakeup(dev))
|
| 461 | irq_set_irq_wake(rtc->alarm_irq, 1);
|
| 462 |
|
| 463 | return 0;
|
| 464 | }
|
| 465 |
|
| 466 | static int sh_rtc_resume(struct device *dev)
|
| 467 | {
|
| 468 | struct sh_rtc *rtc = dev_get_drvdata(dev);
|
| 469 |
|
| 470 | if (device_may_wakeup(dev))
|
| 471 | irq_set_irq_wake(rtc->alarm_irq, 0);
|
| 472 |
|
| 473 | return 0;
|
| 474 | }
|
| 475 |
|
| 476 | static DEFINE_SIMPLE_DEV_PM_OPS(sh_rtc_pm_ops, sh_rtc_suspend, sh_rtc_resume);
|
| 477 |
|
| 478 | static const struct of_device_id sh_rtc_of_match[] = {
|
| 479 | { .compatible = "renesas,sh-rtc", },
|
| 480 | { }
|
| 481 | };
|
| 482 | MODULE_DEVICE_TABLE(of, sh_rtc_of_match);
|
| 483 |
|
| 484 | |
| 485 | * sh_rtc_remove() lives in .exit.text. For drivers registered via
|
| 486 | * module_platform_driver_probe() this is ok because they cannot get unbound at
|
| 487 | * runtime. So mark the driver struct with __refdata to prevent modpost
|
| 488 | * triggering a section mismatch warning.
|
| 489 |
|
| 490 | static struct platform_driver sh_rtc_platform_driver __refdata = {
|
| 491 | .driver = {
|
| 492 | .name = DRV_NAME,
|
| 493 | .pm = pm_sleep_ptr(&sh_rtc_pm_ops),
|
| 494 | .of_match_table = sh_rtc_of_match,
|
| 495 | },
|
| 496 | .remove = __exit_p(sh_rtc_remove),
|
| 497 | };
|
| 498 |
|
| 499 | module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe);
|
| 500 |
|
| 501 | MODULE_DESCRIPTION("SuperH on-chip RTC driver");
|
| 502 | MODULE_AUTHOR("Paul Mundt <[email protected]>");
|
| 503 | MODULE_AUTHOR("Jamie Lenehan <[email protected]>");
|
| 504 | MODULE_AUTHOR("Angelo Castello <[email protected]>");
|
| 505 | MODULE_LICENSE("GPL v2");
|
| 506 | MODULE_ALIAS("platform:" DRV_NAME);
|