| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * DaVinci Power Management and Real Time Clock Driver for TI platforms |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2009 Texas Instruments, Inc |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to the Free Software |
|---|
| 20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 21 | 8 | */ |
|---|
| 22 | 9 | #include <linux/kernel.h> |
|---|
| 23 | 10 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 240 | 227 | return ret; |
|---|
| 241 | 228 | } |
|---|
| 242 | 229 | |
|---|
| 243 | | -static int convertfromdays(u16 days, struct rtc_time *tm) |
|---|
| 230 | +static void convertfromdays(u16 days, struct rtc_time *tm) |
|---|
| 244 | 231 | { |
|---|
| 245 | 232 | int tmp_days, year, mon; |
|---|
| 246 | 233 | |
|---|
| .. | .. |
|---|
| 263 | 250 | break; |
|---|
| 264 | 251 | } |
|---|
| 265 | 252 | } |
|---|
| 266 | | - return 0; |
|---|
| 267 | 253 | } |
|---|
| 268 | 254 | |
|---|
| 269 | | -static int convert2days(u16 *days, struct rtc_time *tm) |
|---|
| 255 | +static void convert2days(u16 *days, struct rtc_time *tm) |
|---|
| 270 | 256 | { |
|---|
| 271 | 257 | int i; |
|---|
| 272 | 258 | *days = 0; |
|---|
| 273 | | - |
|---|
| 274 | | - /* epoch == 1900 */ |
|---|
| 275 | | - if (tm->tm_year < 100 || tm->tm_year > 199) |
|---|
| 276 | | - return -EINVAL; |
|---|
| 277 | 259 | |
|---|
| 278 | 260 | for (i = 2000; i < 1900 + tm->tm_year; i++) |
|---|
| 279 | 261 | *days += rtc_year_days(1, 12, i); |
|---|
| 280 | 262 | |
|---|
| 281 | 263 | *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year); |
|---|
| 282 | | - |
|---|
| 283 | | - return 0; |
|---|
| 284 | 264 | } |
|---|
| 285 | 265 | |
|---|
| 286 | 266 | static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm) |
|---|
| .. | .. |
|---|
| 313 | 293 | days <<= 8; |
|---|
| 314 | 294 | days |= day0; |
|---|
| 315 | 295 | |
|---|
| 316 | | - if (convertfromdays(days, tm) < 0) |
|---|
| 317 | | - return -EINVAL; |
|---|
| 296 | + convertfromdays(days, tm); |
|---|
| 318 | 297 | |
|---|
| 319 | 298 | return 0; |
|---|
| 320 | 299 | } |
|---|
| .. | .. |
|---|
| 326 | 305 | u8 rtc_cctrl; |
|---|
| 327 | 306 | unsigned long flags; |
|---|
| 328 | 307 | |
|---|
| 329 | | - if (convert2days(&days, tm) < 0) |
|---|
| 330 | | - return -EINVAL; |
|---|
| 308 | + convert2days(&days, tm); |
|---|
| 331 | 309 | |
|---|
| 332 | 310 | spin_lock_irqsave(&davinci_rtc_lock, flags); |
|---|
| 333 | 311 | |
|---|
| .. | .. |
|---|
| 409 | 387 | days <<= 8; |
|---|
| 410 | 388 | days |= day0; |
|---|
| 411 | 389 | |
|---|
| 412 | | - if (convertfromdays(days, &alm->time) < 0) |
|---|
| 413 | | - return -EINVAL; |
|---|
| 390 | + convertfromdays(days, &alm->time); |
|---|
| 414 | 391 | |
|---|
| 415 | 392 | alm->pending = !!(rtcss_read(davinci_rtc, |
|---|
| 416 | 393 | PRTCSS_RTC_CCTRL) & |
|---|
| .. | .. |
|---|
| 426 | 403 | unsigned long flags; |
|---|
| 427 | 404 | u16 days; |
|---|
| 428 | 405 | |
|---|
| 429 | | - if (alm->time.tm_mday <= 0 && alm->time.tm_mon < 0 |
|---|
| 430 | | - && alm->time.tm_year < 0) { |
|---|
| 431 | | - struct rtc_time tm; |
|---|
| 432 | | - unsigned long now, then; |
|---|
| 433 | | - |
|---|
| 434 | | - davinci_rtc_read_time(dev, &tm); |
|---|
| 435 | | - rtc_tm_to_time(&tm, &now); |
|---|
| 436 | | - |
|---|
| 437 | | - alm->time.tm_mday = tm.tm_mday; |
|---|
| 438 | | - alm->time.tm_mon = tm.tm_mon; |
|---|
| 439 | | - alm->time.tm_year = tm.tm_year; |
|---|
| 440 | | - rtc_tm_to_time(&alm->time, &then); |
|---|
| 441 | | - |
|---|
| 442 | | - if (then < now) { |
|---|
| 443 | | - rtc_time_to_tm(now + 24 * 60 * 60, &tm); |
|---|
| 444 | | - alm->time.tm_mday = tm.tm_mday; |
|---|
| 445 | | - alm->time.tm_mon = tm.tm_mon; |
|---|
| 446 | | - alm->time.tm_year = tm.tm_year; |
|---|
| 447 | | - } |
|---|
| 448 | | - } |
|---|
| 449 | | - |
|---|
| 450 | | - if (convert2days(&days, &alm->time) < 0) |
|---|
| 451 | | - return -EINVAL; |
|---|
| 406 | + convert2days(&days, &alm->time); |
|---|
| 452 | 407 | |
|---|
| 453 | 408 | spin_lock_irqsave(&davinci_rtc_lock, flags); |
|---|
| 454 | 409 | |
|---|
| .. | .. |
|---|
| 482 | 437 | { |
|---|
| 483 | 438 | struct device *dev = &pdev->dev; |
|---|
| 484 | 439 | struct davinci_rtc *davinci_rtc; |
|---|
| 485 | | - struct resource *res; |
|---|
| 486 | 440 | int ret = 0; |
|---|
| 487 | 441 | |
|---|
| 488 | 442 | davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 490 | 444 | return -ENOMEM; |
|---|
| 491 | 445 | |
|---|
| 492 | 446 | davinci_rtc->irq = platform_get_irq(pdev, 0); |
|---|
| 493 | | - if (davinci_rtc->irq < 0) { |
|---|
| 494 | | - dev_err(dev, "no RTC irq\n"); |
|---|
| 447 | + if (davinci_rtc->irq < 0) |
|---|
| 495 | 448 | return davinci_rtc->irq; |
|---|
| 496 | | - } |
|---|
| 497 | 449 | |
|---|
| 498 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 499 | | - davinci_rtc->base = devm_ioremap_resource(dev, res); |
|---|
| 450 | + davinci_rtc->base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 500 | 451 | if (IS_ERR(davinci_rtc->base)) |
|---|
| 501 | 452 | return PTR_ERR(davinci_rtc->base); |
|---|
| 502 | 453 | |
|---|
| 503 | 454 | platform_set_drvdata(pdev, davinci_rtc); |
|---|
| 504 | 455 | |
|---|
| 505 | | - davinci_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, |
|---|
| 506 | | - &davinci_rtc_ops, THIS_MODULE); |
|---|
| 507 | | - if (IS_ERR(davinci_rtc->rtc)) { |
|---|
| 508 | | - dev_err(dev, "unable to register RTC device, err %d\n", |
|---|
| 509 | | - ret); |
|---|
| 456 | + davinci_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); |
|---|
| 457 | + if (IS_ERR(davinci_rtc->rtc)) |
|---|
| 510 | 458 | return PTR_ERR(davinci_rtc->rtc); |
|---|
| 511 | | - } |
|---|
| 459 | + |
|---|
| 460 | + davinci_rtc->rtc->ops = &davinci_rtc_ops; |
|---|
| 461 | + davinci_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; |
|---|
| 462 | + davinci_rtc->rtc->range_max = RTC_TIMESTAMP_BEGIN_2000 + (1 << 16) * 86400ULL - 1; |
|---|
| 512 | 463 | |
|---|
| 513 | 464 | rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); |
|---|
| 514 | 465 | rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); |
|---|
| .. | .. |
|---|
| 533 | 484 | |
|---|
| 534 | 485 | device_init_wakeup(&pdev->dev, 0); |
|---|
| 535 | 486 | |
|---|
| 536 | | - return 0; |
|---|
| 487 | + return rtc_register_device(davinci_rtc->rtc); |
|---|
| 537 | 488 | } |
|---|
| 538 | 489 | |
|---|
| 539 | 490 | static int __exit davinci_rtc_remove(struct platform_device *pdev) |
|---|