diff options
Diffstat (limited to 'drivers/rtc')
32 files changed, 1890 insertions, 649 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 123092d8a984..cced4d108319 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -35,8 +35,8 @@ config RTC_HCTOSYS_DEVICE | |||
| 35 | default "rtc0" | 35 | default "rtc0" |
| 36 | help | 36 | help |
| 37 | The RTC device that will be used to (re)initialize the system | 37 | The RTC device that will be used to (re)initialize the system |
| 38 | clock, usually rtc0. Initialization is done when the system | 38 | clock, usually rtc0. Initialization is done when the system |
| 39 | starts up, and when it resumes from a low power state. This | 39 | starts up, and when it resumes from a low power state. This |
| 40 | device should record time in UTC, since the kernel won't do | 40 | device should record time in UTC, since the kernel won't do |
| 41 | timezone correction. | 41 | timezone correction. |
| 42 | 42 | ||
| @@ -44,7 +44,7 @@ config RTC_HCTOSYS_DEVICE | |||
| 44 | functions run, so it must usually be statically linked. | 44 | functions run, so it must usually be statically linked. |
| 45 | 45 | ||
| 46 | This clock should be battery-backed, so that it reads the correct | 46 | This clock should be battery-backed, so that it reads the correct |
| 47 | time when the system boots from a power-off state. Otherwise, your | 47 | time when the system boots from a power-off state. Otherwise, your |
| 48 | system will need an external clock source (like an NTP server). | 48 | system will need an external clock source (like an NTP server). |
| 49 | 49 | ||
| 50 | If the clock you specify here is not battery backed, it may still | 50 | If the clock you specify here is not battery backed, it may still |
| @@ -69,8 +69,7 @@ config RTC_INTF_SYSFS | |||
| 69 | Say yes here if you want to use your RTCs using sysfs interfaces, | 69 | Say yes here if you want to use your RTCs using sysfs interfaces, |
| 70 | /sys/class/rtc/rtc0 through /sys/.../rtcN. | 70 | /sys/class/rtc/rtc0 through /sys/.../rtcN. |
| 71 | 71 | ||
| 72 | This driver can also be built as a module. If so, the module | 72 | If unsure, say Y. |
| 73 | will be called rtc-sysfs. | ||
| 74 | 73 | ||
| 75 | config RTC_INTF_PROC | 74 | config RTC_INTF_PROC |
| 76 | boolean "/proc/driver/rtc (procfs for rtc0)" | 75 | boolean "/proc/driver/rtc (procfs for rtc0)" |
| @@ -78,11 +77,10 @@ config RTC_INTF_PROC | |||
| 78 | default RTC_CLASS | 77 | default RTC_CLASS |
| 79 | help | 78 | help |
| 80 | Say yes here if you want to use your first RTC through the proc | 79 | Say yes here if you want to use your first RTC through the proc |
| 81 | interface, /proc/driver/rtc. Other RTCs will not be available | 80 | interface, /proc/driver/rtc. Other RTCs will not be available |
| 82 | through that API. | 81 | through that API. |
| 83 | 82 | ||
| 84 | This driver can also be built as a module. If so, the module | 83 | If unsure, say Y. |
| 85 | will be called rtc-proc. | ||
| 86 | 84 | ||
| 87 | config RTC_INTF_DEV | 85 | config RTC_INTF_DEV |
| 88 | boolean "/dev/rtcN (character devices)" | 86 | boolean "/dev/rtcN (character devices)" |
| @@ -90,21 +88,27 @@ config RTC_INTF_DEV | |||
| 90 | help | 88 | help |
| 91 | Say yes here if you want to use your RTCs using the /dev | 89 | Say yes here if you want to use your RTCs using the /dev |
| 92 | interfaces, which "udev" sets up as /dev/rtc0 through | 90 | interfaces, which "udev" sets up as /dev/rtc0 through |
| 93 | /dev/rtcN. You may want to set up a symbolic link so one | 91 | /dev/rtcN. |
| 94 | of these can be accessed as /dev/rtc, which is a name | ||
| 95 | expected by "hwclock" and some other programs. | ||
| 96 | 92 | ||
| 97 | This driver can also be built as a module. If so, the module | 93 | You may want to set up a symbolic link so one of these |
| 98 | will be called rtc-dev. | 94 | can be accessed as /dev/rtc, which is a name |
| 95 | expected by "hwclock" and some other programs. Recent | ||
| 96 | versions of "udev" are known to set up the symlink for you. | ||
| 97 | |||
| 98 | If unsure, say Y. | ||
| 99 | 99 | ||
| 100 | config RTC_INTF_DEV_UIE_EMUL | 100 | config RTC_INTF_DEV_UIE_EMUL |
| 101 | bool "RTC UIE emulation on dev interface" | 101 | bool "RTC UIE emulation on dev interface" |
| 102 | depends on RTC_INTF_DEV | 102 | depends on RTC_INTF_DEV |
| 103 | help | 103 | help |
| 104 | Provides an emulation for RTC_UIE if the underlying rtc chip | 104 | Provides an emulation for RTC_UIE if the underlying rtc chip |
| 105 | driver does not expose RTC_UIE ioctls. Those requests generate | 105 | driver does not expose RTC_UIE ioctls. Those requests generate |
| 106 | once-per-second update interrupts, used for synchronization. | 106 | once-per-second update interrupts, used for synchronization. |
| 107 | 107 | ||
| 108 | The emulation code will read the time from the hardware | ||
| 109 | clock several times per second, please enable this option | ||
| 110 | only if you know that you really need it. | ||
| 111 | |||
| 108 | config RTC_DRV_TEST | 112 | config RTC_DRV_TEST |
| 109 | tristate "Test driver/device" | 113 | tristate "Test driver/device" |
| 110 | help | 114 | help |
| @@ -128,14 +132,14 @@ config RTC_DRV_DS1307 | |||
| 128 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" | 132 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" |
| 129 | help | 133 | help |
| 130 | If you say yes here you get support for various compatible RTC | 134 | If you say yes here you get support for various compatible RTC |
| 131 | chips (often with battery backup) connected with I2C. This driver | 135 | chips (often with battery backup) connected with I2C. This driver |
| 132 | should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, | 136 | should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, |
| 133 | and probably other chips. In some cases the RTC must already | 137 | and probably other chips. In some cases the RTC must already |
| 134 | have been initialized (by manufacturing or a bootloader). | 138 | have been initialized (by manufacturing or a bootloader). |
| 135 | 139 | ||
| 136 | The first seven registers on these chips hold an RTC, and other | 140 | The first seven registers on these chips hold an RTC, and other |
| 137 | registers may add features such as NVRAM, a trickle charger for | 141 | registers may add features such as NVRAM, a trickle charger for |
| 138 | the RTC/NVRAM backup power, and alarms. NVRAM is visible in | 142 | the RTC/NVRAM backup power, and alarms. NVRAM is visible in |
| 139 | sysfs, but other chip features may not be available. | 143 | sysfs, but other chip features may not be available. |
| 140 | 144 | ||
| 141 | This driver can also be built as a module. If so, the module | 145 | This driver can also be built as a module. If so, the module |
| @@ -146,10 +150,10 @@ config RTC_DRV_DS1374 | |||
| 146 | depends on RTC_CLASS && I2C | 150 | depends on RTC_CLASS && I2C |
| 147 | help | 151 | help |
| 148 | If you say yes here you get support for Dallas Semiconductor | 152 | If you say yes here you get support for Dallas Semiconductor |
| 149 | DS1374 real-time clock chips. If an interrupt is associated | 153 | DS1374 real-time clock chips. If an interrupt is associated |
| 150 | with the device, the alarm functionality is supported. | 154 | with the device, the alarm functionality is supported. |
| 151 | 155 | ||
| 152 | This driver can also be built as a module. If so, the module | 156 | This driver can also be built as a module. If so, the module |
| 153 | will be called rtc-ds1374. | 157 | will be called rtc-ds1374. |
| 154 | 158 | ||
| 155 | config RTC_DRV_DS1672 | 159 | config RTC_DRV_DS1672 |
| @@ -243,7 +247,7 @@ config RTC_DRV_TWL92330 | |||
| 243 | help | 247 | help |
| 244 | If you say yes here you get support for the RTC on the | 248 | If you say yes here you get support for the RTC on the |
| 245 | TWL92330 "Menelaus" power management chip, used with OMAP2 | 249 | TWL92330 "Menelaus" power management chip, used with OMAP2 |
| 246 | platforms. The support is integrated with the rest of | 250 | platforms. The support is integrated with the rest of |
| 247 | the Menelaus driver; it's not separate module. | 251 | the Menelaus driver; it's not separate module. |
| 248 | 252 | ||
| 249 | config RTC_DRV_TWL4030 | 253 | config RTC_DRV_TWL4030 |
| @@ -304,7 +308,7 @@ config RTC_DRV_DS1305 | |||
| 304 | tristate "Dallas/Maxim DS1305/DS1306" | 308 | tristate "Dallas/Maxim DS1305/DS1306" |
| 305 | help | 309 | help |
| 306 | Select this driver to get support for the Dallas/Maxim DS1305 | 310 | Select this driver to get support for the Dallas/Maxim DS1305 |
| 307 | and DS1306 real time clock chips. These support a trickle | 311 | and DS1306 real time clock chips. These support a trickle |
| 308 | charger, alarms, and NVRAM in addition to the clock. | 312 | charger, alarms, and NVRAM in addition to the clock. |
| 309 | 313 | ||
| 310 | This driver can also be built as a module. If so, the module | 314 | This driver can also be built as a module. If so, the module |
| @@ -313,7 +317,8 @@ config RTC_DRV_DS1305 | |||
| 313 | config RTC_DRV_DS1390 | 317 | config RTC_DRV_DS1390 |
| 314 | tristate "Dallas/Maxim DS1390/93/94" | 318 | tristate "Dallas/Maxim DS1390/93/94" |
| 315 | help | 319 | help |
| 316 | If you say yes here you get support for the DS1390/93/94 chips. | 320 | If you say yes here you get support for the |
| 321 | Dallas/Maxim DS1390/93/94 chips. | ||
| 317 | 322 | ||
| 318 | This driver only supports the RTC feature, and not other chip | 323 | This driver only supports the RTC feature, and not other chip |
| 319 | features such as alarms and trickle charging. | 324 | features such as alarms and trickle charging. |
| @@ -377,7 +382,7 @@ config RTC_DRV_CMOS | |||
| 377 | or LPC bus chips, and so on. | 382 | or LPC bus chips, and so on. |
| 378 | 383 | ||
| 379 | Your system will need to define the platform device used by | 384 | Your system will need to define the platform device used by |
| 380 | this driver, otherwise it won't be accessible. This means | 385 | this driver, otherwise it won't be accessible. This means |
| 381 | you can safely enable this driver if you don't know whether | 386 | you can safely enable this driver if you don't know whether |
| 382 | or not your board has this kind of hardware. | 387 | or not your board has this kind of hardware. |
| 383 | 388 | ||
| @@ -497,6 +502,13 @@ config RTC_DRV_WM8350 | |||
| 497 | This driver can also be built as a module. If so, the module | 502 | This driver can also be built as a module. If so, the module |
| 498 | will be called "rtc-wm8350". | 503 | will be called "rtc-wm8350". |
| 499 | 504 | ||
| 505 | config RTC_DRV_PCF50633 | ||
| 506 | depends on MFD_PCF50633 | ||
| 507 | tristate "NXP PCF50633 RTC" | ||
| 508 | help | ||
| 509 | If you say yes here you get support for the RTC subsystem of the | ||
| 510 | NXP PCF50633 used in embedded systems. | ||
| 511 | |||
| 500 | comment "on-CPU RTC drivers" | 512 | comment "on-CPU RTC drivers" |
| 501 | 513 | ||
| 502 | config RTC_DRV_OMAP | 514 | config RTC_DRV_OMAP |
| @@ -594,7 +606,7 @@ config RTC_DRV_AT91RM9200 | |||
| 594 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL | 606 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL |
| 595 | help | 607 | help |
| 596 | Driver for the internal RTC (Realtime Clock) module found on | 608 | Driver for the internal RTC (Realtime Clock) module found on |
| 597 | Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips | 609 | Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips |
| 598 | this is powered by the backup power supply. | 610 | this is powered by the backup power supply. |
| 599 | 611 | ||
| 600 | config RTC_DRV_AT91SAM9 | 612 | config RTC_DRV_AT91SAM9 |
| @@ -616,8 +628,8 @@ config RTC_DRV_AT91SAM9_RTT | |||
| 616 | prompt "RTT module Number" if ARCH_AT91SAM9263 | 628 | prompt "RTT module Number" if ARCH_AT91SAM9263 |
| 617 | depends on RTC_DRV_AT91SAM9 | 629 | depends on RTC_DRV_AT91SAM9 |
| 618 | help | 630 | help |
| 619 | More than one RTT module is available. You can choose which | 631 | More than one RTT module is available. You can choose which |
| 620 | one will be used as an RTC. The default of zero is normally | 632 | one will be used as an RTC. The default of zero is normally |
| 621 | OK to use, though some systems use that for non-RTC purposes. | 633 | OK to use, though some systems use that for non-RTC purposes. |
| 622 | 634 | ||
| 623 | config RTC_DRV_AT91SAM9_GPBR | 635 | config RTC_DRV_AT91SAM9_GPBR |
| @@ -629,10 +641,20 @@ config RTC_DRV_AT91SAM9_GPBR | |||
| 629 | depends on RTC_DRV_AT91SAM9 | 641 | depends on RTC_DRV_AT91SAM9 |
| 630 | help | 642 | help |
| 631 | The RTC driver needs to use one of the General Purpose Backup | 643 | The RTC driver needs to use one of the General Purpose Backup |
| 632 | Registers (GPBRs) as well as the RTT. You can choose which one | 644 | Registers (GPBRs) as well as the RTT. You can choose which one |
| 633 | will be used. The default of zero is normally OK to use, but | 645 | will be used. The default of zero is normally OK to use, but |
| 634 | on some systems other software needs to use that register. | 646 | on some systems other software needs to use that register. |
| 635 | 647 | ||
| 648 | config RTC_DRV_AU1XXX | ||
| 649 | tristate "Au1xxx Counter0 RTC support" | ||
| 650 | depends on SOC_AU1X00 | ||
| 651 | help | ||
| 652 | This is a driver for the Au1xxx on-chip Counter0 (Time-Of-Year | ||
| 653 | counter) to be used as a RTC. | ||
| 654 | |||
| 655 | This driver can also be built as a module. If so, the module | ||
| 656 | will be called rtc-au1xxx. | ||
| 657 | |||
| 636 | config RTC_DRV_BFIN | 658 | config RTC_DRV_BFIN |
| 637 | tristate "Blackfin On-Chip RTC" | 659 | tristate "Blackfin On-Chip RTC" |
| 638 | depends on BLACKFIN && !BF561 | 660 | depends on BLACKFIN && !BF561 |
| @@ -665,6 +687,17 @@ config RTC_DRV_PPC | |||
| 665 | the RTC. This exposes that functionality through the generic RTC | 687 | the RTC. This exposes that functionality through the generic RTC |
| 666 | class. | 688 | class. |
| 667 | 689 | ||
| 690 | config RTC_DRV_PXA | ||
| 691 | tristate "PXA27x/PXA3xx" | ||
| 692 | depends on ARCH_PXA | ||
| 693 | help | ||
| 694 | If you say Y here you will get access to the real time clock | ||
| 695 | built into your PXA27x or PXA3xx CPU. | ||
| 696 | |||
| 697 | This RTC driver uses PXA RTC registers available since pxa27x | ||
| 698 | series (RDxR, RYxR) instead of legacy RCNR, RTAR. | ||
| 699 | |||
| 700 | |||
| 668 | config RTC_DRV_SUN4V | 701 | config RTC_DRV_SUN4V |
| 669 | bool "SUN4V Hypervisor RTC" | 702 | bool "SUN4V Hypervisor RTC" |
| 670 | depends on SPARC64 | 703 | depends on SPARC64 |
| @@ -679,4 +712,22 @@ config RTC_DRV_STARFIRE | |||
| 679 | If you say Y here you will get support for the RTC found on | 712 | If you say Y here you will get support for the RTC found on |
| 680 | Starfire systems. | 713 | Starfire systems. |
| 681 | 714 | ||
| 715 | config RTC_DRV_TX4939 | ||
| 716 | tristate "TX4939 SoC" | ||
| 717 | depends on SOC_TX4939 | ||
| 718 | help | ||
| 719 | Driver for the internal RTC (Realtime Clock) module found on | ||
| 720 | Toshiba TX4939 SoC. | ||
| 721 | |||
| 722 | config RTC_DRV_MV | ||
| 723 | tristate "Marvell SoC RTC" | ||
| 724 | depends on ARCH_KIRKWOOD | ||
| 725 | help | ||
| 726 | If you say yes here you will get support for the in-chip RTC | ||
| 727 | that can be found in some of Marvell's SoC devices, such as | ||
| 728 | the Kirkwood 88F6281 and 88F6192. | ||
| 729 | |||
| 730 | This driver can also be built as a module. If so, the module | ||
| 731 | will be called rtc-mv. | ||
| 732 | |||
| 682 | endif # RTC_CLASS | 733 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6e79c912bf9e..6e28021abb9d 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -20,6 +20,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | |||
| 20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
| 21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
| 22 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | 22 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o |
| 23 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o | ||
| 23 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | 24 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o |
| 24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 25 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
| 25 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 26 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
| @@ -47,6 +48,7 @@ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o | |||
| 47 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o | 48 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o |
| 48 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 49 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
| 49 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 50 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
| 51 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | ||
| 50 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 52 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o |
| 51 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 53 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
| 52 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 54 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
| @@ -54,6 +56,7 @@ obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o | |||
| 54 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 56 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
| 55 | obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o | 57 | obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o |
| 56 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | 58 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o |
| 59 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o | ||
| 57 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 60 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
| 58 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 61 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
| 59 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 62 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
| @@ -66,7 +69,9 @@ obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o | |||
| 66 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o | 69 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o |
| 67 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | 70 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o |
| 68 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o | 71 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o |
| 72 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | ||
| 69 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 73 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
| 70 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 74 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
| 71 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o | 75 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o |
| 72 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o | 76 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
| 77 | obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o | ||
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 4dfdf019fccc..be5a6b73e601 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
| @@ -48,9 +48,7 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) | |||
| 48 | struct rtc_time tm; | 48 | struct rtc_time tm; |
| 49 | struct timespec ts = current_kernel_time(); | 49 | struct timespec ts = current_kernel_time(); |
| 50 | 50 | ||
| 51 | if (strncmp(rtc->dev.bus_id, | 51 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
| 52 | CONFIG_RTC_HCTOSYS_DEVICE, | ||
| 53 | BUS_ID_SIZE) != 0) | ||
| 54 | return 0; | 52 | return 0; |
| 55 | 53 | ||
| 56 | rtc_read_time(rtc, &tm); | 54 | rtc_read_time(rtc, &tm); |
| @@ -71,20 +69,18 @@ static int rtc_resume(struct device *dev) | |||
| 71 | time_t newtime; | 69 | time_t newtime; |
| 72 | struct timespec time; | 70 | struct timespec time; |
| 73 | 71 | ||
| 74 | if (strncmp(rtc->dev.bus_id, | 72 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
| 75 | CONFIG_RTC_HCTOSYS_DEVICE, | ||
| 76 | BUS_ID_SIZE) != 0) | ||
| 77 | return 0; | 73 | return 0; |
| 78 | 74 | ||
| 79 | rtc_read_time(rtc, &tm); | 75 | rtc_read_time(rtc, &tm); |
| 80 | if (rtc_valid_tm(&tm) != 0) { | 76 | if (rtc_valid_tm(&tm) != 0) { |
| 81 | pr_debug("%s: bogus resume time\n", rtc->dev.bus_id); | 77 | pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); |
| 82 | return 0; | 78 | return 0; |
| 83 | } | 79 | } |
| 84 | rtc_tm_to_time(&tm, &newtime); | 80 | rtc_tm_to_time(&tm, &newtime); |
| 85 | if (newtime <= oldtime) { | 81 | if (newtime <= oldtime) { |
| 86 | if (newtime < oldtime) | 82 | if (newtime < oldtime) |
| 87 | pr_debug("%s: time travel!\n", rtc->dev.bus_id); | 83 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); |
| 88 | return 0; | 84 | return 0; |
| 89 | } | 85 | } |
| 90 | 86 | ||
| @@ -156,7 +152,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
| 156 | init_waitqueue_head(&rtc->irq_queue); | 152 | init_waitqueue_head(&rtc->irq_queue); |
| 157 | 153 | ||
| 158 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); | 154 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); |
| 159 | snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id); | 155 | dev_set_name(&rtc->dev, "rtc%d", id); |
| 160 | 156 | ||
| 161 | rtc_dev_prepare(rtc); | 157 | rtc_dev_prepare(rtc); |
| 162 | 158 | ||
| @@ -169,7 +165,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
| 169 | rtc_proc_add_device(rtc); | 165 | rtc_proc_add_device(rtc); |
| 170 | 166 | ||
| 171 | dev_info(dev, "rtc core: registered %s as %s\n", | 167 | dev_info(dev, "rtc core: registered %s as %s\n", |
| 172 | rtc->name, rtc->dev.bus_id); | 168 | rtc->name, dev_name(&rtc->dev)); |
| 173 | 169 | ||
| 174 | return rtc; | 170 | return rtc; |
| 175 | 171 | ||
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index a04c1b6b1575..4348c4b0d453 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
| @@ -50,10 +50,15 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) | |||
| 50 | 50 | ||
| 51 | if (!rtc->ops) | 51 | if (!rtc->ops) |
| 52 | err = -ENODEV; | 52 | err = -ENODEV; |
| 53 | else if (!rtc->ops->set_time) | 53 | else if (rtc->ops->set_time) |
| 54 | err = -EINVAL; | ||
| 55 | else | ||
| 56 | err = rtc->ops->set_time(rtc->dev.parent, tm); | 54 | err = rtc->ops->set_time(rtc->dev.parent, tm); |
| 55 | else if (rtc->ops->set_mmss) { | ||
| 56 | unsigned long secs; | ||
| 57 | err = rtc_tm_to_time(tm, &secs); | ||
| 58 | if (err == 0) | ||
| 59 | err = rtc->ops->set_mmss(rtc->dev.parent, secs); | ||
| 60 | } else | ||
| 61 | err = -EINVAL; | ||
| 57 | 62 | ||
| 58 | mutex_unlock(&rtc->ops_lock); | 63 | mutex_unlock(&rtc->ops_lock); |
| 59 | return err; | 64 | return err; |
| @@ -307,6 +312,60 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
| 307 | } | 312 | } |
| 308 | EXPORT_SYMBOL_GPL(rtc_set_alarm); | 313 | EXPORT_SYMBOL_GPL(rtc_set_alarm); |
| 309 | 314 | ||
| 315 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) | ||
| 316 | { | ||
| 317 | int err = mutex_lock_interruptible(&rtc->ops_lock); | ||
| 318 | if (err) | ||
| 319 | return err; | ||
| 320 | |||
| 321 | if (!rtc->ops) | ||
| 322 | err = -ENODEV; | ||
| 323 | else if (!rtc->ops->alarm_irq_enable) | ||
| 324 | err = -EINVAL; | ||
| 325 | else | ||
| 326 | err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled); | ||
| 327 | |||
| 328 | mutex_unlock(&rtc->ops_lock); | ||
| 329 | return err; | ||
| 330 | } | ||
| 331 | EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable); | ||
| 332 | |||
| 333 | int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) | ||
| 334 | { | ||
| 335 | int err = mutex_lock_interruptible(&rtc->ops_lock); | ||
| 336 | if (err) | ||
| 337 | return err; | ||
| 338 | |||
| 339 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | ||
| 340 | if (enabled == 0 && rtc->uie_irq_active) { | ||
| 341 | mutex_unlock(&rtc->ops_lock); | ||
| 342 | return rtc_dev_update_irq_enable_emul(rtc, enabled); | ||
| 343 | } | ||
| 344 | #endif | ||
| 345 | |||
| 346 | if (!rtc->ops) | ||
| 347 | err = -ENODEV; | ||
| 348 | else if (!rtc->ops->update_irq_enable) | ||
| 349 | err = -EINVAL; | ||
| 350 | else | ||
| 351 | err = rtc->ops->update_irq_enable(rtc->dev.parent, enabled); | ||
| 352 | |||
| 353 | mutex_unlock(&rtc->ops_lock); | ||
| 354 | |||
| 355 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | ||
| 356 | /* | ||
| 357 | * Enable emulation if the driver did not provide | ||
| 358 | * the update_irq_enable function pointer or if returned | ||
| 359 | * -EINVAL to signal that it has been configured without | ||
| 360 | * interrupts or that are not available at the moment. | ||
| 361 | */ | ||
| 362 | if (err == -EINVAL) | ||
| 363 | err = rtc_dev_update_irq_enable_emul(rtc, enabled); | ||
| 364 | #endif | ||
| 365 | return err; | ||
| 366 | } | ||
| 367 | EXPORT_SYMBOL_GPL(rtc_update_irq_enable); | ||
| 368 | |||
| 310 | /** | 369 | /** |
| 311 | * rtc_update_irq - report RTC periodic, alarm, and/or update irqs | 370 | * rtc_update_irq - report RTC periodic, alarm, and/or update irqs |
| 312 | * @rtc: the rtc device | 371 | * @rtc: the rtc device |
| @@ -335,7 +394,7 @@ static int __rtc_match(struct device *dev, void *data) | |||
| 335 | { | 394 | { |
| 336 | char *name = (char *)data; | 395 | char *name = (char *)data; |
| 337 | 396 | ||
| 338 | if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) | 397 | if (strcmp(dev_name(dev), name) == 0) |
| 339 | return 1; | 398 | return 1; |
| 340 | return 0; | 399 | return 0; |
| 341 | } | 400 | } |
| @@ -450,9 +509,6 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) | |||
| 450 | if (rtc->ops->irq_set_freq == NULL) | 509 | if (rtc->ops->irq_set_freq == NULL) |
| 451 | return -ENXIO; | 510 | return -ENXIO; |
| 452 | 511 | ||
| 453 | if (!is_power_of_2(freq)) | ||
| 454 | return -EINVAL; | ||
| 455 | |||
| 456 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 512 | spin_lock_irqsave(&rtc->irq_task_lock, flags); |
| 457 | if (rtc->irq_task != NULL && task == NULL) | 513 | if (rtc->irq_task != NULL && task == NULL) |
| 458 | err = -EBUSY; | 514 | err = -EBUSY; |
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 90b9a6503e15..e1ec33e40e38 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c | |||
| @@ -205,7 +205,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev) | |||
| 205 | { | 205 | { |
| 206 | struct resource *regs; | 206 | struct resource *regs; |
| 207 | struct rtc_at32ap700x *rtc; | 207 | struct rtc_at32ap700x *rtc; |
| 208 | int irq = -1; | 208 | int irq; |
| 209 | int ret; | 209 | int ret; |
| 210 | 210 | ||
| 211 | rtc = kzalloc(sizeof(struct rtc_at32ap700x), GFP_KERNEL); | 211 | rtc = kzalloc(sizeof(struct rtc_at32ap700x), GFP_KERNEL); |
| @@ -222,7 +222,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev) | |||
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | irq = platform_get_irq(pdev, 0); | 224 | irq = platform_get_irq(pdev, 0); |
| 225 | if (irq < 0) { | 225 | if (irq <= 0) { |
| 226 | dev_dbg(&pdev->dev, "could not get irq\n"); | 226 | dev_dbg(&pdev->dev, "could not get irq\n"); |
| 227 | ret = -ENXIO; | 227 | ret = -ENXIO; |
| 228 | goto out; | 228 | goto out; |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 2133f37906f2..d5e4e637ddec 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include <mach/board.h> | 22 | #include <mach/board.h> |
| 23 | #include <mach/at91_rtt.h> | 23 | #include <mach/at91_rtt.h> |
| 24 | #include <mach/cpu.h> | ||
| 24 | 25 | ||
| 25 | 26 | ||
| 26 | /* | 27 | /* |
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c new file mode 100644 index 000000000000..8906a688e6a6 --- /dev/null +++ b/drivers/rtc/rtc-au1xxx.c | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | /* | ||
| 2 | * Au1xxx counter0 (aka Time-Of-Year counter) RTC interface driver. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
| 5 | * | ||
| 6 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 7 | * License. See the file "COPYING" in the main directory of this archive | ||
| 8 | * for more details. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* All current Au1xxx SoCs have 2 counters fed by an external 32.768 kHz | ||
| 12 | * crystal. Counter 0, which keeps counting during sleep/powerdown, is | ||
| 13 | * used to count seconds since the beginning of the unix epoch. | ||
| 14 | * | ||
| 15 | * The counters must be configured and enabled by bootloader/board code; | ||
| 16 | * no checks as to whether they really get a proper 32.768kHz clock are | ||
| 17 | * made as this would take far too long. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/rtc.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/platform_device.h> | ||
| 25 | #include <linux/io.h> | ||
| 26 | #include <asm/mach-au1x00/au1000.h> | ||
| 27 | |||
| 28 | /* 32kHz clock enabled and detected */ | ||
| 29 | #define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) | ||
| 30 | |||
| 31 | static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 32 | { | ||
| 33 | unsigned long t; | ||
| 34 | |||
| 35 | t = au_readl(SYS_TOYREAD); | ||
| 36 | |||
| 37 | rtc_time_to_tm(t, tm); | ||
| 38 | |||
| 39 | return rtc_valid_tm(tm); | ||
| 40 | } | ||
| 41 | |||
| 42 | static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 43 | { | ||
| 44 | unsigned long t; | ||
| 45 | |||
| 46 | rtc_tm_to_time(tm, &t); | ||
| 47 | |||
| 48 | au_writel(t, SYS_TOYWRITE); | ||
| 49 | au_sync(); | ||
| 50 | |||
| 51 | /* wait for the pending register write to succeed. This can | ||
| 52 | * take up to 6 seconds... | ||
| 53 | */ | ||
| 54 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | ||
| 55 | msleep(1); | ||
| 56 | |||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | static struct rtc_class_ops au1xtoy_rtc_ops = { | ||
| 61 | .read_time = au1xtoy_rtc_read_time, | ||
| 62 | .set_time = au1xtoy_rtc_set_time, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static int __devinit au1xtoy_rtc_probe(struct platform_device *pdev) | ||
| 66 | { | ||
| 67 | struct rtc_device *rtcdev; | ||
| 68 | unsigned long t; | ||
| 69 | int ret; | ||
| 70 | |||
| 71 | t = au_readl(SYS_COUNTER_CNTRL); | ||
| 72 | if (!(t & CNTR_OK)) { | ||
| 73 | dev_err(&pdev->dev, "counters not working; aborting.\n"); | ||
| 74 | ret = -ENODEV; | ||
| 75 | goto out_err; | ||
| 76 | } | ||
| 77 | |||
| 78 | ret = -ETIMEDOUT; | ||
| 79 | |||
| 80 | /* set counter0 tickrate to 1Hz if necessary */ | ||
| 81 | if (au_readl(SYS_TOYTRIM) != 32767) { | ||
| 82 | /* wait until hardware gives access to TRIM register */ | ||
| 83 | t = 0x00100000; | ||
| 84 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && t--) | ||
| 85 | msleep(1); | ||
| 86 | |||
| 87 | if (!t) { | ||
| 88 | /* timed out waiting for register access; assume | ||
| 89 | * counters are unusable. | ||
| 90 | */ | ||
| 91 | dev_err(&pdev->dev, "timeout waiting for access\n"); | ||
| 92 | goto out_err; | ||
| 93 | } | ||
| 94 | |||
| 95 | /* set 1Hz TOY tick rate */ | ||
| 96 | au_writel(32767, SYS_TOYTRIM); | ||
| 97 | au_sync(); | ||
| 98 | } | ||
| 99 | |||
| 100 | /* wait until the hardware allows writes to the counter reg */ | ||
| 101 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | ||
| 102 | msleep(1); | ||
| 103 | |||
| 104 | rtcdev = rtc_device_register("rtc-au1xxx", &pdev->dev, | ||
| 105 | &au1xtoy_rtc_ops, THIS_MODULE); | ||
| 106 | if (IS_ERR(rtcdev)) { | ||
| 107 | ret = PTR_ERR(rtcdev); | ||
| 108 | goto out_err; | ||
| 109 | } | ||
| 110 | |||
| 111 | platform_set_drvdata(pdev, rtcdev); | ||
| 112 | |||
| 113 | return 0; | ||
| 114 | |||
| 115 | out_err: | ||
| 116 | return ret; | ||
| 117 | } | ||
| 118 | |||
| 119 | static int __devexit au1xtoy_rtc_remove(struct platform_device *pdev) | ||
| 120 | { | ||
| 121 | struct rtc_device *rtcdev = platform_get_drvdata(pdev); | ||
| 122 | |||
| 123 | rtc_device_unregister(rtcdev); | ||
| 124 | platform_set_drvdata(pdev, NULL); | ||
| 125 | |||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | static struct platform_driver au1xrtc_driver = { | ||
| 130 | .driver = { | ||
| 131 | .name = "rtc-au1xxx", | ||
| 132 | .owner = THIS_MODULE, | ||
| 133 | }, | ||
| 134 | .remove = __devexit_p(au1xtoy_rtc_remove), | ||
| 135 | }; | ||
| 136 | |||
| 137 | static int __init au1xtoy_rtc_init(void) | ||
| 138 | { | ||
| 139 | return platform_driver_probe(&au1xrtc_driver, au1xtoy_rtc_probe); | ||
| 140 | } | ||
| 141 | |||
| 142 | static void __exit au1xtoy_rtc_exit(void) | ||
| 143 | { | ||
| 144 | platform_driver_unregister(&au1xrtc_driver); | ||
| 145 | } | ||
| 146 | |||
| 147 | module_init(au1xtoy_rtc_init); | ||
| 148 | module_exit(au1xtoy_rtc_exit); | ||
| 149 | |||
| 150 | MODULE_DESCRIPTION("Au1xxx TOY-counter-based RTC driver"); | ||
| 151 | MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>"); | ||
| 152 | MODULE_LICENSE("GPL"); | ||
| 153 | MODULE_ALIAS("platform:rtc-au1xxx"); | ||
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 34439ce3967e..aafd3e6ebb0d 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
| @@ -390,7 +390,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
| 390 | 390 | ||
| 391 | /* Register our RTC with the RTC framework */ | 391 | /* Register our RTC with the RTC framework */ |
| 392 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); | 392 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); |
| 393 | if (unlikely(IS_ERR(rtc))) { | 393 | if (unlikely(IS_ERR(rtc->rtc_dev))) { |
| 394 | ret = PTR_ERR(rtc->rtc_dev); | 394 | ret = PTR_ERR(rtc->rtc_dev); |
| 395 | goto err_irq; | 395 | goto err_irq; |
| 396 | } | 396 | } |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 6cf8e282338f..b6d35f50e404 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
| 36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
| 37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
| 38 | #include <linux/log2.h> | ||
| 38 | 39 | ||
| 39 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 40 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
| 40 | #include <asm-generic/rtc.h> | 41 | #include <asm-generic/rtc.h> |
| @@ -58,7 +59,7 @@ struct cmos_rtc { | |||
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 60 | /* both platform and pnp busses use negative numbers for invalid irqs */ | 61 | /* both platform and pnp busses use negative numbers for invalid irqs */ |
| 61 | #define is_valid_irq(n) ((n) >= 0) | 62 | #define is_valid_irq(n) ((n) > 0) |
| 62 | 63 | ||
| 63 | static const char driver_name[] = "rtc_cmos"; | 64 | static const char driver_name[] = "rtc_cmos"; |
| 64 | 65 | ||
| @@ -384,6 +385,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq) | |||
| 384 | if (!is_valid_irq(cmos->irq)) | 385 | if (!is_valid_irq(cmos->irq)) |
| 385 | return -ENXIO; | 386 | return -ENXIO; |
| 386 | 387 | ||
| 388 | if (!is_power_of_2(freq)) | ||
| 389 | return -EINVAL; | ||
| 387 | /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ | 390 | /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ |
| 388 | f = ffs(freq); | 391 | f = ffs(freq); |
| 389 | if (f-- > 16) | 392 | if (f-- > 16) |
| @@ -729,7 +732,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 729 | 732 | ||
| 730 | cmos_rtc.dev = dev; | 733 | cmos_rtc.dev = dev; |
| 731 | dev_set_drvdata(dev, &cmos_rtc); | 734 | dev_set_drvdata(dev, &cmos_rtc); |
| 732 | rename_region(ports, cmos_rtc.rtc->dev.bus_id); | 735 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); |
| 733 | 736 | ||
| 734 | spin_lock_irq(&rtc_lock); | 737 | spin_lock_irq(&rtc_lock); |
| 735 | 738 | ||
| @@ -777,7 +780,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 777 | rtc_cmos_int_handler = cmos_interrupt; | 780 | rtc_cmos_int_handler = cmos_interrupt; |
| 778 | 781 | ||
| 779 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, | 782 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, |
| 780 | IRQF_DISABLED, cmos_rtc.rtc->dev.bus_id, | 783 | IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev), |
| 781 | cmos_rtc.rtc); | 784 | cmos_rtc.rtc); |
| 782 | if (retval < 0) { | 785 | if (retval < 0) { |
| 783 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); | 786 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); |
| @@ -795,7 +798,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 795 | } | 798 | } |
| 796 | 799 | ||
| 797 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n", | 800 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n", |
| 798 | cmos_rtc.rtc->dev.bus_id, | 801 | dev_name(&cmos_rtc.rtc->dev), |
| 799 | is_valid_irq(rtc_irq) | 802 | is_valid_irq(rtc_irq) |
| 800 | ? (cmos_rtc.mon_alrm | 803 | ? (cmos_rtc.mon_alrm |
| 801 | ? "year" | 804 | ? "year" |
| @@ -885,7 +888,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) | |||
| 885 | } | 888 | } |
| 886 | 889 | ||
| 887 | pr_debug("%s: suspend%s, ctrl %02x\n", | 890 | pr_debug("%s: suspend%s, ctrl %02x\n", |
| 888 | cmos_rtc.rtc->dev.bus_id, | 891 | dev_name(&cmos_rtc.rtc->dev), |
| 889 | (tmp & RTC_AIE) ? ", alarm may wake" : "", | 892 | (tmp & RTC_AIE) ? ", alarm may wake" : "", |
| 890 | tmp); | 893 | tmp); |
| 891 | 894 | ||
| @@ -941,7 +944,7 @@ static int cmos_resume(struct device *dev) | |||
| 941 | } | 944 | } |
| 942 | 945 | ||
| 943 | pr_debug("%s: resume, ctrl %02x\n", | 946 | pr_debug("%s: resume, ctrl %02x\n", |
| 944 | cmos_rtc.rtc->dev.bus_id, | 947 | dev_name(&cmos_rtc.rtc->dev), |
| 945 | tmp); | 948 | tmp); |
| 946 | 949 | ||
| 947 | return 0; | 950 | return 0; |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index ecdea44ae4e5..45152f4952d6 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
| @@ -92,10 +92,10 @@ static void rtc_uie_timer(unsigned long data) | |||
| 92 | spin_unlock_irqrestore(&rtc->irq_lock, flags); | 92 | spin_unlock_irqrestore(&rtc->irq_lock, flags); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static void clear_uie(struct rtc_device *rtc) | 95 | static int clear_uie(struct rtc_device *rtc) |
| 96 | { | 96 | { |
| 97 | spin_lock_irq(&rtc->irq_lock); | 97 | spin_lock_irq(&rtc->irq_lock); |
| 98 | if (rtc->irq_active) { | 98 | if (rtc->uie_irq_active) { |
| 99 | rtc->stop_uie_polling = 1; | 99 | rtc->stop_uie_polling = 1; |
| 100 | if (rtc->uie_timer_active) { | 100 | if (rtc->uie_timer_active) { |
| 101 | spin_unlock_irq(&rtc->irq_lock); | 101 | spin_unlock_irq(&rtc->irq_lock); |
| @@ -108,9 +108,10 @@ static void clear_uie(struct rtc_device *rtc) | |||
| 108 | flush_scheduled_work(); | 108 | flush_scheduled_work(); |
| 109 | spin_lock_irq(&rtc->irq_lock); | 109 | spin_lock_irq(&rtc->irq_lock); |
| 110 | } | 110 | } |
| 111 | rtc->irq_active = 0; | 111 | rtc->uie_irq_active = 0; |
| 112 | } | 112 | } |
| 113 | spin_unlock_irq(&rtc->irq_lock); | 113 | spin_unlock_irq(&rtc->irq_lock); |
| 114 | return 0; | ||
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | static int set_uie(struct rtc_device *rtc) | 117 | static int set_uie(struct rtc_device *rtc) |
| @@ -122,8 +123,8 @@ static int set_uie(struct rtc_device *rtc) | |||
| 122 | if (err) | 123 | if (err) |
| 123 | return err; | 124 | return err; |
| 124 | spin_lock_irq(&rtc->irq_lock); | 125 | spin_lock_irq(&rtc->irq_lock); |
| 125 | if (!rtc->irq_active) { | 126 | if (!rtc->uie_irq_active) { |
| 126 | rtc->irq_active = 1; | 127 | rtc->uie_irq_active = 1; |
| 127 | rtc->stop_uie_polling = 0; | 128 | rtc->stop_uie_polling = 0; |
| 128 | rtc->oldsecs = tm.tm_sec; | 129 | rtc->oldsecs = tm.tm_sec; |
| 129 | rtc->uie_task_active = 1; | 130 | rtc->uie_task_active = 1; |
| @@ -134,6 +135,16 @@ static int set_uie(struct rtc_device *rtc) | |||
| 134 | spin_unlock_irq(&rtc->irq_lock); | 135 | spin_unlock_irq(&rtc->irq_lock); |
| 135 | return 0; | 136 | return 0; |
| 136 | } | 137 | } |
| 138 | |||
| 139 | int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled) | ||
| 140 | { | ||
| 141 | if (enabled) | ||
| 142 | return set_uie(rtc); | ||
| 143 | else | ||
| 144 | return clear_uie(rtc); | ||
| 145 | } | ||
| 146 | EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul); | ||
| 147 | |||
| 137 | #endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ | 148 | #endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ |
| 138 | 149 | ||
| 139 | static ssize_t | 150 | static ssize_t |
| @@ -357,6 +368,22 @@ static long rtc_dev_ioctl(struct file *file, | |||
| 357 | err = rtc_irq_set_state(rtc, NULL, 0); | 368 | err = rtc_irq_set_state(rtc, NULL, 0); |
| 358 | break; | 369 | break; |
| 359 | 370 | ||
| 371 | case RTC_AIE_ON: | ||
| 372 | mutex_unlock(&rtc->ops_lock); | ||
| 373 | return rtc_alarm_irq_enable(rtc, 1); | ||
| 374 | |||
| 375 | case RTC_AIE_OFF: | ||
| 376 | mutex_unlock(&rtc->ops_lock); | ||
| 377 | return rtc_alarm_irq_enable(rtc, 0); | ||
| 378 | |||
| 379 | case RTC_UIE_ON: | ||
| 380 | mutex_unlock(&rtc->ops_lock); | ||
| 381 | return rtc_update_irq_enable(rtc, 1); | ||
| 382 | |||
| 383 | case RTC_UIE_OFF: | ||
| 384 | mutex_unlock(&rtc->ops_lock); | ||
| 385 | return rtc_update_irq_enable(rtc, 0); | ||
| 386 | |||
| 360 | case RTC_IRQP_SET: | 387 | case RTC_IRQP_SET: |
| 361 | err = rtc_irq_set_freq(rtc, NULL, arg); | 388 | err = rtc_irq_set_freq(rtc, NULL, arg); |
| 362 | break; | 389 | break; |
| @@ -401,17 +428,6 @@ static long rtc_dev_ioctl(struct file *file, | |||
| 401 | err = -EFAULT; | 428 | err = -EFAULT; |
| 402 | return err; | 429 | return err; |
| 403 | 430 | ||
| 404 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | ||
| 405 | case RTC_UIE_OFF: | ||
| 406 | mutex_unlock(&rtc->ops_lock); | ||
| 407 | clear_uie(rtc); | ||
| 408 | return 0; | ||
| 409 | |||
| 410 | case RTC_UIE_ON: | ||
| 411 | mutex_unlock(&rtc->ops_lock); | ||
| 412 | err = set_uie(rtc); | ||
| 413 | return err; | ||
| 414 | #endif | ||
| 415 | default: | 431 | default: |
| 416 | err = -ENOTTY; | 432 | err = -ENOTTY; |
| 417 | break; | 433 | break; |
| @@ -440,7 +456,10 @@ static int rtc_dev_release(struct inode *inode, struct file *file) | |||
| 440 | * Leave the alarm alone; it may be set to trigger a system wakeup | 456 | * Leave the alarm alone; it may be set to trigger a system wakeup |
| 441 | * later, or be used by kernel code, and is a one-shot event anyway. | 457 | * later, or be used by kernel code, and is a one-shot event anyway. |
| 442 | */ | 458 | */ |
| 459 | |||
| 460 | /* Keep ioctl until all drivers are converted */ | ||
| 443 | rtc_dev_ioctl(file, RTC_UIE_OFF, 0); | 461 | rtc_dev_ioctl(file, RTC_UIE_OFF, 0); |
| 462 | rtc_update_irq_enable(rtc, 0); | ||
| 444 | rtc_irq_set_state(rtc, NULL, 0); | 463 | rtc_irq_set_state(rtc, NULL, 0); |
| 445 | 464 | ||
| 446 | if (rtc->ops->release) | 465 | if (rtc->ops->release) |
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 9a234a4ec06d..4aedc705518c 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
| 11 | #include <linux/bcd.h> | 11 | #include <linux/bcd.h> |
| 12 | 12 | ||
| 13 | #define DRV_VERSION "0.1" | 13 | #define DRV_VERSION "0.2" |
| 14 | 14 | ||
| 15 | struct ds1216_regs { | 15 | struct ds1216_regs { |
| 16 | u8 tsec; | 16 | u8 tsec; |
| @@ -101,7 +101,8 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
| 101 | tm->tm_year = bcd2bin(regs.year); | 101 | tm->tm_year = bcd2bin(regs.year); |
| 102 | if (tm->tm_year < 70) | 102 | if (tm->tm_year < 70) |
| 103 | tm->tm_year += 100; | 103 | tm->tm_year += 100; |
| 104 | return 0; | 104 | |
| 105 | return rtc_valid_tm(tm); | ||
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) | 108 | static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) |
| @@ -138,9 +139,8 @@ static const struct rtc_class_ops ds1216_rtc_ops = { | |||
| 138 | .set_time = ds1216_rtc_set_time, | 139 | .set_time = ds1216_rtc_set_time, |
| 139 | }; | 140 | }; |
| 140 | 141 | ||
| 141 | static int __devinit ds1216_rtc_probe(struct platform_device *pdev) | 142 | static int __init ds1216_rtc_probe(struct platform_device *pdev) |
| 142 | { | 143 | { |
| 143 | struct rtc_device *rtc; | ||
| 144 | struct resource *res; | 144 | struct resource *res; |
| 145 | struct ds1216_priv *priv; | 145 | struct ds1216_priv *priv; |
| 146 | int ret = 0; | 146 | int ret = 0; |
| @@ -152,7 +152,10 @@ static int __devinit ds1216_rtc_probe(struct platform_device *pdev) | |||
| 152 | priv = kzalloc(sizeof *priv, GFP_KERNEL); | 152 | priv = kzalloc(sizeof *priv, GFP_KERNEL); |
| 153 | if (!priv) | 153 | if (!priv) |
| 154 | return -ENOMEM; | 154 | return -ENOMEM; |
| 155 | priv->size = res->end - res->start + 1; | 155 | |
| 156 | platform_set_drvdata(pdev, priv); | ||
| 157 | |||
| 158 | priv->size = resource_size(res); | ||
| 156 | if (!request_mem_region(res->start, priv->size, pdev->name)) { | 159 | if (!request_mem_region(res->start, priv->size, pdev->name)) { |
| 157 | ret = -EBUSY; | 160 | ret = -EBUSY; |
| 158 | goto out; | 161 | goto out; |
| @@ -163,22 +166,18 @@ static int __devinit ds1216_rtc_probe(struct platform_device *pdev) | |||
| 163 | ret = -ENOMEM; | 166 | ret = -ENOMEM; |
| 164 | goto out; | 167 | goto out; |
| 165 | } | 168 | } |
| 166 | rtc = rtc_device_register("ds1216", &pdev->dev, | 169 | priv->rtc = rtc_device_register("ds1216", &pdev->dev, |
| 167 | &ds1216_rtc_ops, THIS_MODULE); | 170 | &ds1216_rtc_ops, THIS_MODULE); |
| 168 | if (IS_ERR(rtc)) { | 171 | if (IS_ERR(priv->rtc)) { |
| 169 | ret = PTR_ERR(rtc); | 172 | ret = PTR_ERR(priv->rtc); |
| 170 | goto out; | 173 | goto out; |
| 171 | } | 174 | } |
| 172 | priv->rtc = rtc; | ||
| 173 | platform_set_drvdata(pdev, priv); | ||
| 174 | 175 | ||
| 175 | /* dummy read to get clock into a known state */ | 176 | /* dummy read to get clock into a known state */ |
| 176 | ds1216_read(priv->ioaddr, dummy); | 177 | ds1216_read(priv->ioaddr, dummy); |
| 177 | return 0; | 178 | return 0; |
| 178 | 179 | ||
| 179 | out: | 180 | out: |
| 180 | if (priv->rtc) | ||
| 181 | rtc_device_unregister(priv->rtc); | ||
| 182 | if (priv->ioaddr) | 181 | if (priv->ioaddr) |
| 183 | iounmap(priv->ioaddr); | 182 | iounmap(priv->ioaddr); |
| 184 | if (priv->baseaddr) | 183 | if (priv->baseaddr) |
| @@ -187,7 +186,7 @@ out: | |||
| 187 | return ret; | 186 | return ret; |
| 188 | } | 187 | } |
| 189 | 188 | ||
| 190 | static int __devexit ds1216_rtc_remove(struct platform_device *pdev) | 189 | static int __exit ds1216_rtc_remove(struct platform_device *pdev) |
| 191 | { | 190 | { |
| 192 | struct ds1216_priv *priv = platform_get_drvdata(pdev); | 191 | struct ds1216_priv *priv = platform_get_drvdata(pdev); |
| 193 | 192 | ||
| @@ -203,13 +202,12 @@ static struct platform_driver ds1216_rtc_platform_driver = { | |||
| 203 | .name = "rtc-ds1216", | 202 | .name = "rtc-ds1216", |
| 204 | .owner = THIS_MODULE, | 203 | .owner = THIS_MODULE, |
| 205 | }, | 204 | }, |
| 206 | .probe = ds1216_rtc_probe, | 205 | .remove = __exit_p(ds1216_rtc_remove), |
| 207 | .remove = __devexit_p(ds1216_rtc_remove), | ||
| 208 | }; | 206 | }; |
| 209 | 207 | ||
| 210 | static int __init ds1216_rtc_init(void) | 208 | static int __init ds1216_rtc_init(void) |
| 211 | { | 209 | { |
| 212 | return platform_driver_register(&ds1216_rtc_platform_driver); | 210 | return platform_driver_probe(&ds1216_rtc_platform_driver, ds1216_rtc_probe); |
| 213 | } | 211 | } |
| 214 | 212 | ||
| 215 | static void __exit ds1216_rtc_exit(void) | 213 | static void __exit ds1216_rtc_exit(void) |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 162330b9d1dc..7e5155e88ac7 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
| @@ -86,13 +86,11 @@ enum ds_type { | |||
| 86 | 86 | ||
| 87 | 87 | ||
| 88 | struct ds1307 { | 88 | struct ds1307 { |
| 89 | u8 reg_addr; | ||
| 90 | u8 regs[11]; | 89 | u8 regs[11]; |
| 91 | enum ds_type type; | 90 | enum ds_type type; |
| 92 | unsigned long flags; | 91 | unsigned long flags; |
| 93 | #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ | 92 | #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ |
| 94 | #define HAS_ALARM 1 /* bit 1 == irq claimed */ | 93 | #define HAS_ALARM 1 /* bit 1 == irq claimed */ |
| 95 | struct i2c_msg msg[2]; | ||
| 96 | struct i2c_client *client; | 94 | struct i2c_client *client; |
| 97 | struct rtc_device *rtc; | 95 | struct rtc_device *rtc; |
| 98 | struct work_struct work; | 96 | struct work_struct work; |
| @@ -204,13 +202,9 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) | |||
| 204 | int tmp; | 202 | int tmp; |
| 205 | 203 | ||
| 206 | /* read the RTC date and time registers all at once */ | 204 | /* read the RTC date and time registers all at once */ |
| 207 | ds1307->reg_addr = 0; | 205 | tmp = i2c_smbus_read_i2c_block_data(ds1307->client, |
| 208 | ds1307->msg[1].flags = I2C_M_RD; | 206 | DS1307_REG_SECS, 7, ds1307->regs); |
| 209 | ds1307->msg[1].len = 7; | 207 | if (tmp != 7) { |
| 210 | |||
| 211 | tmp = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent), | ||
| 212 | ds1307->msg, 2); | ||
| 213 | if (tmp != 2) { | ||
| 214 | dev_err(dev, "%s error %d\n", "read", tmp); | 208 | dev_err(dev, "%s error %d\n", "read", tmp); |
| 215 | return -EIO; | 209 | return -EIO; |
| 216 | } | 210 | } |
| @@ -257,7 +251,6 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
| 257 | t->tm_hour, t->tm_mday, | 251 | t->tm_hour, t->tm_mday, |
| 258 | t->tm_mon, t->tm_year, t->tm_wday); | 252 | t->tm_mon, t->tm_year, t->tm_wday); |
| 259 | 253 | ||
| 260 | *buf++ = 0; /* first register addr */ | ||
| 261 | buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec); | 254 | buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec); |
| 262 | buf[DS1307_REG_MIN] = bin2bcd(t->tm_min); | 255 | buf[DS1307_REG_MIN] = bin2bcd(t->tm_min); |
| 263 | buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); | 256 | buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); |
| @@ -282,23 +275,19 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
| 282 | break; | 275 | break; |
| 283 | } | 276 | } |
| 284 | 277 | ||
| 285 | ds1307->msg[1].flags = 0; | ||
| 286 | ds1307->msg[1].len = 8; | ||
| 287 | |||
| 288 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", | 278 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", |
| 289 | "write", buf[0], buf[1], buf[2], buf[3], | 279 | "write", buf[0], buf[1], buf[2], buf[3], |
| 290 | buf[4], buf[5], buf[6]); | 280 | buf[4], buf[5], buf[6]); |
| 291 | 281 | ||
| 292 | result = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent), | 282 | result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf); |
| 293 | &ds1307->msg[1], 1); | 283 | if (result < 0) { |
| 294 | if (result != 1) { | 284 | dev_err(dev, "%s error %d\n", "write", result); |
| 295 | dev_err(dev, "%s error %d\n", "write", tmp); | 285 | return result; |
| 296 | return -EIO; | ||
| 297 | } | 286 | } |
| 298 | return 0; | 287 | return 0; |
| 299 | } | 288 | } |
| 300 | 289 | ||
| 301 | static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t) | 290 | static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) |
| 302 | { | 291 | { |
| 303 | struct i2c_client *client = to_i2c_client(dev); | 292 | struct i2c_client *client = to_i2c_client(dev); |
| 304 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | 293 | struct ds1307 *ds1307 = i2c_get_clientdata(client); |
| @@ -308,13 +297,9 @@ static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 308 | return -EINVAL; | 297 | return -EINVAL; |
| 309 | 298 | ||
| 310 | /* read all ALARM1, ALARM2, and status registers at once */ | 299 | /* read all ALARM1, ALARM2, and status registers at once */ |
| 311 | ds1307->reg_addr = DS1339_REG_ALARM1_SECS; | 300 | ret = i2c_smbus_read_i2c_block_data(client, |
| 312 | ds1307->msg[1].flags = I2C_M_RD; | 301 | DS1339_REG_ALARM1_SECS, 9, ds1307->regs); |
| 313 | ds1307->msg[1].len = 9; | 302 | if (ret != 9) { |
| 314 | |||
| 315 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
| 316 | ds1307->msg, 2); | ||
| 317 | if (ret != 2) { | ||
| 318 | dev_err(dev, "%s error %d\n", "alarm read", ret); | 303 | dev_err(dev, "%s error %d\n", "alarm read", ret); |
| 319 | return -EIO; | 304 | return -EIO; |
| 320 | } | 305 | } |
| @@ -353,7 +338,7 @@ static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 353 | return 0; | 338 | return 0; |
| 354 | } | 339 | } |
| 355 | 340 | ||
| 356 | static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 341 | static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
| 357 | { | 342 | { |
| 358 | struct i2c_client *client = to_i2c_client(dev); | 343 | struct i2c_client *client = to_i2c_client(dev); |
| 359 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | 344 | struct ds1307 *ds1307 = i2c_get_clientdata(client); |
| @@ -371,13 +356,9 @@ static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 371 | t->enabled, t->pending); | 356 | t->enabled, t->pending); |
| 372 | 357 | ||
| 373 | /* read current status of both alarms and the chip */ | 358 | /* read current status of both alarms and the chip */ |
| 374 | ds1307->reg_addr = DS1339_REG_ALARM1_SECS; | 359 | ret = i2c_smbus_read_i2c_block_data(client, |
| 375 | ds1307->msg[1].flags = I2C_M_RD; | 360 | DS1339_REG_ALARM1_SECS, 9, buf); |
| 376 | ds1307->msg[1].len = 9; | 361 | if (ret != 9) { |
| 377 | |||
| 378 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
| 379 | ds1307->msg, 2); | ||
| 380 | if (ret != 2) { | ||
| 381 | dev_err(dev, "%s error %d\n", "alarm write", ret); | 362 | dev_err(dev, "%s error %d\n", "alarm write", ret); |
| 382 | return -EIO; | 363 | return -EIO; |
| 383 | } | 364 | } |
| @@ -392,7 +373,6 @@ static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 392 | ds1307->regs[6], control, status); | 373 | ds1307->regs[6], control, status); |
| 393 | 374 | ||
| 394 | /* set ALARM1, using 24 hour and day-of-month modes */ | 375 | /* set ALARM1, using 24 hour and day-of-month modes */ |
| 395 | *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */ | ||
| 396 | buf[0] = bin2bcd(t->time.tm_sec); | 376 | buf[0] = bin2bcd(t->time.tm_sec); |
| 397 | buf[1] = bin2bcd(t->time.tm_min); | 377 | buf[1] = bin2bcd(t->time.tm_min); |
| 398 | buf[2] = bin2bcd(t->time.tm_hour); | 378 | buf[2] = bin2bcd(t->time.tm_hour); |
| @@ -411,14 +391,11 @@ static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 411 | } | 391 | } |
| 412 | buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); | 392 | buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); |
| 413 | 393 | ||
| 414 | ds1307->msg[1].flags = 0; | 394 | ret = i2c_smbus_write_i2c_block_data(client, |
| 415 | ds1307->msg[1].len = 10; | 395 | DS1339_REG_ALARM1_SECS, 9, buf); |
| 416 | 396 | if (ret < 0) { | |
| 417 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
| 418 | &ds1307->msg[1], 1); | ||
| 419 | if (ret != 1) { | ||
| 420 | dev_err(dev, "can't set alarm time\n"); | 397 | dev_err(dev, "can't set alarm time\n"); |
| 421 | return -EIO; | 398 | return ret; |
| 422 | } | 399 | } |
| 423 | 400 | ||
| 424 | return 0; | 401 | return 0; |
| @@ -475,8 +452,8 @@ static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
| 475 | static const struct rtc_class_ops ds13xx_rtc_ops = { | 452 | static const struct rtc_class_ops ds13xx_rtc_ops = { |
| 476 | .read_time = ds1307_get_time, | 453 | .read_time = ds1307_get_time, |
| 477 | .set_time = ds1307_set_time, | 454 | .set_time = ds1307_set_time, |
| 478 | .read_alarm = ds1307_read_alarm, | 455 | .read_alarm = ds1337_read_alarm, |
| 479 | .set_alarm = ds1307_set_alarm, | 456 | .set_alarm = ds1337_set_alarm, |
| 480 | .ioctl = ds1307_ioctl, | 457 | .ioctl = ds1307_ioctl, |
| 481 | }; | 458 | }; |
| 482 | 459 | ||
| @@ -490,7 +467,6 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
| 490 | { | 467 | { |
| 491 | struct i2c_client *client; | 468 | struct i2c_client *client; |
| 492 | struct ds1307 *ds1307; | 469 | struct ds1307 *ds1307; |
| 493 | struct i2c_msg msg[2]; | ||
| 494 | int result; | 470 | int result; |
| 495 | 471 | ||
| 496 | client = kobj_to_i2c_client(kobj); | 472 | client = kobj_to_i2c_client(kobj); |
| @@ -503,24 +479,10 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
| 503 | if (unlikely(!count)) | 479 | if (unlikely(!count)) |
| 504 | return count; | 480 | return count; |
| 505 | 481 | ||
| 506 | msg[0].addr = client->addr; | 482 | result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf); |
| 507 | msg[0].flags = 0; | 483 | if (result < 0) |
| 508 | msg[0].len = 1; | ||
| 509 | msg[0].buf = buf; | ||
| 510 | |||
| 511 | buf[0] = 8 + off; | ||
| 512 | |||
| 513 | msg[1].addr = client->addr; | ||
| 514 | msg[1].flags = I2C_M_RD; | ||
| 515 | msg[1].len = count; | ||
| 516 | msg[1].buf = buf; | ||
| 517 | |||
| 518 | result = i2c_transfer(to_i2c_adapter(client->dev.parent), msg, 2); | ||
| 519 | if (result != 2) { | ||
| 520 | dev_err(&client->dev, "%s error %d\n", "nvram read", result); | 484 | dev_err(&client->dev, "%s error %d\n", "nvram read", result); |
| 521 | return -EIO; | 485 | return result; |
| 522 | } | ||
| 523 | return count; | ||
| 524 | } | 486 | } |
| 525 | 487 | ||
| 526 | static ssize_t | 488 | static ssize_t |
| @@ -528,8 +490,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
| 528 | char *buf, loff_t off, size_t count) | 490 | char *buf, loff_t off, size_t count) |
| 529 | { | 491 | { |
| 530 | struct i2c_client *client; | 492 | struct i2c_client *client; |
| 531 | u8 buffer[NVRAM_SIZE + 1]; | 493 | int result; |
| 532 | int ret; | ||
| 533 | 494 | ||
| 534 | client = kobj_to_i2c_client(kobj); | 495 | client = kobj_to_i2c_client(kobj); |
| 535 | 496 | ||
| @@ -540,11 +501,12 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
| 540 | if (unlikely(!count)) | 501 | if (unlikely(!count)) |
| 541 | return count; | 502 | return count; |
| 542 | 503 | ||
| 543 | buffer[0] = 8 + off; | 504 | result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf); |
| 544 | memcpy(buffer + 1, buf, count); | 505 | if (result < 0) { |
| 545 | 506 | dev_err(&client->dev, "%s error %d\n", "nvram write", result); | |
| 546 | ret = i2c_master_send(client, buffer, count + 1); | 507 | return result; |
| 547 | return (ret < 0) ? ret : (ret - 1); | 508 | } |
| 509 | return count; | ||
| 548 | } | 510 | } |
| 549 | 511 | ||
| 550 | static struct bin_attribute nvram = { | 512 | static struct bin_attribute nvram = { |
| @@ -571,9 +533,11 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
| 571 | const struct chip_desc *chip = &chips[id->driver_data]; | 533 | const struct chip_desc *chip = &chips[id->driver_data]; |
| 572 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 534 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 573 | int want_irq = false; | 535 | int want_irq = false; |
| 536 | unsigned char *buf; | ||
| 574 | 537 | ||
| 575 | if (!i2c_check_functionality(adapter, | 538 | if (!i2c_check_functionality(adapter, |
| 576 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 539 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA | |
| 540 | I2C_FUNC_SMBUS_I2C_BLOCK)) | ||
| 577 | return -EIO; | 541 | return -EIO; |
| 578 | 542 | ||
| 579 | if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) | 543 | if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) |
| @@ -581,18 +545,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
| 581 | 545 | ||
| 582 | ds1307->client = client; | 546 | ds1307->client = client; |
| 583 | i2c_set_clientdata(client, ds1307); | 547 | i2c_set_clientdata(client, ds1307); |
| 584 | |||
| 585 | ds1307->msg[0].addr = client->addr; | ||
| 586 | ds1307->msg[0].flags = 0; | ||
| 587 | ds1307->msg[0].len = 1; | ||
| 588 | ds1307->msg[0].buf = &ds1307->reg_addr; | ||
| 589 | |||
| 590 | ds1307->msg[1].addr = client->addr; | ||
| 591 | ds1307->msg[1].flags = I2C_M_RD; | ||
| 592 | ds1307->msg[1].len = sizeof(ds1307->regs); | ||
| 593 | ds1307->msg[1].buf = ds1307->regs; | ||
| 594 | |||
| 595 | ds1307->type = id->driver_data; | 548 | ds1307->type = id->driver_data; |
| 549 | buf = ds1307->regs; | ||
| 596 | 550 | ||
| 597 | switch (ds1307->type) { | 551 | switch (ds1307->type) { |
| 598 | case ds_1337: | 552 | case ds_1337: |
| @@ -602,21 +556,15 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
| 602 | INIT_WORK(&ds1307->work, ds1307_work); | 556 | INIT_WORK(&ds1307->work, ds1307_work); |
| 603 | want_irq = true; | 557 | want_irq = true; |
| 604 | } | 558 | } |
| 605 | |||
| 606 | ds1307->reg_addr = DS1337_REG_CONTROL; | ||
| 607 | ds1307->msg[1].len = 2; | ||
| 608 | |||
| 609 | /* get registers that the "rtc" read below won't read... */ | 559 | /* get registers that the "rtc" read below won't read... */ |
| 610 | tmp = i2c_transfer(adapter, ds1307->msg, 2); | 560 | tmp = i2c_smbus_read_i2c_block_data(ds1307->client, |
| 561 | DS1337_REG_CONTROL, 2, buf); | ||
| 611 | if (tmp != 2) { | 562 | if (tmp != 2) { |
| 612 | pr_debug("read error %d\n", tmp); | 563 | pr_debug("read error %d\n", tmp); |
| 613 | err = -EIO; | 564 | err = -EIO; |
| 614 | goto exit_free; | 565 | goto exit_free; |
| 615 | } | 566 | } |
| 616 | 567 | ||
| 617 | ds1307->reg_addr = 0; | ||
| 618 | ds1307->msg[1].len = sizeof(ds1307->regs); | ||
| 619 | |||
| 620 | /* oscillator off? turn it on, so clock can tick. */ | 568 | /* oscillator off? turn it on, so clock can tick. */ |
| 621 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) | 569 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) |
| 622 | ds1307->regs[0] &= ~DS1337_BIT_nEOSC; | 570 | ds1307->regs[0] &= ~DS1337_BIT_nEOSC; |
| @@ -647,9 +595,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
| 647 | 595 | ||
| 648 | read_rtc: | 596 | read_rtc: |
| 649 | /* read RTC registers */ | 597 | /* read RTC registers */ |
| 650 | 598 | tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf); | |
| 651 | tmp = i2c_transfer(adapter, ds1307->msg, 2); | 599 | if (tmp != 8) { |
| 652 | if (tmp != 2) { | ||
| 653 | pr_debug("read error %d\n", tmp); | 600 | pr_debug("read error %d\n", tmp); |
| 654 | err = -EIO; | 601 | err = -EIO; |
| 655 | goto exit_free; | 602 | goto exit_free; |
| @@ -707,22 +654,6 @@ read_rtc: | |||
| 707 | break; | 654 | break; |
| 708 | } | 655 | } |
| 709 | 656 | ||
| 710 | tmp = ds1307->regs[DS1307_REG_SECS]; | ||
| 711 | tmp = bcd2bin(tmp & 0x7f); | ||
| 712 | if (tmp > 60) | ||
| 713 | goto exit_bad; | ||
| 714 | tmp = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); | ||
| 715 | if (tmp > 60) | ||
| 716 | goto exit_bad; | ||
| 717 | |||
| 718 | tmp = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f); | ||
| 719 | if (tmp == 0 || tmp > 31) | ||
| 720 | goto exit_bad; | ||
| 721 | |||
| 722 | tmp = bcd2bin(ds1307->regs[DS1307_REG_MONTH] & 0x1f); | ||
| 723 | if (tmp == 0 || tmp > 12) | ||
| 724 | goto exit_bad; | ||
| 725 | |||
| 726 | tmp = ds1307->regs[DS1307_REG_HOUR]; | 657 | tmp = ds1307->regs[DS1307_REG_HOUR]; |
| 727 | switch (ds1307->type) { | 658 | switch (ds1307->type) { |
| 728 | case ds_1340: | 659 | case ds_1340: |
| @@ -779,13 +710,6 @@ read_rtc: | |||
| 779 | 710 | ||
| 780 | return 0; | 711 | return 0; |
| 781 | 712 | ||
| 782 | exit_bad: | ||
| 783 | dev_dbg(&client->dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", | ||
| 784 | "bogus register", | ||
| 785 | ds1307->regs[0], ds1307->regs[1], | ||
| 786 | ds1307->regs[2], ds1307->regs[3], | ||
| 787 | ds1307->regs[4], ds1307->regs[5], | ||
| 788 | ds1307->regs[6]); | ||
| 789 | exit_irq: | 713 | exit_irq: |
| 790 | if (ds1307->rtc) | 714 | if (ds1307->rtc) |
| 791 | rtc_device_unregister(ds1307->rtc); | 715 | rtc_device_unregister(ds1307->rtc); |
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index 599e976bf014..e54b5c619bdf 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * rtc-ds1390.c -- driver for DS1390/93/94 | 2 | * rtc-ds1390.c -- driver for the Dallas/Maxim DS1390/93/94 SPI RTC |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2008 Mercury IMC Ltd | 4 | * Copyright (C) 2008 Mercury IMC Ltd |
| 5 | * Written by Mark Jackson <mpfj@mimc.co.uk> | 5 | * Written by Mark Jackson <mpfj@mimc.co.uk> |
| @@ -8,11 +8,13 @@ | |||
| 8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| 9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
| 10 | * | 10 | * |
| 11 | * NOTE : Currently this driver only supports the bare minimum for read | 11 | * NOTE: Currently this driver only supports the bare minimum for read |
| 12 | * and write the RTC. The extra features provided by the chip family | 12 | * and write the RTC. The extra features provided by the chip family |
| 13 | * (alarms, trickle charger, different control registers) are unavailable. | 13 | * (alarms, trickle charger, different control registers) are unavailable. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/module.h> | ||
| 16 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 17 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
| 18 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
| @@ -42,20 +44,6 @@ struct ds1390 { | |||
| 42 | u8 txrx_buf[9]; /* cmd + 8 registers */ | 44 | u8 txrx_buf[9]; /* cmd + 8 registers */ |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| 45 | static void ds1390_set_reg(struct device *dev, unsigned char address, | ||
| 46 | unsigned char data) | ||
| 47 | { | ||
| 48 | struct spi_device *spi = to_spi_device(dev); | ||
| 49 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
| 50 | |||
| 51 | /* Set MSB to indicate write */ | ||
| 52 | chip->txrx_buf[0] = address | 0x80; | ||
| 53 | chip->txrx_buf[1] = data; | ||
| 54 | |||
| 55 | /* do the i/o */ | ||
| 56 | spi_write_then_read(spi, chip->txrx_buf, 2, NULL, 0); | ||
| 57 | } | ||
| 58 | |||
| 59 | static int ds1390_get_reg(struct device *dev, unsigned char address, | 47 | static int ds1390_get_reg(struct device *dev, unsigned char address, |
| 60 | unsigned char *data) | 48 | unsigned char *data) |
| 61 | { | 49 | { |
| @@ -78,7 +66,7 @@ static int ds1390_get_reg(struct device *dev, unsigned char address, | |||
| 78 | return 0; | 66 | return 0; |
| 79 | } | 67 | } |
| 80 | 68 | ||
| 81 | static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt) | 69 | static int ds1390_read_time(struct device *dev, struct rtc_time *dt) |
| 82 | { | 70 | { |
| 83 | struct spi_device *spi = to_spi_device(dev); | 71 | struct spi_device *spi = to_spi_device(dev); |
| 84 | struct ds1390 *chip = dev_get_drvdata(dev); | 72 | struct ds1390 *chip = dev_get_drvdata(dev); |
| @@ -107,7 +95,7 @@ static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt) | |||
| 107 | return rtc_valid_tm(dt); | 95 | return rtc_valid_tm(dt); |
| 108 | } | 96 | } |
| 109 | 97 | ||
| 110 | static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt) | 98 | static int ds1390_set_time(struct device *dev, struct rtc_time *dt) |
| 111 | { | 99 | { |
| 112 | struct spi_device *spi = to_spi_device(dev); | 100 | struct spi_device *spi = to_spi_device(dev); |
| 113 | struct ds1390 *chip = dev_get_drvdata(dev); | 101 | struct ds1390 *chip = dev_get_drvdata(dev); |
| @@ -127,16 +115,6 @@ static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt) | |||
| 127 | return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0); | 115 | return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0); |
| 128 | } | 116 | } |
| 129 | 117 | ||
| 130 | static int ds1390_read_time(struct device *dev, struct rtc_time *tm) | ||
| 131 | { | ||
| 132 | return ds1390_get_datetime(dev, tm); | ||
| 133 | } | ||
| 134 | |||
| 135 | static int ds1390_set_time(struct device *dev, struct rtc_time *tm) | ||
| 136 | { | ||
| 137 | return ds1390_set_datetime(dev, tm); | ||
| 138 | } | ||
| 139 | |||
| 140 | static const struct rtc_class_ops ds1390_rtc_ops = { | 118 | static const struct rtc_class_ops ds1390_rtc_ops = { |
| 141 | .read_time = ds1390_read_time, | 119 | .read_time = ds1390_read_time, |
| 142 | .set_time = ds1390_set_time, | 120 | .set_time = ds1390_set_time, |
| @@ -149,46 +127,40 @@ static int __devinit ds1390_probe(struct spi_device *spi) | |||
| 149 | struct ds1390 *chip; | 127 | struct ds1390 *chip; |
| 150 | int res; | 128 | int res; |
| 151 | 129 | ||
| 152 | printk(KERN_DEBUG "DS1390 SPI RTC driver\n"); | ||
| 153 | |||
| 154 | rtc = rtc_device_register("ds1390", | ||
| 155 | &spi->dev, &ds1390_rtc_ops, THIS_MODULE); | ||
| 156 | if (IS_ERR(rtc)) { | ||
| 157 | printk(KERN_ALERT "RTC : unable to register device\n"); | ||
| 158 | return PTR_ERR(rtc); | ||
| 159 | } | ||
| 160 | |||
| 161 | spi->mode = SPI_MODE_3; | 130 | spi->mode = SPI_MODE_3; |
| 162 | spi->bits_per_word = 8; | 131 | spi->bits_per_word = 8; |
| 163 | spi_setup(spi); | 132 | spi_setup(spi); |
| 164 | 133 | ||
| 165 | chip = kzalloc(sizeof *chip, GFP_KERNEL); | 134 | chip = kzalloc(sizeof *chip, GFP_KERNEL); |
| 166 | if (!chip) { | 135 | if (!chip) { |
| 167 | printk(KERN_ALERT "RTC : unable to allocate device memory\n"); | 136 | dev_err(&spi->dev, "unable to allocate device memory\n"); |
| 168 | rtc_device_unregister(rtc); | ||
| 169 | return -ENOMEM; | 137 | return -ENOMEM; |
| 170 | } | 138 | } |
| 171 | chip->rtc = rtc; | ||
| 172 | dev_set_drvdata(&spi->dev, chip); | 139 | dev_set_drvdata(&spi->dev, chip); |
| 173 | 140 | ||
| 174 | res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); | 141 | res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); |
| 175 | if (res) { | 142 | if (res != 0) { |
| 176 | printk(KERN_ALERT "RTC : unable to read device\n"); | 143 | dev_err(&spi->dev, "unable to read device\n"); |
| 177 | rtc_device_unregister(rtc); | 144 | kfree(chip); |
| 178 | return res; | 145 | return res; |
| 179 | } | 146 | } |
| 180 | 147 | ||
| 181 | return 0; | 148 | chip->rtc = rtc_device_register("ds1390", |
| 149 | &spi->dev, &ds1390_rtc_ops, THIS_MODULE); | ||
| 150 | if (IS_ERR(chip->rtc)) { | ||
| 151 | dev_err(&spi->dev, "unable to register device\n"); | ||
| 152 | res = PTR_ERR(chip->rtc); | ||
| 153 | kfree(chip); | ||
| 154 | } | ||
| 155 | |||
| 156 | return res; | ||
| 182 | } | 157 | } |
| 183 | 158 | ||
| 184 | static int __devexit ds1390_remove(struct spi_device *spi) | 159 | static int __devexit ds1390_remove(struct spi_device *spi) |
| 185 | { | 160 | { |
| 186 | struct ds1390 *chip = platform_get_drvdata(spi); | 161 | struct ds1390 *chip = platform_get_drvdata(spi); |
| 187 | struct rtc_device *rtc = chip->rtc; | ||
| 188 | |||
| 189 | if (rtc) | ||
| 190 | rtc_device_unregister(rtc); | ||
| 191 | 162 | ||
| 163 | rtc_device_unregister(chip->rtc); | ||
| 192 | kfree(chip); | 164 | kfree(chip); |
| 193 | 165 | ||
| 194 | return 0; | 166 | return 0; |
| @@ -215,6 +187,6 @@ static __exit void ds1390_exit(void) | |||
| 215 | } | 187 | } |
| 216 | module_exit(ds1390_exit); | 188 | module_exit(ds1390_exit); |
| 217 | 189 | ||
| 218 | MODULE_DESCRIPTION("DS1390/93/94 SPI RTC driver"); | 190 | MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver"); |
| 219 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); | 191 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); |
| 220 | MODULE_LICENSE("GPL"); | 192 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 25caada78398..0b6b7730c716 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
| @@ -326,9 +326,9 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 326 | struct platform_device *pdev = to_platform_device(dev); | 326 | struct platform_device *pdev = to_platform_device(dev); |
| 327 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 327 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 328 | 328 | ||
| 329 | if (pdata->irq < 0) { | 329 | if (pdata->irq <= 0) |
| 330 | return -EINVAL; | 330 | return -EINVAL; |
| 331 | } | 331 | |
| 332 | pdata->alrm_mday = alrm->time.tm_mday; | 332 | pdata->alrm_mday = alrm->time.tm_mday; |
| 333 | pdata->alrm_hour = alrm->time.tm_hour; | 333 | pdata->alrm_hour = alrm->time.tm_hour; |
| 334 | pdata->alrm_min = alrm->time.tm_min; | 334 | pdata->alrm_min = alrm->time.tm_min; |
| @@ -346,9 +346,9 @@ ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 346 | struct platform_device *pdev = to_platform_device(dev); | 346 | struct platform_device *pdev = to_platform_device(dev); |
| 347 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 347 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 348 | 348 | ||
| 349 | if (pdata->irq < 0) { | 349 | if (pdata->irq <= 0) |
| 350 | return -EINVAL; | 350 | return -EINVAL; |
| 351 | } | 351 | |
| 352 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | 352 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; |
| 353 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | 353 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; |
| 354 | alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min; | 354 | alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min; |
| @@ -385,7 +385,7 @@ ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
| 385 | struct platform_device *pdev = to_platform_device(dev); | 385 | struct platform_device *pdev = to_platform_device(dev); |
| 386 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 386 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 387 | 387 | ||
| 388 | if (pdata->irq < 0) { | 388 | if (pdata->irq <= 0) { |
| 389 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | 389 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ |
| 390 | } | 390 | } |
| 391 | switch (cmd) { | 391 | switch (cmd) { |
| @@ -503,7 +503,6 @@ ds1511_rtc_probe(struct platform_device *pdev) | |||
| 503 | if (!pdata) { | 503 | if (!pdata) { |
| 504 | return -ENOMEM; | 504 | return -ENOMEM; |
| 505 | } | 505 | } |
| 506 | pdata->irq = -1; | ||
| 507 | pdata->size = res->end - res->start + 1; | 506 | pdata->size = res->end - res->start + 1; |
| 508 | if (!request_mem_region(res->start, pdata->size, pdev->name)) { | 507 | if (!request_mem_region(res->start, pdata->size, pdev->name)) { |
| 509 | ret = -EBUSY; | 508 | ret = -EBUSY; |
| @@ -545,13 +544,13 @@ ds1511_rtc_probe(struct platform_device *pdev) | |||
| 545 | * if the platform has an interrupt in mind for this device, | 544 | * if the platform has an interrupt in mind for this device, |
| 546 | * then by all means, set it | 545 | * then by all means, set it |
| 547 | */ | 546 | */ |
| 548 | if (pdata->irq >= 0) { | 547 | if (pdata->irq > 0) { |
| 549 | rtc_read(RTC_CMD1); | 548 | rtc_read(RTC_CMD1); |
| 550 | if (request_irq(pdata->irq, ds1511_interrupt, | 549 | if (request_irq(pdata->irq, ds1511_interrupt, |
| 551 | IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { | 550 | IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { |
| 552 | 551 | ||
| 553 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 552 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
| 554 | pdata->irq = -1; | 553 | pdata->irq = 0; |
| 555 | } | 554 | } |
| 556 | } | 555 | } |
| 557 | 556 | ||
| @@ -572,7 +571,7 @@ ds1511_rtc_probe(struct platform_device *pdev) | |||
| 572 | if (pdata->rtc) { | 571 | if (pdata->rtc) { |
| 573 | rtc_device_unregister(pdata->rtc); | 572 | rtc_device_unregister(pdata->rtc); |
| 574 | } | 573 | } |
| 575 | if (pdata->irq >= 0) { | 574 | if (pdata->irq > 0) { |
| 576 | free_irq(pdata->irq, pdev); | 575 | free_irq(pdata->irq, pdev); |
| 577 | } | 576 | } |
| 578 | if (ds1511_base) { | 577 | if (ds1511_base) { |
| @@ -595,7 +594,7 @@ ds1511_rtc_remove(struct platform_device *pdev) | |||
| 595 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | 594 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); |
| 596 | rtc_device_unregister(pdata->rtc); | 595 | rtc_device_unregister(pdata->rtc); |
| 597 | pdata->rtc = NULL; | 596 | pdata->rtc = NULL; |
| 598 | if (pdata->irq >= 0) { | 597 | if (pdata->irq > 0) { |
| 599 | /* | 598 | /* |
| 600 | * disable the alarm interrupt | 599 | * disable the alarm interrupt |
| 601 | */ | 600 | */ |
| @@ -631,7 +630,7 @@ ds1511_rtc_init(void) | |||
| 631 | static void __exit | 630 | static void __exit |
| 632 | ds1511_rtc_exit(void) | 631 | ds1511_rtc_exit(void) |
| 633 | { | 632 | { |
| 634 | return platform_driver_unregister(&ds1511_rtc_driver); | 633 | platform_driver_unregister(&ds1511_rtc_driver); |
| 635 | } | 634 | } |
| 636 | 635 | ||
| 637 | module_init(ds1511_rtc_init); | 636 | module_init(ds1511_rtc_init); |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index b9475cd20210..38d472b63406 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
| @@ -162,7 +162,7 @@ static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 162 | struct platform_device *pdev = to_platform_device(dev); | 162 | struct platform_device *pdev = to_platform_device(dev); |
| 163 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 163 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 164 | 164 | ||
| 165 | if (pdata->irq < 0) | 165 | if (pdata->irq <= 0) |
| 166 | return -EINVAL; | 166 | return -EINVAL; |
| 167 | pdata->alrm_mday = alrm->time.tm_mday; | 167 | pdata->alrm_mday = alrm->time.tm_mday; |
| 168 | pdata->alrm_hour = alrm->time.tm_hour; | 168 | pdata->alrm_hour = alrm->time.tm_hour; |
| @@ -179,7 +179,7 @@ static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 179 | struct platform_device *pdev = to_platform_device(dev); | 179 | struct platform_device *pdev = to_platform_device(dev); |
| 180 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 180 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 181 | 181 | ||
| 182 | if (pdata->irq < 0) | 182 | if (pdata->irq <= 0) |
| 183 | return -EINVAL; | 183 | return -EINVAL; |
| 184 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | 184 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; |
| 185 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | 185 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; |
| @@ -213,7 +213,7 @@ static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
| 213 | struct platform_device *pdev = to_platform_device(dev); | 213 | struct platform_device *pdev = to_platform_device(dev); |
| 214 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 214 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 215 | 215 | ||
| 216 | if (pdata->irq < 0) | 216 | if (pdata->irq <= 0) |
| 217 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | 217 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ |
| 218 | switch (cmd) { | 218 | switch (cmd) { |
| 219 | case RTC_AIE_OFF: | 219 | case RTC_AIE_OFF: |
| @@ -301,7 +301,6 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev) | |||
| 301 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 301 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
| 302 | if (!pdata) | 302 | if (!pdata) |
| 303 | return -ENOMEM; | 303 | return -ENOMEM; |
| 304 | pdata->irq = -1; | ||
| 305 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { | 304 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { |
| 306 | ret = -EBUSY; | 305 | ret = -EBUSY; |
| 307 | goto out; | 306 | goto out; |
| @@ -327,13 +326,13 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev) | |||
| 327 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF) | 326 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF) |
| 328 | dev_warn(&pdev->dev, "voltage-low detected.\n"); | 327 | dev_warn(&pdev->dev, "voltage-low detected.\n"); |
| 329 | 328 | ||
| 330 | if (pdata->irq >= 0) { | 329 | if (pdata->irq > 0) { |
| 331 | writeb(0, ioaddr + RTC_INTERRUPTS); | 330 | writeb(0, ioaddr + RTC_INTERRUPTS); |
| 332 | if (request_irq(pdata->irq, ds1553_rtc_interrupt, | 331 | if (request_irq(pdata->irq, ds1553_rtc_interrupt, |
| 333 | IRQF_DISABLED | IRQF_SHARED, | 332 | IRQF_DISABLED | IRQF_SHARED, |
| 334 | pdev->name, pdev) < 0) { | 333 | pdev->name, pdev) < 0) { |
| 335 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 334 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
| 336 | pdata->irq = -1; | 335 | pdata->irq = 0; |
| 337 | } | 336 | } |
| 338 | } | 337 | } |
| 339 | 338 | ||
| @@ -353,7 +352,7 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev) | |||
| 353 | out: | 352 | out: |
| 354 | if (pdata->rtc) | 353 | if (pdata->rtc) |
| 355 | rtc_device_unregister(pdata->rtc); | 354 | rtc_device_unregister(pdata->rtc); |
| 356 | if (pdata->irq >= 0) | 355 | if (pdata->irq > 0) |
| 357 | free_irq(pdata->irq, pdev); | 356 | free_irq(pdata->irq, pdev); |
| 358 | if (ioaddr) | 357 | if (ioaddr) |
| 359 | iounmap(ioaddr); | 358 | iounmap(ioaddr); |
| @@ -369,7 +368,7 @@ static int __devexit ds1553_rtc_remove(struct platform_device *pdev) | |||
| 369 | 368 | ||
| 370 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); | 369 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); |
| 371 | rtc_device_unregister(pdata->rtc); | 370 | rtc_device_unregister(pdata->rtc); |
| 372 | if (pdata->irq >= 0) { | 371 | if (pdata->irq > 0) { |
| 373 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); | 372 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); |
| 374 | free_irq(pdata->irq, pdev); | 373 | free_irq(pdata->irq, pdev); |
| 375 | } | 374 | } |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 4e91419e8911..06dfb54f99b6 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
| @@ -83,32 +83,11 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) | |||
| 83 | return 0; | 83 | return 0; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
| 87 | { | ||
| 88 | unsigned long secs; | ||
| 89 | |||
| 90 | dev_dbg(&client->dev, | ||
| 91 | "%s: secs=%d, mins=%d, hours=%d, " | ||
| 92 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
| 93 | __func__, | ||
| 94 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
| 95 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
| 96 | |||
| 97 | rtc_tm_to_time(tm, &secs); | ||
| 98 | |||
| 99 | return ds1672_set_mmss(client, secs); | ||
| 100 | } | ||
| 101 | |||
| 102 | static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm) | 86 | static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| 103 | { | 87 | { |
| 104 | return ds1672_get_datetime(to_i2c_client(dev), tm); | 88 | return ds1672_get_datetime(to_i2c_client(dev), tm); |
| 105 | } | 89 | } |
| 106 | 90 | ||
| 107 | static int ds1672_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 108 | { | ||
| 109 | return ds1672_set_datetime(to_i2c_client(dev), tm); | ||
| 110 | } | ||
| 111 | |||
| 112 | static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) | 91 | static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) |
| 113 | { | 92 | { |
| 114 | return ds1672_set_mmss(to_i2c_client(dev), secs); | 93 | return ds1672_set_mmss(to_i2c_client(dev), secs); |
| @@ -152,7 +131,6 @@ static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); | |||
| 152 | 131 | ||
| 153 | static const struct rtc_class_ops ds1672_rtc_ops = { | 132 | static const struct rtc_class_ops ds1672_rtc_ops = { |
| 154 | .read_time = ds1672_rtc_read_time, | 133 | .read_time = ds1672_rtc_read_time, |
| 155 | .set_time = ds1672_rtc_set_time, | ||
| 156 | .set_mmss = ds1672_rtc_set_mmss, | 134 | .set_mmss = ds1672_rtc_set_mmss, |
| 157 | }; | 135 | }; |
| 158 | 136 | ||
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c index 45e5b106af73..c51589ede5b7 100644 --- a/drivers/rtc/rtc-ds3234.c +++ b/drivers/rtc/rtc-ds3234.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* drivers/rtc/rtc-ds3234.c | 1 | /* rtc-ds3234.c |
| 2 | * | 2 | * |
| 3 | * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal | 3 | * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal |
| 4 | * and SRAM. | 4 | * and SRAM. |
| @@ -9,13 +9,10 @@ | |||
| 9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
| 10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
| 11 | * | 11 | * |
| 12 | * Changelog: | ||
| 13 | * | ||
| 14 | * 07-May-2008: Dennis Aberilla <denzzzhome@yahoo.com> | ||
| 15 | * - Created based on the max6902 code. Only implements the | ||
| 16 | * date/time keeping functions; no SRAM yet. | ||
| 17 | */ | 12 | */ |
| 18 | 13 | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 19 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 20 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 21 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
| @@ -34,16 +31,7 @@ | |||
| 34 | #define DS3234_REG_CONTROL 0x0E | 31 | #define DS3234_REG_CONTROL 0x0E |
| 35 | #define DS3234_REG_CONT_STAT 0x0F | 32 | #define DS3234_REG_CONT_STAT 0x0F |
| 36 | 33 | ||
| 37 | #undef DS3234_DEBUG | 34 | static int ds3234_set_reg(struct device *dev, unsigned char address, |
| 38 | |||
| 39 | struct ds3234 { | ||
| 40 | struct rtc_device *rtc; | ||
| 41 | u8 buf[8]; /* Burst read: addr + 7 regs */ | ||
| 42 | u8 tx_buf[2]; | ||
| 43 | u8 rx_buf[2]; | ||
| 44 | }; | ||
| 45 | |||
| 46 | static void ds3234_set_reg(struct device *dev, unsigned char address, | ||
| 47 | unsigned char data) | 35 | unsigned char data) |
| 48 | { | 36 | { |
| 49 | struct spi_device *spi = to_spi_device(dev); | 37 | struct spi_device *spi = to_spi_device(dev); |
| @@ -53,107 +41,45 @@ static void ds3234_set_reg(struct device *dev, unsigned char address, | |||
| 53 | buf[0] = address | 0x80; | 41 | buf[0] = address | 0x80; |
| 54 | buf[1] = data; | 42 | buf[1] = data; |
| 55 | 43 | ||
| 56 | spi_write(spi, buf, 2); | 44 | return spi_write_then_read(spi, buf, 2, NULL, 0); |
| 57 | } | 45 | } |
| 58 | 46 | ||
| 59 | static int ds3234_get_reg(struct device *dev, unsigned char address, | 47 | static int ds3234_get_reg(struct device *dev, unsigned char address, |
| 60 | unsigned char *data) | 48 | unsigned char *data) |
| 61 | { | 49 | { |
| 62 | struct spi_device *spi = to_spi_device(dev); | 50 | struct spi_device *spi = to_spi_device(dev); |
| 63 | struct ds3234 *chip = dev_get_drvdata(dev); | ||
| 64 | struct spi_message message; | ||
| 65 | struct spi_transfer xfer; | ||
| 66 | int status; | ||
| 67 | |||
| 68 | if (!data) | ||
| 69 | return -EINVAL; | ||
| 70 | |||
| 71 | /* Build our spi message */ | ||
| 72 | spi_message_init(&message); | ||
| 73 | memset(&xfer, 0, sizeof(xfer)); | ||
| 74 | |||
| 75 | /* Address + dummy tx byte */ | ||
| 76 | xfer.len = 2; | ||
| 77 | xfer.tx_buf = chip->tx_buf; | ||
| 78 | xfer.rx_buf = chip->rx_buf; | ||
| 79 | |||
| 80 | chip->tx_buf[0] = address; | ||
| 81 | chip->tx_buf[1] = 0xff; | ||
| 82 | 51 | ||
| 83 | spi_message_add_tail(&xfer, &message); | 52 | *data = address & 0x7f; |
| 84 | 53 | ||
| 85 | /* do the i/o */ | 54 | return spi_write_then_read(spi, data, 1, data, 1); |
| 86 | status = spi_sync(spi, &message); | ||
| 87 | if (status == 0) | ||
| 88 | status = message.status; | ||
| 89 | else | ||
| 90 | return status; | ||
| 91 | |||
| 92 | *data = chip->rx_buf[1]; | ||
| 93 | |||
| 94 | return status; | ||
| 95 | } | 55 | } |
| 96 | 56 | ||
| 97 | static int ds3234_get_datetime(struct device *dev, struct rtc_time *dt) | 57 | static int ds3234_read_time(struct device *dev, struct rtc_time *dt) |
| 98 | { | 58 | { |
| 59 | int err; | ||
| 60 | unsigned char buf[8]; | ||
| 99 | struct spi_device *spi = to_spi_device(dev); | 61 | struct spi_device *spi = to_spi_device(dev); |
| 100 | struct ds3234 *chip = dev_get_drvdata(dev); | ||
| 101 | struct spi_message message; | ||
| 102 | struct spi_transfer xfer; | ||
| 103 | int status; | ||
| 104 | |||
| 105 | /* build the message */ | ||
| 106 | spi_message_init(&message); | ||
| 107 | memset(&xfer, 0, sizeof(xfer)); | ||
| 108 | xfer.len = 1 + 7; /* Addr + 7 registers */ | ||
| 109 | xfer.tx_buf = chip->buf; | ||
| 110 | xfer.rx_buf = chip->buf; | ||
| 111 | chip->buf[0] = 0x00; /* Start address */ | ||
| 112 | spi_message_add_tail(&xfer, &message); | ||
| 113 | |||
| 114 | /* do the i/o */ | ||
| 115 | status = spi_sync(spi, &message); | ||
| 116 | if (status == 0) | ||
| 117 | status = message.status; | ||
| 118 | else | ||
| 119 | return status; | ||
| 120 | 62 | ||
| 121 | /* Seconds, Minutes, Hours, Day, Date, Month, Year */ | 63 | buf[0] = 0x00; /* Start address */ |
| 122 | dt->tm_sec = bcd2bin(chip->buf[1]); | ||
| 123 | dt->tm_min = bcd2bin(chip->buf[2]); | ||
| 124 | dt->tm_hour = bcd2bin(chip->buf[3] & 0x3f); | ||
| 125 | dt->tm_wday = bcd2bin(chip->buf[4]) - 1; /* 0 = Sun */ | ||
| 126 | dt->tm_mday = bcd2bin(chip->buf[5]); | ||
| 127 | dt->tm_mon = bcd2bin(chip->buf[6] & 0x1f) - 1; /* 0 = Jan */ | ||
| 128 | dt->tm_year = bcd2bin(chip->buf[7] & 0xff) + 100; /* Assume 20YY */ | ||
| 129 | |||
| 130 | #ifdef DS3234_DEBUG | ||
| 131 | dev_dbg(dev, "\n%s : Read RTC values\n", __func__); | ||
| 132 | dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); | ||
| 133 | dev_dbg(dev, "tm_min : %i\n", dt->tm_min); | ||
| 134 | dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); | ||
| 135 | dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); | ||
| 136 | dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); | ||
| 137 | dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); | ||
| 138 | dev_dbg(dev, "tm_year: %i\n", dt->tm_year); | ||
| 139 | #endif | ||
| 140 | 64 | ||
| 141 | return 0; | 65 | err = spi_write_then_read(spi, buf, 1, buf, 8); |
| 66 | if (err != 0) | ||
| 67 | return err; | ||
| 68 | |||
| 69 | /* Seconds, Minutes, Hours, Day, Date, Month, Year */ | ||
| 70 | dt->tm_sec = bcd2bin(buf[0]); | ||
| 71 | dt->tm_min = bcd2bin(buf[1]); | ||
| 72 | dt->tm_hour = bcd2bin(buf[2] & 0x3f); | ||
| 73 | dt->tm_wday = bcd2bin(buf[3]) - 1; /* 0 = Sun */ | ||
| 74 | dt->tm_mday = bcd2bin(buf[4]); | ||
| 75 | dt->tm_mon = bcd2bin(buf[5] & 0x1f) - 1; /* 0 = Jan */ | ||
| 76 | dt->tm_year = bcd2bin(buf[6] & 0xff) + 100; /* Assume 20YY */ | ||
| 77 | |||
| 78 | return rtc_valid_tm(dt); | ||
| 142 | } | 79 | } |
| 143 | 80 | ||
| 144 | static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt) | 81 | static int ds3234_set_time(struct device *dev, struct rtc_time *dt) |
| 145 | { | 82 | { |
| 146 | #ifdef DS3234_DEBUG | ||
| 147 | dev_dbg(dev, "\n%s : Setting RTC values\n", __func__); | ||
| 148 | dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); | ||
| 149 | dev_dbg(dev, "tm_min : %i\n", dt->tm_min); | ||
| 150 | dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); | ||
| 151 | dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); | ||
| 152 | dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); | ||
| 153 | dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); | ||
| 154 | dev_dbg(dev, "tm_year: %i\n", dt->tm_year); | ||
| 155 | #endif | ||
| 156 | |||
| 157 | ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec)); | 83 | ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec)); |
| 158 | ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min)); | 84 | ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min)); |
| 159 | ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f); | 85 | ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f); |
| @@ -174,16 +100,6 @@ static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt) | |||
| 174 | return 0; | 100 | return 0; |
| 175 | } | 101 | } |
| 176 | 102 | ||
| 177 | static int ds3234_read_time(struct device *dev, struct rtc_time *tm) | ||
| 178 | { | ||
| 179 | return ds3234_get_datetime(dev, tm); | ||
| 180 | } | ||
| 181 | |||
| 182 | static int ds3234_set_time(struct device *dev, struct rtc_time *tm) | ||
| 183 | { | ||
| 184 | return ds3234_set_datetime(dev, tm); | ||
| 185 | } | ||
| 186 | |||
| 187 | static const struct rtc_class_ops ds3234_rtc_ops = { | 103 | static const struct rtc_class_ops ds3234_rtc_ops = { |
| 188 | .read_time = ds3234_read_time, | 104 | .read_time = ds3234_read_time, |
| 189 | .set_time = ds3234_set_time, | 105 | .set_time = ds3234_set_time, |
| @@ -193,31 +109,15 @@ static int __devinit ds3234_probe(struct spi_device *spi) | |||
| 193 | { | 109 | { |
| 194 | struct rtc_device *rtc; | 110 | struct rtc_device *rtc; |
| 195 | unsigned char tmp; | 111 | unsigned char tmp; |
| 196 | struct ds3234 *chip; | ||
| 197 | int res; | 112 | int res; |
| 198 | 113 | ||
| 199 | rtc = rtc_device_register("ds3234", | ||
| 200 | &spi->dev, &ds3234_rtc_ops, THIS_MODULE); | ||
| 201 | if (IS_ERR(rtc)) | ||
| 202 | return PTR_ERR(rtc); | ||
| 203 | |||
| 204 | spi->mode = SPI_MODE_3; | 114 | spi->mode = SPI_MODE_3; |
| 205 | spi->bits_per_word = 8; | 115 | spi->bits_per_word = 8; |
| 206 | spi_setup(spi); | 116 | spi_setup(spi); |
| 207 | 117 | ||
| 208 | chip = kzalloc(sizeof(struct ds3234), GFP_KERNEL); | ||
| 209 | if (!chip) { | ||
| 210 | rtc_device_unregister(rtc); | ||
| 211 | return -ENOMEM; | ||
| 212 | } | ||
| 213 | chip->rtc = rtc; | ||
| 214 | dev_set_drvdata(&spi->dev, chip); | ||
| 215 | |||
| 216 | res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp); | 118 | res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp); |
| 217 | if (res) { | 119 | if (res != 0) |
| 218 | rtc_device_unregister(rtc); | ||
| 219 | return res; | 120 | return res; |
| 220 | } | ||
| 221 | 121 | ||
| 222 | /* Control settings | 122 | /* Control settings |
| 223 | * | 123 | * |
| @@ -246,26 +146,27 @@ static int __devinit ds3234_probe(struct spi_device *spi) | |||
| 246 | ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); | 146 | ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); |
| 247 | dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); | 147 | dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); |
| 248 | 148 | ||
| 149 | rtc = rtc_device_register("ds3234", | ||
| 150 | &spi->dev, &ds3234_rtc_ops, THIS_MODULE); | ||
| 151 | if (IS_ERR(rtc)) | ||
| 152 | return PTR_ERR(rtc); | ||
| 153 | |||
| 154 | dev_set_drvdata(&spi->dev, rtc); | ||
| 155 | |||
| 249 | return 0; | 156 | return 0; |
| 250 | } | 157 | } |
| 251 | 158 | ||
| 252 | static int __devexit ds3234_remove(struct spi_device *spi) | 159 | static int __devexit ds3234_remove(struct spi_device *spi) |
| 253 | { | 160 | { |
| 254 | struct ds3234 *chip = platform_get_drvdata(spi); | 161 | struct rtc_device *rtc = platform_get_drvdata(spi); |
| 255 | struct rtc_device *rtc = chip->rtc; | ||
| 256 | |||
| 257 | if (rtc) | ||
| 258 | rtc_device_unregister(rtc); | ||
| 259 | |||
| 260 | kfree(chip); | ||
| 261 | 162 | ||
| 163 | rtc_device_unregister(rtc); | ||
| 262 | return 0; | 164 | return 0; |
| 263 | } | 165 | } |
| 264 | 166 | ||
| 265 | static struct spi_driver ds3234_driver = { | 167 | static struct spi_driver ds3234_driver = { |
| 266 | .driver = { | 168 | .driver = { |
| 267 | .name = "ds3234", | 169 | .name = "ds3234", |
| 268 | .bus = &spi_bus_type, | ||
| 269 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
| 270 | }, | 171 | }, |
| 271 | .probe = ds3234_probe, | 172 | .probe = ds3234_probe, |
| @@ -274,7 +175,6 @@ static struct spi_driver ds3234_driver = { | |||
| 274 | 175 | ||
| 275 | static __init int ds3234_init(void) | 176 | static __init int ds3234_init(void) |
| 276 | { | 177 | { |
| 277 | printk(KERN_INFO "DS3234 SPI RTC Driver\n"); | ||
| 278 | return spi_register_driver(&ds3234_driver); | 178 | return spi_register_driver(&ds3234_driver); |
| 279 | } | 179 | } |
| 280 | module_init(ds3234_init); | 180 | module_init(ds3234_init); |
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 36e4ac0bd69c..f7a3283dd029 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
| @@ -49,18 +49,6 @@ static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) | |||
| 49 | return 0; | 49 | return 0; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 53 | { | ||
| 54 | int err; | ||
| 55 | unsigned long secs; | ||
| 56 | |||
| 57 | err = rtc_tm_to_time(tm, &secs); | ||
| 58 | if (err != 0) | ||
| 59 | return err; | ||
| 60 | |||
| 61 | return ep93xx_rtc_set_mmss(dev, secs); | ||
| 62 | } | ||
| 63 | |||
| 64 | static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) | 52 | static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) |
| 65 | { | 53 | { |
| 66 | unsigned short preload, delete; | 54 | unsigned short preload, delete; |
| @@ -75,7 +63,6 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) | |||
| 75 | 63 | ||
| 76 | static const struct rtc_class_ops ep93xx_rtc_ops = { | 64 | static const struct rtc_class_ops ep93xx_rtc_ops = { |
| 77 | .read_time = ep93xx_rtc_read_time, | 65 | .read_time = ep93xx_rtc_read_time, |
| 78 | .set_time = ep93xx_rtc_set_time, | ||
| 79 | .set_mmss = ep93xx_rtc_set_mmss, | 66 | .set_mmss = ep93xx_rtc_set_mmss, |
| 80 | .proc = ep93xx_rtc_proc, | 67 | .proc = ep93xx_rtc_proc, |
| 81 | }; | 68 | }; |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 43afb7ab5289..33921a6b1707 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
| @@ -450,7 +450,7 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev) | |||
| 450 | * the mode without IRQ. | 450 | * the mode without IRQ. |
| 451 | */ | 451 | */ |
| 452 | m48t59->irq = platform_get_irq(pdev, 0); | 452 | m48t59->irq = platform_get_irq(pdev, 0); |
| 453 | if (m48t59->irq < 0) | 453 | if (m48t59->irq <= 0) |
| 454 | m48t59->irq = NO_IRQ; | 454 | m48t59->irq = NO_IRQ; |
| 455 | 455 | ||
| 456 | if (m48t59->irq != NO_IRQ) { | 456 | if (m48t59->irq != NO_IRQ) { |
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 2f6507df7b49..36a8ea9ed8ba 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
| @@ -9,14 +9,6 @@ | |||
| 9 | * | 9 | * |
| 10 | * Driver for MAX6902 spi RTC | 10 | * Driver for MAX6902 spi RTC |
| 11 | * | 11 | * |
| 12 | * Changelog: | ||
| 13 | * | ||
| 14 | * 24-May-2006: Raphael Assenat <raph@8d.com> | ||
| 15 | * - Major rework | ||
| 16 | * Converted to rtc_device and uses the SPI layer. | ||
| 17 | * | ||
| 18 | * ??-???-2005: Someone at Compulab | ||
| 19 | * - Initial driver creation. | ||
| 20 | */ | 12 | */ |
| 21 | 13 | ||
| 22 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| @@ -26,7 +18,6 @@ | |||
| 26 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
| 27 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
| 28 | #include <linux/bcd.h> | 20 | #include <linux/bcd.h> |
| 29 | #include <linux/delay.h> | ||
| 30 | 21 | ||
| 31 | #define MAX6902_REG_SECONDS 0x01 | 22 | #define MAX6902_REG_SECONDS 0x01 |
| 32 | #define MAX6902_REG_MINUTES 0x03 | 23 | #define MAX6902_REG_MINUTES 0x03 |
| @@ -38,16 +29,7 @@ | |||
| 38 | #define MAX6902_REG_CONTROL 0x0F | 29 | #define MAX6902_REG_CONTROL 0x0F |
| 39 | #define MAX6902_REG_CENTURY 0x13 | 30 | #define MAX6902_REG_CENTURY 0x13 |
| 40 | 31 | ||
| 41 | #undef MAX6902_DEBUG | 32 | static int max6902_set_reg(struct device *dev, unsigned char address, |
| 42 | |||
| 43 | struct max6902 { | ||
| 44 | struct rtc_device *rtc; | ||
| 45 | u8 buf[9]; /* Burst read cmd + 8 registers */ | ||
| 46 | u8 tx_buf[2]; | ||
| 47 | u8 rx_buf[2]; | ||
| 48 | }; | ||
| 49 | |||
| 50 | static void max6902_set_reg(struct device *dev, unsigned char address, | ||
| 51 | unsigned char data) | 33 | unsigned char data) |
| 52 | { | 34 | { |
| 53 | struct spi_device *spi = to_spi_device(dev); | 35 | struct spi_device *spi = to_spi_device(dev); |
| @@ -57,113 +39,58 @@ static void max6902_set_reg(struct device *dev, unsigned char address, | |||
| 57 | buf[0] = address & 0x7f; | 39 | buf[0] = address & 0x7f; |
| 58 | buf[1] = data; | 40 | buf[1] = data; |
| 59 | 41 | ||
| 60 | spi_write(spi, buf, 2); | 42 | return spi_write_then_read(spi, buf, 2, NULL, 0); |
| 61 | } | 43 | } |
| 62 | 44 | ||
| 63 | static int max6902_get_reg(struct device *dev, unsigned char address, | 45 | static int max6902_get_reg(struct device *dev, unsigned char address, |
| 64 | unsigned char *data) | 46 | unsigned char *data) |
| 65 | { | 47 | { |
| 66 | struct spi_device *spi = to_spi_device(dev); | 48 | struct spi_device *spi = to_spi_device(dev); |
| 67 | struct max6902 *chip = dev_get_drvdata(dev); | ||
| 68 | struct spi_message message; | ||
| 69 | struct spi_transfer xfer; | ||
| 70 | int status; | ||
| 71 | |||
| 72 | if (!data) | ||
| 73 | return -EINVAL; | ||
| 74 | |||
| 75 | /* Build our spi message */ | ||
| 76 | spi_message_init(&message); | ||
| 77 | memset(&xfer, 0, sizeof(xfer)); | ||
| 78 | xfer.len = 2; | ||
| 79 | /* Can tx_buf and rx_buf be equal? The doc in spi.h is not sure... */ | ||
| 80 | xfer.tx_buf = chip->tx_buf; | ||
| 81 | xfer.rx_buf = chip->rx_buf; | ||
| 82 | 49 | ||
| 83 | /* Set MSB to indicate read */ | 50 | /* Set MSB to indicate read */ |
| 84 | chip->tx_buf[0] = address | 0x80; | 51 | *data = address | 0x80; |
| 85 | |||
| 86 | spi_message_add_tail(&xfer, &message); | ||
| 87 | 52 | ||
| 88 | /* do the i/o */ | 53 | return spi_write_then_read(spi, data, 1, data, 1); |
| 89 | status = spi_sync(spi, &message); | ||
| 90 | |||
| 91 | if (status == 0) | ||
| 92 | *data = chip->rx_buf[1]; | ||
| 93 | return status; | ||
| 94 | } | 54 | } |
| 95 | 55 | ||
| 96 | static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) | 56 | static int max6902_read_time(struct device *dev, struct rtc_time *dt) |
| 97 | { | 57 | { |
| 98 | unsigned char tmp; | 58 | int err, century; |
| 99 | int century; | ||
| 100 | int err; | ||
| 101 | struct spi_device *spi = to_spi_device(dev); | 59 | struct spi_device *spi = to_spi_device(dev); |
| 102 | struct max6902 *chip = dev_get_drvdata(dev); | 60 | unsigned char buf[8]; |
| 103 | struct spi_message message; | ||
| 104 | struct spi_transfer xfer; | ||
| 105 | int status; | ||
| 106 | 61 | ||
| 107 | err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &tmp); | 62 | buf[0] = 0xbf; /* Burst read */ |
| 108 | if (err) | ||
| 109 | return err; | ||
| 110 | |||
| 111 | /* build the message */ | ||
| 112 | spi_message_init(&message); | ||
| 113 | memset(&xfer, 0, sizeof(xfer)); | ||
| 114 | xfer.len = 1 + 7; /* Burst read command + 7 registers */ | ||
| 115 | xfer.tx_buf = chip->buf; | ||
| 116 | xfer.rx_buf = chip->buf; | ||
| 117 | chip->buf[0] = 0xbf; /* Burst read */ | ||
| 118 | spi_message_add_tail(&xfer, &message); | ||
| 119 | 63 | ||
| 120 | /* do the i/o */ | 64 | err = spi_write_then_read(spi, buf, 1, buf, 8); |
| 121 | status = spi_sync(spi, &message); | 65 | if (err != 0) |
| 122 | if (status) | 66 | return err; |
| 123 | return status; | ||
| 124 | 67 | ||
| 125 | /* The chip sends data in this order: | 68 | /* The chip sends data in this order: |
| 126 | * Seconds, Minutes, Hours, Date, Month, Day, Year */ | 69 | * Seconds, Minutes, Hours, Date, Month, Day, Year */ |
| 127 | dt->tm_sec = bcd2bin(chip->buf[1]); | 70 | dt->tm_sec = bcd2bin(buf[0]); |
| 128 | dt->tm_min = bcd2bin(chip->buf[2]); | 71 | dt->tm_min = bcd2bin(buf[1]); |
| 129 | dt->tm_hour = bcd2bin(chip->buf[3]); | 72 | dt->tm_hour = bcd2bin(buf[2]); |
| 130 | dt->tm_mday = bcd2bin(chip->buf[4]); | 73 | dt->tm_mday = bcd2bin(buf[3]); |
| 131 | dt->tm_mon = bcd2bin(chip->buf[5]) - 1; | 74 | dt->tm_mon = bcd2bin(buf[4]) - 1; |
| 132 | dt->tm_wday = bcd2bin(chip->buf[6]); | 75 | dt->tm_wday = bcd2bin(buf[5]); |
| 133 | dt->tm_year = bcd2bin(chip->buf[7]); | 76 | dt->tm_year = bcd2bin(buf[6]); |
| 77 | |||
| 78 | /* Read century */ | ||
| 79 | err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &buf[0]); | ||
| 80 | if (err != 0) | ||
| 81 | return err; | ||
| 134 | 82 | ||
| 135 | century = bcd2bin(tmp) * 100; | 83 | century = bcd2bin(buf[0]) * 100; |
| 136 | 84 | ||
| 137 | dt->tm_year += century; | 85 | dt->tm_year += century; |
| 138 | dt->tm_year -= 1900; | 86 | dt->tm_year -= 1900; |
| 139 | 87 | ||
| 140 | #ifdef MAX6902_DEBUG | 88 | return rtc_valid_tm(dt); |
| 141 | printk("\n%s : Read RTC values\n",__func__); | ||
| 142 | printk("tm_hour: %i\n",dt->tm_hour); | ||
| 143 | printk("tm_min : %i\n",dt->tm_min); | ||
| 144 | printk("tm_sec : %i\n",dt->tm_sec); | ||
| 145 | printk("tm_year: %i\n",dt->tm_year); | ||
| 146 | printk("tm_mon : %i\n",dt->tm_mon); | ||
| 147 | printk("tm_mday: %i\n",dt->tm_mday); | ||
| 148 | printk("tm_wday: %i\n",dt->tm_wday); | ||
| 149 | #endif | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | } | 89 | } |
| 153 | 90 | ||
| 154 | static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | 91 | static int max6902_set_time(struct device *dev, struct rtc_time *dt) |
| 155 | { | 92 | { |
| 156 | dt->tm_year = dt->tm_year+1900; | 93 | dt->tm_year = dt->tm_year + 1900; |
| 157 | |||
| 158 | #ifdef MAX6902_DEBUG | ||
| 159 | printk("\n%s : Setting RTC values\n",__func__); | ||
| 160 | printk("tm_sec : %i\n",dt->tm_sec); | ||
| 161 | printk("tm_min : %i\n",dt->tm_min); | ||
| 162 | printk("tm_hour: %i\n",dt->tm_hour); | ||
| 163 | printk("tm_mday: %i\n",dt->tm_mday); | ||
| 164 | printk("tm_wday: %i\n",dt->tm_wday); | ||
| 165 | printk("tm_year: %i\n",dt->tm_year); | ||
| 166 | #endif | ||
| 167 | 94 | ||
| 168 | /* Remove write protection */ | 95 | /* Remove write protection */ |
| 169 | max6902_set_reg(dev, 0xF, 0); | 96 | max6902_set_reg(dev, 0xF, 0); |
| @@ -173,10 +100,10 @@ static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | |||
| 173 | max6902_set_reg(dev, 0x05, bin2bcd(dt->tm_hour)); | 100 | max6902_set_reg(dev, 0x05, bin2bcd(dt->tm_hour)); |
| 174 | 101 | ||
| 175 | max6902_set_reg(dev, 0x07, bin2bcd(dt->tm_mday)); | 102 | max6902_set_reg(dev, 0x07, bin2bcd(dt->tm_mday)); |
| 176 | max6902_set_reg(dev, 0x09, bin2bcd(dt->tm_mon+1)); | 103 | max6902_set_reg(dev, 0x09, bin2bcd(dt->tm_mon + 1)); |
| 177 | max6902_set_reg(dev, 0x0B, bin2bcd(dt->tm_wday)); | 104 | max6902_set_reg(dev, 0x0B, bin2bcd(dt->tm_wday)); |
| 178 | max6902_set_reg(dev, 0x0D, bin2bcd(dt->tm_year%100)); | 105 | max6902_set_reg(dev, 0x0D, bin2bcd(dt->tm_year % 100)); |
| 179 | max6902_set_reg(dev, 0x13, bin2bcd(dt->tm_year/100)); | 106 | max6902_set_reg(dev, 0x13, bin2bcd(dt->tm_year / 100)); |
| 180 | 107 | ||
| 181 | /* Compulab used a delay here. However, the datasheet | 108 | /* Compulab used a delay here. However, the datasheet |
| 182 | * does not mention a delay being required anywhere... */ | 109 | * does not mention a delay being required anywhere... */ |
| @@ -188,16 +115,6 @@ static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | |||
| 188 | return 0; | 115 | return 0; |
| 189 | } | 116 | } |
| 190 | 117 | ||
| 191 | static int max6902_read_time(struct device *dev, struct rtc_time *tm) | ||
| 192 | { | ||
| 193 | return max6902_get_datetime(dev, tm); | ||
| 194 | } | ||
| 195 | |||
| 196 | static int max6902_set_time(struct device *dev, struct rtc_time *tm) | ||
| 197 | { | ||
| 198 | return max6902_set_datetime(dev, tm); | ||
| 199 | } | ||
| 200 | |||
| 201 | static const struct rtc_class_ops max6902_rtc_ops = { | 118 | static const struct rtc_class_ops max6902_rtc_ops = { |
| 202 | .read_time = max6902_read_time, | 119 | .read_time = max6902_read_time, |
| 203 | .set_time = max6902_set_time, | 120 | .set_time = max6902_set_time, |
| @@ -207,45 +124,29 @@ static int __devinit max6902_probe(struct spi_device *spi) | |||
| 207 | { | 124 | { |
| 208 | struct rtc_device *rtc; | 125 | struct rtc_device *rtc; |
| 209 | unsigned char tmp; | 126 | unsigned char tmp; |
| 210 | struct max6902 *chip; | ||
| 211 | int res; | 127 | int res; |
| 212 | 128 | ||
| 213 | rtc = rtc_device_register("max6902", | ||
| 214 | &spi->dev, &max6902_rtc_ops, THIS_MODULE); | ||
| 215 | if (IS_ERR(rtc)) | ||
| 216 | return PTR_ERR(rtc); | ||
| 217 | |||
| 218 | spi->mode = SPI_MODE_3; | 129 | spi->mode = SPI_MODE_3; |
| 219 | spi->bits_per_word = 8; | 130 | spi->bits_per_word = 8; |
| 220 | spi_setup(spi); | 131 | spi_setup(spi); |
| 221 | 132 | ||
| 222 | chip = kzalloc(sizeof *chip, GFP_KERNEL); | ||
| 223 | if (!chip) { | ||
| 224 | rtc_device_unregister(rtc); | ||
| 225 | return -ENOMEM; | ||
| 226 | } | ||
| 227 | chip->rtc = rtc; | ||
| 228 | dev_set_drvdata(&spi->dev, chip); | ||
| 229 | |||
| 230 | res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp); | 133 | res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp); |
| 231 | if (res) { | 134 | if (res != 0) |
| 232 | rtc_device_unregister(rtc); | ||
| 233 | return res; | 135 | return res; |
| 234 | } | 136 | |
| 137 | rtc = rtc_device_register("max6902", | ||
| 138 | &spi->dev, &max6902_rtc_ops, THIS_MODULE); | ||
| 139 | if (IS_ERR(rtc)) | ||
| 140 | return PTR_ERR(rtc); | ||
| 235 | 141 | ||
| 236 | return 0; | 142 | return 0; |
| 237 | } | 143 | } |
| 238 | 144 | ||
| 239 | static int __devexit max6902_remove(struct spi_device *spi) | 145 | static int __devexit max6902_remove(struct spi_device *spi) |
| 240 | { | 146 | { |
| 241 | struct max6902 *chip = platform_get_drvdata(spi); | 147 | struct rtc_device *rtc = platform_get_drvdata(spi); |
| 242 | struct rtc_device *rtc = chip->rtc; | ||
| 243 | |||
| 244 | if (rtc) | ||
| 245 | rtc_device_unregister(rtc); | ||
| 246 | |||
| 247 | kfree(chip); | ||
| 248 | 148 | ||
| 149 | rtc_device_unregister(rtc); | ||
| 249 | return 0; | 150 | return 0; |
| 250 | } | 151 | } |
| 251 | 152 | ||
| @@ -261,7 +162,6 @@ static struct spi_driver max6902_driver = { | |||
| 261 | 162 | ||
| 262 | static __init int max6902_init(void) | 163 | static __init int max6902_init(void) |
| 263 | { | 164 | { |
| 264 | printk("max6902 spi driver\n"); | ||
| 265 | return spi_register_driver(&max6902_driver); | 165 | return spi_register_driver(&max6902_driver); |
| 266 | } | 166 | } |
| 267 | module_init(max6902_init); | 167 | module_init(max6902_init); |
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c new file mode 100644 index 000000000000..45f12dcd3716 --- /dev/null +++ b/drivers/rtc/rtc-mv.c | |||
| @@ -0,0 +1,163 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the RTC in Marvell SoCs. | ||
| 3 | * | ||
| 4 | * This file is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2. This program is licensed "as is" without any | ||
| 6 | * warranty of any kind, whether express or implied. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/rtc.h> | ||
| 12 | #include <linux/bcd.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | |||
| 17 | #define RTC_TIME_REG_OFFS 0 | ||
| 18 | #define RTC_SECONDS_OFFS 0 | ||
| 19 | #define RTC_MINUTES_OFFS 8 | ||
| 20 | #define RTC_HOURS_OFFS 16 | ||
| 21 | #define RTC_WDAY_OFFS 24 | ||
| 22 | #define RTC_HOURS_12H_MODE (1 << 22) /* 12 hours mode */ | ||
| 23 | |||
| 24 | #define RTC_DATE_REG_OFFS 4 | ||
| 25 | #define RTC_MDAY_OFFS 0 | ||
| 26 | #define RTC_MONTH_OFFS 8 | ||
| 27 | #define RTC_YEAR_OFFS 16 | ||
| 28 | |||
| 29 | |||
| 30 | struct rtc_plat_data { | ||
| 31 | struct rtc_device *rtc; | ||
| 32 | void __iomem *ioaddr; | ||
| 33 | }; | ||
| 34 | |||
| 35 | static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 36 | { | ||
| 37 | struct rtc_plat_data *pdata = dev_get_drvdata(dev); | ||
| 38 | void __iomem *ioaddr = pdata->ioaddr; | ||
| 39 | u32 rtc_reg; | ||
| 40 | |||
| 41 | rtc_reg = (bin2bcd(tm->tm_sec) << RTC_SECONDS_OFFS) | | ||
| 42 | (bin2bcd(tm->tm_min) << RTC_MINUTES_OFFS) | | ||
| 43 | (bin2bcd(tm->tm_hour) << RTC_HOURS_OFFS) | | ||
| 44 | (bin2bcd(tm->tm_wday) << RTC_WDAY_OFFS); | ||
| 45 | writel(rtc_reg, ioaddr + RTC_TIME_REG_OFFS); | ||
| 46 | |||
| 47 | rtc_reg = (bin2bcd(tm->tm_mday) << RTC_MDAY_OFFS) | | ||
| 48 | (bin2bcd(tm->tm_mon + 1) << RTC_MONTH_OFFS) | | ||
| 49 | (bin2bcd(tm->tm_year % 100) << RTC_YEAR_OFFS); | ||
| 50 | writel(rtc_reg, ioaddr + RTC_DATE_REG_OFFS); | ||
| 51 | |||
| 52 | return 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | static int mv_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 56 | { | ||
| 57 | struct rtc_plat_data *pdata = dev_get_drvdata(dev); | ||
| 58 | void __iomem *ioaddr = pdata->ioaddr; | ||
| 59 | u32 rtc_time, rtc_date; | ||
| 60 | unsigned int year, month, day, hour, minute, second, wday; | ||
| 61 | |||
| 62 | rtc_time = readl(ioaddr + RTC_TIME_REG_OFFS); | ||
| 63 | rtc_date = readl(ioaddr + RTC_DATE_REG_OFFS); | ||
| 64 | |||
| 65 | second = rtc_time & 0x7f; | ||
| 66 | minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f; | ||
| 67 | hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hours mode */ | ||
| 68 | wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7; | ||
| 69 | |||
| 70 | day = rtc_date & 0x3f; | ||
| 71 | month = (rtc_date >> RTC_MONTH_OFFS) & 0x3f; | ||
| 72 | year = (rtc_date >> RTC_YEAR_OFFS) & 0xff; | ||
| 73 | |||
| 74 | tm->tm_sec = bcd2bin(second); | ||
| 75 | tm->tm_min = bcd2bin(minute); | ||
| 76 | tm->tm_hour = bcd2bin(hour); | ||
| 77 | tm->tm_mday = bcd2bin(day); | ||
| 78 | tm->tm_wday = bcd2bin(wday); | ||
| 79 | tm->tm_mon = bcd2bin(month) - 1; | ||
| 80 | /* hw counts from year 2000, but tm_year is relative to 1900 */ | ||
| 81 | tm->tm_year = bcd2bin(year) + 100; | ||
| 82 | |||
| 83 | return rtc_valid_tm(tm); | ||
| 84 | } | ||
| 85 | |||
| 86 | static const struct rtc_class_ops mv_rtc_ops = { | ||
| 87 | .read_time = mv_rtc_read_time, | ||
| 88 | .set_time = mv_rtc_set_time, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static int __init mv_rtc_probe(struct platform_device *pdev) | ||
| 92 | { | ||
| 93 | struct resource *res; | ||
| 94 | struct rtc_plat_data *pdata; | ||
| 95 | resource_size_t size; | ||
| 96 | u32 rtc_time; | ||
| 97 | |||
| 98 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 99 | if (!res) | ||
| 100 | return -ENODEV; | ||
| 101 | |||
| 102 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
| 103 | if (!pdata) | ||
| 104 | return -ENOMEM; | ||
| 105 | |||
| 106 | size = resource_size(res); | ||
| 107 | if (!devm_request_mem_region(&pdev->dev, res->start, size, | ||
| 108 | pdev->name)) | ||
| 109 | return -EBUSY; | ||
| 110 | |||
| 111 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, size); | ||
| 112 | if (!pdata->ioaddr) | ||
| 113 | return -ENOMEM; | ||
| 114 | |||
| 115 | /* make sure the 24 hours mode is enabled */ | ||
| 116 | rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); | ||
| 117 | if (rtc_time & RTC_HOURS_12H_MODE) { | ||
| 118 | dev_err(&pdev->dev, "24 Hours mode not supported.\n"); | ||
| 119 | return -EINVAL; | ||
| 120 | } | ||
| 121 | |||
| 122 | platform_set_drvdata(pdev, pdata); | ||
| 123 | pdata->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
| 124 | &mv_rtc_ops, THIS_MODULE); | ||
| 125 | if (IS_ERR(pdata->rtc)) | ||
| 126 | return PTR_ERR(pdata->rtc); | ||
| 127 | |||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | static int __exit mv_rtc_remove(struct platform_device *pdev) | ||
| 132 | { | ||
| 133 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
| 134 | |||
| 135 | rtc_device_unregister(pdata->rtc); | ||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static struct platform_driver mv_rtc_driver = { | ||
| 140 | .remove = __exit_p(mv_rtc_remove), | ||
| 141 | .driver = { | ||
| 142 | .name = "rtc-mv", | ||
| 143 | .owner = THIS_MODULE, | ||
| 144 | }, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static __init int mv_init(void) | ||
| 148 | { | ||
| 149 | return platform_driver_probe(&mv_rtc_driver, mv_rtc_probe); | ||
| 150 | } | ||
| 151 | |||
| 152 | static __exit void mv_exit(void) | ||
| 153 | { | ||
| 154 | platform_driver_unregister(&mv_rtc_driver); | ||
| 155 | } | ||
| 156 | |||
| 157 | module_init(mv_init); | ||
| 158 | module_exit(mv_exit); | ||
| 159 | |||
| 160 | MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>"); | ||
| 161 | MODULE_DESCRIPTION("Marvell RTC driver"); | ||
| 162 | MODULE_LICENSE("GPL"); | ||
| 163 | MODULE_ALIAS("platform:rtc-mv"); | ||
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c index 346d633655e7..c6bfa6fe1a2a 100644 --- a/drivers/rtc/rtc-parisc.c +++ b/drivers/rtc/rtc-parisc.c | |||
| @@ -34,7 +34,8 @@ static int parisc_get_time(struct device *dev, struct rtc_time *tm) | |||
| 34 | static int parisc_set_time(struct device *dev, struct rtc_time *tm) | 34 | static int parisc_set_time(struct device *dev, struct rtc_time *tm) |
| 35 | { | 35 | { |
| 36 | struct parisc_rtc *p = dev_get_drvdata(dev); | 36 | struct parisc_rtc *p = dev_get_drvdata(dev); |
| 37 | unsigned long flags, ret; | 37 | unsigned long flags; |
| 38 | int ret; | ||
| 38 | 39 | ||
| 39 | spin_lock_irqsave(&p->lock, flags); | 40 | spin_lock_irqsave(&p->lock, flags); |
| 40 | ret = set_rtc_time(tm); | 41 | ret = set_rtc_time(tm); |
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c new file mode 100644 index 000000000000..f4dd87e29075 --- /dev/null +++ b/drivers/rtc/rtc-pcf50633.c | |||
| @@ -0,0 +1,344 @@ | |||
| 1 | /* NXP PCF50633 RTC Driver | ||
| 2 | * | ||
| 3 | * (C) 2006-2008 by Openmoko, Inc. | ||
| 4 | * Author: Balaji Rao <balajirrao@openmoko.org> | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Broken down from monstrous PCF50633 driver mainly by | ||
| 8 | * Harald Welte, Andy Green and Werner Almesberger | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 13 | * option) any later version. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/device.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/rtc.h> | ||
| 23 | #include <linux/bcd.h> | ||
| 24 | #include <linux/err.h> | ||
| 25 | |||
| 26 | #include <linux/mfd/pcf50633/core.h> | ||
| 27 | |||
| 28 | #define PCF50633_REG_RTCSC 0x59 /* Second */ | ||
| 29 | #define PCF50633_REG_RTCMN 0x5a /* Minute */ | ||
| 30 | #define PCF50633_REG_RTCHR 0x5b /* Hour */ | ||
| 31 | #define PCF50633_REG_RTCWD 0x5c /* Weekday */ | ||
| 32 | #define PCF50633_REG_RTCDT 0x5d /* Day */ | ||
| 33 | #define PCF50633_REG_RTCMT 0x5e /* Month */ | ||
| 34 | #define PCF50633_REG_RTCYR 0x5f /* Year */ | ||
| 35 | #define PCF50633_REG_RTCSCA 0x60 /* Alarm Second */ | ||
| 36 | #define PCF50633_REG_RTCMNA 0x61 /* Alarm Minute */ | ||
| 37 | #define PCF50633_REG_RTCHRA 0x62 /* Alarm Hour */ | ||
| 38 | #define PCF50633_REG_RTCWDA 0x63 /* Alarm Weekday */ | ||
| 39 | #define PCF50633_REG_RTCDTA 0x64 /* Alarm Day */ | ||
| 40 | #define PCF50633_REG_RTCMTA 0x65 /* Alarm Month */ | ||
| 41 | #define PCF50633_REG_RTCYRA 0x66 /* Alarm Year */ | ||
| 42 | |||
| 43 | enum pcf50633_time_indexes { | ||
| 44 | PCF50633_TI_SEC, | ||
| 45 | PCF50633_TI_MIN, | ||
| 46 | PCF50633_TI_HOUR, | ||
| 47 | PCF50633_TI_WKDAY, | ||
| 48 | PCF50633_TI_DAY, | ||
| 49 | PCF50633_TI_MONTH, | ||
| 50 | PCF50633_TI_YEAR, | ||
| 51 | PCF50633_TI_EXTENT /* always last */ | ||
| 52 | }; | ||
| 53 | |||
| 54 | struct pcf50633_time { | ||
| 55 | u_int8_t time[PCF50633_TI_EXTENT]; | ||
| 56 | }; | ||
| 57 | |||
| 58 | struct pcf50633_rtc { | ||
| 59 | int alarm_enabled; | ||
| 60 | int second_enabled; | ||
| 61 | |||
| 62 | struct pcf50633 *pcf; | ||
| 63 | struct rtc_device *rtc_dev; | ||
| 64 | }; | ||
| 65 | |||
| 66 | static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50633_time *pcf) | ||
| 67 | { | ||
| 68 | rtc->tm_sec = bcd2bin(pcf->time[PCF50633_TI_SEC]); | ||
| 69 | rtc->tm_min = bcd2bin(pcf->time[PCF50633_TI_MIN]); | ||
| 70 | rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]); | ||
| 71 | rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]); | ||
| 72 | rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]); | ||
| 73 | rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]); | ||
| 74 | rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100; | ||
| 75 | } | ||
| 76 | |||
| 77 | static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc) | ||
| 78 | { | ||
| 79 | pcf->time[PCF50633_TI_SEC] = bin2bcd(rtc->tm_sec); | ||
| 80 | pcf->time[PCF50633_TI_MIN] = bin2bcd(rtc->tm_min); | ||
| 81 | pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour); | ||
| 82 | pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday); | ||
| 83 | pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday); | ||
| 84 | pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon); | ||
| 85 | pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100); | ||
| 86 | } | ||
| 87 | |||
| 88 | static int | ||
| 89 | pcf50633_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
| 90 | { | ||
| 91 | struct pcf50633_rtc *rtc = dev_get_drvdata(dev); | ||
| 92 | int err; | ||
| 93 | |||
| 94 | if (enabled) | ||
| 95 | err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 96 | else | ||
| 97 | err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 98 | |||
| 99 | if (err < 0) | ||
| 100 | return err; | ||
| 101 | |||
| 102 | rtc->alarm_enabled = enabled; | ||
| 103 | |||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int | ||
| 108 | pcf50633_rtc_update_irq_enable(struct device *dev, unsigned int enabled) | ||
| 109 | { | ||
| 110 | struct pcf50633_rtc *rtc = dev_get_drvdata(dev); | ||
| 111 | int err; | ||
| 112 | |||
| 113 | if (enabled) | ||
| 114 | err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
| 115 | else | ||
| 116 | err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
| 117 | |||
| 118 | if (err < 0) | ||
| 119 | return err; | ||
| 120 | |||
| 121 | rtc->second_enabled = enabled; | ||
| 122 | |||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 127 | { | ||
| 128 | struct pcf50633_rtc *rtc; | ||
| 129 | struct pcf50633_time pcf_tm; | ||
| 130 | int ret; | ||
| 131 | |||
| 132 | rtc = dev_get_drvdata(dev); | ||
| 133 | |||
| 134 | ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSC, | ||
| 135 | PCF50633_TI_EXTENT, | ||
| 136 | &pcf_tm.time[0]); | ||
| 137 | if (ret != PCF50633_TI_EXTENT) { | ||
| 138 | dev_err(dev, "Failed to read time\n"); | ||
| 139 | return -EIO; | ||
| 140 | } | ||
| 141 | |||
| 142 | dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", | ||
| 143 | pcf_tm.time[PCF50633_TI_DAY], | ||
| 144 | pcf_tm.time[PCF50633_TI_MONTH], | ||
| 145 | pcf_tm.time[PCF50633_TI_YEAR], | ||
| 146 | pcf_tm.time[PCF50633_TI_HOUR], | ||
| 147 | pcf_tm.time[PCF50633_TI_MIN], | ||
| 148 | pcf_tm.time[PCF50633_TI_SEC]); | ||
| 149 | |||
| 150 | pcf2rtc_time(tm, &pcf_tm); | ||
| 151 | |||
| 152 | dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", | ||
| 153 | tm->tm_mday, tm->tm_mon, tm->tm_year, | ||
| 154 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
| 155 | |||
| 156 | return rtc_valid_tm(tm); | ||
| 157 | } | ||
| 158 | |||
| 159 | static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 160 | { | ||
| 161 | struct pcf50633_rtc *rtc; | ||
| 162 | struct pcf50633_time pcf_tm; | ||
| 163 | int second_masked, alarm_masked, ret = 0; | ||
| 164 | |||
| 165 | rtc = dev_get_drvdata(dev); | ||
| 166 | |||
| 167 | dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", | ||
| 168 | tm->tm_mday, tm->tm_mon, tm->tm_year, | ||
| 169 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
| 170 | |||
| 171 | rtc2pcf_time(&pcf_tm, tm); | ||
| 172 | |||
| 173 | dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", | ||
| 174 | pcf_tm.time[PCF50633_TI_DAY], | ||
| 175 | pcf_tm.time[PCF50633_TI_MONTH], | ||
| 176 | pcf_tm.time[PCF50633_TI_YEAR], | ||
| 177 | pcf_tm.time[PCF50633_TI_HOUR], | ||
| 178 | pcf_tm.time[PCF50633_TI_MIN], | ||
| 179 | pcf_tm.time[PCF50633_TI_SEC]); | ||
| 180 | |||
| 181 | |||
| 182 | second_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_SECOND); | ||
| 183 | alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 184 | |||
| 185 | if (!second_masked) | ||
| 186 | pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
| 187 | if (!alarm_masked) | ||
| 188 | pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 189 | |||
| 190 | /* Returns 0 on success */ | ||
| 191 | ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSC, | ||
| 192 | PCF50633_TI_EXTENT, | ||
| 193 | &pcf_tm.time[0]); | ||
| 194 | |||
| 195 | if (!second_masked) | ||
| 196 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
| 197 | if (!alarm_masked) | ||
| 198 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 199 | |||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | |||
| 203 | static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 204 | { | ||
| 205 | struct pcf50633_rtc *rtc; | ||
| 206 | struct pcf50633_time pcf_tm; | ||
| 207 | int ret = 0; | ||
| 208 | |||
| 209 | rtc = dev_get_drvdata(dev); | ||
| 210 | |||
| 211 | alrm->enabled = rtc->alarm_enabled; | ||
| 212 | |||
| 213 | ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA, | ||
| 214 | PCF50633_TI_EXTENT, &pcf_tm.time[0]); | ||
| 215 | if (ret != PCF50633_TI_EXTENT) { | ||
| 216 | dev_err(dev, "Failed to read time\n"); | ||
| 217 | return -EIO; | ||
| 218 | } | ||
| 219 | |||
| 220 | pcf2rtc_time(&alrm->time, &pcf_tm); | ||
| 221 | |||
| 222 | return rtc_valid_tm(&alrm->time); | ||
| 223 | } | ||
| 224 | |||
| 225 | static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 226 | { | ||
| 227 | struct pcf50633_rtc *rtc; | ||
| 228 | struct pcf50633_time pcf_tm; | ||
| 229 | int alarm_masked, ret = 0; | ||
| 230 | |||
| 231 | rtc = dev_get_drvdata(dev); | ||
| 232 | |||
| 233 | rtc2pcf_time(&pcf_tm, &alrm->time); | ||
| 234 | |||
| 235 | /* do like mktime does and ignore tm_wday */ | ||
| 236 | pcf_tm.time[PCF50633_TI_WKDAY] = 7; | ||
| 237 | |||
| 238 | alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 239 | |||
| 240 | /* disable alarm interrupt */ | ||
| 241 | if (!alarm_masked) | ||
| 242 | pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 243 | |||
| 244 | /* Returns 0 on success */ | ||
| 245 | ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA, | ||
| 246 | PCF50633_TI_EXTENT, &pcf_tm.time[0]); | ||
| 247 | |||
| 248 | if (!alarm_masked) | ||
| 249 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 250 | |||
| 251 | return ret; | ||
| 252 | } | ||
| 253 | |||
| 254 | static struct rtc_class_ops pcf50633_rtc_ops = { | ||
| 255 | .read_time = pcf50633_rtc_read_time, | ||
| 256 | .set_time = pcf50633_rtc_set_time, | ||
| 257 | .read_alarm = pcf50633_rtc_read_alarm, | ||
| 258 | .set_alarm = pcf50633_rtc_set_alarm, | ||
| 259 | .alarm_irq_enable = pcf50633_rtc_alarm_irq_enable, | ||
| 260 | .update_irq_enable = pcf50633_rtc_update_irq_enable, | ||
| 261 | }; | ||
| 262 | |||
| 263 | static void pcf50633_rtc_irq(int irq, void *data) | ||
| 264 | { | ||
| 265 | struct pcf50633_rtc *rtc = data; | ||
| 266 | |||
| 267 | switch (irq) { | ||
| 268 | case PCF50633_IRQ_ALARM: | ||
| 269 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | ||
| 270 | break; | ||
| 271 | case PCF50633_IRQ_SECOND: | ||
| 272 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); | ||
| 273 | break; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) | ||
| 278 | { | ||
| 279 | struct pcf50633_subdev_pdata *pdata; | ||
| 280 | struct pcf50633_rtc *rtc; | ||
| 281 | |||
| 282 | |||
| 283 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | ||
| 284 | if (!rtc) | ||
| 285 | return -ENOMEM; | ||
| 286 | |||
| 287 | pdata = pdev->dev.platform_data; | ||
| 288 | rtc->pcf = pdata->pcf; | ||
| 289 | platform_set_drvdata(pdev, rtc); | ||
| 290 | rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev, | ||
| 291 | &pcf50633_rtc_ops, THIS_MODULE); | ||
| 292 | |||
| 293 | if (IS_ERR(rtc->rtc_dev)) { | ||
| 294 | kfree(rtc); | ||
| 295 | return PTR_ERR(rtc->rtc_dev); | ||
| 296 | } | ||
| 297 | |||
| 298 | pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM, | ||
| 299 | pcf50633_rtc_irq, rtc); | ||
| 300 | pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_SECOND, | ||
| 301 | pcf50633_rtc_irq, rtc); | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | static int __devexit pcf50633_rtc_remove(struct platform_device *pdev) | ||
| 307 | { | ||
| 308 | struct pcf50633_rtc *rtc; | ||
| 309 | |||
| 310 | rtc = platform_get_drvdata(pdev); | ||
| 311 | |||
| 312 | pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM); | ||
| 313 | pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_SECOND); | ||
| 314 | |||
| 315 | rtc_device_unregister(rtc->rtc_dev); | ||
| 316 | kfree(rtc); | ||
| 317 | |||
| 318 | return 0; | ||
| 319 | } | ||
| 320 | |||
| 321 | static struct platform_driver pcf50633_rtc_driver = { | ||
| 322 | .driver = { | ||
| 323 | .name = "pcf50633-rtc", | ||
| 324 | }, | ||
| 325 | .probe = pcf50633_rtc_probe, | ||
| 326 | .remove = __devexit_p(pcf50633_rtc_remove), | ||
| 327 | }; | ||
| 328 | |||
| 329 | static int __init pcf50633_rtc_init(void) | ||
| 330 | { | ||
| 331 | return platform_driver_register(&pcf50633_rtc_driver); | ||
| 332 | } | ||
| 333 | module_init(pcf50633_rtc_init); | ||
| 334 | |||
| 335 | static void __exit pcf50633_rtc_exit(void) | ||
| 336 | { | ||
| 337 | platform_driver_unregister(&pcf50633_rtc_driver); | ||
| 338 | } | ||
| 339 | module_exit(pcf50633_rtc_exit); | ||
| 340 | |||
| 341 | MODULE_DESCRIPTION("PCF50633 RTC driver"); | ||
| 342 | MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); | ||
| 343 | MODULE_LICENSE("GPL"); | ||
| 344 | |||
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c new file mode 100644 index 000000000000..bd56a033bfd0 --- /dev/null +++ b/drivers/rtc/rtc-pxa.c | |||
| @@ -0,0 +1,491 @@ | |||
| 1 | /* | ||
| 2 | * Real Time Clock interface for XScale PXA27x and PXA3xx | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Robert Jarzmik | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/platform_device.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/rtc.h> | ||
| 26 | #include <linux/seq_file.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/io.h> | ||
| 29 | |||
| 30 | #include <mach/hardware.h> | ||
| 31 | |||
| 32 | #define TIMER_FREQ CLOCK_TICK_RATE | ||
| 33 | #define RTC_DEF_DIVIDER (32768 - 1) | ||
| 34 | #define RTC_DEF_TRIM 0 | ||
| 35 | #define MAXFREQ_PERIODIC 1000 | ||
| 36 | |||
| 37 | /* | ||
| 38 | * PXA Registers and bits definitions | ||
| 39 | */ | ||
| 40 | #define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */ | ||
| 41 | #define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */ | ||
| 42 | #define RTSR_PIAL (1 << 13) /* Periodic interrupt detected */ | ||
| 43 | #define RTSR_SWALE2 (1 << 11) /* RTC stopwatch alarm2 enable */ | ||
| 44 | #define RTSR_SWAL2 (1 << 10) /* RTC stopwatch alarm2 detected */ | ||
| 45 | #define RTSR_SWALE1 (1 << 9) /* RTC stopwatch alarm1 enable */ | ||
| 46 | #define RTSR_SWAL1 (1 << 8) /* RTC stopwatch alarm1 detected */ | ||
| 47 | #define RTSR_RDALE2 (1 << 7) /* RTC alarm2 enable */ | ||
| 48 | #define RTSR_RDAL2 (1 << 6) /* RTC alarm2 detected */ | ||
| 49 | #define RTSR_RDALE1 (1 << 5) /* RTC alarm1 enable */ | ||
| 50 | #define RTSR_RDAL1 (1 << 4) /* RTC alarm1 detected */ | ||
| 51 | #define RTSR_HZE (1 << 3) /* HZ interrupt enable */ | ||
| 52 | #define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ | ||
| 53 | #define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ | ||
| 54 | #define RTSR_AL (1 << 0) /* RTC alarm detected */ | ||
| 55 | #define RTSR_TRIG_MASK (RTSR_AL | RTSR_HZ | RTSR_RDAL1 | RTSR_RDAL2\ | ||
| 56 | | RTSR_SWAL1 | RTSR_SWAL2) | ||
| 57 | #define RYxR_YEAR_S 9 | ||
| 58 | #define RYxR_YEAR_MASK (0xfff << RYxR_YEAR_S) | ||
| 59 | #define RYxR_MONTH_S 5 | ||
| 60 | #define RYxR_MONTH_MASK (0xf << RYxR_MONTH_S) | ||
| 61 | #define RYxR_DAY_MASK 0x1f | ||
| 62 | #define RDxR_HOUR_S 12 | ||
| 63 | #define RDxR_HOUR_MASK (0x1f << RDxR_HOUR_S) | ||
| 64 | #define RDxR_MIN_S 6 | ||
| 65 | #define RDxR_MIN_MASK (0x3f << RDxR_MIN_S) | ||
| 66 | #define RDxR_SEC_MASK 0x3f | ||
| 67 | |||
| 68 | #define RTSR 0x08 | ||
| 69 | #define RTTR 0x0c | ||
| 70 | #define RDCR 0x10 | ||
| 71 | #define RYCR 0x14 | ||
| 72 | #define RDAR1 0x18 | ||
| 73 | #define RYAR1 0x1c | ||
| 74 | #define RTCPICR 0x34 | ||
| 75 | #define PIAR 0x38 | ||
| 76 | |||
| 77 | #define rtc_readl(pxa_rtc, reg) \ | ||
| 78 | __raw_readl((pxa_rtc)->base + (reg)) | ||
| 79 | #define rtc_writel(pxa_rtc, reg, value) \ | ||
| 80 | __raw_writel((value), (pxa_rtc)->base + (reg)) | ||
| 81 | |||
| 82 | struct pxa_rtc { | ||
| 83 | struct resource *ress; | ||
| 84 | void __iomem *base; | ||
| 85 | int irq_1Hz; | ||
| 86 | int irq_Alrm; | ||
| 87 | struct rtc_device *rtc; | ||
| 88 | spinlock_t lock; /* Protects this structure */ | ||
| 89 | struct rtc_time rtc_alarm; | ||
| 90 | }; | ||
| 91 | |||
| 92 | static u32 ryxr_calc(struct rtc_time *tm) | ||
| 93 | { | ||
| 94 | return ((tm->tm_year + 1900) << RYxR_YEAR_S) | ||
| 95 | | ((tm->tm_mon + 1) << RYxR_MONTH_S) | ||
| 96 | | tm->tm_mday; | ||
| 97 | } | ||
| 98 | |||
| 99 | static u32 rdxr_calc(struct rtc_time *tm) | ||
| 100 | { | ||
| 101 | return (tm->tm_hour << RDxR_HOUR_S) | (tm->tm_min << RDxR_MIN_S) | ||
| 102 | | tm->tm_sec; | ||
| 103 | } | ||
| 104 | |||
| 105 | static void tm_calc(u32 rycr, u32 rdcr, struct rtc_time *tm) | ||
| 106 | { | ||
| 107 | tm->tm_year = ((rycr & RYxR_YEAR_MASK) >> RYxR_YEAR_S) - 1900; | ||
| 108 | tm->tm_mon = (((rycr & RYxR_MONTH_MASK) >> RYxR_MONTH_S)) - 1; | ||
| 109 | tm->tm_mday = (rycr & RYxR_DAY_MASK); | ||
| 110 | tm->tm_hour = (rdcr & RDxR_HOUR_MASK) >> RDxR_HOUR_S; | ||
| 111 | tm->tm_min = (rdcr & RDxR_MIN_MASK) >> RDxR_MIN_S; | ||
| 112 | tm->tm_sec = rdcr & RDxR_SEC_MASK; | ||
| 113 | } | ||
| 114 | |||
| 115 | static void rtsr_clear_bits(struct pxa_rtc *pxa_rtc, u32 mask) | ||
| 116 | { | ||
| 117 | u32 rtsr; | ||
| 118 | |||
| 119 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
| 120 | rtsr &= ~RTSR_TRIG_MASK; | ||
| 121 | rtsr &= ~mask; | ||
| 122 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
| 123 | } | ||
| 124 | |||
| 125 | static void rtsr_set_bits(struct pxa_rtc *pxa_rtc, u32 mask) | ||
| 126 | { | ||
| 127 | u32 rtsr; | ||
| 128 | |||
| 129 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
| 130 | rtsr &= ~RTSR_TRIG_MASK; | ||
| 131 | rtsr |= mask; | ||
| 132 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
| 133 | } | ||
| 134 | |||
| 135 | static irqreturn_t pxa_rtc_irq(int irq, void *dev_id) | ||
| 136 | { | ||
| 137 | struct platform_device *pdev = to_platform_device(dev_id); | ||
| 138 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
| 139 | u32 rtsr; | ||
| 140 | unsigned long events = 0; | ||
| 141 | |||
| 142 | spin_lock(&pxa_rtc->lock); | ||
| 143 | |||
| 144 | /* clear interrupt sources */ | ||
| 145 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
| 146 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
| 147 | |||
| 148 | /* temporary disable rtc interrupts */ | ||
| 149 | rtsr_clear_bits(pxa_rtc, RTSR_RDALE1 | RTSR_PIALE | RTSR_HZE); | ||
| 150 | |||
| 151 | /* clear alarm interrupt if it has occurred */ | ||
| 152 | if (rtsr & RTSR_RDAL1) | ||
| 153 | rtsr &= ~RTSR_RDALE1; | ||
| 154 | |||
| 155 | /* update irq data & counter */ | ||
| 156 | if (rtsr & RTSR_RDAL1) | ||
| 157 | events |= RTC_AF | RTC_IRQF; | ||
| 158 | if (rtsr & RTSR_HZ) | ||
| 159 | events |= RTC_UF | RTC_IRQF; | ||
| 160 | if (rtsr & RTSR_PIAL) | ||
| 161 | events |= RTC_PF | RTC_IRQF; | ||
| 162 | |||
| 163 | rtc_update_irq(pxa_rtc->rtc, 1, events); | ||
| 164 | |||
| 165 | /* enable back rtc interrupts */ | ||
| 166 | rtc_writel(pxa_rtc, RTSR, rtsr & ~RTSR_TRIG_MASK); | ||
| 167 | |||
| 168 | spin_unlock(&pxa_rtc->lock); | ||
| 169 | return IRQ_HANDLED; | ||
| 170 | } | ||
| 171 | |||
| 172 | static int pxa_rtc_open(struct device *dev) | ||
| 173 | { | ||
| 174 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 175 | int ret; | ||
| 176 | |||
| 177 | ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, IRQF_DISABLED, | ||
| 178 | "rtc 1Hz", dev); | ||
| 179 | if (ret < 0) { | ||
| 180 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz, | ||
| 181 | ret); | ||
| 182 | goto err_irq_1Hz; | ||
| 183 | } | ||
| 184 | ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, IRQF_DISABLED, | ||
| 185 | "rtc Alrm", dev); | ||
| 186 | if (ret < 0) { | ||
| 187 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm, | ||
| 188 | ret); | ||
| 189 | goto err_irq_Alrm; | ||
| 190 | } | ||
| 191 | |||
| 192 | return 0; | ||
| 193 | |||
| 194 | err_irq_Alrm: | ||
| 195 | free_irq(pxa_rtc->irq_1Hz, dev); | ||
| 196 | err_irq_1Hz: | ||
| 197 | return ret; | ||
| 198 | } | ||
| 199 | |||
| 200 | static void pxa_rtc_release(struct device *dev) | ||
| 201 | { | ||
| 202 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 203 | |||
| 204 | spin_lock_irq(&pxa_rtc->lock); | ||
| 205 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE); | ||
| 206 | spin_unlock_irq(&pxa_rtc->lock); | ||
| 207 | |||
| 208 | free_irq(pxa_rtc->irq_Alrm, dev); | ||
| 209 | free_irq(pxa_rtc->irq_1Hz, dev); | ||
| 210 | } | ||
| 211 | |||
| 212 | static int pxa_periodic_irq_set_freq(struct device *dev, int freq) | ||
| 213 | { | ||
| 214 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 215 | int period_ms; | ||
| 216 | |||
| 217 | if (freq < 1 || freq > MAXFREQ_PERIODIC) | ||
| 218 | return -EINVAL; | ||
| 219 | |||
| 220 | period_ms = 1000 / freq; | ||
| 221 | rtc_writel(pxa_rtc, PIAR, period_ms); | ||
| 222 | |||
| 223 | return 0; | ||
| 224 | } | ||
| 225 | |||
| 226 | static int pxa_periodic_irq_set_state(struct device *dev, int enabled) | ||
| 227 | { | ||
| 228 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 229 | |||
| 230 | if (enabled) | ||
| 231 | rtsr_set_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); | ||
| 232 | else | ||
| 233 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); | ||
| 234 | |||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 238 | static int pxa_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
| 239 | unsigned long arg) | ||
| 240 | { | ||
| 241 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 242 | int ret = 0; | ||
| 243 | |||
| 244 | spin_lock_irq(&pxa_rtc->lock); | ||
| 245 | switch (cmd) { | ||
| 246 | case RTC_AIE_OFF: | ||
| 247 | rtsr_clear_bits(pxa_rtc, RTSR_RDALE1); | ||
| 248 | break; | ||
| 249 | case RTC_AIE_ON: | ||
| 250 | rtsr_set_bits(pxa_rtc, RTSR_RDALE1); | ||
| 251 | break; | ||
| 252 | case RTC_UIE_OFF: | ||
| 253 | rtsr_clear_bits(pxa_rtc, RTSR_HZE); | ||
| 254 | break; | ||
| 255 | case RTC_UIE_ON: | ||
| 256 | rtsr_set_bits(pxa_rtc, RTSR_HZE); | ||
| 257 | break; | ||
| 258 | default: | ||
| 259 | ret = -ENOIOCTLCMD; | ||
| 260 | } | ||
| 261 | |||
| 262 | spin_unlock_irq(&pxa_rtc->lock); | ||
| 263 | return ret; | ||
| 264 | } | ||
| 265 | |||
| 266 | static int pxa_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 267 | { | ||
| 268 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 269 | u32 rycr, rdcr; | ||
| 270 | |||
| 271 | rycr = rtc_readl(pxa_rtc, RYCR); | ||
| 272 | rdcr = rtc_readl(pxa_rtc, RDCR); | ||
| 273 | |||
| 274 | tm_calc(rycr, rdcr, tm); | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static int pxa_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 279 | { | ||
| 280 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 281 | |||
| 282 | rtc_writel(pxa_rtc, RYCR, ryxr_calc(tm)); | ||
| 283 | rtc_writel(pxa_rtc, RDCR, rdxr_calc(tm)); | ||
| 284 | |||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | static int pxa_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 289 | { | ||
| 290 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 291 | u32 rtsr, ryar, rdar; | ||
| 292 | |||
| 293 | ryar = rtc_readl(pxa_rtc, RYAR1); | ||
| 294 | rdar = rtc_readl(pxa_rtc, RDAR1); | ||
| 295 | tm_calc(ryar, rdar, &alrm->time); | ||
| 296 | |||
| 297 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
| 298 | alrm->enabled = (rtsr & RTSR_RDALE1) ? 1 : 0; | ||
| 299 | alrm->pending = (rtsr & RTSR_RDAL1) ? 1 : 0; | ||
| 300 | return 0; | ||
| 301 | } | ||
| 302 | |||
| 303 | static int pxa_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 304 | { | ||
| 305 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 306 | u32 rtsr; | ||
| 307 | |||
| 308 | spin_lock_irq(&pxa_rtc->lock); | ||
| 309 | |||
| 310 | rtc_writel(pxa_rtc, RYAR1, ryxr_calc(&alrm->time)); | ||
| 311 | rtc_writel(pxa_rtc, RDAR1, rdxr_calc(&alrm->time)); | ||
| 312 | |||
| 313 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
| 314 | if (alrm->enabled) | ||
| 315 | rtsr |= RTSR_RDALE1; | ||
| 316 | else | ||
| 317 | rtsr &= ~RTSR_RDALE1; | ||
| 318 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
| 319 | |||
| 320 | spin_unlock_irq(&pxa_rtc->lock); | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | static int pxa_rtc_proc(struct device *dev, struct seq_file *seq) | ||
| 326 | { | ||
| 327 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
| 328 | |||
| 329 | seq_printf(seq, "trim/divider\t: 0x%08x\n", rtc_readl(pxa_rtc, RTTR)); | ||
| 330 | seq_printf(seq, "update_IRQ\t: %s\n", | ||
| 331 | (rtc_readl(pxa_rtc, RTSR) & RTSR_HZE) ? "yes" : "no"); | ||
| 332 | seq_printf(seq, "periodic_IRQ\t: %s\n", | ||
| 333 | (rtc_readl(pxa_rtc, RTSR) & RTSR_PIALE) ? "yes" : "no"); | ||
| 334 | seq_printf(seq, "periodic_freq\t: %u\n", rtc_readl(pxa_rtc, PIAR)); | ||
| 335 | |||
| 336 | return 0; | ||
| 337 | } | ||
| 338 | |||
| 339 | static const struct rtc_class_ops pxa_rtc_ops = { | ||
| 340 | .open = pxa_rtc_open, | ||
| 341 | .release = pxa_rtc_release, | ||
| 342 | .ioctl = pxa_rtc_ioctl, | ||
| 343 | .read_time = pxa_rtc_read_time, | ||
| 344 | .set_time = pxa_rtc_set_time, | ||
| 345 | .read_alarm = pxa_rtc_read_alarm, | ||
| 346 | .set_alarm = pxa_rtc_set_alarm, | ||
| 347 | .proc = pxa_rtc_proc, | ||
| 348 | .irq_set_state = pxa_periodic_irq_set_state, | ||
| 349 | .irq_set_freq = pxa_periodic_irq_set_freq, | ||
| 350 | }; | ||
| 351 | |||
| 352 | static int __init pxa_rtc_probe(struct platform_device *pdev) | ||
| 353 | { | ||
| 354 | struct device *dev = &pdev->dev; | ||
| 355 | struct pxa_rtc *pxa_rtc; | ||
| 356 | int ret; | ||
| 357 | u32 rttr; | ||
| 358 | |||
| 359 | pxa_rtc = kzalloc(sizeof(struct pxa_rtc), GFP_KERNEL); | ||
| 360 | if (!pxa_rtc) | ||
| 361 | return -ENOMEM; | ||
| 362 | |||
| 363 | spin_lock_init(&pxa_rtc->lock); | ||
| 364 | platform_set_drvdata(pdev, pxa_rtc); | ||
| 365 | |||
| 366 | ret = -ENXIO; | ||
| 367 | pxa_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 368 | if (!pxa_rtc->ress) { | ||
| 369 | dev_err(dev, "No I/O memory resource defined\n"); | ||
| 370 | goto err_ress; | ||
| 371 | } | ||
| 372 | |||
| 373 | pxa_rtc->irq_1Hz = platform_get_irq(pdev, 0); | ||
| 374 | if (pxa_rtc->irq_1Hz < 0) { | ||
| 375 | dev_err(dev, "No 1Hz IRQ resource defined\n"); | ||
| 376 | goto err_ress; | ||
| 377 | } | ||
| 378 | pxa_rtc->irq_Alrm = platform_get_irq(pdev, 1); | ||
| 379 | if (pxa_rtc->irq_Alrm < 0) { | ||
| 380 | dev_err(dev, "No alarm IRQ resource defined\n"); | ||
| 381 | goto err_ress; | ||
| 382 | } | ||
| 383 | |||
| 384 | ret = -ENOMEM; | ||
| 385 | pxa_rtc->base = ioremap(pxa_rtc->ress->start, | ||
| 386 | resource_size(pxa_rtc->ress)); | ||
| 387 | if (!pxa_rtc->base) { | ||
| 388 | dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n"); | ||
| 389 | goto err_map; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* | ||
| 393 | * If the clock divider is uninitialized then reset it to the | ||
| 394 | * default value to get the 1Hz clock. | ||
| 395 | */ | ||
| 396 | if (rtc_readl(pxa_rtc, RTTR) == 0) { | ||
| 397 | rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | ||
| 398 | rtc_writel(pxa_rtc, RTTR, rttr); | ||
| 399 | dev_warn(dev, "warning: initializing default clock" | ||
| 400 | " divider/trim value\n"); | ||
| 401 | } | ||
| 402 | |||
| 403 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE); | ||
| 404 | |||
| 405 | pxa_rtc->rtc = rtc_device_register("pxa-rtc", &pdev->dev, &pxa_rtc_ops, | ||
| 406 | THIS_MODULE); | ||
| 407 | ret = PTR_ERR(pxa_rtc->rtc); | ||
| 408 | if (IS_ERR(pxa_rtc->rtc)) { | ||
| 409 | dev_err(dev, "Failed to register RTC device -> %d\n", ret); | ||
| 410 | goto err_rtc_reg; | ||
| 411 | } | ||
| 412 | |||
| 413 | device_init_wakeup(dev, 1); | ||
| 414 | |||
| 415 | return 0; | ||
| 416 | |||
| 417 | err_rtc_reg: | ||
| 418 | iounmap(pxa_rtc->base); | ||
| 419 | err_ress: | ||
| 420 | err_map: | ||
| 421 | kfree(pxa_rtc); | ||
| 422 | return ret; | ||
| 423 | } | ||
| 424 | |||
| 425 | static int __exit pxa_rtc_remove(struct platform_device *pdev) | ||
| 426 | { | ||
| 427 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
| 428 | |||
| 429 | rtc_device_unregister(pxa_rtc->rtc); | ||
| 430 | |||
| 431 | spin_lock_irq(&pxa_rtc->lock); | ||
| 432 | iounmap(pxa_rtc->base); | ||
| 433 | spin_unlock_irq(&pxa_rtc->lock); | ||
| 434 | |||
| 435 | kfree(pxa_rtc); | ||
| 436 | |||
| 437 | return 0; | ||
| 438 | } | ||
| 439 | |||
| 440 | #ifdef CONFIG_PM | ||
| 441 | static int pxa_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 442 | { | ||
| 443 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
| 444 | |||
| 445 | if (device_may_wakeup(&pdev->dev)) | ||
| 446 | enable_irq_wake(pxa_rtc->irq_Alrm); | ||
| 447 | return 0; | ||
| 448 | } | ||
| 449 | |||
| 450 | static int pxa_rtc_resume(struct platform_device *pdev) | ||
| 451 | { | ||
| 452 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
| 453 | |||
| 454 | if (device_may_wakeup(&pdev->dev)) | ||
| 455 | disable_irq_wake(pxa_rtc->irq_Alrm); | ||
| 456 | return 0; | ||
| 457 | } | ||
| 458 | #else | ||
| 459 | #define pxa_rtc_suspend NULL | ||
| 460 | #define pxa_rtc_resume NULL | ||
| 461 | #endif | ||
| 462 | |||
| 463 | static struct platform_driver pxa_rtc_driver = { | ||
| 464 | .remove = __exit_p(pxa_rtc_remove), | ||
| 465 | .suspend = pxa_rtc_suspend, | ||
| 466 | .resume = pxa_rtc_resume, | ||
| 467 | .driver = { | ||
| 468 | .name = "pxa-rtc", | ||
| 469 | }, | ||
| 470 | }; | ||
| 471 | |||
| 472 | static int __init pxa_rtc_init(void) | ||
| 473 | { | ||
| 474 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) | ||
| 475 | return platform_driver_probe(&pxa_rtc_driver, pxa_rtc_probe); | ||
| 476 | |||
| 477 | return -ENODEV; | ||
| 478 | } | ||
| 479 | |||
| 480 | static void __exit pxa_rtc_exit(void) | ||
| 481 | { | ||
| 482 | platform_driver_unregister(&pxa_rtc_driver); | ||
| 483 | } | ||
| 484 | |||
| 485 | module_init(pxa_rtc_init); | ||
| 486 | module_exit(pxa_rtc_exit); | ||
| 487 | |||
| 488 | MODULE_AUTHOR("Robert Jarzmik"); | ||
| 489 | MODULE_DESCRIPTION("PXA27x/PXA3xx Realtime Clock Driver (RTC)"); | ||
| 490 | MODULE_LICENSE("GPL"); | ||
| 491 | MODULE_ALIAS("platform:pxa-rtc"); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index f59277bbedaa..e0d7b9991505 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
| 27 | #include <asm/io.h> | 27 | #include <asm/io.h> |
| 28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
| 29 | #include <asm/plat-s3c/regs-rtc.h> | 29 | #include <plat/regs-rtc.h> |
| 30 | 30 | ||
| 31 | /* I have yet to find an S3C implementation with more than one | 31 | /* I have yet to find an S3C implementation with more than one |
| 32 | * of these rtc blocks in */ | 32 | * of these rtc blocks in */ |
| @@ -94,6 +94,9 @@ static int s3c_rtc_setfreq(struct device *dev, int freq) | |||
| 94 | { | 94 | { |
| 95 | unsigned int tmp; | 95 | unsigned int tmp; |
| 96 | 96 | ||
| 97 | if (!is_power_of_2(freq)) | ||
| 98 | return -EINVAL; | ||
| 99 | |||
| 97 | spin_lock_irq(&s3c_rtc_pie_lock); | 100 | spin_lock_irq(&s3c_rtc_pie_lock); |
| 98 | 101 | ||
| 99 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | 102 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 66a9bb85bbe8..d26a5f82aaba 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
| @@ -38,11 +38,11 @@ | |||
| 38 | #include <mach/pxa-regs.h> | 38 | #include <mach/pxa-regs.h> |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | #define TIMER_FREQ CLOCK_TICK_RATE | ||
| 42 | #define RTC_DEF_DIVIDER 32768 - 1 | 41 | #define RTC_DEF_DIVIDER 32768 - 1 |
| 43 | #define RTC_DEF_TRIM 0 | 42 | #define RTC_DEF_TRIM 0 |
| 44 | 43 | ||
| 45 | static unsigned long rtc_freq = 1024; | 44 | static unsigned long rtc_freq = 1024; |
| 45 | static unsigned long timer_freq; | ||
| 46 | static struct rtc_time rtc_alarm; | 46 | static struct rtc_time rtc_alarm; |
| 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); | 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
| 48 | 48 | ||
| @@ -157,7 +157,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) | |||
| 157 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); | 157 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); |
| 158 | 158 | ||
| 159 | if (rtc_timer1_count == 1) | 159 | if (rtc_timer1_count == 1) |
| 160 | rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); | 160 | rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); |
| 161 | 161 | ||
| 162 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
| 163 | } | 163 | } |
| @@ -166,7 +166,7 @@ static int sa1100_rtc_read_callback(struct device *dev, int data) | |||
| 166 | { | 166 | { |
| 167 | if (data & RTC_PF) { | 167 | if (data & RTC_PF) { |
| 168 | /* interpolate missed periods and set match for the next */ | 168 | /* interpolate missed periods and set match for the next */ |
| 169 | unsigned long period = TIMER_FREQ/rtc_freq; | 169 | unsigned long period = timer_freq / rtc_freq; |
| 170 | unsigned long oscr = OSCR; | 170 | unsigned long oscr = OSCR; |
| 171 | unsigned long osmr1 = OSMR1; | 171 | unsigned long osmr1 = OSMR1; |
| 172 | unsigned long missed = (oscr - osmr1)/period; | 172 | unsigned long missed = (oscr - osmr1)/period; |
| @@ -263,7 +263,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
| 263 | return 0; | 263 | return 0; |
| 264 | case RTC_PIE_ON: | 264 | case RTC_PIE_ON: |
| 265 | spin_lock_irq(&sa1100_rtc_lock); | 265 | spin_lock_irq(&sa1100_rtc_lock); |
| 266 | OSMR1 = TIMER_FREQ/rtc_freq + OSCR; | 266 | OSMR1 = timer_freq / rtc_freq + OSCR; |
| 267 | OIER |= OIER_E1; | 267 | OIER |= OIER_E1; |
| 268 | rtc_timer1_count = 1; | 268 | rtc_timer1_count = 1; |
| 269 | spin_unlock_irq(&sa1100_rtc_lock); | 269 | spin_unlock_irq(&sa1100_rtc_lock); |
| @@ -271,7 +271,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
| 271 | case RTC_IRQP_READ: | 271 | case RTC_IRQP_READ: |
| 272 | return put_user(rtc_freq, (unsigned long *)arg); | 272 | return put_user(rtc_freq, (unsigned long *)arg); |
| 273 | case RTC_IRQP_SET: | 273 | case RTC_IRQP_SET: |
| 274 | if (arg < 1 || arg > TIMER_FREQ) | 274 | if (arg < 1 || arg > timer_freq) |
| 275 | return -EINVAL; | 275 | return -EINVAL; |
| 276 | rtc_freq = arg; | 276 | rtc_freq = arg; |
| 277 | return 0; | 277 | return 0; |
| @@ -352,6 +352,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
| 352 | { | 352 | { |
| 353 | struct rtc_device *rtc; | 353 | struct rtc_device *rtc; |
| 354 | 354 | ||
| 355 | timer_freq = get_clock_tick_rate(); | ||
| 356 | |||
| 355 | /* | 357 | /* |
| 356 | * According to the manual we should be able to let RTTR be zero | 358 | * According to the manual we should be able to let RTTR be zero |
| 357 | * and then a default diviser for a 32.768KHz clock is used. | 359 | * and then a default diviser for a 32.768KHz clock is used. |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index aaf9d6a337cc..1c3fc6b428e9 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
| 25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
| 26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
| 27 | #include <linux/log2.h> | ||
| 27 | #include <asm/rtc.h> | 28 | #include <asm/rtc.h> |
| 28 | 29 | ||
| 29 | #define DRV_NAME "sh-rtc" | 30 | #define DRV_NAME "sh-rtc" |
| @@ -89,7 +90,9 @@ struct sh_rtc { | |||
| 89 | void __iomem *regbase; | 90 | void __iomem *regbase; |
| 90 | unsigned long regsize; | 91 | unsigned long regsize; |
| 91 | struct resource *res; | 92 | struct resource *res; |
| 92 | unsigned int alarm_irq, periodic_irq, carry_irq; | 93 | int alarm_irq; |
| 94 | int periodic_irq; | ||
| 95 | int carry_irq; | ||
| 93 | struct rtc_device *rtc_dev; | 96 | struct rtc_device *rtc_dev; |
| 94 | spinlock_t lock; | 97 | spinlock_t lock; |
| 95 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ | 98 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ |
| @@ -549,6 +552,8 @@ static int sh_rtc_irq_set_state(struct device *dev, int enabled) | |||
| 549 | 552 | ||
| 550 | static int sh_rtc_irq_set_freq(struct device *dev, int freq) | 553 | static int sh_rtc_irq_set_freq(struct device *dev, int freq) |
| 551 | { | 554 | { |
| 555 | if (!is_power_of_2(freq)) | ||
| 556 | return -EINVAL; | ||
| 552 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); | 557 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); |
| 553 | } | 558 | } |
| 554 | 559 | ||
| @@ -578,7 +583,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 578 | 583 | ||
| 579 | /* get periodic/carry/alarm irqs */ | 584 | /* get periodic/carry/alarm irqs */ |
| 580 | ret = platform_get_irq(pdev, 0); | 585 | ret = platform_get_irq(pdev, 0); |
| 581 | if (unlikely(ret < 0)) { | 586 | if (unlikely(ret <= 0)) { |
| 582 | ret = -ENOENT; | 587 | ret = -ENOENT; |
| 583 | dev_err(&pdev->dev, "No IRQ for period\n"); | 588 | dev_err(&pdev->dev, "No IRQ for period\n"); |
| 584 | goto err_badres; | 589 | goto err_badres; |
| @@ -586,7 +591,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 586 | rtc->periodic_irq = ret; | 591 | rtc->periodic_irq = ret; |
| 587 | 592 | ||
| 588 | ret = platform_get_irq(pdev, 1); | 593 | ret = platform_get_irq(pdev, 1); |
| 589 | if (unlikely(ret < 0)) { | 594 | if (unlikely(ret <= 0)) { |
| 590 | ret = -ENOENT; | 595 | ret = -ENOENT; |
| 591 | dev_err(&pdev->dev, "No IRQ for carry\n"); | 596 | dev_err(&pdev->dev, "No IRQ for carry\n"); |
| 592 | goto err_badres; | 597 | goto err_badres; |
| @@ -594,7 +599,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 594 | rtc->carry_irq = ret; | 599 | rtc->carry_irq = ret; |
| 595 | 600 | ||
| 596 | ret = platform_get_irq(pdev, 2); | 601 | ret = platform_get_irq(pdev, 2); |
| 597 | if (unlikely(ret < 0)) { | 602 | if (unlikely(ret <= 0)) { |
| 598 | ret = -ENOENT; | 603 | ret = -ENOENT; |
| 599 | dev_err(&pdev->dev, "No IRQ for alarm\n"); | 604 | dev_err(&pdev->dev, "No IRQ for alarm\n"); |
| 600 | goto err_badres; | 605 | goto err_badres; |
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index f4cd46e15af9..7d1547b0070e 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c | |||
| @@ -170,7 +170,7 @@ static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 170 | struct platform_device *pdev = to_platform_device(dev); | 170 | struct platform_device *pdev = to_platform_device(dev); |
| 171 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 171 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 172 | 172 | ||
| 173 | if (pdata->irq < 0) | 173 | if (pdata->irq <= 0) |
| 174 | return -EINVAL; | 174 | return -EINVAL; |
| 175 | pdata->alrm_mday = alrm->time.tm_mday; | 175 | pdata->alrm_mday = alrm->time.tm_mday; |
| 176 | pdata->alrm_hour = alrm->time.tm_hour; | 176 | pdata->alrm_hour = alrm->time.tm_hour; |
| @@ -187,7 +187,7 @@ static int stk17ta8_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 187 | struct platform_device *pdev = to_platform_device(dev); | 187 | struct platform_device *pdev = to_platform_device(dev); |
| 188 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 188 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 189 | 189 | ||
| 190 | if (pdata->irq < 0) | 190 | if (pdata->irq <= 0) |
| 191 | return -EINVAL; | 191 | return -EINVAL; |
| 192 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | 192 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; |
| 193 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | 193 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; |
| @@ -221,7 +221,7 @@ static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
| 221 | struct platform_device *pdev = to_platform_device(dev); | 221 | struct platform_device *pdev = to_platform_device(dev); |
| 222 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 222 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
| 223 | 223 | ||
| 224 | if (pdata->irq < 0) | 224 | if (pdata->irq <= 0) |
| 225 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | 225 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ |
| 226 | switch (cmd) { | 226 | switch (cmd) { |
| 227 | case RTC_AIE_OFF: | 227 | case RTC_AIE_OFF: |
| @@ -303,7 +303,6 @@ static int __init stk17ta8_rtc_probe(struct platform_device *pdev) | |||
| 303 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 303 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
| 304 | if (!pdata) | 304 | if (!pdata) |
| 305 | return -ENOMEM; | 305 | return -ENOMEM; |
| 306 | pdata->irq = -1; | ||
| 307 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { | 306 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { |
| 308 | ret = -EBUSY; | 307 | ret = -EBUSY; |
| 309 | goto out; | 308 | goto out; |
| @@ -329,13 +328,13 @@ static int __init stk17ta8_rtc_probe(struct platform_device *pdev) | |||
| 329 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF) | 328 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF) |
| 330 | dev_warn(&pdev->dev, "voltage-low detected.\n"); | 329 | dev_warn(&pdev->dev, "voltage-low detected.\n"); |
| 331 | 330 | ||
| 332 | if (pdata->irq >= 0) { | 331 | if (pdata->irq > 0) { |
| 333 | writeb(0, ioaddr + RTC_INTERRUPTS); | 332 | writeb(0, ioaddr + RTC_INTERRUPTS); |
| 334 | if (request_irq(pdata->irq, stk17ta8_rtc_interrupt, | 333 | if (request_irq(pdata->irq, stk17ta8_rtc_interrupt, |
| 335 | IRQF_DISABLED | IRQF_SHARED, | 334 | IRQF_DISABLED | IRQF_SHARED, |
| 336 | pdev->name, pdev) < 0) { | 335 | pdev->name, pdev) < 0) { |
| 337 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 336 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
| 338 | pdata->irq = -1; | 337 | pdata->irq = 0; |
| 339 | } | 338 | } |
| 340 | } | 339 | } |
| 341 | 340 | ||
| @@ -355,7 +354,7 @@ static int __init stk17ta8_rtc_probe(struct platform_device *pdev) | |||
| 355 | out: | 354 | out: |
| 356 | if (pdata->rtc) | 355 | if (pdata->rtc) |
| 357 | rtc_device_unregister(pdata->rtc); | 356 | rtc_device_unregister(pdata->rtc); |
| 358 | if (pdata->irq >= 0) | 357 | if (pdata->irq > 0) |
| 359 | free_irq(pdata->irq, pdev); | 358 | free_irq(pdata->irq, pdev); |
| 360 | if (ioaddr) | 359 | if (ioaddr) |
| 361 | iounmap(ioaddr); | 360 | iounmap(ioaddr); |
| @@ -371,7 +370,7 @@ static int __devexit stk17ta8_rtc_remove(struct platform_device *pdev) | |||
| 371 | 370 | ||
| 372 | sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); | 371 | sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); |
| 373 | rtc_device_unregister(pdata->rtc); | 372 | rtc_device_unregister(pdata->rtc); |
| 374 | if (pdata->irq >= 0) { | 373 | if (pdata->irq > 0) { |
| 375 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); | 374 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); |
| 376 | free_irq(pdata->irq, pdev); | 375 | free_irq(pdata->irq, pdev); |
| 377 | } | 376 | } |
| @@ -400,7 +399,7 @@ static __init int stk17ta8_init(void) | |||
| 400 | 399 | ||
| 401 | static __exit void stk17ta8_exit(void) | 400 | static __exit void stk17ta8_exit(void) |
| 402 | { | 401 | { |
| 403 | return platform_driver_unregister(&stk17ta8_rtc_driver); | 402 | platform_driver_unregister(&stk17ta8_rtc_driver); |
| 404 | } | 403 | } |
| 405 | 404 | ||
| 406 | module_init(stk17ta8_init); | 405 | module_init(stk17ta8_init); |
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index bc930022004a..e478280ff628 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
| @@ -34,14 +34,9 @@ static int test_rtc_read_time(struct device *dev, | |||
| 34 | return 0; | 34 | return 0; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | static int test_rtc_set_time(struct device *dev, | ||
| 38 | struct rtc_time *tm) | ||
| 39 | { | ||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | static int test_rtc_set_mmss(struct device *dev, unsigned long secs) | 37 | static int test_rtc_set_mmss(struct device *dev, unsigned long secs) |
| 44 | { | 38 | { |
| 39 | dev_info(dev, "%s, secs = %lu\n", __func__, secs); | ||
| 45 | return 0; | 40 | return 0; |
| 46 | } | 41 | } |
| 47 | 42 | ||
| @@ -78,7 +73,6 @@ static int test_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
| 78 | static const struct rtc_class_ops test_rtc_ops = { | 73 | static const struct rtc_class_ops test_rtc_ops = { |
| 79 | .proc = test_rtc_proc, | 74 | .proc = test_rtc_proc, |
| 80 | .read_time = test_rtc_read_time, | 75 | .read_time = test_rtc_read_time, |
| 81 | .set_time = test_rtc_set_time, | ||
| 82 | .read_alarm = test_rtc_read_alarm, | 76 | .read_alarm = test_rtc_read_alarm, |
| 83 | .set_alarm = test_rtc_set_alarm, | 77 | .set_alarm = test_rtc_set_alarm, |
| 84 | .set_mmss = test_rtc_set_mmss, | 78 | .set_mmss = test_rtc_set_mmss, |
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index 01d8da9afdc8..ad35f76c46b7 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/errno.h> | ||
| 22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 24 | #include <linux/types.h> | 25 | #include <linux/types.h> |
| @@ -119,7 +120,7 @@ static int twl4030_rtc_write_u8(u8 data, u8 reg) | |||
| 119 | static unsigned char rtc_irq_bits; | 120 | static unsigned char rtc_irq_bits; |
| 120 | 121 | ||
| 121 | /* | 122 | /* |
| 122 | * Enable timer and/or alarm interrupts. | 123 | * Enable 1/second update and/or alarm interrupts. |
| 123 | */ | 124 | */ |
| 124 | static int set_rtc_irq_bit(unsigned char bit) | 125 | static int set_rtc_irq_bit(unsigned char bit) |
| 125 | { | 126 | { |
| @@ -127,6 +128,7 @@ static int set_rtc_irq_bit(unsigned char bit) | |||
| 127 | int ret; | 128 | int ret; |
| 128 | 129 | ||
| 129 | val = rtc_irq_bits | bit; | 130 | val = rtc_irq_bits | bit; |
| 131 | val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; | ||
| 130 | ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); | 132 | ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); |
| 131 | if (ret == 0) | 133 | if (ret == 0) |
| 132 | rtc_irq_bits = val; | 134 | rtc_irq_bits = val; |
| @@ -135,7 +137,7 @@ static int set_rtc_irq_bit(unsigned char bit) | |||
| 135 | } | 137 | } |
| 136 | 138 | ||
| 137 | /* | 139 | /* |
| 138 | * Disable timer and/or alarm interrupts. | 140 | * Disable update and/or alarm interrupts. |
| 139 | */ | 141 | */ |
| 140 | static int mask_rtc_irq_bit(unsigned char bit) | 142 | static int mask_rtc_irq_bit(unsigned char bit) |
| 141 | { | 143 | { |
| @@ -150,7 +152,7 @@ static int mask_rtc_irq_bit(unsigned char bit) | |||
| 150 | return ret; | 152 | return ret; |
| 151 | } | 153 | } |
| 152 | 154 | ||
| 153 | static inline int twl4030_rtc_alarm_irq_set_state(int enabled) | 155 | static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) |
| 154 | { | 156 | { |
| 155 | int ret; | 157 | int ret; |
| 156 | 158 | ||
| @@ -162,7 +164,7 @@ static inline int twl4030_rtc_alarm_irq_set_state(int enabled) | |||
| 162 | return ret; | 164 | return ret; |
| 163 | } | 165 | } |
| 164 | 166 | ||
| 165 | static inline int twl4030_rtc_irq_set_state(int enabled) | 167 | static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled) |
| 166 | { | 168 | { |
| 167 | int ret; | 169 | int ret; |
| 168 | 170 | ||
| @@ -291,7 +293,7 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
| 291 | unsigned char alarm_data[ALL_TIME_REGS + 1]; | 293 | unsigned char alarm_data[ALL_TIME_REGS + 1]; |
| 292 | int ret; | 294 | int ret; |
| 293 | 295 | ||
| 294 | ret = twl4030_rtc_alarm_irq_set_state(0); | 296 | ret = twl4030_rtc_alarm_irq_enable(dev, 0); |
| 295 | if (ret) | 297 | if (ret) |
| 296 | goto out; | 298 | goto out; |
| 297 | 299 | ||
| @@ -311,35 +313,11 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
| 311 | } | 313 | } |
| 312 | 314 | ||
| 313 | if (alm->enabled) | 315 | if (alm->enabled) |
| 314 | ret = twl4030_rtc_alarm_irq_set_state(1); | 316 | ret = twl4030_rtc_alarm_irq_enable(dev, 1); |
| 315 | out: | 317 | out: |
| 316 | return ret; | 318 | return ret; |
| 317 | } | 319 | } |
| 318 | 320 | ||
| 319 | #ifdef CONFIG_RTC_INTF_DEV | ||
| 320 | |||
| 321 | static int twl4030_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
| 322 | unsigned long arg) | ||
| 323 | { | ||
| 324 | switch (cmd) { | ||
| 325 | case RTC_AIE_OFF: | ||
| 326 | return twl4030_rtc_alarm_irq_set_state(0); | ||
| 327 | case RTC_AIE_ON: | ||
| 328 | return twl4030_rtc_alarm_irq_set_state(1); | ||
| 329 | case RTC_UIE_OFF: | ||
| 330 | return twl4030_rtc_irq_set_state(0); | ||
| 331 | case RTC_UIE_ON: | ||
| 332 | return twl4030_rtc_irq_set_state(1); | ||
| 333 | |||
| 334 | default: | ||
| 335 | return -ENOIOCTLCMD; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | #else | ||
| 340 | #define twl4030_rtc_ioctl NULL | ||
| 341 | #endif | ||
| 342 | |||
| 343 | static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) | 321 | static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) |
| 344 | { | 322 | { |
| 345 | unsigned long events = 0; | 323 | unsigned long events = 0; |
| @@ -399,11 +377,12 @@ out: | |||
| 399 | } | 377 | } |
| 400 | 378 | ||
| 401 | static struct rtc_class_ops twl4030_rtc_ops = { | 379 | static struct rtc_class_ops twl4030_rtc_ops = { |
| 402 | .ioctl = twl4030_rtc_ioctl, | ||
| 403 | .read_time = twl4030_rtc_read_time, | 380 | .read_time = twl4030_rtc_read_time, |
| 404 | .set_time = twl4030_rtc_set_time, | 381 | .set_time = twl4030_rtc_set_time, |
| 405 | .read_alarm = twl4030_rtc_read_alarm, | 382 | .read_alarm = twl4030_rtc_read_alarm, |
| 406 | .set_alarm = twl4030_rtc_set_alarm, | 383 | .set_alarm = twl4030_rtc_set_alarm, |
| 384 | .alarm_irq_enable = twl4030_rtc_alarm_irq_enable, | ||
| 385 | .update_irq_enable = twl4030_rtc_update_irq_enable, | ||
| 407 | }; | 386 | }; |
| 408 | 387 | ||
| 409 | /*----------------------------------------------------------------------*/ | 388 | /*----------------------------------------------------------------------*/ |
| @@ -415,13 +394,13 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) | |||
| 415 | int irq = platform_get_irq(pdev, 0); | 394 | int irq = platform_get_irq(pdev, 0); |
| 416 | u8 rd_reg; | 395 | u8 rd_reg; |
| 417 | 396 | ||
| 418 | if (irq < 0) | 397 | if (irq <= 0) |
| 419 | return irq; | 398 | return -EINVAL; |
| 420 | 399 | ||
| 421 | rtc = rtc_device_register(pdev->name, | 400 | rtc = rtc_device_register(pdev->name, |
| 422 | &pdev->dev, &twl4030_rtc_ops, THIS_MODULE); | 401 | &pdev->dev, &twl4030_rtc_ops, THIS_MODULE); |
| 423 | if (IS_ERR(rtc)) { | 402 | if (IS_ERR(rtc)) { |
| 424 | ret = -EINVAL; | 403 | ret = PTR_ERR(rtc); |
| 425 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", | 404 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", |
| 426 | PTR_ERR(rtc)); | 405 | PTR_ERR(rtc)); |
| 427 | goto out0; | 406 | goto out0; |
| @@ -431,7 +410,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) | |||
| 431 | platform_set_drvdata(pdev, rtc); | 410 | platform_set_drvdata(pdev, rtc); |
| 432 | 411 | ||
| 433 | ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); | 412 | ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); |
| 434 | |||
| 435 | if (ret < 0) | 413 | if (ret < 0) |
| 436 | goto out1; | 414 | goto out1; |
| 437 | 415 | ||
| @@ -474,7 +452,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) | |||
| 474 | 452 | ||
| 475 | return ret; | 453 | return ret; |
| 476 | 454 | ||
| 477 | |||
| 478 | out2: | 455 | out2: |
| 479 | free_irq(irq, rtc); | 456 | free_irq(irq, rtc); |
| 480 | out1: | 457 | out1: |
| @@ -505,8 +482,9 @@ static int __devexit twl4030_rtc_remove(struct platform_device *pdev) | |||
| 505 | 482 | ||
| 506 | static void twl4030_rtc_shutdown(struct platform_device *pdev) | 483 | static void twl4030_rtc_shutdown(struct platform_device *pdev) |
| 507 | { | 484 | { |
| 508 | mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M | | 485 | /* mask timer interrupts, but leave alarm interrupts on to enable |
| 509 | BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); | 486 | power-on when alarm is triggered */ |
| 487 | mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); | ||
| 510 | } | 488 | } |
| 511 | 489 | ||
| 512 | #ifdef CONFIG_PM | 490 | #ifdef CONFIG_PM |
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c new file mode 100644 index 000000000000..4ee4857ff207 --- /dev/null +++ b/drivers/rtc/rtc-tx4939.c | |||
| @@ -0,0 +1,317 @@ | |||
| 1 | /* | ||
| 2 | * TX4939 internal RTC driver | ||
| 3 | * Based on RBTX49xx patch from CELF patch archive. | ||
| 4 | * | ||
| 5 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 6 | * License. See the file "COPYING" in the main directory of this archive | ||
| 7 | * for more details. | ||
| 8 | * | ||
| 9 | * (C) Copyright TOSHIBA CORPORATION 2005-2007 | ||
| 10 | */ | ||
| 11 | #include <linux/rtc.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <asm/txx9/tx4939.h> | ||
| 16 | |||
| 17 | struct tx4939rtc_plat_data { | ||
| 18 | struct rtc_device *rtc; | ||
| 19 | struct tx4939_rtc_reg __iomem *rtcreg; | ||
| 20 | }; | ||
| 21 | |||
| 22 | static struct tx4939rtc_plat_data *get_tx4939rtc_plat_data(struct device *dev) | ||
| 23 | { | ||
| 24 | return platform_get_drvdata(to_platform_device(dev)); | ||
| 25 | } | ||
| 26 | |||
| 27 | static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd) | ||
| 28 | { | ||
| 29 | int i = 0; | ||
| 30 | |||
| 31 | __raw_writel(cmd, &rtcreg->ctl); | ||
| 32 | /* This might take 30us (next 32.768KHz clock) */ | ||
| 33 | while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) { | ||
| 34 | /* timeout on approx. 100us (@ GBUS200MHz) */ | ||
| 35 | if (i++ > 200 * 100) | ||
| 36 | return -EBUSY; | ||
| 37 | cpu_relax(); | ||
| 38 | } | ||
| 39 | return 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int tx4939_rtc_set_mmss(struct device *dev, unsigned long secs) | ||
| 43 | { | ||
| 44 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
| 45 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
| 46 | int i, ret; | ||
| 47 | unsigned char buf[6]; | ||
| 48 | |||
| 49 | buf[0] = 0; | ||
| 50 | buf[1] = 0; | ||
| 51 | buf[2] = secs; | ||
| 52 | buf[3] = secs >> 8; | ||
| 53 | buf[4] = secs >> 16; | ||
| 54 | buf[5] = secs >> 24; | ||
| 55 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
| 56 | __raw_writel(0, &rtcreg->adr); | ||
| 57 | for (i = 0; i < 6; i++) | ||
| 58 | __raw_writel(buf[i], &rtcreg->dat); | ||
| 59 | ret = tx4939_rtc_cmd(rtcreg, | ||
| 60 | TX4939_RTCCTL_COMMAND_SETTIME | | ||
| 61 | (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); | ||
| 62 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 63 | return ret; | ||
| 64 | } | ||
| 65 | |||
| 66 | static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 67 | { | ||
| 68 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
| 69 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
| 70 | int i, ret; | ||
| 71 | unsigned long sec; | ||
| 72 | unsigned char buf[6]; | ||
| 73 | |||
| 74 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
| 75 | ret = tx4939_rtc_cmd(rtcreg, | ||
| 76 | TX4939_RTCCTL_COMMAND_GETTIME | | ||
| 77 | (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); | ||
| 78 | if (ret) { | ||
| 79 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 80 | return ret; | ||
| 81 | } | ||
| 82 | __raw_writel(2, &rtcreg->adr); | ||
| 83 | for (i = 2; i < 6; i++) | ||
| 84 | buf[i] = __raw_readl(&rtcreg->dat); | ||
| 85 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 86 | sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; | ||
| 87 | rtc_time_to_tm(sec, tm); | ||
| 88 | return rtc_valid_tm(tm); | ||
| 89 | } | ||
| 90 | |||
| 91 | static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 92 | { | ||
| 93 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
| 94 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
| 95 | int i, ret; | ||
| 96 | unsigned long sec; | ||
| 97 | unsigned char buf[6]; | ||
| 98 | |||
| 99 | if (alrm->time.tm_sec < 0 || | ||
| 100 | alrm->time.tm_min < 0 || | ||
| 101 | alrm->time.tm_hour < 0 || | ||
| 102 | alrm->time.tm_mday < 0 || | ||
| 103 | alrm->time.tm_mon < 0 || | ||
| 104 | alrm->time.tm_year < 0) | ||
| 105 | return -EINVAL; | ||
| 106 | rtc_tm_to_time(&alrm->time, &sec); | ||
| 107 | buf[0] = 0; | ||
| 108 | buf[1] = 0; | ||
| 109 | buf[2] = sec; | ||
| 110 | buf[3] = sec >> 8; | ||
| 111 | buf[4] = sec >> 16; | ||
| 112 | buf[5] = sec >> 24; | ||
| 113 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
| 114 | __raw_writel(0, &rtcreg->adr); | ||
| 115 | for (i = 0; i < 6; i++) | ||
| 116 | __raw_writel(buf[i], &rtcreg->dat); | ||
| 117 | ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM | | ||
| 118 | (alrm->enabled ? TX4939_RTCCTL_ALME : 0)); | ||
| 119 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 120 | return ret; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 124 | { | ||
| 125 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
| 126 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
| 127 | int i, ret; | ||
| 128 | unsigned long sec; | ||
| 129 | unsigned char buf[6]; | ||
| 130 | u32 ctl; | ||
| 131 | |||
| 132 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
| 133 | ret = tx4939_rtc_cmd(rtcreg, | ||
| 134 | TX4939_RTCCTL_COMMAND_GETALARM | | ||
| 135 | (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); | ||
| 136 | if (ret) { | ||
| 137 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 138 | return ret; | ||
| 139 | } | ||
| 140 | __raw_writel(2, &rtcreg->adr); | ||
| 141 | for (i = 2; i < 6; i++) | ||
| 142 | buf[i] = __raw_readl(&rtcreg->dat); | ||
| 143 | ctl = __raw_readl(&rtcreg->ctl); | ||
| 144 | alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0; | ||
| 145 | alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0; | ||
| 146 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 147 | sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; | ||
| 148 | rtc_time_to_tm(sec, &alrm->time); | ||
| 149 | return rtc_valid_tm(&alrm->time); | ||
| 150 | } | ||
| 151 | |||
| 152 | static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
| 153 | { | ||
| 154 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
| 155 | |||
| 156 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
| 157 | tx4939_rtc_cmd(pdata->rtcreg, | ||
| 158 | TX4939_RTCCTL_COMMAND_NOP | | ||
| 159 | (enabled ? TX4939_RTCCTL_ALME : 0)); | ||
| 160 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id) | ||
| 165 | { | ||
| 166 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev_id); | ||
| 167 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
| 168 | unsigned long events = RTC_IRQF; | ||
| 169 | |||
| 170 | spin_lock(&pdata->rtc->irq_lock); | ||
| 171 | if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) { | ||
| 172 | events |= RTC_AF; | ||
| 173 | tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP); | ||
| 174 | } | ||
| 175 | spin_unlock(&pdata->rtc->irq_lock); | ||
| 176 | rtc_update_irq(pdata->rtc, 1, events); | ||
| 177 | return IRQ_HANDLED; | ||
| 178 | } | ||
| 179 | |||
| 180 | static const struct rtc_class_ops tx4939_rtc_ops = { | ||
| 181 | .read_time = tx4939_rtc_read_time, | ||
| 182 | .read_alarm = tx4939_rtc_read_alarm, | ||
| 183 | .set_alarm = tx4939_rtc_set_alarm, | ||
| 184 | .set_mmss = tx4939_rtc_set_mmss, | ||
| 185 | .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, | ||
| 186 | }; | ||
| 187 | |||
| 188 | static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, | ||
| 189 | struct bin_attribute *bin_attr, | ||
| 190 | char *buf, loff_t pos, size_t size) | ||
| 191 | { | ||
| 192 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 193 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
| 194 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
| 195 | ssize_t count; | ||
| 196 | |||
| 197 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
| 198 | for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; | ||
| 199 | count++, size--) { | ||
| 200 | __raw_writel(pos++, &rtcreg->adr); | ||
| 201 | *buf++ = __raw_readl(&rtcreg->dat); | ||
| 202 | } | ||
| 203 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 204 | return count; | ||
| 205 | } | ||
| 206 | |||
| 207 | static ssize_t tx4939_rtc_nvram_write(struct kobject *kobj, | ||
| 208 | struct bin_attribute *bin_attr, | ||
| 209 | char *buf, loff_t pos, size_t size) | ||
| 210 | { | ||
| 211 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 212 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
| 213 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
| 214 | ssize_t count; | ||
| 215 | |||
| 216 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
| 217 | for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; | ||
| 218 | count++, size--) { | ||
| 219 | __raw_writel(pos++, &rtcreg->adr); | ||
| 220 | __raw_writel(*buf++, &rtcreg->dat); | ||
| 221 | } | ||
| 222 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
| 223 | return count; | ||
| 224 | } | ||
| 225 | |||
| 226 | static struct bin_attribute tx4939_rtc_nvram_attr = { | ||
| 227 | .attr = { | ||
| 228 | .name = "nvram", | ||
| 229 | .mode = S_IRUGO | S_IWUSR, | ||
| 230 | }, | ||
| 231 | .size = TX4939_RTC_REG_RAMSIZE, | ||
| 232 | .read = tx4939_rtc_nvram_read, | ||
| 233 | .write = tx4939_rtc_nvram_write, | ||
| 234 | }; | ||
| 235 | |||
| 236 | static int __init tx4939_rtc_probe(struct platform_device *pdev) | ||
| 237 | { | ||
| 238 | struct rtc_device *rtc; | ||
| 239 | struct tx4939rtc_plat_data *pdata; | ||
| 240 | struct resource *res; | ||
| 241 | int irq, ret; | ||
| 242 | |||
| 243 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 244 | if (!res) | ||
| 245 | return -ENODEV; | ||
| 246 | irq = platform_get_irq(pdev, 0); | ||
| 247 | if (irq < 0) | ||
| 248 | return -ENODEV; | ||
| 249 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
| 250 | if (!pdata) | ||
| 251 | return -ENOMEM; | ||
| 252 | platform_set_drvdata(pdev, pdata); | ||
| 253 | |||
| 254 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
| 255 | resource_size(res), pdev->name)) | ||
| 256 | return -EBUSY; | ||
| 257 | pdata->rtcreg = devm_ioremap(&pdev->dev, res->start, | ||
| 258 | resource_size(res)); | ||
| 259 | if (!pdata->rtcreg) | ||
| 260 | return -EBUSY; | ||
| 261 | |||
| 262 | tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); | ||
| 263 | if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, | ||
| 264 | IRQF_DISABLED | IRQF_SHARED, | ||
| 265 | pdev->name, &pdev->dev) < 0) { | ||
| 266 | return -EBUSY; | ||
| 267 | } | ||
| 268 | rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
| 269 | &tx4939_rtc_ops, THIS_MODULE); | ||
| 270 | if (IS_ERR(rtc)) | ||
| 271 | return PTR_ERR(rtc); | ||
| 272 | pdata->rtc = rtc; | ||
| 273 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); | ||
| 274 | if (ret) | ||
| 275 | rtc_device_unregister(rtc); | ||
| 276 | return ret; | ||
| 277 | } | ||
| 278 | |||
| 279 | static int __exit tx4939_rtc_remove(struct platform_device *pdev) | ||
| 280 | { | ||
| 281 | struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
| 282 | struct rtc_device *rtc = pdata->rtc; | ||
| 283 | |||
| 284 | spin_lock_irq(&rtc->irq_lock); | ||
| 285 | tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); | ||
| 286 | spin_unlock_irq(&rtc->irq_lock); | ||
| 287 | sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); | ||
| 288 | rtc_device_unregister(rtc); | ||
| 289 | platform_set_drvdata(pdev, NULL); | ||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | static struct platform_driver tx4939_rtc_driver = { | ||
| 294 | .remove = __exit_p(tx4939_rtc_remove), | ||
| 295 | .driver = { | ||
| 296 | .name = "tx4939rtc", | ||
| 297 | .owner = THIS_MODULE, | ||
| 298 | }, | ||
| 299 | }; | ||
| 300 | |||
| 301 | static int __init tx4939rtc_init(void) | ||
| 302 | { | ||
| 303 | return platform_driver_probe(&tx4939_rtc_driver, tx4939_rtc_probe); | ||
| 304 | } | ||
| 305 | |||
| 306 | static void __exit tx4939rtc_exit(void) | ||
| 307 | { | ||
| 308 | platform_driver_unregister(&tx4939_rtc_driver); | ||
| 309 | } | ||
| 310 | |||
| 311 | module_init(tx4939rtc_init); | ||
| 312 | module_exit(tx4939rtc_exit); | ||
| 313 | |||
| 314 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | ||
| 315 | MODULE_DESCRIPTION("TX4939 internal RTC driver"); | ||
| 316 | MODULE_LICENSE("GPL"); | ||
| 317 | MODULE_ALIAS("platform:tx4939rtc"); | ||
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 834dcc6d785f..f11297aff854 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/rtc.h> | 27 | #include <linux/rtc.h> |
| 28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
| 29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
| 30 | #include <linux/log2.h> | ||
| 30 | 31 | ||
| 31 | #include <asm/div64.h> | 32 | #include <asm/div64.h> |
| 32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
| @@ -84,8 +85,8 @@ static DEFINE_SPINLOCK(rtc_lock); | |||
| 84 | static char rtc_name[] = "RTC"; | 85 | static char rtc_name[] = "RTC"; |
| 85 | static unsigned long periodic_count; | 86 | static unsigned long periodic_count; |
| 86 | static unsigned int alarm_enabled; | 87 | static unsigned int alarm_enabled; |
| 87 | static int aie_irq = -1; | 88 | static int aie_irq; |
| 88 | static int pie_irq = -1; | 89 | static int pie_irq; |
| 89 | 90 | ||
| 90 | static inline unsigned long read_elapsed_second(void) | 91 | static inline unsigned long read_elapsed_second(void) |
| 91 | { | 92 | { |
| @@ -210,6 +211,8 @@ static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq) | |||
| 210 | { | 211 | { |
| 211 | unsigned long count; | 212 | unsigned long count; |
| 212 | 213 | ||
| 214 | if (!is_power_of_2(freq)) | ||
| 215 | return -EINVAL; | ||
| 213 | count = RTC_FREQUENCY; | 216 | count = RTC_FREQUENCY; |
| 214 | do_div(count, freq); | 217 | do_div(count, freq); |
| 215 | 218 | ||
| @@ -360,7 +363,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
| 360 | spin_unlock_irq(&rtc_lock); | 363 | spin_unlock_irq(&rtc_lock); |
| 361 | 364 | ||
| 362 | aie_irq = platform_get_irq(pdev, 0); | 365 | aie_irq = platform_get_irq(pdev, 0); |
| 363 | if (aie_irq < 0 || aie_irq >= nr_irqs) { | 366 | if (aie_irq <= 0) { |
| 364 | retval = -EBUSY; | 367 | retval = -EBUSY; |
| 365 | goto err_device_unregister; | 368 | goto err_device_unregister; |
| 366 | } | 369 | } |
| @@ -371,7 +374,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
| 371 | goto err_device_unregister; | 374 | goto err_device_unregister; |
| 372 | 375 | ||
| 373 | pie_irq = platform_get_irq(pdev, 1); | 376 | pie_irq = platform_get_irq(pdev, 1); |
| 374 | if (pie_irq < 0 || pie_irq >= nr_irqs) | 377 | if (pie_irq <= 0) |
| 375 | goto err_free_irq; | 378 | goto err_free_irq; |
| 376 | 379 | ||
| 377 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, | 380 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, |
