Pull RTC updates from Alexandre Belloni: "Core: - use is_visible() to control sysfs attributes - switch wakealarm attribute to DEVICE_ATTR_RW - make rtc_does_wakealarm() return boolean - properly manage lifetime of dev and cdev in rtc device - remove unnecessary device_get() in rtc_device_unregister - fix double free in rtc_register_device() error path New drivers: - NXP LPC24xx - Xilinx Zynq MP - Dialog DA9062 Subsystem wide cleanups: - fix drivers that consider 0 as a valid IRQ in client->irq - Drop (un)likely before IS_ERR(_OR_NULL) - drop the remaining owner assignment for i2c_driver and platform_driver - module autoload fixes Drivers: - 88pm80x: add device tree support - abx80x: fix RTC write bit - ab8500: Add a sentinel to ab85xx_rtc_ids[] - armada38x: Align RTC set time procedure with the official errata - as3722: correct month value - at91sam9: cleanups - at91rm9200: get and use slow clock and cleanups - bq32k: remove redundant check - cmos: century support, proper fix for the spurious wakeup - ds1307: cleanups and wakeup irq support - ds1374: Remove unused variable - ds1685: Use module_platform_driver - ds3232: fix WARNING trace in resume function - gemini: fix ptr_ret.cocci warnings - mt6397: implement suspend/resume - omap: support internal and external clock enabling - opal: Enable alarms only when opal supports tpo - pcf2127: use OFS flag to detect unreliable date and warn the user - pl031: fix typo for author email - rx8025: huge cleanup and fixes - sa1100/pxa: share common code - s5m: fix to update ctrl register - s3c: fix clocks and wakeup, cleanup - sirfsoc: use regmap - nvram_read()/nvram_write() functions for cmos, ds1305, ds1307, ds1343, ds1511, ds1553, ds1742, m48t59, rp5c01, stk17ta8, tx4939 - use rtc_valid_tm() error code when reading date/time instead of 0 for isl12022, pcf2123, pcf2127" * tag 'rtc-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (90 commits) rtc: abx80x: fix RTC write bit rtc: ab8500: Add a sentinel to ab85xx_rtc_ids[] rtc: ds1374: Remove unused variable rtc: Fix module autoload for OF platform drivers rtc: Fix module autoload for rtc-{ab8500,max8997,s5m} drivers rtc: omap: Add external clock enabling support rtc: omap: Add internal clock enabling support ARM: dts: AM437x: Add the internal and external clock nodes for rtc rtc: s5m: fix to update ctrl register rtc: add xilinx zynqmp rtc driver devicetree: bindings: rtc: add bindings for xilinx zynqmp rtc rtc: as3722: correct month value ARM: config: Switch PXA27x platforms to use PXA RTC driver ARM: mmp: remove unused RTC register definitions ARM: sa1100: remove unused RTC register definitions rtc: sa1100/pxa: convert to run-time register mapping ARM: pxa: add memory resource to SA1100 RTC device rtc: pxa: convert to use shared sa1100 functions rtc: sa1100: prepare to share sa1100_rtc_ops rtc: ds3232: fix WARNING trace in resume function ...
Unified · Split
| @@ -0,0 +1,21 @@ | ||
| 1 | +NXP LPC1788 real-time clock | |
| 2 | + | |
| 3 | +The LPC1788 RTC provides calendar and clock functionality | |
| 4 | +together with periodic tick and alarm interrupt support. | |
| 5 | + | |
| 6 | +Required properties: | |
| 7 | +- compatible : must contain "nxp,lpc1788-rtc" | |
| 8 | +- reg : Specifies base physical address and size of the registers. | |
| 9 | +- interrupts : A single interrupt specifier. | |
| 10 | +- clocks : Must contain clock specifiers for rtc and register clock | |
| 11 | +- clock-names : Must contain "rtc" and "reg" | |
| 12 | + See ../clocks/clock-bindings.txt for details. | |
| 13 | + | |
| 14 | +Example: | |
| 15 | +rtc: rtc@40046000 { | |
| 16 | + compatible = "nxp,lpc1788-rtc"; | |
| 17 | + reg = <0x40046000 0x1000>; | |
| 18 | + interrupts = <47>; | |
| 19 | + clocks = <&creg_clk 0>, <&ccu1 CLK_CPU_BUS>; | |
| 20 | + clock-names = "rtc", "reg"; | |
| 21 | +}; | |
| @@ -16,6 +16,8 @@ Required properties: · 15 unmodified lines | ||
| 16 | 16 | Optional properties: |
| 17 | 17 | - system-power-controller: whether the rtc is controlling the system power |
| 18 | 18 | through pmic_power_en |
| 19 | +- clocks: Any internal or external clocks feeding in to rtc | |
| 20 | +- clock-names: Corresponding names of the clocks | |
| 19 | 21 | |
| 20 | 22 | Example: |
| 21 | 23 | |
| @@ -26,4 +28,6 @@ rtc@1c23000 { · 4 unmodified lines | ||
| 26 | 28 | 19>; |
| 27 | 29 | interrupt-parent = <&intc>; |
| 28 | 30 | system-power-controller; |
| 31 | + clocks = <&clk_32k_rtc>, <&clk_32768_ck>; | |
| 32 | + clock-names = "ext-clk", "int-clk"; | |
| 29 | 33 | }; |
| @@ -0,0 +1,25 @@ | ||
| 1 | +* Xilinx Zynq Ultrascale+ MPSoC Real Time Clock | |
| 2 | + | |
| 3 | +RTC controller for the Xilinx Zynq MPSoC Real Time Clock | |
| 4 | +Separate IRQ lines for seconds and alarm | |
| 5 | + | |
| 6 | +Required properties: | |
| 7 | +- compatible: Should be "xlnx,zynqmp-rtc" | |
| 8 | +- reg: Physical base address of the controller and length | |
| 9 | + of memory mapped region. | |
| 10 | +- interrupts: IRQ lines for the RTC. | |
| 11 | +- interrupt-names: interrupt line names eg. "sec" "alarm" | |
| 12 | + | |
| 13 | +Optional: | |
| 14 | +- calibration: calibration value for 1 sec period which will | |
| 15 | + be programmed directly to calibration register | |
| 16 | + | |
| 17 | +Example: | |
| 18 | +rtc: rtc@ffa60000 { | |
| 19 | + compatible = "xlnx,zynqmp-rtc"; | |
| 20 | + reg = <0x0 0xffa60000 0x100>; | |
| 21 | + interrupt-parent = <&gic>; | |
| 22 | + interrupts = <0 26 4>, <0 27 4>; | |
| 23 | + interrupt-names = "alarm", "sec"; | |
| 24 | + calibration = <0x198233>; | |
| 25 | +}; | |
| @@ -358,6 +358,8 @@ · 357 unmodified lines | ||
| 358 | 358 | interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH |
| 359 | 359 | GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; |
| 360 | 360 | ti,hwmods = "rtc"; |
| 361 | + clocks = <&clk_32768_ck>; | |
| 362 | + clock-names = "int-clk"; | |
| 361 | 363 | status = "disabled"; |
| 362 | 364 | }; |
| 363 | 365 | |
| @@ -112,6 +112,13 @@ · 111 unmodified lines | ||
| 112 | 112 | clock-frequency = <12000000>; |
| 113 | 113 | }; |
| 114 | 114 | |
| 115 | + /* fixed 32k external oscillator clock */ | |
| 116 | + clk_32k_rtc: clk_32k_rtc { | |
| 117 | + #clock-cells = <0>; | |
| 118 | + compatible = "fixed-clock"; | |
| 119 | + clock-frequency = <32768>; | |
| 120 | + }; | |
| 121 | + | |
| 115 | 122 | sound0: sound@0 { |
| 116 | 123 | compatible = "simple-audio-card"; |
| 117 | 124 | simple-audio-card,name = "AM437x-GP-EVM"; |
| @@ -941,3 +948,9 @@ · 823 unmodified lines | ||
| 941 | 948 | tx-num-evt = <32>; |
| 942 | 949 | rx-num-evt = <32>; |
| 943 | 950 | }; |
| 951 | + | |
| 952 | +&rtc { | |
| 953 | + clocks = <&clk_32k_rtc>, <&clk_32768_ck>; | |
| 954 | + clock-names = "ext-clk", "int-clk"; | |
| 955 | + status = "okay"; | |
| 956 | +}; | |
| @@ -110,6 +110,13 @@ · 109 unmodified lines | ||
| 110 | 110 | gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; |
| 111 | 111 | }; |
| 112 | 112 | }; |
| 113 | + | |
| 114 | + /* fixed 32k external oscillator clock */ | |
| 115 | + clk_32k_rtc: clk_32k_rtc { | |
| 116 | + #clock-cells = <0>; | |
| 117 | + compatible = "fixed-clock"; | |
| 118 | + clock-frequency = <32768>; | |
| 119 | + }; | |
| 113 | 120 | }; |
| 114 | 121 | |
| 115 | 122 | &am43xx_pinmux { |
| @@ -394,6 +401,8 @@ · 278 unmodified lines | ||
| 394 | 401 | }; |
| 395 | 402 | |
| 396 | 403 | &rtc { |
| 404 | + clocks = <&clk_32k_rtc>, <&clk_32768_ck>; | |
| 405 | + clock-names = "ext-clk", "int-clk"; | |
| 397 | 406 | status = "okay"; |
| 398 | 407 | }; |
| 399 | 408 | |
| @@ -24,6 +24,13 @@ · 23 unmodified lines | ||
| 24 | 24 | display0 = &lcd0; |
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | + /* fixed 32k external oscillator clock */ | |
| 28 | + clk_32k_rtc: clk_32k_rtc { | |
| 29 | + #clock-cells = <0>; | |
| 30 | + compatible = "fixed-clock"; | |
| 31 | + clock-frequency = <32768>; | |
| 32 | + }; | |
| 33 | + | |
| 27 | 34 | backlight { |
| 28 | 35 | compatible = "pwm-backlight"; |
| 29 | 36 | pwms = <&ecap0 0 50000 PWM_POLARITY_INVERTED>; |
| @@ -697,6 +704,8 @@ · 667 unmodified lines | ||
| 697 | 704 | }; |
| 698 | 705 | |
| 699 | 706 | &rtc { |
| 707 | + clocks = <&clk_32k_rtc>, <&clk_32768_ck>; | |
| 708 | + clock-names = "ext-clk", "int-clk"; | |
| 700 | 709 | status = "okay"; |
| 701 | 710 | }; |
| 702 | 711 | |
| @@ -157,7 +157,7 @@ CONFIG_LEDS_TRIGGERS=y · 156 unmodified lines | ||
| 157 | 157 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
| 158 | 158 | CONFIG_RTC_CLASS=y |
| 159 | 159 | CONFIG_RTC_DRV_V3020=y |
| 160 | −CONFIG_RTC_DRV_SA1100=y | |
| 160 | +CONFIG_RTC_DRV_PXA=y | |
| 161 | 161 | CONFIG_EXT2_FS=y |
| 162 | 162 | CONFIG_EXT3_FS=y |
| 163 | 163 | CONFIG_INOTIFY=y |
| @@ -157,7 +157,7 @@ CONFIG_LEDS_TRIGGERS=y · 156 unmodified lines | ||
| 157 | 157 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
| 158 | 158 | CONFIG_RTC_CLASS=y |
| 159 | 159 | CONFIG_RTC_DRV_V3020=y |
| 160 | −CONFIG_RTC_DRV_SA1100=y | |
| 160 | +CONFIG_RTC_DRV_PXA=y | |
| 161 | 161 | CONFIG_EXT2_FS=y |
| 162 | 162 | CONFIG_EXT3_FS=y |
| 163 | 163 | CONFIG_INOTIFY=y |
| @@ -150,7 +150,7 @@ CONFIG_LEDS_TRIGGERS=y · 149 unmodified lines | ||
| 150 | 150 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y |
| 151 | 151 | CONFIG_RTC_CLASS=y |
| 152 | 152 | CONFIG_RTC_DEBUG=y |
| 153 | −CONFIG_RTC_DRV_SA1100=y | |
| 153 | +CONFIG_RTC_DRV_PXA=y | |
| 154 | 154 | CONFIG_EXT2_FS=y |
| 155 | 155 | CONFIG_INOTIFY=y |
| 156 | 156 | CONFIG_MSDOS_FS=m |
| @@ -67,7 +67,7 @@ CONFIG_MMC=y · 66 unmodified lines | ||
| 67 | 67 | CONFIG_MMC_DEBUG=y |
| 68 | 68 | CONFIG_MMC_PXA=y |
| 69 | 69 | CONFIG_RTC_CLASS=y |
| 70 | −CONFIG_RTC_DRV_SA1100=y | |
| 70 | +CONFIG_RTC_DRV_PXA=y | |
| 71 | 71 | CONFIG_EXT2_FS=y |
| 72 | 72 | CONFIG_EXT3_FS=y |
| 73 | 73 | # CONFIG_DNOTIFY is not set |
| @@ -82,7 +82,7 @@ CONFIG_MMC=y · 81 unmodified lines | ||
| 82 | 82 | CONFIG_MMC_PXA=y |
| 83 | 83 | CONFIG_RTC_CLASS=y |
| 84 | 84 | CONFIG_RTC_DRV_PCF8563=m |
| 85 | −CONFIG_RTC_DRV_SA1100=m | |
| 85 | +CONFIG_RTC_DRV_PXA=m | |
| 86 | 86 | CONFIG_EXT2_FS=m |
| 87 | 87 | CONFIG_EXT3_FS=m |
| 88 | 88 | # CONFIG_DNOTIFY is not set |
| @@ -177,7 +177,7 @@ CONFIG_NEW_LEDS=y · 176 unmodified lines | ||
| 177 | 177 | CONFIG_RTC_CLASS=y |
| 178 | 178 | # CONFIG_RTC_HCTOSYS is not set |
| 179 | 179 | CONFIG_RTC_DRV_PCF8583=m |
| 180 | −CONFIG_RTC_DRV_SA1100=y | |
| 180 | +CONFIG_RTC_DRV_PXA=y | |
| 181 | 181 | CONFIG_EXT2_FS=y |
| 182 | 182 | CONFIG_EXT2_FS_XATTR=y |
| 183 | 183 | CONFIG_EXT2_FS_POSIX_ACL=y |
| @@ -1,23 +0,0 @@ | ||
| 1 | −#ifndef __ASM_MACH_REGS_RTC_H | |
| 2 | −#define __ASM_MACH_REGS_RTC_H | |
| 3 | − | |
| 4 | −#include <mach/addr-map.h> | |
| 5 | − | |
| 6 | −#define RTC_VIRT_BASE (APB_VIRT_BASE + 0x10000) | |
| 7 | −#define RTC_REG(x) (*((volatile u32 __iomem *)(RTC_VIRT_BASE + (x)))) | |
| 8 | − | |
| 9 | −/* | |
| 10 | − * Real Time Clock | |
| 11 | − */ | |
| 12 | − | |
| 13 | −#define RCNR RTC_REG(0x00) /* RTC Count Register */ | |
| 14 | −#define RTAR RTC_REG(0x04) /* RTC Alarm Register */ | |
| 15 | −#define RTSR RTC_REG(0x08) /* RTC Status Register */ | |
| 16 | −#define RTTR RTC_REG(0x0C) /* RTC Timer Trim Register */ | |
| 17 | − | |
| 18 | −#define RTSR_HZE (1 << 3) /* HZ interrupt enable */ | |
| 19 | −#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ | |
| 20 | −#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ | |
| 21 | −#define RTSR_AL (1 << 0) /* RTC alarm detected */ | |
| 22 | − | |
| 23 | −#endif /* __ASM_MACH_REGS_RTC_H */ | |
| @@ -440,25 +440,11 @@ struct platform_device pxa_device_rtc = { · 439 unmodified lines | ||
| 440 | 440 | .resource = pxa_rtc_resources, |
| 441 | 441 | }; |
| 442 | 442 | |
| 443 | −static struct resource sa1100_rtc_resources[] = { | |
| 444 | − { | |
| 445 | − .start = IRQ_RTC1Hz, | |
| 446 | − .end = IRQ_RTC1Hz, | |
| 447 | − .name = "rtc 1Hz", | |
| 448 | − .flags = IORESOURCE_IRQ, | |
| 449 | − }, { | |
| 450 | − .start = IRQ_RTCAlrm, | |
| 451 | − .end = IRQ_RTCAlrm, | |
| 452 | − .name = "rtc alarm", | |
| 453 | − .flags = IORESOURCE_IRQ, | |
| 454 | − }, | |
| 455 | −}; | |
| 456 | − | |
| 457 | 443 | struct platform_device sa1100_device_rtc = { |
| 458 | 444 | .name = "sa1100-rtc", |
| 459 | 445 | .id = -1, |
| 460 | − .num_resources = ARRAY_SIZE(sa1100_rtc_resources), | |
| 461 | − .resource = sa1100_rtc_resources, | |
| 446 | + .num_resources = ARRAY_SIZE(pxa_rtc_resources), | |
| 447 | + .resource = pxa_rtc_resources, | |
| 462 | 448 | }; |
| 463 | 449 | |
| 464 | 450 | static struct resource pxa_ac97_resources[] = { |
| @@ -282,7 +282,6 @@ static struct platform_device *devices[] __initdata = { · 281 unmodified lines | ||
| 282 | 282 | &pxa_device_asoc_ssp2, |
| 283 | 283 | &pxa_device_asoc_ssp3, |
| 284 | 284 | &pxa_device_asoc_platform, |
| 285 | − &sa1100_device_rtc, | |
| 286 | 285 | &pxa_device_rtc, |
| 287 | 286 | &pxa27x_device_ssp1, |
| 288 | 287 | &pxa27x_device_ssp2, |
| @@ -394,7 +394,6 @@ static struct platform_device *devices[] __initdata = { · 393 unmodified lines | ||
| 394 | 394 | &pxa_device_asoc_ssp3, |
| 395 | 395 | &pxa_device_asoc_ssp4, |
| 396 | 396 | &pxa_device_asoc_platform, |
| 397 | − &sa1100_device_rtc, | |
| 398 | 397 | &pxa_device_rtc, |
| 399 | 398 | &pxa3xx_device_ssp1, |
| 400 | 399 | &pxa3xx_device_ssp2, |
| @@ -857,40 +857,6 @@ · 856 unmodified lines | ||
| 857 | 857 | #define OIER_E3 OIER_E (3) /* match interrupt Enable 3 */ |
| 858 | 858 | |
| 859 | 859 | |
| 860 | −/* | |
| 861 | − * Real-Time Clock (RTC) control registers | |
| 862 | − * | |
| 863 | − * Registers | |
| 864 | − * RTAR Real-Time Clock (RTC) Alarm Register (read/write). | |
| 865 | − * RCNR Real-Time Clock (RTC) CouNt Register (read/write). | |
| 866 | − * RTTR Real-Time Clock (RTC) Trim Register (read/write). | |
| 867 | − * RTSR Real-Time Clock (RTC) Status Register (read/write). | |
| 868 | − * | |
| 869 | − * Clocks | |
| 870 | − * frtx, Trtx Frequency, period of the real-time clock crystal | |
| 871 | − * (32.768 kHz nominal). | |
| 872 | − * frtc, Trtc Frequency, period of the real-time clock counter | |
| 873 | − * (1 Hz nominal). | |
| 874 | − */ | |
| 875 | − | |
| 876 | −#define RTAR __REG(0x90010000) /* RTC Alarm Reg. */ | |
| 877 | −#define RCNR __REG(0x90010004) /* RTC CouNt Reg. */ | |
| 878 | −#define RTTR __REG(0x90010008) /* RTC Trim Reg. */ | |
| 879 | −#define RTSR __REG(0x90010010) /* RTC Status Reg. */ | |
| 880 | − | |
| 881 | −#define RTTR_C Fld (16, 0) /* clock divider Count - 1 */ | |
| 882 | −#define RTTR_D Fld (10, 16) /* trim Delete count */ | |
| 883 | − /* frtc = (1023*(C + 1) - D)*frtx/ */ | |
| 884 | − /* (1023*(C + 1)^2) */ | |
| 885 | − /* Trtc = (1023*(C + 1)^2)*Trtx/ */ | |
| 886 | − /* (1023*(C + 1) - D) */ | |
| 887 | − | |
| 888 | −#define RTSR_AL 0x00000001 /* ALarm detected */ | |
| 889 | −#define RTSR_HZ 0x00000002 /* 1 Hz clock detected */ | |
| 890 | −#define RTSR_ALE 0x00000004 /* ALarm interrupt Enable */ | |
| 891 | −#define RTSR_HZE 0x00000008 /* 1 Hz clock interrupt Enable */ | |
| 892 | − | |
| 893 | − | |
| 894 | 860 | /* |
| 895 | 861 | * Power Manager (PM) control registers |
| 896 | 862 | * |
| @@ -945,11 +945,11 @@ config RTC_DRV_DA9055 · 944 unmodified lines | ||
| 945 | 945 | will be called rtc-da9055 |
| 946 | 946 | |
| 947 | 947 | config RTC_DRV_DA9063 |
| 948 | − tristate "Dialog Semiconductor DA9063 RTC" | |
| 949 | − depends on MFD_DA9063 | |
| 948 | + tristate "Dialog Semiconductor DA9063/DA9062 RTC" | |
| 949 | + depends on MFD_DA9063 || MFD_DA9062 | |
| 950 | 950 | help |
| 951 | 951 | If you say yes here you will get support for the RTC subsystem |
| 952 | − of the Dialog Semiconductor DA9063. | |
| 952 | + for the Dialog Semiconductor PMIC chips DA9063 and DA9062. | |
| 953 | 953 | |
| 954 | 954 | This driver can also be built as a module. If so, the module |
| 955 | 955 | will be called "rtc-da9063". |
| @@ -1116,6 +1116,13 @@ config RTC_DRV_OPAL · 160 unmodified lines | ||
| 1116 | 1116 | This driver can also be built as a module. If so, the module |
| 1117 | 1117 | will be called rtc-opal. |
| 1118 | 1118 | |
| 1119 | +config RTC_DRV_ZYNQMP | |
| 1120 | + tristate "Xilinx Zynq Ultrascale+ MPSoC RTC" | |
| 1121 | + depends on OF | |
| 1122 | + help | |
| 1123 | + If you say yes here you get support for the RTC controller found on | |
| 1124 | + Xilinx Zynq Ultrascale+ MPSoC. | |
| 1125 | + | |
| 1119 | 1126 | comment "on-CPU RTC drivers" |
| 1120 | 1127 | |
| 1121 | 1128 | config RTC_DRV_DAVINCI |
| @@ -1306,11 +1313,13 @@ config RTC_DRV_GENERIC · 184 unmodified lines | ||
| 1306 | 1313 | just say Y. |
| 1307 | 1314 | |
| 1308 | 1315 | config RTC_DRV_PXA |
| 1309 | − tristate "PXA27x/PXA3xx" | |
| 1310 | − depends on ARCH_PXA | |
| 1311 | − help | |
| 1312 | − If you say Y here you will get access to the real time clock | |
| 1313 | − built into your PXA27x or PXA3xx CPU. | |
| 1316 | + tristate "PXA27x/PXA3xx" | |
| 1317 | + depends on ARCH_PXA | |
| 1318 | + select RTC_DRV_SA1100 | |
| 1319 | + help | |
| 1320 | + If you say Y here you will get access to the real time clock | |
| 1321 | + built into your PXA27x or PXA3xx CPU. This RTC is actually 2 RTCs | |
| 1322 | + consisting of an SA1100 compatible RTC and the extended PXA RTC. | |
| 1314 | 1323 | |
| 1315 | 1324 | This RTC driver uses PXA RTC registers available since pxa27x |
| 1316 | 1325 | series (RDxR, RYxR) instead of legacy RCNR, RTAR. |
| @@ -1456,6 +1465,18 @@ config RTC_DRV_JZ4740 · 139 unmodified lines | ||
| 1456 | 1465 | This driver can also be buillt as a module. If so, the module |
| 1457 | 1466 | will be called rtc-jz4740. |
| 1458 | 1467 | |
| 1468 | +config RTC_DRV_LPC24XX | |
| 1469 | + tristate "NXP RTC for LPC178x/18xx/408x/43xx" | |
| 1470 | + depends on ARCH_LPC18XX || COMPILE_TEST | |
| 1471 | + depends on OF && HAS_IOMEM | |
| 1472 | + help | |
| 1473 | + This enables support for the NXP RTC found which can be found on | |
| 1474 | + NXP LPC178x/18xx/408x/43xx devices. | |
| 1475 | + | |
| 1476 | + If you have one of the devices above enable this driver to use | |
| 1477 | + the hardware RTC. This driver can also be buillt as a module. If | |
| 1478 | + so, the module will be called rtc-lpc24xx. | |
| 1479 | + | |
| 1459 | 1480 | config RTC_DRV_LPC32XX |
| 1460 | 1481 | depends on ARCH_LPC32XX |
| 1461 | 1482 | tristate "NXP LPC32XX RTC" |
| @@ -74,6 +74,7 @@ obj-$(CONFIG_RTC_DRV_ISL12057) += rtc-isl12057.o · 73 unmodified lines | ||
| 74 | 74 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
| 75 | 75 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o |
| 76 | 76 | obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o |
| 77 | +obj-$(CONFIG_RTC_DRV_LPC24XX) += rtc-lpc24xx.o | |
| 77 | 78 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o |
| 78 | 79 | obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o |
| 79 | 80 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
| @@ -158,3 +159,4 @@ obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o · 78 unmodified lines | ||
| 158 | 159 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o |
| 159 | 160 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
| 160 | 161 | obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o |
| 162 | +obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o | |
| @@ -202,6 +202,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, · 201 unmodified lines | ||
| 202 | 202 | rtc->max_user_freq = 64; |
| 203 | 203 | rtc->dev.parent = dev; |
| 204 | 204 | rtc->dev.class = rtc_class; |
| 205 | + rtc->dev.groups = rtc_get_dev_attribute_groups(); | |
| 205 | 206 | rtc->dev.release = rtc_device_release; |
| 206 | 207 | |
| 207 | 208 | mutex_init(&rtc->ops_lock); |
| @@ -234,12 +235,12 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, · 26 unmodified lines | ||
| 234 | 235 | |
| 235 | 236 | err = device_register(&rtc->dev); |
| 236 | 237 | if (err) { |
| 238 | + /* This will free both memory and the ID */ | |
| 237 | 239 | put_device(&rtc->dev); |
| 238 | − goto exit_kfree; | |
| 240 | + goto exit; | |
| 239 | 241 | } |
| 240 | 242 | |
| 241 | 243 | rtc_dev_add_device(rtc); |
| 242 | − rtc_sysfs_add_device(rtc); | |
| 243 | 244 | rtc_proc_add_device(rtc); |
| 244 | 245 | |
| 245 | 246 | dev_info(dev, "rtc core: registered %s as %s\n", |
| @@ -247,9 +248,6 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, · 1 unmodified line | ||
| 247 | 248 | |
| 248 | 249 | return rtc; |
| 249 | 250 | |
| 250 | −exit_kfree: | |
| 251 | − kfree(rtc); | |
| 252 | − | |
| 253 | 251 | exit_ida: |
| 254 | 252 | ida_simple_remove(&rtc_ida, id); |
| 255 | 253 | |
| @@ -268,19 +266,17 @@ EXPORT_SYMBOL_GPL(rtc_device_register); · 12 unmodified lines | ||
| 268 | 266 | */ |
| 269 | 267 | void rtc_device_unregister(struct rtc_device *rtc) |
| 270 | 268 | { |
| 271 | − if (get_device(&rtc->dev) != NULL) { | |
| 272 | − mutex_lock(&rtc->ops_lock); | |
| 273 | − /* remove innards of this RTC, then disable it, before | |
| 274 | − * letting any rtc_class_open() users access it again | |
| 275 | − */ | |
| 276 | − rtc_sysfs_del_device(rtc); | |
| 277 | − rtc_dev_del_device(rtc); | |
| 278 | − rtc_proc_del_device(rtc); | |
| 279 | − device_unregister(&rtc->dev); | |
| 280 | − rtc->ops = NULL; | |
| 281 | − mutex_unlock(&rtc->ops_lock); | |
| 282 | − put_device(&rtc->dev); | |
| 283 | − } | |
| 269 | + mutex_lock(&rtc->ops_lock); | |
| 270 | + /* | |
| 271 | + * Remove innards of this RTC, then disable it, before | |
| 272 | + * letting any rtc_class_open() users access it again | |
| 273 | + */ | |
| 274 | + rtc_dev_del_device(rtc); | |
| 275 | + rtc_proc_del_device(rtc); | |
| 276 | + device_del(&rtc->dev); | |
| 277 | + rtc->ops = NULL; | |
| 278 | + mutex_unlock(&rtc->ops_lock); | |
| 279 | + put_device(&rtc->dev); | |
| 284 | 280 | } |
| 285 | 281 | EXPORT_SYMBOL_GPL(rtc_device_unregister); |
| 286 | 282 | |
| @@ -363,7 +359,6 @@ static int __init rtc_init(void) · 76 unmodified lines | ||
| 363 | 359 | } |
| 364 | 360 | rtc_class->pm = RTC_CLASS_DEV_PM_OPS; |
| 365 | 361 | rtc_dev_init(); |
| 366 | − rtc_sysfs_init(rtc_class); | |
| 367 | 362 | return 0; |
| 368 | 363 | } |
| 369 | 364 | |
| @@ -564,7 +564,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) · 563 unmodified lines | ||
| 564 | 564 | void rtc_update_irq(struct rtc_device *rtc, |
| 565 | 565 | unsigned long num, unsigned long events) |
| 566 | 566 | { |
| 567 | − if (unlikely(IS_ERR_OR_NULL(rtc))) | |
| 567 | + if (IS_ERR_OR_NULL(rtc)) | |
| 568 | 568 | return; |
| 569 | 569 | |
| 570 | 570 | pm_stay_awake(rtc->dev.parent); |
| @@ -251,17 +251,26 @@ static SIMPLE_DEV_PM_OPS(pm80x_rtc_pm_ops, pm80x_rtc_suspend, pm80x_rtc_resume); · 250 unmodified lines | ||
| 251 | 251 | static int pm80x_rtc_probe(struct platform_device *pdev) |
| 252 | 252 | { |
| 253 | 253 | struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
| 254 | − struct pm80x_platform_data *pm80x_pdata = | |
| 255 | − dev_get_platdata(pdev->dev.parent); | |
| 256 | − struct pm80x_rtc_pdata *pdata = NULL; | |
| 254 | + struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev); | |
| 257 | 255 | struct pm80x_rtc_info *info; |
| 256 | + struct device_node *node = pdev->dev.of_node; | |
| 258 | 257 | struct rtc_time tm; |
| 259 | 258 | unsigned long ticks = 0; |
| 260 | 259 | int ret; |
| 261 | 260 | |
| 262 | − pdata = dev_get_platdata(&pdev->dev); | |
| 263 | − if (pdata == NULL) | |
| 264 | − dev_warn(&pdev->dev, "No platform data!\n"); | |
| 261 | + if (!pdata && !node) { | |
| 262 | + dev_err(&pdev->dev, | |
| 263 | + "pm80x-rtc requires platform data or of_node\n"); | |
| 264 | + return -EINVAL; | |
| 265 | + } | |
| 266 | + | |
| 267 | + if (!pdata) { | |
| 268 | + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | |
| 269 | + if (!pdata) { | |
| 270 | + dev_err(&pdev->dev, "failed to allocate memory\n"); | |
| 271 | + return -ENOMEM; | |
| 272 | + } | |
| 273 | + } | |
| 265 | 274 | |
| 266 | 275 | info = |
| 267 | 276 | devm_kzalloc(&pdev->dev, sizeof(struct pm80x_rtc_info), GFP_KERNEL); |
| @@ -327,11 +336,8 @@ static int pm80x_rtc_probe(struct platform_device *pdev) · 59 unmodified lines | ||
| 327 | 336 | regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_RTC1_USE_XO, |
| 328 | 337 | PM800_RTC1_USE_XO); |
| 329 | 338 | |
| 330 | − if (pm80x_pdata) { | |
| 331 | − pdata = pm80x_pdata->rtc; | |
| 332 | − if (pdata) | |
| 333 | − info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup; | |
| 334 | − } | |
| 339 | + /* remember whether this power up is caused by PMIC RTC or not */ | |
| 340 | + info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup; | |
| 335 | 341 | |
| 336 | 342 | device_init_wakeup(&pdev->dev, 1); |
| 337 | 343 | |
| @@ -1009,6 +1009,7 @@ static const struct of_device_id abb5zes3_dt_match[] = { · 1008 unmodified lines | ||
| 1009 | 1009 | { .compatible = "abracon,abb5zes3" }, |
| 1010 | 1010 | { }, |
| 1011 | 1011 | }; |
| 1012 | +MODULE_DEVICE_TABLE(of, abb5zes3_dt_match); | |
| 1012 | 1013 | #endif |
| 1013 | 1014 | |
| 1014 | 1015 | static const struct i2c_device_id abb5zes3_id[] = { |
| @@ -1020,7 +1021,6 @@ MODULE_DEVICE_TABLE(i2c, abb5zes3_id); · 5 unmodified lines | ||
| 1020 | 1021 | static struct i2c_driver abb5zes3_driver = { |
| 1021 | 1022 | .driver = { |
| 1022 | 1023 | .name = DRV_NAME, |
| 1023 | − .owner = THIS_MODULE, | |
| 1024 | 1024 | .pm = &abb5zes3_rtc_pm_ops, |
| 1025 | 1025 | .of_match_table = of_match_ptr(abb5zes3_dt_match), |
| 1026 | 1026 | }, |
| @@ -445,7 +445,9 @@ static const struct rtc_class_ops ab8540_rtc_ops = { · 444 unmodified lines | ||
| 445 | 445 | static const struct platform_device_id ab85xx_rtc_ids[] = { |
| 446 | 446 | { "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, }, |
| 447 | 447 | { "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, }, |
| 448 | + { /* sentinel */ } | |
| 448 | 449 | }; |
| 450 | +MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids); | |
| 449 | 451 | |
| 450 | 452 | static int ab8500_rtc_probe(struct platform_device *pdev) |
| 451 | 453 | { |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #define ABX8XX_REG_WD 0x07 |
| 29 | 29 | |
| 30 | 30 | #define ABX8XX_REG_CTRL1 0x10 |
| 31 | −#define ABX8XX_CTRL_WRITE BIT(1) | |
| 31 | +#define ABX8XX_CTRL_WRITE BIT(0) | |
| 32 | 32 | #define ABX8XX_CTRL_12_24 BIT(6) |
| 33 | 33 | |
| 34 | 34 | #define ABX8XX_REG_CFG_KEY 0x1f |
| @@ -40,13 +40,6 @@ struct armada38x_rtc { · 39 unmodified lines | ||
| 40 | 40 | void __iomem *regs; |
| 41 | 41 | void __iomem *regs_soc; |
| 42 | 42 | spinlock_t lock; |
| 43 | − /* | |
| 44 | − * While setting the time, the RTC TIME register should not be | |
| 45 | − * accessed. Setting the RTC time involves sleeping during | |
| 46 | − * 100ms, so a mutex instead of a spinlock is used to protect | |
| 47 | − * it | |
| 48 | − */ | |
| 49 | − struct mutex mutex_time; | |
| 50 | 43 | int irq; |
| 51 | 44 | }; |
| 52 | 45 | |
| @@ -64,9 +57,9 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset) · 11 unmodified lines | ||
| 64 | 57 | static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| 65 | 58 | { |
| 66 | 59 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); |
| 67 | − unsigned long time, time_check; | |
| 60 | + unsigned long time, time_check, flags; | |
| 68 | 61 | |
| 69 | − mutex_lock(&rtc->mutex_time); | |
| 62 | + spin_lock_irqsave(&rtc->lock, flags); | |
| 70 | 63 | time = readl(rtc->regs + RTC_TIME); |
| 71 | 64 | /* |
| 72 | 65 | * WA for failing time set attempts. As stated in HW ERRATA if |
| @@ -77,7 +70,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) · 4 unmodified lines | ||
| 77 | 70 | if ((time_check - time) > 1) |
| 78 | 71 | time_check = readl(rtc->regs + RTC_TIME); |
| 79 | 72 | |
| 80 | − mutex_unlock(&rtc->mutex_time); | |
| 73 | + spin_unlock_irqrestore(&rtc->lock, flags); | |
| 81 | 74 | |
| 82 | 75 | rtc_time_to_tm(time_check, tm); |
| 83 | 76 | |
| @@ -88,23 +81,23 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) · 4 unmodified lines | ||
| 88 | 81 | { |
| 89 | 82 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); |
| 90 | 83 | int ret = 0; |
| 91 | − unsigned long time; | |
| 84 | + unsigned long time, flags; | |
| 92 | 85 | |
| 93 | 86 | ret = rtc_tm_to_time(tm, &time); |
| 94 | 87 | |
| 95 | 88 | if (ret) |
| 96 | 89 | goto out; |
| 97 | 90 | /* |
| 98 | − * Setting the RTC time not always succeeds. According to the | |
| 99 | − * errata we need to first write on the status register and | |
| 100 | − * then wait for 100ms before writing to the time register to be | |
| 101 | − * sure that the data will be taken into account. | |
| 91 | + * According to errata FE-3124064, Write to RTC TIME register | |
| 92 | + * may fail. As a workaround, after writing to RTC TIME | |
| 93 | + * register, issue a dummy write of 0x0 twice to RTC Status | |
| 94 | + * register. | |
| 102 | 95 | */ |
| 103 | − mutex_lock(&rtc->mutex_time); | |
| 104 | − rtc_delayed_write(0, rtc, RTC_STATUS); | |
| 105 | − msleep(100); | |
| 96 | + spin_lock_irqsave(&rtc->lock, flags); | |
| 106 | 97 | rtc_delayed_write(time, rtc, RTC_TIME); |
| 107 | − mutex_unlock(&rtc->mutex_time); | |
| 98 | + rtc_delayed_write(0, rtc, RTC_STATUS); | |
| 99 | + rtc_delayed_write(0, rtc, RTC_STATUS); | |
| 100 | + spin_unlock_irqrestore(&rtc->lock, flags); | |
| 108 | 101 | |
| 109 | 102 | out: |
| 110 | 103 | return ret; |
| @@ -229,7 +222,6 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev) · 118 unmodified lines | ||
| 229 | 222 | return -ENOMEM; |
| 230 | 223 | |
| 231 | 224 | spin_lock_init(&rtc->lock); |
| 232 | − mutex_init(&rtc->mutex_time); | |
| 233 | 225 | |
| 234 | 226 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); |
| 235 | 227 | rtc->regs = devm_ioremap_resource(&pdev->dev, res); |
| @@ -303,6 +295,7 @@ static const struct of_device_id armada38x_rtc_of_match_table[] = { · 67 unmodified lines | ||
| 303 | 295 | { .compatible = "marvell,armada-380-rtc", }, |
| 304 | 296 | {} |
| 305 | 297 | }; |
| 298 | +MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table); | |
| 306 | 299 | #endif |
| 307 | 300 | |
| 308 | 301 | static struct platform_driver armada38x_rtc_driver = { |
| @@ -45,7 +45,7 @@ static void as3722_time_to_reg(u8 *rbuff, struct rtc_time *tm) · 44 unmodified lines | ||
| 45 | 45 | rbuff[1] = bin2bcd(tm->tm_min); |
| 46 | 46 | rbuff[2] = bin2bcd(tm->tm_hour); |
| 47 | 47 | rbuff[3] = bin2bcd(tm->tm_mday); |
| 48 | − rbuff[4] = bin2bcd(tm->tm_mon); | |
| 48 | + rbuff[4] = bin2bcd(tm->tm_mon + 1); | |
| 49 | 49 | rbuff[5] = bin2bcd(tm->tm_year - (AS3722_RTC_START_YEAR - 1900)); |
| 50 | 50 | } |
| 51 | 51 | |
| @@ -55,7 +55,7 @@ static void as3722_reg_to_time(u8 *rbuff, struct rtc_time *tm) · 3 unmodified lines | ||
| 55 | 55 | tm->tm_min = bcd2bin(rbuff[1] & 0x7F); |
| 56 | 56 | tm->tm_hour = bcd2bin(rbuff[2] & 0x3F); |
| 57 | 57 | tm->tm_mday = bcd2bin(rbuff[3] & 0x3F); |
| 58 | − tm->tm_mon = bcd2bin(rbuff[4] & 0x1F); | |
| 58 | + tm->tm_mon = bcd2bin(rbuff[4] & 0x1F) - 1; | |
| 59 | 59 | tm->tm_year = (AS3722_RTC_START_YEAR - 1900) + bcd2bin(rbuff[5] & 0x7F); |
| 60 | 60 | return; |
| 61 | 61 | } |
| @@ -18,20 +18,21 @@ · 17 unmodified lines | ||
| 18 | 18 | * |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | −#include <linux/module.h> | |
| 22 | −#include <linux/kernel.h> | |
| 23 | −#include <linux/platform_device.h> | |
| 24 | −#include <linux/time.h> | |
| 25 | −#include <linux/rtc.h> | |
| 26 | 21 | #include <linux/bcd.h> |
| 22 | +#include <linux/clk.h> | |
| 23 | +#include <linux/completion.h> | |
| 27 | 24 | #include <linux/interrupt.h> |
| 28 | −#include <linux/spinlock.h> | |
| 29 | 25 | #include <linux/ioctl.h> |
| 30 | −#include <linux/completion.h> | |
| 31 | 26 | #include <linux/io.h> |
| 32 | −#include <linux/of.h> | |
| 27 | +#include <linux/kernel.h> | |
| 28 | +#include <linux/module.h> | |
| 33 | 29 | #include <linux/of_device.h> |
| 30 | +#include <linux/of.h> | |
| 31 | +#include <linux/platform_device.h> | |
| 32 | +#include <linux/rtc.h> | |
| 33 | +#include <linux/spinlock.h> | |
| 34 | 34 | #include <linux/suspend.h> |
| 35 | +#include <linux/time.h> | |
| 35 | 36 | #include <linux/uaccess.h> |
| 36 | 37 | |
| 37 | 38 | #include "rtc-at91rm9200.h" |
| @@ -59,6 +60,7 @@ static bool suspended; · 21 unmodified lines | ||
| 59 | 60 | static DEFINE_SPINLOCK(suspended_lock); |
| 60 | 61 | static unsigned long cached_events; |
| 61 | 62 | static u32 at91_rtc_imr; |
| 63 | +static struct clk *sclk; | |
| 62 | 64 | |
| 63 | 65 | static void at91_rtc_write_ier(u32 mask) |
| 64 | 66 | { |
| @@ -407,6 +409,16 @@ static int __init at91_rtc_probe(struct platform_device *pdev) · 342 unmodified lines | ||
| 407 | 409 | return -ENOMEM; |
| 408 | 410 | } |
| 409 | 411 | |
| 412 | + sclk = devm_clk_get(&pdev->dev, NULL); | |
| 413 | + if (IS_ERR(sclk)) | |
| 414 | + return PTR_ERR(sclk); | |
| 415 | + | |
| 416 | + ret = clk_prepare_enable(sclk); | |
| 417 | + if (ret) { | |
| 418 | + dev_err(&pdev->dev, "Could not enable slow clock\n"); | |
| 419 | + return ret; | |
| 420 | + } | |
| 421 | + | |
| 410 | 422 | at91_rtc_write(AT91_RTC_CR, 0); |
| 411 | 423 | at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */ |
| 412 | 424 | |
| @@ -420,7 +432,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 420 | 432 | "at91_rtc", pdev); |
| 421 | 433 | if (ret) { |
| 422 | 434 | dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); |
| 423 | − return ret; | |
| 435 | + goto err_clk; | |
| 424 | 436 | } |
| 425 | 437 | |
| 426 | 438 | /* cpu init code should really have flagged this device as |
| @@ -431,8 +443,10 @@ static int __init at91_rtc_probe(struct platform_device *pdev) · 4 unmodified lines | ||
| 431 | 443 | |
| 432 | 444 | rtc = devm_rtc_device_register(&pdev->dev, pdev->name, |
| 433 | 445 | &at91_rtc_ops, THIS_MODULE); |
| 434 | − if (IS_ERR(rtc)) | |
| 435 | − return PTR_ERR(rtc); | |
| 446 | + if (IS_ERR(rtc)) { | |
| 447 | + ret = PTR_ERR(rtc); | |
| 448 | + goto err_clk; | |
| 449 | + } | |
| 436 | 450 | platform_set_drvdata(pdev, rtc); |
| 437 | 451 | |
| 438 | 452 | /* enable SECEV interrupt in order to initialize at91_rtc_upd_rdy |
| @@ -442,6 +456,11 @@ static int __init at91_rtc_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 442 | 456 | |
| 443 | 457 | dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); |
| 444 | 458 | return 0; |
| 459 | + | |
| 460 | +err_clk: | |
| 461 | + clk_disable_unprepare(sclk); | |
| 462 | + | |
| 463 | + return ret; | |
| 445 | 464 | } |
| 446 | 465 | |
| 447 | 466 | /* |
| @@ -454,6 +473,8 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) · 6 unmodified lines | ||
| 454 | 473 | AT91_RTC_SECEV | AT91_RTC_TIMEV | |
| 455 | 474 | AT91_RTC_CALEV); |
| 456 | 475 | |
| 476 | + clk_disable_unprepare(sclk); | |
| 477 | + | |
| 457 | 478 | return 0; |
| 458 | 479 | } |
| 459 | 480 | |
| @@ -11,20 +11,20 @@ · 10 unmodified lines | ||
| 11 | 11 | * 2 of the License, or (at your option) any later version. |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | −#include <linux/module.h> | |
| 15 | −#include <linux/kernel.h> | |
| 16 | −#include <linux/platform_device.h> | |
| 17 | −#include <linux/time.h> | |
| 18 | −#include <linux/rtc.h> | |
| 14 | +#include <linux/clk.h> | |
| 19 | 15 | #include <linux/interrupt.h> |
| 20 | 16 | #include <linux/ioctl.h> |
| 21 | −#include <linux/slab.h> | |
| 22 | −#include <linux/platform_data/atmel.h> | |
| 23 | 17 | #include <linux/io.h> |
| 18 | +#include <linux/kernel.h> | |
| 24 | 19 | #include <linux/mfd/syscon.h> |
| 20 | +#include <linux/module.h> | |
| 21 | +#include <linux/of.h> | |
| 22 | +#include <linux/platform_device.h> | |
| 25 | 23 | #include <linux/regmap.h> |
| 24 | +#include <linux/rtc.h> | |
| 25 | +#include <linux/slab.h> | |
| 26 | 26 | #include <linux/suspend.h> |
| 27 | −#include <linux/clk.h> | |
| 27 | +#include <linux/time.h> | |
| 28 | 28 | |
| 29 | 29 | /* |
| 30 | 30 | * This driver uses two configurable hardware resources that live in the |
| @@ -425,18 +425,19 @@ static int at91_rtc_probe(struct platform_device *pdev) · 394 unmodified lines | ||
| 425 | 425 | if (IS_ERR(rtc->sclk)) |
| 426 | 426 | return PTR_ERR(rtc->sclk); |
| 427 | 427 | |
| 428 | − sclk_rate = clk_get_rate(rtc->sclk); | |
| 429 | − if (!sclk_rate || sclk_rate > AT91_RTT_RTPRES) { | |
| 430 | − dev_err(&pdev->dev, "Invalid slow clock rate\n"); | |
| 431 | − return -EINVAL; | |
| 432 | − } | |
| 433 | − | |
| 434 | 428 | ret = clk_prepare_enable(rtc->sclk); |
| 435 | 429 | if (ret) { |
| 436 | 430 | dev_err(&pdev->dev, "Could not enable slow clock\n"); |
| 437 | 431 | return ret; |
| 438 | 432 | } |
| 439 | 433 | |
| 434 | + sclk_rate = clk_get_rate(rtc->sclk); | |
| 435 | + if (!sclk_rate || sclk_rate > AT91_RTT_RTPRES) { | |
| 436 | + dev_err(&pdev->dev, "Invalid slow clock rate\n"); | |
| 437 | + ret = -EINVAL; | |
| 438 | + goto err_clk; | |
| 439 | + } | |
| 440 | + | |
| 440 | 441 | mr = rtt_readl(rtc, MR); |
| 441 | 442 | |
| 442 | 443 | /* unless RTT is counting at 1 Hz, re-initialize it */ |
| @@ -451,8 +452,10 @@ static int at91_rtc_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 451 | 452 | |
| 452 | 453 | rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name, |
| 453 | 454 | &at91_rtc_ops, THIS_MODULE); |
| 454 | − if (IS_ERR(rtc->rtcdev)) | |
| 455 | − return PTR_ERR(rtc->rtcdev); | |
| 455 | + if (IS_ERR(rtc->rtcdev)) { | |
| 456 | + ret = PTR_ERR(rtc->rtcdev); | |
| 457 | + goto err_clk; | |
| 458 | + } | |
| 456 | 459 | |
| 457 | 460 | /* register irq handler after we know what name we'll use */ |
| 458 | 461 | ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, |
| @@ -460,7 +463,7 @@ static int at91_rtc_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 460 | 463 | dev_name(&rtc->rtcdev->dev), rtc); |
| 461 | 464 | if (ret) { |
| 462 | 465 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); |
| 463 | − return ret; | |
| 466 | + goto err_clk; | |
| 464 | 467 | } |
| 465 | 468 | |
| 466 | 469 | /* NOTE: sam9260 rev A silicon has a ROM bug which resets the |
| @@ -474,6 +477,11 @@ static int at91_rtc_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 474 | 477 | dev_name(&rtc->rtcdev->dev)); |
| 475 | 478 | |
| 476 | 479 | return 0; |
| 480 | + | |
| 481 | +err_clk: | |
| 482 | + clk_disable_unprepare(rtc->sclk); | |
| 483 | + | |
| 484 | + return ret; | |
| 477 | 485 | } |
| 478 | 486 | |
| 479 | 487 | /* |
| @@ -487,8 +495,7 @@ static int at91_rtc_remove(struct platform_device *pdev) · 7 unmodified lines | ||
| 487 | 495 | /* disable all interrupts */ |
| 488 | 496 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); |
| 489 | 497 | |
| 490 | − if (!IS_ERR(rtc->sclk)) | |
| 491 | − clk_disable_unprepare(rtc->sclk); | |
| 498 | + clk_disable_unprepare(rtc->sclk); | |
| 492 | 499 | |
| 493 | 500 | return 0; |
| 494 | 501 | } |
| @@ -361,7 +361,7 @@ static int bfin_rtc_probe(struct platform_device *pdev) · 360 unmodified lines | ||
| 361 | 361 | /* Register our RTC with the RTC framework */ |
| 362 | 362 | rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops, |
| 363 | 363 | THIS_MODULE); |
| 364 | − if (unlikely(IS_ERR(rtc->rtc_dev))) | |
| 364 | + if (IS_ERR(rtc->rtc_dev)) | |
| 365 | 365 | return PTR_ERR(rtc->rtc_dev); |
| 366 | 366 | |
| 367 | 367 | /* Grab the IRQ and init the hardware */ |
| @@ -212,7 +212,7 @@ static int bq32k_probe(struct i2c_client *client, · 211 unmodified lines | ||
| 212 | 212 | if (error) |
| 213 | 213 | return error; |
| 214 | 214 | |
| 215 | − if (client && client->dev.of_node) | |
| 215 | + if (client->dev.of_node) | |
| 216 | 216 | trickle_charger_of_init(dev, client->dev.of_node); |
| 217 | 217 | |
| 218 | 218 | rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name, |
| @@ -234,7 +234,6 @@ MODULE_DEVICE_TABLE(i2c, bq32k_id); · 15 unmodified lines | ||
| 234 | 234 | static struct i2c_driver bq32k_driver = { |
| 235 | 235 | .driver = { |
| 236 | 236 | .name = "bq32k", |
| 237 | − .owner = THIS_MODULE, | |
| 238 | 237 | }, |
| 239 | 238 | .probe = bq32k_probe, |
| 240 | 239 | .id_table = bq32k_id, |
| @@ -41,7 +41,6 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <linux/pm.h> |
| 42 | 42 | #include <linux/of.h> |
| 43 | 43 | #include <linux/of_platform.h> |
| 44 | −#include <linux/dmi.h> | |
| 45 | 44 | |
| 46 | 45 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
| 47 | 46 | #include <asm-generic/rtc.h> |
| @@ -51,6 +50,7 @@ struct cmos_rtc { · 3 unmodified lines | ||
| 51 | 50 | struct device *dev; |
| 52 | 51 | int irq; |
| 53 | 52 | struct resource *iomem; |
| 53 | + time64_t alarm_expires; | |
| 54 | 54 | |
| 55 | 55 | void (*wake_on)(struct device *); |
| 56 | 56 | void (*wake_off)(struct device *); |
| @@ -377,53 +377,11 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) · 320 unmodified lines | ||
| 377 | 377 | |
| 378 | 378 | spin_unlock_irq(&rtc_lock); |
| 379 | 379 | |
| 380 | − return 0; | |
| 381 | −} | |
| 382 | − | |
| 383 | −/* | |
| 384 | − * Do not disable RTC alarm on shutdown - workaround for b0rked BIOSes. | |
| 385 | − */ | |
| 386 | −static bool alarm_disable_quirk; | |
| 380 | + cmos->alarm_expires = rtc_tm_to_time64(&t->time); | |
| 387 | 381 | |
| 388 | −static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) | |
| 389 | −{ | |
| 390 | − alarm_disable_quirk = true; | |
| 391 | − pr_info("BIOS has alarm-disable quirk - RTC alarms disabled\n"); | |
| 392 | 382 | return 0; |
| 393 | 383 | } |
| 394 | 384 | |
| 395 | −static const struct dmi_system_id rtc_quirks[] __initconst = { | |
| 396 | − /* https://bugzilla.novell.com/show_bug.cgi?id=805740 */ | |
| 397 | − { | |
| 398 | − .callback = set_alarm_disable_quirk, | |
| 399 | − .ident = "IBM Truman", | |
| 400 | − .matches = { | |
| 401 | − DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
| 402 | − DMI_MATCH(DMI_PRODUCT_NAME, "4852570"), | |
| 403 | − }, | |
| 404 | − }, | |
| 405 | − /* https://bugzilla.novell.com/show_bug.cgi?id=812592 */ | |
| 406 | − { | |
| 407 | − .callback = set_alarm_disable_quirk, | |
| 408 | − .ident = "Gigabyte GA-990XA-UD3", | |
| 409 | − .matches = { | |
| 410 | − DMI_MATCH(DMI_SYS_VENDOR, | |
| 411 | − "Gigabyte Technology Co., Ltd."), | |
| 412 | − DMI_MATCH(DMI_PRODUCT_NAME, "GA-990XA-UD3"), | |
| 413 | − }, | |
| 414 | − }, | |
| 415 | − /* http://permalink.gmane.org/gmane.linux.kernel/1604474 */ | |
| 416 | − { | |
| 417 | − .callback = set_alarm_disable_quirk, | |
| 418 | − .ident = "Toshiba Satellite L300", | |
| 419 | − .matches = { | |
| 420 | − DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
| 421 | − DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), | |
| 422 | − }, | |
| 423 | − }, | |
| 424 | − {} | |
| 425 | −}; | |
| 426 | − | |
| 427 | 385 | static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) |
| 428 | 386 | { |
| 429 | 387 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
| @@ -432,9 +390,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) · 2 unmodified lines | ||
| 432 | 390 | if (!is_valid_irq(cmos->irq)) |
| 433 | 391 | return -EINVAL; |
| 434 | 392 | |
| 435 | − if (alarm_disable_quirk) | |
| 436 | − return 0; | |
| 437 | − | |
| 438 | 393 | spin_lock_irqsave(&rtc_lock, flags); |
| 439 | 394 | |
| 440 | 395 | if (enabled) |
| @@ -512,13 +467,6 @@ cmos_nvram_read(struct file *filp, struct kobject *kobj, · 71 unmodified lines | ||
| 512 | 467 | { |
| 513 | 468 | int retval; |
| 514 | 469 | |
| 515 | − if (unlikely(off >= attr->size)) | |
| 516 | − return 0; | |
| 517 | − if (unlikely(off < 0)) | |
| 518 | − return -EINVAL; | |
| 519 | − if ((off + count) > attr->size) | |
| 520 | − count = attr->size - off; | |
| 521 | − | |
| 522 | 470 | off += NVRAM_OFFSET; |
| 523 | 471 | spin_lock_irq(&rtc_lock); |
| 524 | 472 | for (retval = 0; count; count--, off++, retval++) { |
| @@ -543,12 +491,6 @@ cmos_nvram_write(struct file *filp, struct kobject *kobj, · 18 unmodified lines | ||
| 543 | 491 | int retval; |
| 544 | 492 | |
| 545 | 493 | cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); |
| 546 | − if (unlikely(off >= attr->size)) | |
| 547 | − return -EFBIG; | |
| 548 | − if (unlikely(off < 0)) | |
| 549 | − return -EINVAL; | |
| 550 | − if ((off + count) > attr->size) | |
| 551 | − count = attr->size - off; | |
| 552 | 494 | |
| 553 | 495 | /* NOTE: on at least PCs and Ataris, the boot firmware uses a |
| 554 | 496 | * checksum on part of the NVRAM data. That's currently ignored |
| @@ -860,6 +802,51 @@ static void __exit cmos_do_remove(struct device *dev) · 305 unmodified lines | ||
| 860 | 802 | cmos->dev = NULL; |
| 861 | 803 | } |
| 862 | 804 | |
| 805 | +static int cmos_aie_poweroff(struct device *dev) | |
| 806 | +{ | |
| 807 | + struct cmos_rtc *cmos = dev_get_drvdata(dev); | |
| 808 | + struct rtc_time now; | |
| 809 | + time64_t t_now; | |
| 810 | + int retval = 0; | |
| 811 | + unsigned char rtc_control; | |
| 812 | + | |
| 813 | + if (!cmos->alarm_expires) | |
| 814 | + return -EINVAL; | |
| 815 | + | |
| 816 | + spin_lock_irq(&rtc_lock); | |
| 817 | + rtc_control = CMOS_READ(RTC_CONTROL); | |
| 818 | + spin_unlock_irq(&rtc_lock); | |
| 819 | + | |
| 820 | + /* We only care about the situation where AIE is disabled. */ | |
| 821 | + if (rtc_control & RTC_AIE) | |
| 822 | + return -EBUSY; | |
| 823 | + | |
| 824 | + cmos_read_time(dev, &now); | |
| 825 | + t_now = rtc_tm_to_time64(&now); | |
| 826 | + | |
| 827 | + /* | |
| 828 | + * When enabling "RTC wake-up" in BIOS setup, the machine reboots | |
| 829 | + * automatically right after shutdown on some buggy boxes. | |
| 830 | + * This automatic rebooting issue won't happen when the alarm | |
| 831 | + * time is larger than now+1 seconds. | |
| 832 | + * | |
| 833 | + * If the alarm time is equal to now+1 seconds, the issue can be | |
| 834 | + * prevented by cancelling the alarm. | |
| 835 | + */ | |
| 836 | + if (cmos->alarm_expires == t_now + 1) { | |
| 837 | + struct rtc_wkalrm alarm; | |
| 838 | + | |
| 839 | + /* Cancel the AIE timer by configuring the past time. */ | |
| 840 | + rtc_time64_to_tm(t_now - 1, &alarm.time); | |
| 841 | + alarm.enabled = 0; | |
| 842 | + retval = cmos_set_alarm(dev, &alarm); | |
| 843 | + } else if (cmos->alarm_expires > t_now + 1) { | |
| 844 | + retval = -EBUSY; | |
| 845 | + } | |
| 846 | + | |
| 847 | + return retval; | |
| 848 | +} | |
| 849 | + | |
| 863 | 850 | #ifdef CONFIG_PM |
| 864 | 851 | |
| 865 | 852 | static int cmos_suspend(struct device *dev) |
| @@ -1094,8 +1081,12 @@ static void cmos_pnp_shutdown(struct pnp_dev *pnp) · 228 unmodified lines | ||
| 1094 | 1081 | struct device *dev = &pnp->dev; |
| 1095 | 1082 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
| 1096 | 1083 | |
| 1097 | − if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev)) | |
| 1098 | − return; | |
| 1084 | + if (system_state == SYSTEM_POWER_OFF) { | |
| 1085 | + int retval = cmos_poweroff(dev); | |
| 1086 | + | |
| 1087 | + if (cmos_aie_poweroff(dev) < 0 && !retval) | |
| 1088 | + return; | |
| 1089 | + } | |
| 1099 | 1090 | |
| 1100 | 1091 | cmos_do_shutdown(cmos->irq); |
| 1101 | 1092 | } |
| @@ -1200,8 +1191,12 @@ static void cmos_platform_shutdown(struct platform_device *pdev) · 98 unmodified lines | ||
| 1200 | 1191 | struct device *dev = &pdev->dev; |
| 1201 | 1192 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
| 1202 | 1193 | |
| 1203 | − if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev)) | |
| 1204 | − return; | |
| 1194 | + if (system_state == SYSTEM_POWER_OFF) { | |
| 1195 | + int retval = cmos_poweroff(dev); | |
| 1196 | + | |
| 1197 | + if (cmos_aie_poweroff(dev) < 0 && !retval) | |
| 1198 | + return; | |
| 1199 | + } | |
| 1205 | 1200 | |
| 1206 | 1201 | cmos_do_shutdown(cmos->irq); |
| 1207 | 1202 | } |
| @@ -1243,8 +1238,6 @@ static int __init cmos_init(void) · 35 unmodified lines | ||
| 1243 | 1238 | platform_driver_registered = true; |
| 1244 | 1239 | } |
| 1245 | 1240 | |
| 1246 | − dmi_check_system(rtc_quirks); | |
| 1247 | − | |
| 1248 | 1241 | if (retval == 0) |
| 1249 | 1242 | return 0; |
| 1250 | 1243 | |
| @@ -263,6 +263,7 @@ static const struct of_device_id coh901331_dt_match[] = { · 262 unmodified lines | ||
| 263 | 263 | { .compatible = "stericsson,coh901331" }, |
| 264 | 264 | {}, |
| 265 | 265 | }; |
| 266 | +MODULE_DEVICE_TABLE(of, coh901331_dt_match); | |
| 266 | 267 | |
| 267 | 268 | static struct platform_driver coh901331_driver = { |
| 268 | 269 | .driver = { |
| @@ -48,23 +48,10 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc) · 47 unmodified lines | ||
| 48 | 48 | #endif |
| 49 | 49 | |
| 50 | 50 | #ifdef CONFIG_RTC_INTF_SYSFS |
| 51 | − | |
| 52 | −extern void __init rtc_sysfs_init(struct class *); | |
| 53 | −extern void rtc_sysfs_add_device(struct rtc_device *rtc); | |
| 54 | −extern void rtc_sysfs_del_device(struct rtc_device *rtc); | |
| 55 | − | |
| 51 | +const struct attribute_group **rtc_get_dev_attribute_groups(void); | |
| 56 | 52 | #else |
| 57 | − | |
| 58 | −static inline void rtc_sysfs_init(struct class *rtc) | |
| 59 | −{ | |
| 60 | −} | |
| 61 | − | |
| 62 | −static inline void rtc_sysfs_add_device(struct rtc_device *rtc) | |
| 53 | +static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) | |
| 63 | 54 | { |
| 55 | + return NULL; | |
| 64 | 56 | } |
| 65 | − | |
| 66 | −static inline void rtc_sysfs_del_device(struct rtc_device *rtc) | |
| 67 | −{ | |
| 68 | −} | |
| 69 | − | |
| 70 | 57 | #endif |
| @@ -12,15 +12,18 @@ · 11 unmodified lines | ||
| 12 | 12 | * Library General Public License for more details. |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | +#include <linux/delay.h> | |
| 16 | +#include <linux/init.h> | |
| 17 | +#include <linux/interrupt.h> | |
| 15 | 18 | #include <linux/kernel.h> |
| 16 | 19 | #include <linux/module.h> |
| 17 | −#include <linux/init.h> | |
| 20 | +#include <linux/of.h> | |
| 18 | 21 | #include <linux/platform_device.h> |
| 19 | −#include <linux/interrupt.h> | |
| 22 | +#include <linux/regmap.h> | |
| 20 | 23 | #include <linux/rtc.h> |
| 21 | 24 | #include <linux/slab.h> |
| 22 | −#include <linux/delay.h> | |
| 23 | −#include <linux/regmap.h> | |
| 25 | + | |
| 26 | +#include <linux/mfd/da9062/registers.h> | |
| 24 | 27 | #include <linux/mfd/da9063/registers.h> |
| 25 | 28 | #include <linux/mfd/da9063/core.h> |
| 26 | 29 | |
| @@ -29,99 +32,231 @@ · 2 unmodified lines | ||
| 29 | 32 | #define YEARS_FROM_DA9063(year) ((year) + 100) |
| 30 | 33 | #define MONTHS_FROM_DA9063(month) ((month) - 1) |
| 31 | 34 | |
| 32 | −#define RTC_ALARM_DATA_LEN (DA9063_AD_REG_ALARM_Y - DA9063_AD_REG_ALARM_MI + 1) | |
| 33 | − | |
| 34 | −#define RTC_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) | |
| 35 | −#define RTC_SEC 0 | |
| 36 | −#define RTC_MIN 1 | |
| 37 | −#define RTC_HOUR 2 | |
| 38 | −#define RTC_DAY 3 | |
| 39 | −#define RTC_MONTH 4 | |
| 40 | −#define RTC_YEAR 5 | |
| 41 | − | |
| 42 | −struct da9063_rtc { | |
| 43 | − struct rtc_device *rtc_dev; | |
| 44 | − struct da9063 *hw; | |
| 45 | − struct rtc_time alarm_time; | |
| 46 | − bool rtc_sync; | |
| 47 | − int alarm_year; | |
| 48 | − int alarm_start; | |
| 49 | − int alarm_len; | |
| 50 | − int data_start; | |
| 35 | +enum { | |
| 36 | + RTC_SEC = 0, | |
| 37 | + RTC_MIN = 1, | |
| 38 | + RTC_HOUR = 2, | |
| 39 | + RTC_DAY = 3, | |
| 40 | + RTC_MONTH = 4, | |
| 41 | + RTC_YEAR = 5, | |
| 42 | + RTC_DATA_LEN | |
| 43 | +}; | |
| 44 | + | |
| 45 | +struct da9063_compatible_rtc_regmap { | |
| 46 | + /* REGS */ | |
| 47 | + int rtc_enable_reg; | |
| 48 | + int rtc_enable_32k_crystal_reg; | |
| 49 | + int rtc_alarm_secs_reg; | |
| 50 | + int rtc_alarm_year_reg; | |
| 51 | + int rtc_count_secs_reg; | |
| 52 | + int rtc_count_year_reg; | |
| 53 | + int rtc_event_reg; | |
| 54 | + /* MASKS */ | |
| 55 | + int rtc_enable_mask; | |
| 56 | + int rtc_crystal_mask; | |
| 57 | + int rtc_event_alarm_mask; | |
| 58 | + int rtc_alarm_on_mask; | |
| 59 | + int rtc_alarm_status_mask; | |
| 60 | + int rtc_tick_on_mask; | |
| 61 | + int rtc_ready_to_read_mask; | |
| 62 | + int rtc_count_sec_mask; | |
| 63 | + int rtc_count_min_mask; | |
| 64 | + int rtc_count_hour_mask; | |
| 65 | + int rtc_count_day_mask; | |
| 66 | + int rtc_count_month_mask; | |
| 67 | + int rtc_count_year_mask; | |
| 68 | + /* ALARM CONFIG */ | |
| 69 | + int rtc_data_start; | |
| 70 | + int rtc_alarm_len; | |
| 71 | +}; | |
| 72 | + | |
| 73 | +struct da9063_compatible_rtc { | |
| 74 | + struct rtc_device *rtc_dev; | |
| 75 | + struct rtc_time alarm_time; | |
| 76 | + struct regmap *regmap; | |
| 77 | + const struct da9063_compatible_rtc_regmap *config; | |
| 78 | + bool rtc_sync; | |
| 79 | +}; | |
| 80 | + | |
| 81 | +static const struct da9063_compatible_rtc_regmap da9063_ad_regs = { | |
| 82 | + /* REGS */ | |
| 83 | + .rtc_enable_reg = DA9063_REG_CONTROL_E, | |
| 84 | + .rtc_alarm_secs_reg = DA9063_AD_REG_ALARM_MI, | |
| 85 | + .rtc_alarm_year_reg = DA9063_AD_REG_ALARM_Y, | |
| 86 | + .rtc_count_secs_reg = DA9063_REG_COUNT_S, | |
| 87 | + .rtc_count_year_reg = DA9063_REG_COUNT_Y, | |
| 88 | + .rtc_event_reg = DA9063_REG_EVENT_A, | |
| 89 | + /* MASKS */ | |
| 90 | + .rtc_enable_mask = DA9063_RTC_EN, | |
| 91 | + .rtc_crystal_mask = DA9063_CRYSTAL, | |
| 92 | + .rtc_enable_32k_crystal_reg = DA9063_REG_EN_32K, | |
| 93 | + .rtc_event_alarm_mask = DA9063_E_ALARM, | |
| 94 | + .rtc_alarm_on_mask = DA9063_ALARM_ON, | |
| 95 | + .rtc_alarm_status_mask = DA9063_ALARM_STATUS_ALARM | | |
| 96 | + DA9063_ALARM_STATUS_TICK, | |
| 97 | + .rtc_tick_on_mask = DA9063_TICK_ON, | |
| 98 | + .rtc_ready_to_read_mask = DA9063_RTC_READ, | |
| 99 | + .rtc_count_sec_mask = DA9063_COUNT_SEC_MASK, | |
| 100 | + .rtc_count_min_mask = DA9063_COUNT_MIN_MASK, | |
| 101 | + .rtc_count_hour_mask = DA9063_COUNT_HOUR_MASK, | |
| 102 | + .rtc_count_day_mask = DA9063_COUNT_DAY_MASK, | |
| 103 | + .rtc_count_month_mask = DA9063_COUNT_MONTH_MASK, | |
| 104 | + .rtc_count_year_mask = DA9063_COUNT_YEAR_MASK, | |
| 105 | + /* ALARM CONFIG */ | |
| 106 | + .rtc_data_start = RTC_MIN, | |
| 107 | + .rtc_alarm_len = RTC_DATA_LEN - 1, | |
| 108 | +}; | |
| 109 | + | |
| 110 | +static const struct da9063_compatible_rtc_regmap da9063_bb_regs = { | |
| 111 | + /* REGS */ | |
| 112 | + .rtc_enable_reg = DA9063_REG_CONTROL_E, | |
| 113 | + .rtc_alarm_secs_reg = DA9063_BB_REG_ALARM_S, | |
| 114 | + .rtc_alarm_year_reg = DA9063_BB_REG_ALARM_Y, | |
| 115 | + .rtc_count_secs_reg = DA9063_REG_COUNT_S, | |
| 116 | + .rtc_count_year_reg = DA9063_REG_COUNT_Y, | |
| 117 | + .rtc_event_reg = DA9063_REG_EVENT_A, | |
| 118 | + /* MASKS */ | |
| 119 | + .rtc_enable_mask = DA9063_RTC_EN, | |
| 120 | + .rtc_crystal_mask = DA9063_CRYSTAL, | |
| 121 | + .rtc_enable_32k_crystal_reg = DA9063_REG_EN_32K, | |
| 122 | + .rtc_event_alarm_mask = DA9063_E_ALARM, | |
| 123 | + .rtc_alarm_on_mask = DA9063_ALARM_ON, | |
| 124 | + .rtc_alarm_status_mask = DA9063_ALARM_STATUS_ALARM | | |
| 125 | + DA9063_ALARM_STATUS_TICK, | |
| 126 | + .rtc_tick_on_mask = DA9063_TICK_ON, | |
| 127 | + .rtc_ready_to_read_mask = DA9063_RTC_READ, | |
| 128 | + .rtc_count_sec_mask = DA9063_COUNT_SEC_MASK, | |
| 129 | + .rtc_count_min_mask = DA9063_COUNT_MIN_MASK, | |
| 130 | + .rtc_count_hour_mask = DA9063_COUNT_HOUR_MASK, | |
| 131 | + .rtc_count_day_mask = DA9063_COUNT_DAY_MASK, | |
| 132 | + .rtc_count_month_mask = DA9063_COUNT_MONTH_MASK, | |
| 133 | + .rtc_count_year_mask = DA9063_COUNT_YEAR_MASK, | |
| 134 | + /* ALARM CONFIG */ | |
| 135 | + .rtc_data_start = RTC_SEC, | |
| 136 | + .rtc_alarm_len = RTC_DATA_LEN, | |
| 137 | +}; | |
| 138 | + | |
| 139 | +static const struct da9063_compatible_rtc_regmap da9062_aa_regs = { | |
| 140 | + /* REGS */ | |
| 141 | + .rtc_enable_reg = DA9062AA_CONTROL_E, | |
| 142 | + .rtc_alarm_secs_reg = DA9062AA_ALARM_S, | |
| 143 | + .rtc_alarm_year_reg = DA9062AA_ALARM_Y, | |
| 144 | + .rtc_count_secs_reg = DA9062AA_COUNT_S, | |
| 145 | + .rtc_count_year_reg = DA9062AA_COUNT_Y, | |
| 146 | + .rtc_event_reg = DA9062AA_EVENT_A, | |
| 147 | + /* MASKS */ | |
| 148 | + .rtc_enable_mask = DA9062AA_RTC_EN_MASK, | |
| 149 | + .rtc_crystal_mask = DA9062AA_CRYSTAL_MASK, | |
| 150 | + .rtc_enable_32k_crystal_reg = DA9062AA_EN_32K, | |
| 151 | + .rtc_event_alarm_mask = DA9062AA_M_ALARM_MASK, | |
| 152 | + .rtc_alarm_on_mask = DA9062AA_ALARM_ON_MASK, | |
| 153 | + .rtc_alarm_status_mask = (0x02 << 6), | |
| 154 | + .rtc_tick_on_mask = DA9062AA_TICK_ON_MASK, | |
| 155 | + .rtc_ready_to_read_mask = DA9062AA_RTC_READ_MASK, | |
| 156 | + .rtc_count_sec_mask = DA9062AA_COUNT_SEC_MASK, | |
| 157 | + .rtc_count_min_mask = DA9062AA_COUNT_MIN_MASK, | |
| 158 | + .rtc_count_hour_mask = DA9062AA_COUNT_HOUR_MASK, | |
| 159 | + .rtc_count_day_mask = DA9062AA_COUNT_DAY_MASK, | |
| 160 | + .rtc_count_month_mask = DA9062AA_COUNT_MONTH_MASK, | |
| 161 | + .rtc_count_year_mask = DA9062AA_COUNT_YEAR_MASK, | |
| 162 | + /* ALARM CONFIG */ | |
| 163 | + .rtc_data_start = RTC_SEC, | |
| 164 | + .rtc_alarm_len = RTC_DATA_LEN, | |
| 165 | +}; | |
| 166 | + | |
| 167 | +static const struct of_device_id da9063_compatible_reg_id_table[] = { | |
| 168 | + { .compatible = "dlg,da9063-rtc", .data = &da9063_bb_regs }, | |
| 169 | + { .compatible = "dlg,da9062-rtc", .data = &da9062_aa_regs }, | |
| 170 | + { }, | |
| 51 | 171 | }; |
| 172 | +MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table); | |
| 52 | 173 | |
| 53 | −static void da9063_data_to_tm(u8 *data, struct rtc_time *tm) | |
| 174 | +static void da9063_data_to_tm(u8 *data, struct rtc_time *tm, | |
| 175 | + struct da9063_compatible_rtc *rtc) | |
| 54 | 176 | { |
| 55 | − tm->tm_sec = data[RTC_SEC] & DA9063_COUNT_SEC_MASK; | |
| 56 | − tm->tm_min = data[RTC_MIN] & DA9063_COUNT_MIN_MASK; | |
| 57 | − tm->tm_hour = data[RTC_HOUR] & DA9063_COUNT_HOUR_MASK; | |
| 58 | − tm->tm_mday = data[RTC_DAY] & DA9063_COUNT_DAY_MASK; | |
| 177 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 178 | + | |
| 179 | + tm->tm_sec = data[RTC_SEC] & config->rtc_count_sec_mask; | |
| 180 | + tm->tm_min = data[RTC_MIN] & config->rtc_count_min_mask; | |
| 181 | + tm->tm_hour = data[RTC_HOUR] & config->rtc_count_hour_mask; | |
| 182 | + tm->tm_mday = data[RTC_DAY] & config->rtc_count_day_mask; | |
| 59 | 183 | tm->tm_mon = MONTHS_FROM_DA9063(data[RTC_MONTH] & |
| 60 | − DA9063_COUNT_MONTH_MASK); | |
| 184 | + config->rtc_count_month_mask); | |
| 61 | 185 | tm->tm_year = YEARS_FROM_DA9063(data[RTC_YEAR] & |
| 62 | − DA9063_COUNT_YEAR_MASK); | |
| 186 | + config->rtc_count_year_mask); | |
| 63 | 187 | } |
| 64 | 188 | |
| 65 | −static void da9063_tm_to_data(struct rtc_time *tm, u8 *data) | |
| 189 | +static void da9063_tm_to_data(struct rtc_time *tm, u8 *data, | |
| 190 | + struct da9063_compatible_rtc *rtc) | |
| 66 | 191 | { |
| 67 | − data[RTC_SEC] &= ~DA9063_COUNT_SEC_MASK; | |
| 68 | − data[RTC_SEC] |= tm->tm_sec & DA9063_COUNT_SEC_MASK; | |
| 192 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 193 | + | |
| 194 | + data[RTC_SEC] &= ~config->rtc_count_sec_mask; | |
| 195 | + data[RTC_SEC] |= tm->tm_sec & config->rtc_count_sec_mask; | |
| 69 | 196 | |
| 70 | − data[RTC_MIN] &= ~DA9063_COUNT_MIN_MASK; | |
| 71 | − data[RTC_MIN] |= tm->tm_min & DA9063_COUNT_MIN_MASK; | |
| 197 | + data[RTC_MIN] &= ~config->rtc_count_min_mask; | |
| 198 | + data[RTC_MIN] |= tm->tm_min & config->rtc_count_min_mask; | |
| 72 | 199 | |
| 73 | − data[RTC_HOUR] &= ~DA9063_COUNT_HOUR_MASK; | |
| 74 | − data[RTC_HOUR] |= tm->tm_hour & DA9063_COUNT_HOUR_MASK; | |
| 200 | + data[RTC_HOUR] &= ~config->rtc_count_hour_mask; | |
| 201 | + data[RTC_HOUR] |= tm->tm_hour & config->rtc_count_hour_mask; | |
| 75 | 202 | |
| 76 | − data[RTC_DAY] &= ~DA9063_COUNT_DAY_MASK; | |
| 77 | − data[RTC_DAY] |= tm->tm_mday & DA9063_COUNT_DAY_MASK; | |
| 203 | + data[RTC_DAY] &= ~config->rtc_count_day_mask; | |
| 204 | + data[RTC_DAY] |= tm->tm_mday & config->rtc_count_day_mask; | |
| 78 | 205 | |
| 79 | − data[RTC_MONTH] &= ~DA9063_COUNT_MONTH_MASK; | |
| 206 | + data[RTC_MONTH] &= ~config->rtc_count_month_mask; | |
| 80 | 207 | data[RTC_MONTH] |= MONTHS_TO_DA9063(tm->tm_mon) & |
| 81 | − DA9063_COUNT_MONTH_MASK; | |
| 208 | + config->rtc_count_month_mask; | |
| 82 | 209 | |
| 83 | − data[RTC_YEAR] &= ~DA9063_COUNT_YEAR_MASK; | |
| 210 | + data[RTC_YEAR] &= ~config->rtc_count_year_mask; | |
| 84 | 211 | data[RTC_YEAR] |= YEARS_TO_DA9063(tm->tm_year) & |
| 85 | − DA9063_COUNT_YEAR_MASK; | |
| 212 | + config->rtc_count_year_mask; | |
| 86 | 213 | } |
| 87 | 214 | |
| 88 | 215 | static int da9063_rtc_stop_alarm(struct device *dev) |
| 89 | 216 | { |
| 90 | − struct da9063_rtc *rtc = dev_get_drvdata(dev); | |
| 217 | + struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); | |
| 218 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 91 | 219 | |
| 92 | − return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, | |
| 93 | − DA9063_ALARM_ON, 0); | |
| 220 | + return regmap_update_bits(rtc->regmap, | |
| 221 | + config->rtc_alarm_year_reg, | |
| 222 | + config->rtc_alarm_on_mask, | |
| 223 | + 0); | |
| 94 | 224 | } |
| 95 | 225 | |
| 96 | 226 | static int da9063_rtc_start_alarm(struct device *dev) |
| 97 | 227 | { |
| 98 | − struct da9063_rtc *rtc = dev_get_drvdata(dev); | |
| 228 | + struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); | |
| 229 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 99 | 230 | |
| 100 | − return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, | |
| 101 | − DA9063_ALARM_ON, DA9063_ALARM_ON); | |
| 231 | + return regmap_update_bits(rtc->regmap, | |
| 232 | + config->rtc_alarm_year_reg, | |
| 233 | + config->rtc_alarm_on_mask, | |
| 234 | + config->rtc_alarm_on_mask); | |
| 102 | 235 | } |
| 103 | 236 | |
| 104 | 237 | static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| 105 | 238 | { |
| 106 | − struct da9063_rtc *rtc = dev_get_drvdata(dev); | |
| 239 | + struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); | |
| 240 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 107 | 241 | unsigned long tm_secs; |
| 108 | 242 | unsigned long al_secs; |
| 109 | 243 | u8 data[RTC_DATA_LEN]; |
| 110 | 244 | int ret; |
| 111 | 245 | |
| 112 | − ret = regmap_bulk_read(rtc->hw->regmap, DA9063_REG_COUNT_S, | |
| 246 | + ret = regmap_bulk_read(rtc->regmap, | |
| 247 | + config->rtc_count_secs_reg, | |
| 113 | 248 | data, RTC_DATA_LEN); |
| 114 | 249 | if (ret < 0) { |
| 115 | 250 | dev_err(dev, "Failed to read RTC time data: %d\n", ret); |
| 116 | 251 | return ret; |
| 117 | 252 | } |
| 118 | 253 | |
| 119 | − if (!(data[RTC_SEC] & DA9063_RTC_READ)) { | |
| 254 | + if (!(data[RTC_SEC] & config->rtc_ready_to_read_mask)) { | |
| 120 | 255 | dev_dbg(dev, "RTC not yet ready to be read by the host\n"); |
| 121 | 256 | return -EINVAL; |
| 122 | 257 | } |
| 123 | 258 | |
| 124 | − da9063_data_to_tm(data, tm); | |
| 259 | + da9063_data_to_tm(data, tm, rtc); | |
| 125 | 260 | |
| 126 | 261 | rtc_tm_to_time(tm, &tm_secs); |
| 127 | 262 | rtc_tm_to_time(&rtc->alarm_time, &al_secs); |
| @@ -137,12 +272,14 @@ static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm) · 9 unmodified lines | ||
| 137 | 272 | |
| 138 | 273 | static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm) |
| 139 | 274 | { |
| 140 | − struct da9063_rtc *rtc = dev_get_drvdata(dev); | |
| 275 | + struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); | |
| 276 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 141 | 277 | u8 data[RTC_DATA_LEN]; |
| 142 | 278 | int ret; |
| 143 | 279 | |
| 144 | − da9063_tm_to_data(tm, data); | |
| 145 | − ret = regmap_bulk_write(rtc->hw->regmap, DA9063_REG_COUNT_S, | |
| 280 | + da9063_tm_to_data(tm, data, rtc); | |
| 281 | + ret = regmap_bulk_write(rtc->regmap, | |
| 282 | + config->rtc_count_secs_reg, | |
| 146 | 283 | data, RTC_DATA_LEN); |
| 147 | 284 | if (ret < 0) |
| 148 | 285 | dev_err(dev, "Failed to set RTC time data: %d\n", ret); |
| @@ -152,26 +289,31 @@ static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm) · 3 unmodified lines | ||
| 152 | 289 | |
| 153 | 290 | static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| 154 | 291 | { |
| 155 | − struct da9063_rtc *rtc = dev_get_drvdata(dev); | |
| 292 | + struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); | |
| 293 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 156 | 294 | u8 data[RTC_DATA_LEN]; |
| 157 | 295 | int ret; |
| 158 | 296 | unsigned int val; |
| 159 | 297 | |
| 160 | 298 | data[RTC_SEC] = 0; |
| 161 | − ret = regmap_bulk_read(rtc->hw->regmap, rtc->alarm_start, | |
| 162 | − &data[rtc->data_start], rtc->alarm_len); | |
| 299 | + ret = regmap_bulk_read(rtc->regmap, | |
| 300 | + config->rtc_alarm_secs_reg, | |
| 301 | + &data[config->rtc_data_start], | |
| 302 | + config->rtc_alarm_len); | |
| 163 | 303 | if (ret < 0) |
| 164 | 304 | return ret; |
| 165 | 305 | |
| 166 | − da9063_data_to_tm(data, &alrm->time); | |
| 306 | + da9063_data_to_tm(data, &alrm->time, rtc); | |
| 167 | 307 | |
| 168 | − alrm->enabled = !!(data[RTC_YEAR] & DA9063_ALARM_ON); | |
| 308 | + alrm->enabled = !!(data[RTC_YEAR] & config->rtc_alarm_on_mask); | |
| 169 | 309 | |
| 170 | − ret = regmap_read(rtc->hw->regmap, DA9063_REG_EVENT_A, &val); | |
| 310 | + ret = regmap_read(rtc->regmap, | |
| 311 | + config->rtc_event_reg, | |
| 312 | + &val); | |
| 171 | 313 | if (ret < 0) |
| 172 | 314 | return ret; |
| 173 | 315 | |
| 174 | − if (val & (DA9063_E_ALARM)) | |
| 316 | + if (val & config->rtc_event_alarm_mask) | |
| 175 | 317 | alrm->pending = 1; |
| 176 | 318 | else |
| 177 | 319 | alrm->pending = 0; |
| @@ -181,11 +323,12 @@ static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) · 3 unmodified lines | ||
| 181 | 323 | |
| 182 | 324 | static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| 183 | 325 | { |
| 184 | − struct da9063_rtc *rtc = dev_get_drvdata(dev); | |
| 326 | + struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); | |
| 327 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 185 | 328 | u8 data[RTC_DATA_LEN]; |
| 186 | 329 | int ret; |
| 187 | 330 | |
| 188 | − da9063_tm_to_data(&alrm->time, data); | |
| 331 | + da9063_tm_to_data(&alrm->time, data, rtc); | |
| 189 | 332 | |
| 190 | 333 | ret = da9063_rtc_stop_alarm(dev); |
| 191 | 334 | if (ret < 0) { |
| @@ -193,14 +336,16 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) · 1 unmodified line | ||
| 193 | 336 | return ret; |
| 194 | 337 | } |
| 195 | 338 | |
| 196 | − ret = regmap_bulk_write(rtc->hw->regmap, rtc->alarm_start, | |
| 197 | − &data[rtc->data_start], rtc->alarm_len); | |
| 339 | + ret = regmap_bulk_write(rtc->regmap, | |
| 340 | + config->rtc_alarm_secs_reg, | |
| 341 | + &data[config->rtc_data_start], | |
| 342 | + config->rtc_alarm_len); | |
| 198 | 343 | if (ret < 0) { |
| 199 | 344 | dev_err(dev, "Failed to write alarm: %d\n", ret); |
| 200 | 345 | return ret; |
| 201 | 346 | } |
| 202 | 347 | |
| 203 | − da9063_data_to_tm(data, &rtc->alarm_time); | |
| 348 | + da9063_data_to_tm(data, &rtc->alarm_time, rtc); | |
| 204 | 349 | |
| 205 | 350 | if (alrm->enabled) { |
| 206 | 351 | ret = da9063_rtc_start_alarm(dev); |
| @@ -213,7 +358,8 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) · 6 unmodified lines | ||
| 213 | 358 | return ret; |
| 214 | 359 | } |
| 215 | 360 | |
| 216 | −static int da9063_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |
| 361 | +static int da9063_rtc_alarm_irq_enable(struct device *dev, | |
| 362 | + unsigned int enabled) | |
| 217 | 363 | { |
| 218 | 364 | if (enabled) |
| 219 | 365 | return da9063_rtc_start_alarm(dev); |
| @@ -223,10 +369,13 @@ static int da9063_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) · 3 unmodified lines | ||
| 223 | 369 | |
| 224 | 370 | static irqreturn_t da9063_alarm_event(int irq, void *data) |
| 225 | 371 | { |
| 226 | − struct da9063_rtc *rtc = data; | |
| 372 | + struct da9063_compatible_rtc *rtc = data; | |
| 373 | + const struct da9063_compatible_rtc_regmap *config = rtc->config; | |
| 227 | 374 | |
| 228 | − regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, | |
| 229 | − DA9063_ALARM_ON, 0); | |
| 375 | + regmap_update_bits(rtc->regmap, | |
| 376 | + config->rtc_alarm_year_reg, | |
| 377 | + config->rtc_alarm_on_mask, | |
| 378 | + 0); | |
| 230 | 379 | |
| 231 | 380 | rtc->rtc_sync = true; |
| 232 | 381 | rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); |
| @@ -244,72 +393,92 @@ static const struct rtc_class_ops da9063_rtc_ops = { · 11 unmodified lines | ||
| 244 | 393 | |
| 245 | 394 | static int da9063_rtc_probe(struct platform_device *pdev) |
| 246 | 395 | { |
| 247 | − struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); | |
| 248 | − struct da9063_rtc *rtc; | |
| 396 | + struct da9063_compatible_rtc *rtc; | |
| 397 | + const struct da9063_compatible_rtc_regmap *config; | |
| 398 | + const struct of_device_id *match; | |
| 249 | 399 | int irq_alarm; |
| 250 | 400 | u8 data[RTC_DATA_LEN]; |
| 251 | 401 | int ret; |
| 252 | 402 | |
| 253 | − ret = regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_E, | |
| 254 | − DA9063_RTC_EN, DA9063_RTC_EN); | |
| 255 | − if (ret < 0) { | |
| 256 | − dev_err(&pdev->dev, "Failed to enable RTC\n"); | |
| 257 | − goto err; | |
| 258 | − } | |
| 403 | + if (!pdev->dev.of_node) | |
| 404 | + return -ENXIO; | |
| 259 | 405 | |
| 260 | − ret = regmap_update_bits(da9063->regmap, DA9063_REG_EN_32K, | |
| 261 | − DA9063_CRYSTAL, DA9063_CRYSTAL); | |
| 262 | − if (ret < 0) { | |
| 263 | − dev_err(&pdev->dev, "Failed to run 32kHz oscillator\n"); | |
| 264 | − goto err; | |
| 265 | − } | |
| 406 | + match = of_match_node(da9063_compatible_reg_id_table, | |
| 407 | + pdev->dev.of_node); | |
| 266 | 408 | |
| 267 | 409 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); |
| 268 | 410 | if (!rtc) |
| 269 | 411 | return -ENOMEM; |
| 270 | 412 | |
| 271 | − if (da9063->variant_code == PMIC_DA9063_AD) { | |
| 272 | − rtc->alarm_year = DA9063_AD_REG_ALARM_Y; | |
| 273 | − rtc->alarm_start = DA9063_AD_REG_ALARM_MI; | |
| 274 | − rtc->alarm_len = RTC_ALARM_DATA_LEN; | |
| 275 | − rtc->data_start = RTC_MIN; | |
| 276 | − } else { | |
| 277 | − rtc->alarm_year = DA9063_BB_REG_ALARM_Y; | |
| 278 | − rtc->alarm_start = DA9063_BB_REG_ALARM_S; | |
| 279 | − rtc->alarm_len = RTC_DATA_LEN; | |
| 280 | − rtc->data_start = RTC_SEC; | |
| 413 | + rtc->config = match->data; | |
| 414 | + if (of_device_is_compatible(pdev->dev.of_node, "dlg,da9063-rtc")) { | |
| 415 | + struct da9063 *chip = dev_get_drvdata(pdev->dev.parent); | |
| 416 | + | |
| 417 | + if (chip->variant_code == PMIC_DA9063_AD) | |
| 418 | + rtc->config = &da9063_ad_regs; | |
| 281 | 419 | } |
| 282 | 420 | |
| 283 | − ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, | |
| 284 | − DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM, | |
| 285 | − 0); | |
| 421 | + rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); | |
| 422 | + if (!rtc->regmap) { | |
| 423 | + dev_warn(&pdev->dev, "Parent regmap unavailable.\n"); | |
| 424 | + return -ENXIO; | |
| 425 | + } | |
| 426 | + | |
| 427 | + config = rtc->config; | |
| 428 | + ret = regmap_update_bits(rtc->regmap, | |
| 429 | + config->rtc_enable_reg, | |
| 430 | + config->rtc_enable_mask, | |
| 431 | + config->rtc_enable_mask); | |
| 432 | + if (ret < 0) { | |
| 433 | + dev_err(&pdev->dev, "Failed to enable RTC\n"); | |
| 434 | + return ret; | |
| 435 | + } | |
| 436 | + | |
| 437 | + ret = regmap_update_bits(rtc->regmap, | |
| 438 | + config->rtc_enable_32k_crystal_reg, | |
| 439 | + config->rtc_crystal_mask, | |
| 440 | + config->rtc_crystal_mask); | |
| 441 | + if (ret < 0) { | |
| 442 | + dev_err(&pdev->dev, "Failed to run 32kHz oscillator\n"); | |
| 443 | + return ret; | |
| 444 | + } | |
| 445 | + | |
| 446 | + ret = regmap_update_bits(rtc->regmap, | |
| 447 | + config->rtc_alarm_secs_reg, | |
| 448 | + config->rtc_alarm_status_mask, | |
| 449 | + 0); | |
| 286 | 450 | if (ret < 0) { |
| 287 | 451 | dev_err(&pdev->dev, "Failed to access RTC alarm register\n"); |
| 288 | − goto err; | |
| 452 | + return ret; | |
| 289 | 453 | } |
| 290 | 454 | |
| 291 | − ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, | |
| 455 | + ret = regmap_update_bits(rtc->regmap, | |
| 456 | + config->rtc_alarm_secs_reg, | |
| 292 | 457 | DA9063_ALARM_STATUS_ALARM, |
| 293 | 458 | DA9063_ALARM_STATUS_ALARM); |
| 294 | 459 | if (ret < 0) { |
| 295 | 460 | dev_err(&pdev->dev, "Failed to access RTC alarm register\n"); |
| 296 | − goto err; | |
| 461 | + return ret; | |
| 297 | 462 | } |
| 298 | 463 | |
| 299 | − ret = regmap_update_bits(da9063->regmap, rtc->alarm_year, | |
| 300 | − DA9063_TICK_ON, 0); | |
| 464 | + ret = regmap_update_bits(rtc->regmap, | |
| 465 | + config->rtc_alarm_year_reg, | |
| 466 | + config->rtc_tick_on_mask, | |
| 467 | + 0); | |
| 301 | 468 | if (ret < 0) { |
| 302 | 469 | dev_err(&pdev->dev, "Failed to disable TICKs\n"); |
| 303 | − goto err; | |
| 470 | + return ret; | |
| 304 | 471 | } |
| 305 | 472 | |
| 306 | 473 | data[RTC_SEC] = 0; |
| 307 | − ret = regmap_bulk_read(da9063->regmap, rtc->alarm_start, | |
| 308 | − &data[rtc->data_start], rtc->alarm_len); | |
| 474 | + ret = regmap_bulk_read(rtc->regmap, | |
| 475 | + config->rtc_alarm_secs_reg, | |
| 476 | + &data[config->rtc_data_start], | |
| 477 | + config->rtc_alarm_len); | |
| 309 | 478 | if (ret < 0) { |
| 310 | 479 | dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n", |
| 311 | 480 | ret); |
| 312 | − goto err; | |
| 481 | + return ret; | |
| 313 | 482 | } |
| 314 | 483 | |
| 315 | 484 | platform_set_drvdata(pdev, rtc); |
| @@ -322,18 +491,16 @@ static int da9063_rtc_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 322 | 491 | if (ret) { |
| 323 | 492 | dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n", |
| 324 | 493 | irq_alarm, ret); |
| 325 | − goto err; | |
| 494 | + return ret; | |
| 326 | 495 | } |
| 327 | 496 | |
| 328 | − rtc->hw = da9063; | |
| 329 | 497 | rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC, |
| 330 | 498 | &da9063_rtc_ops, THIS_MODULE); |
| 331 | 499 | if (IS_ERR(rtc->rtc_dev)) |
| 332 | 500 | return PTR_ERR(rtc->rtc_dev); |
| 333 | 501 | |
| 334 | − da9063_data_to_tm(data, &rtc->alarm_time); | |
| 502 | + da9063_data_to_tm(data, &rtc->alarm_time, rtc); | |
| 335 | 503 | rtc->rtc_sync = false; |
| 336 | −err: | |
| 337 | 504 | return ret; |
| 338 | 505 | } |
| 339 | 506 | |
| @@ -341,6 +508,7 @@ static struct platform_driver da9063_rtc_driver = { · 1 unmodified line | ||
| 341 | 508 | .probe = da9063_rtc_probe, |
| 342 | 509 | .driver = { |
| 343 | 510 | .name = DA9063_DRVNAME_RTC, |
| 511 | + .of_match_table = da9063_compatible_reg_id_table, | |
| 344 | 512 | }, |
| 345 | 513 | }; |
| 346 | 514 | |
| @@ -477,6 +477,7 @@ void rtc_dev_prepare(struct rtc_device *rtc) · 476 unmodified lines | ||
| 477 | 477 | |
| 478 | 478 | cdev_init(&rtc->char_dev, &rtc_dev_fops); |
| 479 | 479 | rtc->char_dev.owner = rtc->owner; |
| 480 | + rtc->char_dev.kobj.parent = &rtc->dev.kobj; | |
| 480 | 481 | } |
| 481 | 482 | |
| 482 | 483 | void rtc_dev_add_device(struct rtc_device *rtc) |
| @@ -538,15 +538,6 @@ ds1305_nvram_read(struct file *filp, struct kobject *kobj, · 537 unmodified lines | ||
| 538 | 538 | |
| 539 | 539 | spi = container_of(kobj, struct spi_device, dev.kobj); |
| 540 | 540 | |
| 541 | − if (unlikely(off >= DS1305_NVRAM_LEN)) | |
| 542 | − return 0; | |
| 543 | − if (count >= DS1305_NVRAM_LEN) | |
| 544 | − count = DS1305_NVRAM_LEN; | |
| 545 | − if ((off + count) > DS1305_NVRAM_LEN) | |
| 546 | − count = DS1305_NVRAM_LEN - off; | |
| 547 | − if (unlikely(!count)) | |
| 548 | − return count; | |
| 549 | − | |
| 550 | 541 | addr = DS1305_NVRAM + off; |
| 551 | 542 | msg_init(&m, x, &addr, count, NULL, buf); |
| 552 | 543 | |
| @@ -569,15 +560,6 @@ ds1305_nvram_write(struct file *filp, struct kobject *kobj, · 16 unmodified lines | ||
| 569 | 560 | |
| 570 | 561 | spi = container_of(kobj, struct spi_device, dev.kobj); |
| 571 | 562 | |
| 572 | − if (unlikely(off >= DS1305_NVRAM_LEN)) | |
| 573 | − return -EFBIG; | |
| 574 | − if (count >= DS1305_NVRAM_LEN) | |
| 575 | − count = DS1305_NVRAM_LEN; | |
| 576 | − if ((off + count) > DS1305_NVRAM_LEN) | |
| 577 | − count = DS1305_NVRAM_LEN - off; | |
| 578 | − if (unlikely(!count)) | |
| 579 | − return count; | |
| 580 | − | |
| 581 | 563 | addr = (DS1305_WRITE | DS1305_NVRAM) + off; |
| 582 | 564 | msg_init(&m, x, &addr, count, buf, NULL); |
| 583 | 565 | |
| @@ -11,14 +11,17 @@ · 10 unmodified lines | ||
| 11 | 11 | * published by the Free Software Foundation. |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | −#include <linux/module.h> | |
| 14 | +#include <linux/bcd.h> | |
| 15 | +#include <linux/i2c.h> | |
| 15 | 16 | #include <linux/init.h> |
| 17 | +#include <linux/module.h> | |
| 18 | +#include <linux/of_device.h> | |
| 19 | +#include <linux/of_irq.h> | |
| 20 | +#include <linux/pm_wakeirq.h> | |
| 21 | +#include <linux/rtc/ds1307.h> | |
| 22 | +#include <linux/rtc.h> | |
| 16 | 23 | #include <linux/slab.h> |
| 17 | −#include <linux/i2c.h> | |
| 18 | 24 | #include <linux/string.h> |
| 19 | −#include <linux/rtc.h> | |
| 20 | −#include <linux/bcd.h> | |
| 21 | −#include <linux/rtc/ds1307.h> | |
| 22 | 25 | |
| 23 | 26 | /* |
| 24 | 27 | * We can't determine type by probing, but if we expect pre-Linux code |
| @@ -114,7 +117,7 @@ struct ds1307 { · 89 unmodified lines | ||
| 114 | 117 | #define HAS_ALARM 1 /* bit 1 == irq claimed */ |
| 115 | 118 | struct i2c_client *client; |
| 116 | 119 | struct rtc_device *rtc; |
| 117 | − struct work_struct work; | |
| 120 | + int wakeirq; | |
| 118 | 121 | s32 (*read_block_data)(const struct i2c_client *client, u8 command, |
| 119 | 122 | u8 length, u8 *values); |
| 120 | 123 | s32 (*write_block_data)(const struct i2c_client *client, u8 command, |
| @@ -311,27 +314,17 @@ static s32 ds1307_native_smbus_read_block_data(const struct i2c_client *client, · 190 unmodified lines | ||
| 311 | 314 | /*----------------------------------------------------------------------*/ |
| 312 | 315 | |
| 313 | 316 | /* |
| 314 | − * The IRQ logic includes a "real" handler running in IRQ context just | |
| 315 | − * long enough to schedule this workqueue entry. We need a task context | |
| 316 | − * to talk to the RTC, since I2C I/O calls require that; and disable the | |
| 317 | − * IRQ until we clear its status on the chip, so that this handler can | |
| 318 | − * work with any type of triggering (not just falling edge). | |
| 319 | − * | |
| 320 | 317 | * The ds1337 and ds1339 both have two alarms, but we only use the first |
| 321 | 318 | * one (with a "seconds" field). For ds1337 we expect nINTA is our alarm |
| 322 | 319 | * signal; ds1339 chips have only one alarm signal. |
| 323 | 320 | */ |
| 324 | −static void ds1307_work(struct work_struct *work) | |
| 321 | +static irqreturn_t ds1307_irq(int irq, void *dev_id) | |
| 325 | 322 | { |
| 326 | − struct ds1307 *ds1307; | |
| 327 | − struct i2c_client *client; | |
| 328 | − struct mutex *lock; | |
| 323 | + struct i2c_client *client = dev_id; | |
| 324 | + struct ds1307 *ds1307 = i2c_get_clientdata(client); | |
| 325 | + struct mutex *lock = &ds1307->rtc->ops_lock; | |
| 329 | 326 | int stat, control; |
| 330 | 327 | |
| 331 | − ds1307 = container_of(work, struct ds1307, work); | |
| 332 | − client = ds1307->client; | |
| 333 | − lock = &ds1307->rtc->ops_lock; | |
| 334 | − | |
| 335 | 328 | mutex_lock(lock); |
| 336 | 329 | stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); |
| 337 | 330 | if (stat < 0) |
| @@ -352,18 +345,8 @@ static void ds1307_work(struct work_struct *work) · 14 unmodified lines | ||
| 352 | 345 | } |
| 353 | 346 | |
| 354 | 347 | out: |
| 355 | − if (test_bit(HAS_ALARM, &ds1307->flags)) | |
| 356 | − enable_irq(client->irq); | |
| 357 | 348 | mutex_unlock(lock); |
| 358 | −} | |
| 359 | 349 | |
| 360 | −static irqreturn_t ds1307_irq(int irq, void *dev_id) | |
| 361 | −{ | |
| 362 | − struct i2c_client *client = dev_id; | |
| 363 | − struct ds1307 *ds1307 = i2c_get_clientdata(client); | |
| 364 | − | |
| 365 | − disable_irq_nosync(irq); | |
| 366 | − schedule_work(&ds1307->work); | |
| 367 | 350 | return IRQ_HANDLED; |
| 368 | 351 | } |
| 369 | 352 | |
| @@ -634,13 +617,14 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { · 264 unmodified lines | ||
| 634 | 617 | MCP794XX_BIT_ALMX_C1 | \ |
| 635 | 618 | MCP794XX_BIT_ALMX_C2) |
| 636 | 619 | |
| 637 | −static void mcp794xx_work(struct work_struct *work) | |
| 620 | +static irqreturn_t mcp794xx_irq(int irq, void *dev_id) | |
| 638 | 621 | { |
| 639 | − struct ds1307 *ds1307 = container_of(work, struct ds1307, work); | |
| 640 | − struct i2c_client *client = ds1307->client; | |
| 622 | + struct i2c_client *client = dev_id; | |
| 623 | + struct ds1307 *ds1307 = i2c_get_clientdata(client); | |
| 624 | + struct mutex *lock = &ds1307->rtc->ops_lock; | |
| 641 | 625 | int reg, ret; |
| 642 | 626 | |
| 643 | − mutex_lock(&ds1307->rtc->ops_lock); | |
| 627 | + mutex_lock(lock); | |
| 644 | 628 | |
| 645 | 629 | /* Check and clear alarm 0 interrupt flag. */ |
| 646 | 630 | reg = i2c_smbus_read_byte_data(client, MCP794XX_REG_ALARM0_CTRL); |
| @@ -665,9 +649,9 @@ static void mcp794xx_work(struct work_struct *work) · 18 unmodified lines | ||
| 665 | 649 | rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF); |
| 666 | 650 | |
| 667 | 651 | out: |
| 668 | − if (test_bit(HAS_ALARM, &ds1307->flags)) | |
| 669 | − enable_irq(client->irq); | |
| 670 | − mutex_unlock(&ds1307->rtc->ops_lock); | |
| 652 | + mutex_unlock(lock); | |
| 653 | + | |
| 654 | + return IRQ_HANDLED; | |
| 671 | 655 | } |
| 672 | 656 | |
| 673 | 657 | static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) |
| @@ -798,13 +782,6 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj, · 124 unmodified lines | ||
| 798 | 782 | client = kobj_to_i2c_client(kobj); |
| 799 | 783 | ds1307 = i2c_get_clientdata(client); |
| 800 | 784 | |
| 801 | − if (unlikely(off >= ds1307->nvram->size)) | |
| 802 | − return 0; | |
| 803 | − if ((off + count) > ds1307->nvram->size) | |
| 804 | − count = ds1307->nvram->size - off; | |
| 805 | − if (unlikely(!count)) | |
| 806 | − return count; | |
| 807 | − | |
| 808 | 785 | result = ds1307->read_block_data(client, ds1307->nvram_offset + off, |
| 809 | 786 | count, buf); |
| 810 | 787 | if (result < 0) |
| @@ -824,13 +801,6 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, · 13 unmodified lines | ||
| 824 | 801 | client = kobj_to_i2c_client(kobj); |
| 825 | 802 | ds1307 = i2c_get_clientdata(client); |
| 826 | 803 | |
| 827 | − if (unlikely(off >= ds1307->nvram->size)) | |
| 828 | − return -EFBIG; | |
| 829 | − if ((off + count) > ds1307->nvram->size) | |
| 830 | − count = ds1307->nvram->size - off; | |
| 831 | − if (unlikely(!count)) | |
| 832 | − return count; | |
| 833 | − | |
| 834 | 804 | result = ds1307->write_block_data(client, ds1307->nvram_offset + off, |
| 835 | 805 | count, buf); |
| 836 | 806 | if (result < 0) { |
| @@ -896,6 +866,8 @@ static int ds1307_probe(struct i2c_client *client, · 59 unmodified lines | ||
| 896 | 866 | bool want_irq = false; |
| 897 | 867 | unsigned char *buf; |
| 898 | 868 | struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); |
| 869 | + irq_handler_t irq_handler = ds1307_irq; | |
| 870 | + | |
| 899 | 871 | static const int bbsqi_bitpos[] = { |
| 900 | 872 | [ds_1337] = 0, |
| 901 | 873 | [ds_1339] = DS1339_BIT_BBSQI, |
| @@ -962,8 +934,6 @@ static int ds1307_probe(struct i2c_client *client, · 60 unmodified lines | ||
| 962 | 934 | * running on Vbackup (BBSQI/BBSQW) |
| 963 | 935 | */ |
| 964 | 936 | if (ds1307->client->irq > 0 && chip->alarm) { |
| 965 | − INIT_WORK(&ds1307->work, ds1307_work); | |
| 966 | − | |
| 967 | 937 | ds1307->regs[0] |= DS1337_BIT_INTCN |
| 968 | 938 | | bbsqi_bitpos[ds1307->type]; |
| 969 | 939 | ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); |
| @@ -1053,7 +1023,7 @@ static int ds1307_probe(struct i2c_client *client, · 83 unmodified lines | ||
| 1053 | 1023 | case mcp794xx: |
| 1054 | 1024 | rtc_ops = &mcp794xx_rtc_ops; |
| 1055 | 1025 | if (ds1307->client->irq > 0 && chip->alarm) { |
| 1056 | − INIT_WORK(&ds1307->work, mcp794xx_work); | |
| 1026 | + irq_handler = mcp794xx_irq; | |
| 1057 | 1027 | want_irq = true; |
| 1058 | 1028 | } |
| 1059 | 1029 | break; |
| @@ -1176,18 +1146,43 @@ read_rtc: · 116 unmodified lines | ||
| 1176 | 1146 | } |
| 1177 | 1147 | |
| 1178 | 1148 | if (want_irq) { |
| 1179 | − err = request_irq(client->irq, ds1307_irq, IRQF_SHARED, | |
| 1180 | − ds1307->rtc->name, client); | |
| 1149 | + struct device_node *node = client->dev.of_node; | |
| 1150 | + | |
| 1151 | + err = devm_request_threaded_irq(&client->dev, | |
| 1152 | + client->irq, NULL, irq_handler, | |
| 1153 | + IRQF_SHARED | IRQF_ONESHOT, | |
| 1154 | + ds1307->rtc->name, client); | |
| 1181 | 1155 | if (err) { |
| 1182 | 1156 | client->irq = 0; |
| 1183 | 1157 | dev_err(&client->dev, "unable to request IRQ!\n"); |
| 1184 | − } else { | |
| 1158 | + goto no_irq; | |
| 1159 | + } | |
| 1160 | + | |
| 1161 | + set_bit(HAS_ALARM, &ds1307->flags); | |
| 1162 | + dev_dbg(&client->dev, "got IRQ %d\n", client->irq); | |
| 1163 | + | |
| 1164 | + /* Currently supported by OF code only! */ | |
| 1165 | + if (!node) | |
| 1166 | + goto no_irq; | |
| 1167 | + | |
| 1168 | + err = of_irq_get(node, 1); | |
| 1169 | + if (err <= 0) { | |
| 1170 | + if (err == -EPROBE_DEFER) | |
| 1171 | + goto exit; | |
| 1172 | + goto no_irq; | |
| 1173 | + } | |
| 1174 | + ds1307->wakeirq = err; | |
| 1185 | 1175 | |
| 1186 | − set_bit(HAS_ALARM, &ds1307->flags); | |
| 1187 | − dev_dbg(&client->dev, "got IRQ %d\n", client->irq); | |
| 1176 | + err = dev_pm_set_dedicated_wake_irq(&client->dev, | |
| 1177 | + ds1307->wakeirq); | |
| 1178 | + if (err) { | |
| 1179 | + dev_err(&client->dev, "unable to setup wakeIRQ %d!\n", | |
| 1180 | + err); | |
| 1181 | + goto exit; | |
| 1188 | 1182 | } |
| 1189 | 1183 | } |
| 1190 | 1184 | |
| 1185 | +no_irq: | |
| 1191 | 1186 | if (chip->nvram_size) { |
| 1192 | 1187 | |
| 1193 | 1188 | ds1307->nvram = devm_kzalloc(&client->dev, |
| @@ -1231,10 +1226,8 @@ static int ds1307_remove(struct i2c_client *client) · 37 unmodified lines | ||
| 1231 | 1226 | { |
| 1232 | 1227 | struct ds1307 *ds1307 = i2c_get_clientdata(client); |
| 1233 | 1228 | |
| 1234 | − if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { | |
| 1235 | − free_irq(client->irq, client); | |
| 1236 | − cancel_work_sync(&ds1307->work); | |
| 1237 | − } | |
| 1229 | + if (ds1307->wakeirq) | |
| 1230 | + dev_pm_clear_wake_irq(&client->dev); | |
| 1238 | 1231 | |
| 1239 | 1232 | if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) |
| 1240 | 1233 | sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram); |
| @@ -1245,7 +1238,6 @@ static int ds1307_remove(struct i2c_client *client) · 4 unmodified lines | ||
| 1245 | 1238 | static struct i2c_driver ds1307_driver = { |
| 1246 | 1239 | .driver = { |
| 1247 | 1240 | .name = "rtc-ds1307", |
| 1248 | − .owner = THIS_MODULE, | |
| 1249 | 1241 | }, |
| 1250 | 1242 | .probe = ds1307_probe, |
| 1251 | 1243 | .remove = ds1307_remove, |
| @@ -162,12 +162,6 @@ static ssize_t ds1343_nvram_write(struct file *filp, struct kobject *kobj, · 161 unmodified lines | ||
| 162 | 162 | struct device *dev = kobj_to_dev(kobj); |
| 163 | 163 | struct ds1343_priv *priv = dev_get_drvdata(dev); |
| 164 | 164 | |
| 165 | − if (unlikely(!count)) | |
| 166 | − return count; | |
| 167 | − | |
| 168 | − if ((count + off) > DS1343_NVRAM_LEN) | |
| 169 | − count = DS1343_NVRAM_LEN - off; | |
| 170 | − | |
| 171 | 165 | address = DS1343_NVRAM + off; |
| 172 | 166 | |
| 173 | 167 | ret = regmap_bulk_write(priv->map, address, buf, count); |
| @@ -187,12 +181,6 @@ static ssize_t ds1343_nvram_read(struct file *filp, struct kobject *kobj, · 13 unmodified lines | ||
| 187 | 181 | struct device *dev = kobj_to_dev(kobj); |
| 188 | 182 | struct ds1343_priv *priv = dev_get_drvdata(dev); |
| 189 | 183 | |
| 190 | − if (unlikely(!count)) | |
| 191 | − return count; | |
| 192 | − | |
| 193 | − if ((count + off) > DS1343_NVRAM_LEN) | |
| 194 | − count = DS1343_NVRAM_LEN - off; | |
| 195 | − | |
| 196 | 184 | address = DS1343_NVRAM + off; |
| 197 | 185 | |
| 198 | 186 | ret = regmap_bulk_read(priv->map, address, buf, count); |
| @@ -664,8 +664,6 @@ static int ds1374_remove(struct i2c_client *client) · 663 unmodified lines | ||
| 664 | 664 | { |
| 665 | 665 | struct ds1374 *ds1374 = i2c_get_clientdata(client); |
| 666 | 666 | #ifdef CONFIG_RTC_DRV_DS1374_WDT |
| 667 | − int res; | |
| 668 | − | |
| 669 | 667 | misc_deregister(&ds1374_miscdev); |
| 670 | 668 | ds1374_miscdev.parent = NULL; |
| 671 | 669 | unregister_reboot_notifier(&ds1374_wdt_notifier); |
| @@ -688,7 +686,7 @@ static int ds1374_suspend(struct device *dev) · 16 unmodified lines | ||
| 688 | 686 | { |
| 689 | 687 | struct i2c_client *client = to_i2c_client(dev); |
| 690 | 688 | |
| 691 | − if (client->irq >= 0 && device_may_wakeup(&client->dev)) | |
| 689 | + if (client->irq > 0 && device_may_wakeup(&client->dev)) | |
| 692 | 690 | enable_irq_wake(client->irq); |
| 693 | 691 | return 0; |
| 694 | 692 | } |
| @@ -697,7 +695,7 @@ static int ds1374_resume(struct device *dev) · 2 unmodified lines | ||
| 697 | 695 | { |
| 698 | 696 | struct i2c_client *client = to_i2c_client(dev); |
| 699 | 697 | |
| 700 | − if (client->irq >= 0 && device_may_wakeup(&client->dev)) | |
| 698 | + if (client->irq > 0 && device_may_wakeup(&client->dev)) | |
| 701 | 699 | disable_irq_wake(client->irq); |
| 702 | 700 | return 0; |
| 703 | 701 | } |
| @@ -708,7 +706,6 @@ static SIMPLE_DEV_PM_OPS(ds1374_pm, ds1374_suspend, ds1374_resume); · 4 unmodified lines | ||
| 708 | 706 | static struct i2c_driver ds1374_driver = { |
| 709 | 707 | .driver = { |
| 710 | 708 | .name = "rtc-ds1374", |
| 711 | − .owner = THIS_MODULE, | |
| 712 | 709 | .pm = &ds1374_pm, |
| 713 | 710 | }, |
| 714 | 711 | .probe = ds1374_probe, |
| @@ -64,7 +64,7 @@ enum ds1511reg { · 63 unmodified lines | ||
| 64 | 64 | #define DS1511_KIE 0x04 |
| 65 | 65 | #define DS1511_WDE 0x02 |
| 66 | 66 | #define DS1511_WDS 0x01 |
| 67 | −#define DS1511_RAM_MAX 0xff | |
| 67 | +#define DS1511_RAM_MAX 0x100 | |
| 68 | 68 | |
| 69 | 69 | #define RTC_CMD DS1511_CONTROL_B |
| 70 | 70 | #define RTC_CMD1 DS1511_CONTROL_A |
| @@ -159,7 +159,7 @@ ds1511_wdog_set(unsigned long deciseconds) · 88 unmodified lines | ||
| 159 | 159 | /* |
| 160 | 160 | * set wdog enable and wdog 'steering' bit to issue a reset |
| 161 | 161 | */ |
| 162 | − rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD); | |
| 162 | + rtc_write(rtc_read(RTC_CMD) | DS1511_WDE | DS1511_WDS, RTC_CMD); | |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | void |
| @@ -407,26 +407,10 @@ ds1511_nvram_read(struct file *filp, struct kobject *kobj, · 241 unmodified lines | ||
| 407 | 407 | { |
| 408 | 408 | ssize_t count; |
| 409 | 409 | |
| 410 | − /* | |
| 411 | − * if count is more than one, turn on "burst" mode | |
| 412 | − * turn it off when you're done | |
| 413 | − */ | |
| 414 | − if (size > 1) | |
| 415 | − rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | |
| 416 | − | |
| 417 | − if (pos > DS1511_RAM_MAX) | |
| 418 | − pos = DS1511_RAM_MAX; | |
| 419 | − | |
| 420 | − if (size + pos > DS1511_RAM_MAX + 1) | |
| 421 | − size = DS1511_RAM_MAX - pos + 1; | |
| 422 | − | |
| 423 | 410 | rtc_write(pos, DS1511_RAMADDR_LSB); |
| 424 | − for (count = 0; size > 0; count++, size--) | |
| 411 | + for (count = 0; count < size; count++) | |
| 425 | 412 | *buf++ = rtc_read(DS1511_RAMDATA); |
| 426 | 413 | |
| 427 | − if (count > 1) | |
| 428 | − rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | |
| 429 | − | |
| 430 | 414 | return count; |
| 431 | 415 | } |
| 432 | 416 | |
| @@ -437,26 +421,10 @@ ds1511_nvram_write(struct file *filp, struct kobject *kobj, · 4 unmodified lines | ||
| 437 | 421 | { |
| 438 | 422 | ssize_t count; |
| 439 | 423 | |
| 440 | − /* | |
| 441 | − * if count is more than one, turn on "burst" mode | |
| 442 | − * turn it off when you're done | |
| 443 | − */ | |
| 444 | − if (size > 1) | |
| 445 | − rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | |
| 446 | − | |
| 447 | − if (pos > DS1511_RAM_MAX) | |
| 448 | − pos = DS1511_RAM_MAX; | |
| 449 | − | |
| 450 | − if (size + pos > DS1511_RAM_MAX + 1) | |
| 451 | − size = DS1511_RAM_MAX - pos + 1; | |
| 452 | − | |
| 453 | 424 | rtc_write(pos, DS1511_RAMADDR_LSB); |
| 454 | − for (count = 0; size > 0; count++, size--) | |
| 425 | + for (count = 0; count < size; count++) | |
| 455 | 426 | rtc_write(*buf++, DS1511_RAMDATA); |
| 456 | 427 | |
| 457 | − if (count > 1) | |
| 458 | − rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | |
| 459 | − | |
| 460 | 428 | return count; |
| 461 | 429 | } |
| 462 | 430 | |
| @@ -490,7 +458,7 @@ static int ds1511_rtc_probe(struct platform_device *pdev) · 27 unmodified lines | ||
| 490 | 458 | /* |
| 491 | 459 | * turn on the clock and the crystal, etc. |
| 492 | 460 | */ |
| 493 | − rtc_write(0, RTC_CMD); | |
| 461 | + rtc_write(DS1511_BME, RTC_CMD); | |
| 494 | 462 | rtc_write(0, RTC_CMD1); |
| 495 | 463 | /* |
| 496 | 464 | * clear the wdog counter |
| @@ -245,7 +245,7 @@ static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, · 244 unmodified lines | ||
| 245 | 245 | void __iomem *ioaddr = pdata->ioaddr; |
| 246 | 246 | ssize_t count; |
| 247 | 247 | |
| 248 | − for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) | |
| 248 | + for (count = 0; count < size; count++) | |
| 249 | 249 | *buf++ = readb(ioaddr + pos++); |
| 250 | 250 | return count; |
| 251 | 251 | } |
| @@ -260,7 +260,7 @@ static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj, · 8 unmodified lines | ||
| 260 | 260 | void __iomem *ioaddr = pdata->ioaddr; |
| 261 | 261 | ssize_t count; |
| 262 | 262 | |
| 263 | − for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) | |
| 263 | + for (count = 0; count < size; count++) | |
| 264 | 264 | writeb(*buf++, ioaddr + pos++); |
| 265 | 265 | return count; |
| 266 | 266 | } |
| @@ -2145,27 +2145,7 @@ static struct platform_driver ds1685_rtc_driver = { · 2144 unmodified lines | ||
| 2145 | 2145 | .probe = ds1685_rtc_probe, |
| 2146 | 2146 | .remove = ds1685_rtc_remove, |
| 2147 | 2147 | }; |
| 2148 | − | |
| 2149 | −/** | |
| 2150 | − * ds1685_rtc_init - rtc module init. | |
| 2151 | − */ | |
| 2152 | −static int __init | |
| 2153 | −ds1685_rtc_init(void) | |
| 2154 | −{ | |
| 2155 | − return platform_driver_register(&ds1685_rtc_driver); | |
| 2156 | −} | |
| 2157 | − | |
| 2158 | −/** | |
| 2159 | − * ds1685_rtc_exit - rtc module exit. | |
| 2160 | − */ | |
| 2161 | −static void __exit | |
| 2162 | −ds1685_rtc_exit(void) | |
| 2163 | −{ | |
| 2164 | − platform_driver_unregister(&ds1685_rtc_driver); | |
| 2165 | −} | |
| 2166 | − | |
| 2167 | −module_init(ds1685_rtc_init); | |
| 2168 | −module_exit(ds1685_rtc_exit); | |
| 2148 | +module_platform_driver(ds1685_rtc_driver); | |
| 2169 | 2149 | /* ----------------------------------------------------------------------- */ |
| 2170 | 2150 | |
| 2171 | 2151 | |
| @@ -134,7 +134,7 @@ static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj, · 133 unmodified lines | ||
| 134 | 134 | void __iomem *ioaddr = pdata->ioaddr_nvram; |
| 135 | 135 | ssize_t count; |
| 136 | 136 | |
| 137 | − for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--) | |
| 137 | + for (count = 0; count < size; count++) | |
| 138 | 138 | *buf++ = readb(ioaddr + pos++); |
| 139 | 139 | return count; |
| 140 | 140 | } |
| @@ -149,7 +149,7 @@ static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, · 8 unmodified lines | ||
| 149 | 149 | void __iomem *ioaddr = pdata->ioaddr_nvram; |
| 150 | 150 | ssize_t count; |
| 151 | 151 | |
| 152 | − for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--) | |
| 152 | + for (count = 0; count < size; count++) | |
| 153 | 153 | writeb(*buf++, ioaddr + pos++); |
| 154 | 154 | return count; |
| 155 | 155 | } |
| @@ -443,7 +443,7 @@ static int ds3232_remove(struct i2c_client *client) · 442 unmodified lines | ||
| 443 | 443 | { |
| 444 | 444 | struct ds3232 *ds3232 = i2c_get_clientdata(client); |
| 445 | 445 | |
| 446 | − if (client->irq >= 0) { | |
| 446 | + if (client->irq > 0) { | |
| 447 | 447 | mutex_lock(&ds3232->mutex); |
| 448 | 448 | ds3232->exiting = 1; |
| 449 | 449 | mutex_unlock(&ds3232->mutex); |
| @@ -463,7 +463,10 @@ static int ds3232_suspend(struct device *dev) · 13 unmodified lines | ||
| 463 | 463 | |
| 464 | 464 | if (device_can_wakeup(dev)) { |
| 465 | 465 | ds3232->suspended = true; |
| 466 | − irq_set_irq_wake(client->irq, 1); | |
| 466 | + if (irq_set_irq_wake(client->irq, 1)) { | |
| 467 | + dev_warn_once(dev, "Cannot set wakeup source\n"); | |
| 468 | + ds3232->suspended = false; | |
| 469 | + } | |
| 467 | 470 | } |
| 468 | 471 | |
| 469 | 472 | return 0; |
| @@ -500,7 +503,6 @@ MODULE_DEVICE_TABLE(i2c, ds3232_id); · 30 unmodified lines | ||
| 500 | 503 | static struct i2c_driver ds3232_driver = { |
| 501 | 504 | .driver = { |
| 502 | 505 | .name = "rtc-ds3232", |
| 503 | − .owner = THIS_MODULE, | |
| 504 | 506 | .pm = &ds3232_pm_ops, |
| 505 | 507 | }, |
| 506 | 508 | .probe = ds3232_probe, |
| @@ -523,7 +523,6 @@ exit_free: · 522 unmodified lines | ||
| 523 | 523 | static struct i2c_driver fm3130_driver = { |
| 524 | 524 | .driver = { |
| 525 | 525 | .name = "rtc-fm3130", |
| 526 | − .owner = THIS_MODULE, | |
| 527 | 526 | }, |
| 528 | 527 | .probe = fm3130_probe, |
| 529 | 528 | .id_table = fm3130_id, |
| @@ -148,10 +148,7 @@ static int gemini_rtc_probe(struct platform_device *pdev) · 147 unmodified lines | ||
| 148 | 148 | |
| 149 | 149 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, |
| 150 | 150 | &gemini_rtc_ops, THIS_MODULE); |
| 151 | − if (likely(IS_ERR(rtc->rtc_dev))) | |
| 152 | − return PTR_ERR(rtc->rtc_dev); | |
| 153 | − | |
| 154 | − return 0; | |
| 151 | + return PTR_ERR_OR_ZERO(rtc->rtc_dev); | |
| 155 | 152 | } |
| 156 | 153 | |
| 157 | 154 | static int gemini_rtc_remove(struct platform_device *pdev) |
| @@ -599,7 +599,6 @@ MODULE_DEVICE_TABLE(of, hym8563_dt_idtable); · 598 unmodified lines | ||
| 599 | 599 | static struct i2c_driver hym8563_driver = { |
| 600 | 600 | .driver = { |
| 601 | 601 | .name = "rtc-hym8563", |
| 602 | − .owner = THIS_MODULE, | |
| 603 | 602 | .pm = &hym8563_pm_ops, |
| 604 | 603 | .of_match_table = hym8563_dt_idtable, |
| 605 | 604 | }, |
| @@ -151,12 +151,7 @@ static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm) · 150 unmodified lines | ||
| 151 | 151 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
| 152 | 152 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
| 153 | 153 | |
| 154 | − /* The clock can give out invalid datetime, but we cannot return | |
| 155 | − * -EINVAL otherwise hwclock will refuse to set the time on bootup. */ | |
| 156 | − if (rtc_valid_tm(tm) < 0) | |
| 157 | − dev_err(&client->dev, "retrieved date and time is invalid.\n"); | |
| 158 | − | |
| 159 | − return 0; | |
| 154 | + return rtc_valid_tm(tm); | |
| 160 | 155 | } |
| 161 | 156 | |
| 162 | 157 | static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
| @@ -279,6 +274,7 @@ static const struct of_device_id isl12022_dt_match[] = { · 116 unmodified lines | ||
| 279 | 274 | { .compatible = "isil,isl12022" }, |
| 280 | 275 | { }, |
| 281 | 276 | }; |
| 277 | +MODULE_DEVICE_TABLE(of, isl12022_dt_match); | |
| 282 | 278 | #endif |
| 283 | 279 | |
| 284 | 280 | static const struct i2c_device_id isl12022_id[] = { |
| @@ -648,6 +648,7 @@ static const struct of_device_id isl12057_dt_match[] = { · 647 unmodified lines | ||
| 648 | 648 | { .compatible = "isil,isl12057" }, |
| 649 | 649 | { }, |
| 650 | 650 | }; |
| 651 | +MODULE_DEVICE_TABLE(of, isl12057_dt_match); | |
| 651 | 652 | #endif |
| 652 | 653 | |
| 653 | 654 | static const struct i2c_device_id isl12057_id[] = { |
| @@ -659,7 +660,6 @@ MODULE_DEVICE_TABLE(i2c, isl12057_id); · 5 unmodified lines | ||
| 659 | 660 | static struct i2c_driver isl12057_driver = { |
| 660 | 661 | .driver = { |
| 661 | 662 | .name = DRV_NAME, |
| 662 | − .owner = THIS_MODULE, | |
| 663 | 663 | .pm = &isl12057_rtc_pm_ops, |
| 664 | 664 | .of_match_table = of_match_ptr(isl12057_dt_match), |
| 665 | 665 | }, |
| @@ -0,0 +1,310 @@ | ||
| 1 | +/* | |
| 2 | + * RTC driver for NXP LPC178x/18xx/43xx Real-Time Clock (RTC) | |
| 3 | + * | |
| 4 | + * Copyright (C) 2011 NXP Semiconductors | |
| 5 | + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + */ | |
| 13 | + | |
| 14 | +#include <linux/clk.h> | |
| 15 | +#include <linux/io.h> | |
| 16 | +#include <linux/kernel.h> | |
| 17 | +#include <linux/module.h> | |
| 18 | +#include <linux/of.h> | |
| 19 | +#include <linux/of_device.h> | |
| 20 | +#include <linux/platform_device.h> | |
| 21 | +#include <linux/rtc.h> | |
| 22 | + | |
| 23 | +/* LPC24xx RTC register offsets and bits */ | |
| 24 | +#define LPC24XX_ILR 0x00 | |
| 25 | +#define LPC24XX_RTCCIF BIT(0) | |
| 26 | +#define LPC24XX_RTCALF BIT(1) | |
| 27 | +#define LPC24XX_CTC 0x04 | |
| 28 | +#define LPC24XX_CCR 0x08 | |
| 29 | +#define LPC24XX_CLKEN BIT(0) | |
| 30 | +#define LPC178X_CCALEN BIT(4) | |
| 31 | +#define LPC24XX_CIIR 0x0c | |
| 32 | +#define LPC24XX_AMR 0x10 | |
| 33 | +#define LPC24XX_ALARM_DISABLE 0xff | |
| 34 | +#define LPC24XX_CTIME0 0x14 | |
| 35 | +#define LPC24XX_CTIME1 0x18 | |
| 36 | +#define LPC24XX_CTIME2 0x1c | |
| 37 | +#define LPC24XX_SEC 0x20 | |
| 38 | +#define LPC24XX_MIN 0x24 | |
| 39 | +#define LPC24XX_HOUR 0x28 | |
| 40 | +#define LPC24XX_DOM 0x2c | |
| 41 | +#define LPC24XX_DOW 0x30 | |
| 42 | +#define LPC24XX_DOY 0x34 | |
| 43 | +#define LPC24XX_MONTH 0x38 | |
| 44 | +#define LPC24XX_YEAR 0x3c | |
| 45 | +#define LPC24XX_ALSEC 0x60 | |
| 46 | +#define LPC24XX_ALMIN 0x64 | |
| 47 | +#define LPC24XX_ALHOUR 0x68 | |
| 48 | +#define LPC24XX_ALDOM 0x6c | |
| 49 | +#define LPC24XX_ALDOW 0x70 | |
| 50 | +#define LPC24XX_ALDOY 0x74 | |
| 51 | +#define LPC24XX_ALMON 0x78 | |
| 52 | +#define LPC24XX_ALYEAR 0x7c | |
| 53 | + | |
| 54 | +/* Macros to read fields in consolidated time (CT) registers */ | |
| 55 | +#define CT0_SECS(x) (((x) >> 0) & 0x3f) | |
| 56 | +#define CT0_MINS(x) (((x) >> 8) & 0x3f) | |
| 57 | +#define CT0_HOURS(x) (((x) >> 16) & 0x1f) | |
| 58 | +#define CT0_DOW(x) (((x) >> 24) & 0x07) | |
| 59 | +#define CT1_DOM(x) (((x) >> 0) & 0x1f) | |
| 60 | +#define CT1_MONTH(x) (((x) >> 8) & 0x0f) | |
| 61 | +#define CT1_YEAR(x) (((x) >> 16) & 0xfff) | |
| 62 | +#define CT2_DOY(x) (((x) >> 0) & 0xfff) | |
| 63 | + | |
| 64 | +#define rtc_readl(dev, reg) readl((dev)->rtc_base + (reg)) | |
| 65 | +#define rtc_writel(dev, reg, val) writel((val), (dev)->rtc_base + (reg)) | |
| 66 | + | |
| 67 | +struct lpc24xx_rtc { | |
| 68 | + void __iomem *rtc_base; | |
| 69 | + struct rtc_device *rtc; | |
| 70 | + struct clk *clk_rtc; | |
| 71 | + struct clk *clk_reg; | |
| 72 | +}; | |
| 73 | + | |
| 74 | +static int lpc24xx_rtc_set_time(struct device *dev, struct rtc_time *tm) | |
| 75 | +{ | |
| 76 | + struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); | |
| 77 | + | |
| 78 | + /* Disable RTC during update */ | |
| 79 | + rtc_writel(rtc, LPC24XX_CCR, LPC178X_CCALEN); | |
| 80 | + | |
| 81 | + rtc_writel(rtc, LPC24XX_SEC, tm->tm_sec); | |
| 82 | + rtc_writel(rtc, LPC24XX_MIN, tm->tm_min); | |
| 83 | + rtc_writel(rtc, LPC24XX_HOUR, tm->tm_hour); | |
| 84 | + rtc_writel(rtc, LPC24XX_DOW, tm->tm_wday); | |
| 85 | + rtc_writel(rtc, LPC24XX_DOM, tm->tm_mday); | |
| 86 | + rtc_writel(rtc, LPC24XX_DOY, tm->tm_yday); | |
| 87 | + rtc_writel(rtc, LPC24XX_MONTH, tm->tm_mon); | |
| 88 | + rtc_writel(rtc, LPC24XX_YEAR, tm->tm_year); | |
| 89 | + | |
| 90 | + rtc_writel(rtc, LPC24XX_CCR, LPC24XX_CLKEN | LPC178X_CCALEN); | |
| 91 | + | |
| 92 | + return 0; | |
| 93 | +} | |
| 94 | + | |
| 95 | +static int lpc24xx_rtc_read_time(struct device *dev, struct rtc_time *tm) | |
| 96 | +{ | |
| 97 | + struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); | |
| 98 | + u32 ct0, ct1, ct2; | |
| 99 | + | |
| 100 | + ct0 = rtc_readl(rtc, LPC24XX_CTIME0); | |
| 101 | + ct1 = rtc_readl(rtc, LPC24XX_CTIME1); | |
| 102 | + ct2 = rtc_readl(rtc, LPC24XX_CTIME2); | |
| 103 | + | |
| 104 | + tm->tm_sec = CT0_SECS(ct0); | |
| 105 | + tm->tm_min = CT0_MINS(ct0); | |
| 106 | + tm->tm_hour = CT0_HOURS(ct0); | |
| 107 | + tm->tm_wday = CT0_DOW(ct0); | |
| 108 | + tm->tm_mon = CT1_MONTH(ct1); | |
| 109 | + tm->tm_mday = CT1_DOM(ct1); | |
| 110 | + tm->tm_year = CT1_YEAR(ct1); | |
| 111 | + tm->tm_yday = CT2_DOY(ct2); | |
| 112 | + | |
| 113 | + return rtc_valid_tm(tm); | |
| 114 | +} | |
| 115 | + | |
| 116 | +static int lpc24xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |
| 117 | +{ | |
| 118 | + struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); | |
| 119 | + struct rtc_time *tm = &wkalrm->time; | |
| 120 | + | |
| 121 | + tm->tm_sec = rtc_readl(rtc, LPC24XX_ALSEC); | |
| 122 | + tm->tm_min = rtc_readl(rtc, LPC24XX_ALMIN); | |
| 123 | + tm->tm_hour = rtc_readl(rtc, LPC24XX_ALHOUR); | |
| 124 | + tm->tm_mday = rtc_readl(rtc, LPC24XX_ALDOM); | |
| 125 | + tm->tm_wday = rtc_readl(rtc, LPC24XX_ALDOW); | |
| 126 | + tm->tm_yday = rtc_readl(rtc, LPC24XX_ALDOY); | |
| 127 | + tm->tm_mon = rtc_readl(rtc, LPC24XX_ALMON); | |
| 128 | + tm->tm_year = rtc_readl(rtc, LPC24XX_ALYEAR); | |
| 129 | + | |
| 130 | + wkalrm->enabled = rtc_readl(rtc, LPC24XX_AMR) == 0; | |
| 131 | + wkalrm->pending = !!(rtc_readl(rtc, LPC24XX_ILR) & LPC24XX_RTCCIF); | |
| 132 | + | |
| 133 | + return rtc_valid_tm(&wkalrm->time); | |
| 134 | +} | |
| 135 | + | |
| 136 | +static int lpc24xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |
| 137 | +{ | |
| 138 | + struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); | |
| 139 | + struct rtc_time *tm = &wkalrm->time; | |
| 140 | + | |
| 141 | + /* Disable alarm irq during update */ | |
| 142 | + rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); | |
| 143 | + | |
| 144 | + rtc_writel(rtc, LPC24XX_ALSEC, tm->tm_sec); | |
| 145 | + rtc_writel(rtc, LPC24XX_ALMIN, tm->tm_min); | |
| 146 | + rtc_writel(rtc, LPC24XX_ALHOUR, tm->tm_hour); | |
| 147 | + rtc_writel(rtc, LPC24XX_ALDOM, tm->tm_mday); | |
| 148 | + rtc_writel(rtc, LPC24XX_ALDOW, tm->tm_wday); | |
| 149 | + rtc_writel(rtc, LPC24XX_ALDOY, tm->tm_yday); | |
| 150 | + rtc_writel(rtc, LPC24XX_ALMON, tm->tm_mon); | |
| 151 | + rtc_writel(rtc, LPC24XX_ALYEAR, tm->tm_year); | |
| 152 | + | |
| 153 | + if (wkalrm->enabled) | |
| 154 | + rtc_writel(rtc, LPC24XX_AMR, 0); | |
| 155 | + | |
| 156 | + return 0; | |
| 157 | +} | |
| 158 | + | |
| 159 | +static int lpc24xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) | |
| 160 | +{ | |
| 161 | + struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); | |
| 162 | + | |
| 163 | + if (enable) | |
| 164 | + rtc_writel(rtc, LPC24XX_AMR, 0); | |
| 165 | + else | |
| 166 | + rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); | |
| 167 | + | |
| 168 | + return 0; | |
| 169 | +} | |
| 170 | + | |
| 171 | +static irqreturn_t lpc24xx_rtc_interrupt(int irq, void *data) | |
| 172 | +{ | |
| 173 | + unsigned long events = RTC_IRQF; | |
| 174 | + struct lpc24xx_rtc *rtc = data; | |
| 175 | + u32 rtc_iir; | |
| 176 | + | |
| 177 | + /* Check interrupt cause */ | |
| 178 | + rtc_iir = rtc_readl(rtc, LPC24XX_ILR); | |
| 179 | + if (rtc_iir & LPC24XX_RTCALF) { | |
| 180 | + events |= RTC_AF; | |
| 181 | + rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); | |
| 182 | + } | |
| 183 | + | |
| 184 | + /* Clear interrupt status and report event */ | |
| 185 | + rtc_writel(rtc, LPC24XX_ILR, rtc_iir); | |
| 186 | + rtc_update_irq(rtc->rtc, 1, events); | |
| 187 | + | |
| 188 | + return IRQ_HANDLED; | |
| 189 | +} | |
| 190 | + | |
| 191 | +static const struct rtc_class_ops lpc24xx_rtc_ops = { | |
| 192 | + .read_time = lpc24xx_rtc_read_time, | |
| 193 | + .set_time = lpc24xx_rtc_set_time, | |
| 194 | + .read_alarm = lpc24xx_rtc_read_alarm, | |
| 195 | + .set_alarm = lpc24xx_rtc_set_alarm, | |
| 196 | + .alarm_irq_enable = lpc24xx_rtc_alarm_irq_enable, | |
| 197 | +}; | |
| 198 | + | |
| 199 | +static int lpc24xx_rtc_probe(struct platform_device *pdev) | |
| 200 | +{ | |
| 201 | + struct lpc24xx_rtc *rtc; | |
| 202 | + struct resource *res; | |
| 203 | + int irq, ret; | |
| 204 | + | |
| 205 | + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | |
| 206 | + if (!rtc) | |
| 207 | + return -ENOMEM; | |
| 208 | + | |
| 209 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 210 | + rtc->rtc_base = devm_ioremap_resource(&pdev->dev, res); | |
| 211 | + if (IS_ERR(rtc->rtc_base)) | |
| 212 | + return PTR_ERR(rtc->rtc_base); | |
| 213 | + | |
| 214 | + irq = platform_get_irq(pdev, 0); | |
| 215 | + if (irq < 0) { | |
| 216 | + dev_warn(&pdev->dev, "can't get interrupt resource\n"); | |
| 217 | + return irq; | |
| 218 | + } | |
| 219 | + | |
| 220 | + rtc->clk_rtc = devm_clk_get(&pdev->dev, "rtc"); | |
| 221 | + if (IS_ERR(rtc->clk_rtc)) { | |
| 222 | + dev_err(&pdev->dev, "error getting rtc clock\n"); | |
| 223 | + return PTR_ERR(rtc->clk_rtc); | |
| 224 | + } | |
| 225 | + | |
| 226 | + rtc->clk_reg = devm_clk_get(&pdev->dev, "reg"); | |
| 227 | + if (IS_ERR(rtc->clk_reg)) { | |
| 228 | + dev_err(&pdev->dev, "error getting reg clock\n"); | |
| 229 | + return PTR_ERR(rtc->clk_reg); | |
| 230 | + } | |
| 231 | + | |
| 232 | + ret = clk_prepare_enable(rtc->clk_rtc); | |
| 233 | + if (ret) { | |
| 234 | + dev_err(&pdev->dev, "unable to enable rtc clock\n"); | |
| 235 | + return ret; | |
| 236 | + } | |
| 237 | + | |
| 238 | + ret = clk_prepare_enable(rtc->clk_reg); | |
| 239 | + if (ret) { | |
| 240 | + dev_err(&pdev->dev, "unable to enable reg clock\n"); | |
| 241 | + goto disable_rtc_clk; | |
| 242 | + } | |
| 243 | + | |
| 244 | + platform_set_drvdata(pdev, rtc); | |
| 245 | + | |
| 246 | + /* Clear any pending interrupts */ | |
| 247 | + rtc_writel(rtc, LPC24XX_ILR, LPC24XX_RTCCIF | LPC24XX_RTCALF); | |
| 248 | + | |
| 249 | + /* Enable RTC count */ | |
| 250 | + rtc_writel(rtc, LPC24XX_CCR, LPC24XX_CLKEN | LPC178X_CCALEN); | |
| 251 | + | |
| 252 | + ret = devm_request_irq(&pdev->dev, irq, lpc24xx_rtc_interrupt, 0, | |
| 253 | + pdev->name, rtc); | |
| 254 | + if (ret < 0) { | |
| 255 | + dev_warn(&pdev->dev, "can't request interrupt\n"); | |
| 256 | + goto disable_clks; | |
| 257 | + } | |
| 258 | + | |
| 259 | + rtc->rtc = devm_rtc_device_register(&pdev->dev, "lpc24xx-rtc", | |
| 260 | + &lpc24xx_rtc_ops, THIS_MODULE); | |
| 261 | + if (IS_ERR(rtc->rtc)) { | |
| 262 | + dev_err(&pdev->dev, "can't register rtc device\n"); | |
| 263 | + ret = PTR_ERR(rtc->rtc); | |
| 264 | + goto disable_clks; | |
| 265 | + } | |
| 266 | + | |
| 267 | + return 0; | |
| 268 | + | |
| 269 | +disable_clks: | |
| 270 | + clk_disable_unprepare(rtc->clk_reg); | |
| 271 | +disable_rtc_clk: | |
| 272 | + clk_disable_unprepare(rtc->clk_rtc); | |
| 273 | + return ret; | |
| 274 | +} | |
| 275 | + | |
| 276 | +static int lpc24xx_rtc_remove(struct platform_device *pdev) | |
| 277 | +{ | |
| 278 | + struct lpc24xx_rtc *rtc = platform_get_drvdata(pdev); | |
| 279 | + | |
| 280 | + /* Ensure all interrupt sources are masked */ | |
| 281 | + rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); | |
| 282 | + rtc_writel(rtc, LPC24XX_CIIR, 0); | |
| 283 | + | |
| 284 | + rtc_writel(rtc, LPC24XX_CCR, LPC178X_CCALEN); | |
| 285 | + | |
| 286 | + clk_disable_unprepare(rtc->clk_rtc); | |
| 287 | + clk_disable_unprepare(rtc->clk_reg); | |
| 288 | + | |
| 289 | + return 0; | |
| 290 | +} | |
| 291 | + | |
| 292 | +static const struct of_device_id lpc24xx_rtc_match[] = { | |
| 293 | + { .compatible = "nxp,lpc1788-rtc" }, | |
| 294 | + { } | |
| 295 | +}; | |
| 296 | +MODULE_DEVICE_TABLE(of, lpc24xx_rtc_match); | |
| 297 | + | |
| 298 | +static struct platform_driver lpc24xx_rtc_driver = { | |
| 299 | + .probe = lpc24xx_rtc_probe, | |
| 300 | + .remove = lpc24xx_rtc_remove, | |
| 301 | + .driver = { | |
| 302 | + .name = "lpc24xx-rtc", | |
| 303 | + .of_match_table = lpc24xx_rtc_match, | |
| 304 | + }, | |
| 305 | +}; | |
| 306 | +module_platform_driver(lpc24xx_rtc_driver); | |
| 307 | + | |
| 308 | +MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com>"); | |
| 309 | +MODULE_DESCRIPTION("RTC driver for the LPC178x/18xx/408x/43xx SoCs"); | |
| 310 | +MODULE_LICENSE("GPL"); | |
| @@ -345,11 +345,12 @@ static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, · 344 unmodified lines | ||
| 345 | 345 | ssize_t cnt = 0; |
| 346 | 346 | unsigned long flags; |
| 347 | 347 | |
| 348 | − for (; size > 0 && pos < pdata->offset; cnt++, size--) { | |
| 349 | − spin_lock_irqsave(&m48t59->lock, flags); | |
| 348 | + spin_lock_irqsave(&m48t59->lock, flags); | |
| 349 | + | |
| 350 | + for (; cnt < size; cnt++) | |
| 350 | 351 | *buf++ = M48T59_READ(cnt); |
| 351 | − spin_unlock_irqrestore(&m48t59->lock, flags); | |
| 352 | − } | |
| 352 | + | |
| 353 | + spin_unlock_irqrestore(&m48t59->lock, flags); | |
| 353 | 354 | |
| 354 | 355 | return cnt; |
| 355 | 356 | } |
| @@ -365,11 +366,12 @@ static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, · 9 unmodified lines | ||
| 365 | 366 | ssize_t cnt = 0; |
| 366 | 367 | unsigned long flags; |
| 367 | 368 | |
| 368 | − for (; size > 0 && pos < pdata->offset; cnt++, size--) { | |
| 369 | − spin_lock_irqsave(&m48t59->lock, flags); | |
| 369 | + spin_lock_irqsave(&m48t59->lock, flags); | |
| 370 | + | |
| 371 | + for (; cnt < size; cnt++) | |
| 370 | 372 | M48T59_WRITE(*buf++, cnt); |
| 371 | − spin_unlock_irqrestore(&m48t59->lock, flags); | |
| 372 | − } | |
| 373 | + | |
| 374 | + spin_unlock_irqrestore(&m48t59->lock, flags); | |
| 373 | 375 | |
| 374 | 376 | return cnt; |
| 375 | 377 | } |
| @@ -521,6 +521,7 @@ static const struct platform_device_id rtc_id[] = { · 520 unmodified lines | ||
| 521 | 521 | { "max8997-rtc", 0 }, |
| 522 | 522 | {}, |
| 523 | 523 | }; |
| 524 | +MODULE_DEVICE_TABLE(platform, rtc_id); | |
| 524 | 525 | |
| 525 | 526 | static struct platform_driver max8997_rtc_driver = { |
| 526 | 527 | .driver = { |
| @@ -312,6 +312,7 @@ static const struct of_device_id moxart_rtc_match[] = { · 311 unmodified lines | ||
| 312 | 312 | { .compatible = "moxa,moxart-rtc" }, |
| 313 | 313 | { }, |
| 314 | 314 | }; |
| 315 | +MODULE_DEVICE_TABLE(of, moxart_rtc_match); | |
| 315 | 316 | |
| 316 | 317 | static struct platform_driver moxart_rtc_driver = { |
| 317 | 318 | .probe = moxart_rtc_probe, |
| @@ -406,6 +406,7 @@ static const struct of_device_id mpc5121_rtc_match[] = { · 405 unmodified lines | ||
| 406 | 406 | { .compatible = "fsl,mpc5200-rtc", }, |
| 407 | 407 | {}, |
| 408 | 408 | }; |
| 409 | +MODULE_DEVICE_TABLE(of, mpc5121_rtc_match); | |
| 409 | 410 | #endif |
| 410 | 411 | |
| 411 | 412 | static struct platform_driver mpc5121_rtc_driver = { |
| @@ -373,15 +373,42 @@ static int mtk_rtc_remove(struct platform_device *pdev) · 372 unmodified lines | ||
| 373 | 373 | return 0; |
| 374 | 374 | } |
| 375 | 375 | |
| 376 | +#ifdef CONFIG_PM_SLEEP | |
| 377 | +static int mt6397_rtc_suspend(struct device *dev) | |
| 378 | +{ | |
| 379 | + struct mt6397_rtc *rtc = dev_get_drvdata(dev); | |
| 380 | + | |
| 381 | + if (device_may_wakeup(dev)) | |
| 382 | + enable_irq_wake(rtc->irq); | |
| 383 | + | |
| 384 | + return 0; | |
| 385 | +} | |
| 386 | + | |
| 387 | +static int mt6397_rtc_resume(struct device *dev) | |
| 388 | +{ | |
| 389 | + struct mt6397_rtc *rtc = dev_get_drvdata(dev); | |
| 390 | + | |
| 391 | + if (device_may_wakeup(dev)) | |
| 392 | + disable_irq_wake(rtc->irq); | |
| 393 | + | |
| 394 | + return 0; | |
| 395 | +} | |
| 396 | +#endif | |
| 397 | + | |
| 398 | +static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend, | |
| 399 | + mt6397_rtc_resume); | |
| 400 | + | |
| 376 | 401 | static const struct of_device_id mt6397_rtc_of_match[] = { |
| 377 | 402 | { .compatible = "mediatek,mt6397-rtc", }, |
| 378 | 403 | { } |
| 379 | 404 | }; |
| 405 | +MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match); | |
| 380 | 406 | |
| 381 | 407 | static struct platform_driver mtk_rtc_driver = { |
| 382 | 408 | .driver = { |
| 383 | 409 | .name = "mt6397-rtc", |
| 384 | 410 | .of_match_table = mt6397_rtc_of_match, |
| 411 | + .pm = &mt6397_pm_ops, | |
| 385 | 412 | }, |
| 386 | 413 | .probe = mtk_rtc_probe, |
| 387 | 414 | .remove = mtk_rtc_remove, |
| @@ -324,6 +324,7 @@ static const struct of_device_id rtc_mv_of_match_table[] = { · 323 unmodified lines | ||
| 324 | 324 | { .compatible = "marvell,orion-rtc", }, |
| 325 | 325 | {} |
| 326 | 326 | }; |
| 327 | +MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table); | |
| 327 | 328 | #endif |
| 328 | 329 | |
| 329 | 330 | static struct platform_driver mv_rtc_driver = { |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/of_device.h> |
| 26 | 26 | #include <linux/pm_runtime.h> |
| 27 | 27 | #include <linux/io.h> |
| 28 | +#include <linux/clk.h> | |
| 28 | 29 | |
| 29 | 30 | /* |
| 30 | 31 | * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock |
| @@ -107,6 +108,7 @@ · 76 unmodified lines | ||
| 107 | 108 | |
| 108 | 109 | /* OMAP_RTC_OSC_REG bit fields: */ |
| 109 | 110 | #define OMAP_RTC_OSC_32KCLK_EN BIT(6) |
| 111 | +#define OMAP_RTC_OSC_SEL_32KCLK_SRC BIT(3) | |
| 110 | 112 | |
| 111 | 113 | /* OMAP_RTC_IRQWAKEEN bit fields: */ |
| 112 | 114 | #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) |
| @@ -132,10 +134,12 @@ struct omap_rtc_device_type { · 19 unmodified lines | ||
| 132 | 134 | struct omap_rtc { |
| 133 | 135 | struct rtc_device *rtc; |
| 134 | 136 | void __iomem *base; |
| 137 | + struct clk *clk; | |
| 135 | 138 | int irq_alarm; |
| 136 | 139 | int irq_timer; |
| 137 | 140 | u8 interrupts_reg; |
| 138 | 141 | bool is_pmic_controller; |
| 142 | + bool has_ext_clk; | |
| 139 | 143 | const struct omap_rtc_device_type *type; |
| 140 | 144 | }; |
| 141 | 145 | |
| @@ -553,6 +557,15 @@ static int omap_rtc_probe(struct platform_device *pdev) · 411 unmodified lines | ||
| 553 | 557 | if (rtc->irq_alarm <= 0) |
| 554 | 558 | return -ENOENT; |
| 555 | 559 | |
| 560 | + rtc->clk = devm_clk_get(&pdev->dev, "ext-clk"); | |
| 561 | + if (!IS_ERR(rtc->clk)) | |
| 562 | + rtc->has_ext_clk = true; | |
| 563 | + else | |
| 564 | + rtc->clk = devm_clk_get(&pdev->dev, "int-clk"); | |
| 565 | + | |
| 566 | + if (!IS_ERR(rtc->clk)) | |
| 567 | + clk_prepare_enable(rtc->clk); | |
| 568 | + | |
| 556 | 569 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 557 | 570 | rtc->base = devm_ioremap_resource(&pdev->dev, res); |
| 558 | 571 | if (IS_ERR(rtc->base)) |
| @@ -627,6 +640,16 @@ static int omap_rtc_probe(struct platform_device *pdev) · 68 unmodified lines | ||
| 627 | 640 | if (reg != new_ctrl) |
| 628 | 641 | rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); |
| 629 | 642 | |
| 643 | + /* | |
| 644 | + * If we have the external clock then switch to it so we can keep | |
| 645 | + * ticking across suspend. | |
| 646 | + */ | |
| 647 | + if (rtc->has_ext_clk) { | |
| 648 | + reg = rtc_read(rtc, OMAP_RTC_OSC_REG); | |
| 649 | + rtc_write(rtc, OMAP_RTC_OSC_REG, | |
| 650 | + reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); | |
| 651 | + } | |
| 652 | + | |
| 630 | 653 | rtc->type->lock(rtc); |
| 631 | 654 | |
| 632 | 655 | device_init_wakeup(&pdev->dev, true); |
| @@ -672,6 +695,7 @@ err: · 39 unmodified lines | ||
| 672 | 695 | static int __exit omap_rtc_remove(struct platform_device *pdev) |
| 673 | 696 | { |
| 674 | 697 | struct omap_rtc *rtc = platform_get_drvdata(pdev); |
| 698 | + u8 reg; | |
| 675 | 699 | |
| 676 | 700 | if (pm_power_off == omap_rtc_power_off && |
| 677 | 701 | omap_rtc_power_off_rtc == rtc) { |
| @@ -681,10 +705,19 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) · 3 unmodified lines | ||
| 681 | 705 | |
| 682 | 706 | device_init_wakeup(&pdev->dev, 0); |
| 683 | 707 | |
| 708 | + if (!IS_ERR(rtc->clk)) | |
| 709 | + clk_disable_unprepare(rtc->clk); | |
| 710 | + | |
| 684 | 711 | rtc->type->unlock(rtc); |
| 685 | 712 | /* leave rtc running, but disable irqs */ |
| 686 | 713 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
| 687 | 714 | |
| 715 | + if (rtc->has_ext_clk) { | |
| 716 | + reg = rtc_read(rtc, OMAP_RTC_OSC_REG); | |
| 717 | + reg &= ~OMAP_RTC_OSC_SEL_32KCLK_SRC; | |
| 718 | + rtc_write(rtc, OMAP_RTC_OSC_REG, reg); | |
| 719 | + } | |
| 720 | + | |
| 688 | 721 | rtc->type->lock(rtc); |
| 689 | 722 | |
| 690 | 723 | /* Disable the clock/module */ |
| @@ -190,11 +190,9 @@ exit: · 189 unmodified lines | ||
| 190 | 190 | return rc; |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | −static const struct rtc_class_ops opal_rtc_ops = { | |
| 193 | +static struct rtc_class_ops opal_rtc_ops = { | |
| 194 | 194 | .read_time = opal_get_rtc_time, |
| 195 | 195 | .set_time = opal_set_rtc_time, |
| 196 | − .read_alarm = opal_get_tpo_time, | |
| 197 | − .set_alarm = opal_set_tpo_time, | |
| 198 | 196 | }; |
| 199 | 197 | |
| 200 | 198 | static int opal_rtc_probe(struct platform_device *pdev) |
| @@ -202,8 +200,11 @@ static int opal_rtc_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 202 | 200 | struct rtc_device *rtc; |
| 203 | 201 | |
| 204 | 202 | if (pdev->dev.of_node && of_get_property(pdev->dev.of_node, "has-tpo", |
| 205 | − NULL)) | |
| 203 | + NULL)) { | |
| 206 | 204 | device_set_wakeup_capable(&pdev->dev, true); |
| 205 | + opal_rtc_ops.read_alarm = opal_get_tpo_time; | |
| 206 | + opal_rtc_ops.set_alarm = opal_set_tpo_time; | |
| 207 | + } | |
| 207 | 208 | |
| 208 | 209 | rtc = devm_rtc_device_register(&pdev->dev, DRVNAME, &opal_rtc_ops, |
| 209 | 210 | THIS_MODULE); |
| @@ -236,7 +237,6 @@ static struct platform_driver opal_rtc_driver = { · 26 unmodified lines | ||
| 236 | 237 | .id_table = opal_rtc_driver_ids, |
| 237 | 238 | .driver = { |
| 238 | 239 | .name = DRVNAME, |
| 239 | − .owner = THIS_MODULE, | |
| 240 | 240 | .of_match_table = opal_rtc_match, |
| 241 | 241 | }, |
| 242 | 242 | }; |
| @@ -165,13 +165,7 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) · 164 unmodified lines | ||
| 165 | 165 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
| 166 | 166 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
| 167 | 167 | |
| 168 | − /* the clock can give out invalid datetime, but we cannot return | |
| 169 | − * -EINVAL otherwise hwclock will refuse to set the time on bootup. | |
| 170 | − */ | |
| 171 | − if (rtc_valid_tm(tm) < 0) | |
| 172 | − dev_err(dev, "retrieved date/time is not valid.\n"); | |
| 173 | − | |
| 174 | − return 0; | |
| 168 | + return rtc_valid_tm(tm); | |
| 175 | 169 | } |
| 176 | 170 | |
| 177 | 171 | static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) |
| @@ -33,11 +33,14 @@ · 32 unmodified lines | ||
| 33 | 33 | #define PCF2127_REG_MO (0x08) |
| 34 | 34 | #define PCF2127_REG_YR (0x09) |
| 35 | 35 | |
| 36 | +#define PCF2127_OSF BIT(7) /* Oscillator Fail flag */ | |
| 37 | + | |
| 36 | 38 | static struct i2c_driver pcf2127_driver; |
| 37 | 39 | |
| 38 | 40 | struct pcf2127 { |
| 39 | 41 | struct rtc_device *rtc; |
| 40 | 42 | int voltage_low; /* indicates if a low_voltage was detected */ |
| 43 | + int oscillator_failed; /* OSF was detected and date is unreliable */ | |
| 41 | 44 | }; |
| 42 | 45 | |
| 43 | 46 | /* |
| @@ -59,7 +62,18 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm) · 15 unmodified lines | ||
| 59 | 62 | if (buf[PCF2127_REG_CTRL3] & 0x04) { |
| 60 | 63 | pcf2127->voltage_low = 1; |
| 61 | 64 | dev_info(&client->dev, |
| 62 | − "low voltage detected, date/time is not reliable.\n"); | |
| 65 | + "low voltage detected, check/replace RTC battery.\n"); | |
| 66 | + } | |
| 67 | + | |
| 68 | + if (buf[PCF2127_REG_SC] & PCF2127_OSF) { | |
| 69 | + /* | |
| 70 | + * no need clear the flag here, | |
| 71 | + * it will be cleared once the new date is saved | |
| 72 | + */ | |
| 73 | + pcf2127->oscillator_failed = 1; | |
| 74 | + dev_warn(&client->dev, | |
| 75 | + "oscillator stop detected, date/time is not reliable\n"); | |
| 76 | + return -EINVAL; | |
| 63 | 77 | } |
| 64 | 78 | |
| 65 | 79 | dev_dbg(&client->dev, |
| @@ -88,17 +102,12 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm) · 22 unmodified lines | ||
| 88 | 102 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
| 89 | 103 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
| 90 | 104 | |
| 91 | − /* the clock can give out invalid datetime, but we cannot return | |
| 92 | − * -EINVAL otherwise hwclock will refuse to set the time on bootup. | |
| 93 | − */ | |
| 94 | − if (rtc_valid_tm(tm) < 0) | |
| 95 | − dev_err(&client->dev, "retrieved date/time is not valid.\n"); | |
| 96 | − | |
| 97 | − return 0; | |
| 105 | + return rtc_valid_tm(tm); | |
| 98 | 106 | } |
| 99 | 107 | |
| 100 | 108 | static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
| 101 | 109 | { |
| 110 | + struct pcf2127 *pcf2127 = i2c_get_clientdata(client); | |
| 102 | 111 | unsigned char buf[8]; |
| 103 | 112 | int i = 0, err; |
| 104 | 113 | |
| @@ -112,7 +121,7 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm) · 7 unmodified lines | ||
| 112 | 121 | buf[i++] = PCF2127_REG_SC; |
| 113 | 122 | |
| 114 | 123 | /* hours, minutes and seconds */ |
| 115 | − buf[i++] = bin2bcd(tm->tm_sec); | |
| 124 | + buf[i++] = bin2bcd(tm->tm_sec); /* this will also clear OSF flag */ | |
| 116 | 125 | buf[i++] = bin2bcd(tm->tm_min); |
| 117 | 126 | buf[i++] = bin2bcd(tm->tm_hour); |
| 118 | 127 | buf[i++] = bin2bcd(tm->tm_mday); |
| @@ -132,6 +141,9 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm) · 13 unmodified lines | ||
| 132 | 141 | return -EIO; |
| 133 | 142 | } |
| 134 | 143 | |
| 144 | + /* clear OSF flag in client data */ | |
| 145 | + pcf2127->oscillator_failed = 0; | |
| 146 | + | |
| 135 | 147 | return 0; |
| 136 | 148 | } |
| 137 | 149 | |
| @@ -144,7 +156,9 @@ static int pcf2127_rtc_ioctl(struct device *dev, · 6 unmodified lines | ||
| 144 | 156 | switch (cmd) { |
| 145 | 157 | case RTC_VL_READ: |
| 146 | 158 | if (pcf2127->voltage_low) |
| 147 | − dev_info(dev, "low voltage detected, date/time is not reliable.\n"); | |
| 159 | + dev_info(dev, "low voltage detected, check/replace battery\n"); | |
| 160 | + if (pcf2127->oscillator_failed) | |
| 161 | + dev_info(dev, "oscillator stop detected, date/time is not reliable\n"); | |
| 148 | 162 | |
| 149 | 163 | if (copy_to_user((void __user *)arg, &pcf2127->voltage_low, |
| 150 | 164 | sizeof(int))) |
| @@ -217,7 +231,6 @@ MODULE_DEVICE_TABLE(of, pcf2127_of_match); · 66 unmodified lines | ||
| 217 | 231 | static struct i2c_driver pcf2127_driver = { |
| 218 | 232 | .driver = { |
| 219 | 233 | .name = "rtc-pcf2127", |
| 220 | − .owner = THIS_MODULE, | |
| 221 | 234 | .of_match_table = of_match_ptr(pcf2127_of_match), |
| 222 | 235 | }, |
| 223 | 236 | .probe = pcf2127_probe, |
| @@ -189,7 +189,6 @@ MODULE_DEVICE_TABLE(of, pcf85063_of_match); · 188 unmodified lines | ||
| 189 | 189 | static struct i2c_driver pcf85063_driver = { |
| 190 | 190 | .driver = { |
| 191 | 191 | .name = "rtc-pcf85063", |
| 192 | − .owner = THIS_MODULE, | |
| 193 | 192 | .of_match_table = of_match_ptr(pcf85063_of_match), |
| 194 | 193 | }, |
| 195 | 194 | .probe = pcf85063_probe, |
| @@ -334,7 +334,6 @@ MODULE_DEVICE_TABLE(of, pcf8523_of_match); · 333 unmodified lines | ||
| 334 | 334 | static struct i2c_driver pcf8523_driver = { |
| 335 | 335 | .driver = { |
| 336 | 336 | .name = DRIVER_NAME, |
| 337 | − .owner = THIS_MODULE, | |
| 338 | 337 | .of_match_table = of_match_ptr(pcf8523_of_match), |
| 339 | 338 | }, |
| 340 | 339 | .probe = pcf8523_probe, |
| @@ -483,7 +483,6 @@ MODULE_DEVICE_TABLE(of, pcf8563_of_match); · 482 unmodified lines | ||
| 483 | 483 | static struct i2c_driver pcf8563_driver = { |
| 484 | 484 | .driver = { |
| 485 | 485 | .name = "rtc-pcf8563", |
| 486 | − .owner = THIS_MODULE, | |
| 487 | 486 | .of_match_table = of_match_ptr(pcf8563_of_match), |
| 488 | 487 | }, |
| 489 | 488 | .probe = pcf8563_probe, |
| @@ -309,7 +309,6 @@ MODULE_DEVICE_TABLE(i2c, pcf8583_id); · 308 unmodified lines | ||
| 309 | 309 | static struct i2c_driver pcf8583_driver = { |
| 310 | 310 | .driver = { |
| 311 | 311 | .name = "pcf8583", |
| 312 | − .owner = THIS_MODULE, | |
| 313 | 312 | }, |
| 314 | 313 | .probe = pcf8583_probe, |
| 315 | 314 | .id_table = pcf8583_id, |
| @@ -476,6 +476,6 @@ static struct amba_driver pl031_driver = { · 475 unmodified lines | ||
| 476 | 476 | |
| 477 | 477 | module_amba_driver(pl031_driver); |
| 478 | 478 | |
| 479 | −MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net"); | |
| 479 | +MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); | |
| 480 | 480 | MODULE_DESCRIPTION("ARM AMBA PL031 RTC Driver"); |
| 481 | 481 | MODULE_LICENSE("GPL"); |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #include <mach/hardware.h> |
| 34 | 34 | |
| 35 | +#include "rtc-sa1100.h" | |
| 36 | + | |
| 35 | 37 | #define RTC_DEF_DIVIDER (32768 - 1) |
| 36 | 38 | #define RTC_DEF_TRIM 0 |
| 37 | 39 | #define MAXFREQ_PERIODIC 1000 |
| @@ -86,10 +88,9 @@ · 48 unmodified lines | ||
| 86 | 88 | __raw_writel((value), (pxa_rtc)->base + (reg)) |
| 87 | 89 | |
| 88 | 90 | struct pxa_rtc { |
| 91 | + struct sa1100_rtc sa1100_rtc; | |
| 89 | 92 | struct resource *ress; |
| 90 | 93 | void __iomem *base; |
| 91 | − int irq_1Hz; | |
| 92 | − int irq_Alrm; | |
| 93 | 94 | struct rtc_device *rtc; |
| 94 | 95 | spinlock_t lock; /* Protects this structure */ |
| 95 | 96 | }; |
| @@ -184,25 +185,25 @@ static int pxa_rtc_open(struct device *dev) · 88 unmodified lines | ||
| 184 | 185 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); |
| 185 | 186 | int ret; |
| 186 | 187 | |
| 187 | − ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, 0, | |
| 188 | + ret = request_irq(pxa_rtc->sa1100_rtc.irq_1hz, pxa_rtc_irq, 0, | |
| 188 | 189 | "rtc 1Hz", dev); |
| 189 | 190 | if (ret < 0) { |
| 190 | − dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz, | |
| 191 | − ret); | |
| 191 | + dev_err(dev, "can't get irq %i, err %d\n", | |
| 192 | + pxa_rtc->sa1100_rtc.irq_1hz, ret); | |
| 192 | 193 | goto err_irq_1Hz; |
| 193 | 194 | } |
| 194 | − ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, 0, | |
| 195 | + ret = request_irq(pxa_rtc->sa1100_rtc.irq_alarm, pxa_rtc_irq, 0, | |
| 195 | 196 | "rtc Alrm", dev); |
| 196 | 197 | if (ret < 0) { |
| 197 | − dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm, | |
| 198 | − ret); | |
| 198 | + dev_err(dev, "can't get irq %i, err %d\n", | |
| 199 | + pxa_rtc->sa1100_rtc.irq_alarm, ret); | |
| 199 | 200 | goto err_irq_Alrm; |
| 200 | 201 | } |
| 201 | 202 | |
| 202 | 203 | return 0; |
| 203 | 204 | |
| 204 | 205 | err_irq_Alrm: |
| 205 | − free_irq(pxa_rtc->irq_1Hz, dev); | |
| 206 | + free_irq(pxa_rtc->sa1100_rtc.irq_1hz, dev); | |
| 206 | 207 | err_irq_1Hz: |
| 207 | 208 | return ret; |
| 208 | 209 | } |
| @@ -215,8 +216,8 @@ static void pxa_rtc_release(struct device *dev) · 6 unmodified lines | ||
| 215 | 216 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE); |
| 216 | 217 | spin_unlock_irq(&pxa_rtc->lock); |
| 217 | 218 | |
| 218 | − free_irq(pxa_rtc->irq_Alrm, dev); | |
| 219 | − free_irq(pxa_rtc->irq_1Hz, dev); | |
| 219 | + free_irq(pxa_rtc->sa1100_rtc.irq_1hz, dev); | |
| 220 | + free_irq(pxa_rtc->sa1100_rtc.irq_alarm, dev); | |
| 220 | 221 | } |
| 221 | 222 | |
| 222 | 223 | static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) |
| @@ -320,12 +321,13 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) · 97 unmodified lines | ||
| 320 | 321 | { |
| 321 | 322 | struct device *dev = &pdev->dev; |
| 322 | 323 | struct pxa_rtc *pxa_rtc; |
| 324 | + struct sa1100_rtc *sa1100_rtc; | |
| 323 | 325 | int ret; |
| 324 | − u32 rttr; | |
| 325 | 326 | |
| 326 | 327 | pxa_rtc = devm_kzalloc(dev, sizeof(*pxa_rtc), GFP_KERNEL); |
| 327 | 328 | if (!pxa_rtc) |
| 328 | 329 | return -ENOMEM; |
| 330 | + sa1100_rtc = &pxa_rtc->sa1100_rtc; | |
| 329 | 331 | |
| 330 | 332 | spin_lock_init(&pxa_rtc->lock); |
| 331 | 333 | platform_set_drvdata(pdev, pxa_rtc); |
| @@ -336,13 +338,13 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) · 4 unmodified lines | ||
| 336 | 338 | return -ENXIO; |
| 337 | 339 | } |
| 338 | 340 | |
| 339 | − pxa_rtc->irq_1Hz = platform_get_irq(pdev, 0); | |
| 340 | − if (pxa_rtc->irq_1Hz < 0) { | |
| 341 | + sa1100_rtc->irq_1hz = platform_get_irq(pdev, 0); | |
| 342 | + if (sa1100_rtc->irq_1hz < 0) { | |
| 341 | 343 | dev_err(dev, "No 1Hz IRQ resource defined\n"); |
| 342 | 344 | return -ENXIO; |
| 343 | 345 | } |
| 344 | − pxa_rtc->irq_Alrm = platform_get_irq(pdev, 1); | |
| 345 | − if (pxa_rtc->irq_Alrm < 0) { | |
| 346 | + sa1100_rtc->irq_alarm = platform_get_irq(pdev, 1); | |
| 347 | + if (sa1100_rtc->irq_alarm < 0) { | |
| 346 | 348 | dev_err(dev, "No alarm IRQ resource defined\n"); |
| 347 | 349 | return -ENXIO; |
| 348 | 350 | } |
| @@ -354,15 +356,14 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 354 | 356 | return -ENOMEM; |
| 355 | 357 | } |
| 356 | 358 | |
| 357 | − /* | |
| 358 | − * If the clock divider is uninitialized then reset it to the | |
| 359 | − * default value to get the 1Hz clock. | |
| 360 | − */ | |
| 361 | − if (rtc_readl(pxa_rtc, RTTR) == 0) { | |
| 362 | − rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | |
| 363 | − rtc_writel(pxa_rtc, RTTR, rttr); | |
| 364 | − dev_warn(dev, "warning: initializing default clock" | |
| 365 | − " divider/trim value\n"); | |
| 359 | + sa1100_rtc->rcnr = pxa_rtc->base + 0x0; | |
| 360 | + sa1100_rtc->rtsr = pxa_rtc->base + 0x8; | |
| 361 | + sa1100_rtc->rtar = pxa_rtc->base + 0x4; | |
| 362 | + sa1100_rtc->rttr = pxa_rtc->base + 0xc; | |
| 363 | + ret = sa1100_rtc_init(pdev, sa1100_rtc); | |
| 364 | + if (!ret) { | |
| 365 | + dev_err(dev, "Unable to init SA1100 RTC sub-device\n"); | |
| 366 | + return ret; | |
| 366 | 367 | } |
| 367 | 368 | |
| 368 | 369 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE); |
| @@ -402,7 +403,7 @@ static int pxa_rtc_suspend(struct device *dev) · 33 unmodified lines | ||
| 402 | 403 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); |
| 403 | 404 | |
| 404 | 405 | if (device_may_wakeup(dev)) |
| 405 | − enable_irq_wake(pxa_rtc->irq_Alrm); | |
| 406 | + enable_irq_wake(pxa_rtc->sa1100_rtc.irq_alarm); | |
| 406 | 407 | return 0; |
| 407 | 408 | } |
| 408 | 409 | |
| @@ -411,7 +412,7 @@ static int pxa_rtc_resume(struct device *dev) · 2 unmodified lines | ||
| 411 | 412 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); |
| 412 | 413 | |
| 413 | 414 | if (device_may_wakeup(dev)) |
| 414 | − disable_irq_wake(pxa_rtc->irq_Alrm); | |
| 415 | + disable_irq_wake(pxa_rtc->sa1100_rtc.irq_alarm); | |
| 415 | 416 | return 0; |
| 416 | 417 | } |
| 417 | 418 | #endif |
| @@ -170,7 +170,7 @@ static ssize_t rp5c01_nvram_read(struct file *filp, struct kobject *kobj, · 169 unmodified lines | ||
| 170 | 170 | |
| 171 | 171 | spin_lock_irq(&priv->lock); |
| 172 | 172 | |
| 173 | − for (count = 0; size > 0 && pos < RP5C01_MODE; count++, size--) { | |
| 173 | + for (count = 0; count < size; count++) { | |
| 174 | 174 | u8 data; |
| 175 | 175 | |
| 176 | 176 | rp5c01_write(priv, |
| @@ -200,7 +200,7 @@ static ssize_t rp5c01_nvram_write(struct file *filp, struct kobject *kobj, · 23 unmodified lines | ||
| 200 | 200 | |
| 201 | 201 | spin_lock_irq(&priv->lock); |
| 202 | 202 | |
| 203 | − for (count = 0; size > 0 && pos < RP5C01_MODE; count++, size--) { | |
| 203 | + for (count = 0; count < size; count++) { | |
| 204 | 204 | u8 data = *buf++; |
| 205 | 205 | |
| 206 | 206 | rp5c01_write(priv, |
| @@ -18,13 +18,11 @@ · 17 unmodified lines | ||
| 18 | 18 | * modify it under the terms of the GNU General Public License |
| 19 | 19 | * version 2 as published by the Free Software Foundation. |
| 20 | 20 | */ |
| 21 | −#include <linux/kernel.h> | |
| 22 | −#include <linux/module.h> | |
| 23 | −#include <linux/slab.h> | |
| 24 | −#include <linux/init.h> | |
| 25 | 21 | #include <linux/bcd.h> |
| 22 | +#include <linux/bitops.h> | |
| 26 | 23 | #include <linux/i2c.h> |
| 27 | −#include <linux/list.h> | |
| 24 | +#include <linux/kernel.h> | |
| 25 | +#include <linux/module.h> | |
| 28 | 26 | #include <linux/rtc.h> |
| 29 | 27 | |
| 30 | 28 | /* Register definitions */ |
| @@ -48,17 +46,17 @@ · 17 unmodified lines | ||
| 48 | 46 | #define RX8025_BIT_CTRL1_CT (7 << 0) |
| 49 | 47 | /* 1 Hz periodic level irq */ |
| 50 | 48 | #define RX8025_BIT_CTRL1_CT_1HZ 4 |
| 51 | −#define RX8025_BIT_CTRL1_TEST (1 << 3) | |
| 52 | −#define RX8025_BIT_CTRL1_1224 (1 << 5) | |
| 53 | −#define RX8025_BIT_CTRL1_DALE (1 << 6) | |
| 54 | −#define RX8025_BIT_CTRL1_WALE (1 << 7) | |
| 55 | − | |
| 56 | −#define RX8025_BIT_CTRL2_DAFG (1 << 0) | |
| 57 | −#define RX8025_BIT_CTRL2_WAFG (1 << 1) | |
| 58 | −#define RX8025_BIT_CTRL2_CTFG (1 << 2) | |
| 59 | −#define RX8025_BIT_CTRL2_PON (1 << 4) | |
| 60 | −#define RX8025_BIT_CTRL2_XST (1 << 5) | |
| 61 | −#define RX8025_BIT_CTRL2_VDET (1 << 6) | |
| 49 | +#define RX8025_BIT_CTRL1_TEST BIT(3) | |
| 50 | +#define RX8025_BIT_CTRL1_1224 BIT(5) | |
| 51 | +#define RX8025_BIT_CTRL1_DALE BIT(6) | |
| 52 | +#define RX8025_BIT_CTRL1_WALE BIT(7) | |
| 53 | + | |
| 54 | +#define RX8025_BIT_CTRL2_DAFG BIT(0) | |
| 55 | +#define RX8025_BIT_CTRL2_WAFG BIT(1) | |
| 56 | +#define RX8025_BIT_CTRL2_CTFG BIT(2) | |
| 57 | +#define RX8025_BIT_CTRL2_PON BIT(4) | |
| 58 | +#define RX8025_BIT_CTRL2_XST BIT(5) | |
| 59 | +#define RX8025_BIT_CTRL2_VDET BIT(6) | |
| 62 | 60 | |
| 63 | 61 | /* Clock precision adjustment */ |
| 64 | 62 | #define RX8025_ADJ_RESOLUTION 3050 /* in ppb */ |
| @@ -74,84 +72,84 @@ MODULE_DEVICE_TABLE(i2c, rx8025_id); · 9 unmodified lines | ||
| 74 | 72 | struct rx8025_data { |
| 75 | 73 | struct i2c_client *client; |
| 76 | 74 | struct rtc_device *rtc; |
| 77 | − struct work_struct work; | |
| 78 | 75 | u8 ctrl1; |
| 79 | − unsigned exiting:1; | |
| 80 | 76 | }; |
| 81 | 77 | |
| 82 | −static int rx8025_read_reg(struct i2c_client *client, int number, u8 *value) | |
| 78 | +static s32 rx8025_read_reg(const struct i2c_client *client, u8 number) | |
| 83 | 79 | { |
| 84 | − int ret = i2c_smbus_read_byte_data(client, (number << 4) | 0x08); | |
| 85 | − | |
| 86 | − if (ret < 0) { | |
| 87 | − dev_err(&client->dev, "Unable to read register #%d\n", number); | |
| 88 | − return ret; | |
| 89 | − } | |
| 90 | − | |
| 91 | − *value = ret; | |
| 92 | − return 0; | |
| 80 | + return i2c_smbus_read_byte_data(client, number << 4); | |
| 93 | 81 | } |
| 94 | 82 | |
| 95 | −static int rx8025_read_regs(struct i2c_client *client, | |
| 96 | − int number, u8 length, u8 *values) | |
| 83 | +static int rx8025_read_regs(const struct i2c_client *client, | |
| 84 | + u8 number, u8 length, u8 *values) | |
| 97 | 85 | { |
| 98 | − int ret = i2c_smbus_read_i2c_block_data(client, (number << 4) | 0x08, | |
| 99 | − length, values); | |
| 100 | − | |
| 101 | − if (ret != length) { | |
| 102 | − dev_err(&client->dev, "Unable to read registers #%d..#%d\n", | |
| 103 | − number, number + length - 1); | |
| 86 | + int ret = i2c_smbus_read_i2c_block_data(client, number << 4, length, | |
| 87 | + values); | |
| 88 | + if (ret != length) | |
| 104 | 89 | return ret < 0 ? ret : -EIO; |
| 105 | − } | |
| 106 | 90 | |
| 107 | 91 | return 0; |
| 108 | 92 | } |
| 109 | 93 | |
| 110 | −static int rx8025_write_reg(struct i2c_client *client, int number, u8 value) | |
| 94 | +static s32 rx8025_write_reg(const struct i2c_client *client, u8 number, | |
| 95 | + u8 value) | |
| 111 | 96 | { |
| 112 | − int ret = i2c_smbus_write_byte_data(client, number << 4, value); | |
| 113 | − | |
| 114 | − if (ret) | |
| 115 | − dev_err(&client->dev, "Unable to write register #%d\n", | |
| 116 | − number); | |
| 97 | + return i2c_smbus_write_byte_data(client, number << 4, value); | |
| 98 | +} | |
| 117 | 99 | |
| 118 | − return ret; | |
| 100 | +static s32 rx8025_write_regs(const struct i2c_client *client, | |
| 101 | + u8 number, u8 length, const u8 *values) | |
| 102 | +{ | |
| 103 | + return i2c_smbus_write_i2c_block_data(client, number << 4, | |
| 104 | + length, values); | |
| 119 | 105 | } |
| 120 | 106 | |
| 121 | −static int rx8025_write_regs(struct i2c_client *client, | |
| 122 | − int number, u8 length, u8 *values) | |
| 107 | +static int rx8025_check_validity(struct device *dev) | |
| 123 | 108 | { |
| 124 | − int ret = i2c_smbus_write_i2c_block_data(client, (number << 4) | 0x08, | |
| 125 | − length, values); | |
| 109 | + struct rx8025_data *rx8025 = dev_get_drvdata(dev); | |
| 110 | + int ctrl2; | |
| 111 | + | |
| 112 | + ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2); | |
| 113 | + if (ctrl2 < 0) | |
| 114 | + return ctrl2; | |
| 115 | + | |
| 116 | + if (ctrl2 & RX8025_BIT_CTRL2_VDET) | |
| 117 | + dev_warn(dev, "power voltage drop detected\n"); | |
| 118 | + | |
| 119 | + if (ctrl2 & RX8025_BIT_CTRL2_PON) { | |
| 120 | + dev_warn(dev, "power-on reset detected, date is invalid\n"); | |
| 121 | + return -EINVAL; | |
| 122 | + } | |
| 126 | 123 | |
| 127 | − if (ret) | |
| 128 | − dev_err(&client->dev, "Unable to write registers #%d..#%d\n", | |
| 129 | − number, number + length - 1); | |
| 124 | + if (!(ctrl2 & RX8025_BIT_CTRL2_XST)) { | |
| 125 | + dev_warn(dev, "crystal stopped, date is invalid\n"); | |
| 126 | + return -EINVAL; | |
| 127 | + } | |
| 130 | 128 | |
| 131 | − return ret; | |
| 129 | + return 0; | |
| 132 | 130 | } |
| 133 | 131 | |
| 134 | −static irqreturn_t rx8025_irq(int irq, void *dev_id) | |
| 132 | +static int rx8025_reset_validity(struct i2c_client *client) | |
| 135 | 133 | { |
| 136 | − struct i2c_client *client = dev_id; | |
| 137 | − struct rx8025_data *rx8025 = i2c_get_clientdata(client); | |
| 134 | + int ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2); | |
| 138 | 135 | |
| 139 | − disable_irq_nosync(irq); | |
| 140 | − schedule_work(&rx8025->work); | |
| 141 | − return IRQ_HANDLED; | |
| 136 | + if (ctrl2 < 0) | |
| 137 | + return ctrl2; | |
| 138 | + | |
| 139 | + ctrl2 &= ~(RX8025_BIT_CTRL2_PON | RX8025_BIT_CTRL2_VDET); | |
| 140 | + | |
| 141 | + return rx8025_write_reg(client, RX8025_REG_CTRL2, | |
| 142 | + ctrl2 | RX8025_BIT_CTRL2_XST); | |
| 142 | 143 | } |
| 143 | 144 | |
| 144 | −static void rx8025_work(struct work_struct *work) | |
| 145 | +static irqreturn_t rx8025_handle_irq(int irq, void *dev_id) | |
| 145 | 146 | { |
| 146 | − struct rx8025_data *rx8025 = container_of(work, struct rx8025_data, | |
| 147 | − work); | |
| 148 | − struct i2c_client *client = rx8025->client; | |
| 149 | − struct mutex *lock = &rx8025->rtc->ops_lock; | |
| 150 | − u8 status; | |
| 151 | − | |
| 152 | − mutex_lock(lock); | |
| 147 | + struct i2c_client *client = dev_id; | |
| 148 | + struct rx8025_data *rx8025 = i2c_get_clientdata(client); | |
| 149 | + int status; | |
| 153 | 150 | |
| 154 | − if (rx8025_read_reg(client, RX8025_REG_CTRL2, &status)) | |
| 151 | + status = rx8025_read_reg(client, RX8025_REG_CTRL2); | |
| 152 | + if (status < 0) | |
| 155 | 153 | goto out; |
| 156 | 154 | |
| 157 | 155 | if (!(status & RX8025_BIT_CTRL2_XST)) |
| @@ -161,9 +159,7 @@ static void rx8025_work(struct work_struct *work) · 3 unmodified lines | ||
| 161 | 159 | if (status & RX8025_BIT_CTRL2_CTFG) { |
| 162 | 160 | /* periodic */ |
| 163 | 161 | status &= ~RX8025_BIT_CTRL2_CTFG; |
| 164 | − local_irq_disable(); | |
| 165 | 162 | rtc_update_irq(rx8025->rtc, 1, RTC_PF | RTC_IRQF); |
| 166 | − local_irq_enable(); | |
| 167 | 163 | } |
| 168 | 164 | |
| 169 | 165 | if (status & RX8025_BIT_CTRL2_DAFG) { |
| @@ -172,20 +168,11 @@ static void rx8025_work(struct work_struct *work) · 2 unmodified lines | ||
| 172 | 168 | if (rx8025_write_reg(client, RX8025_REG_CTRL1, |
| 173 | 169 | rx8025->ctrl1 & ~RX8025_BIT_CTRL1_DALE)) |
| 174 | 170 | goto out; |
| 175 | − local_irq_disable(); | |
| 176 | 171 | rtc_update_irq(rx8025->rtc, 1, RTC_AF | RTC_IRQF); |
| 177 | − local_irq_enable(); | |
| 178 | 172 | } |
| 179 | 173 | |
| 180 | − /* acknowledge IRQ */ | |
| 181 | − rx8025_write_reg(client, RX8025_REG_CTRL2, | |
| 182 | − status | RX8025_BIT_CTRL2_XST); | |
| 183 | − | |
| 184 | 174 | out: |
| 185 | − if (!rx8025->exiting) | |
| 186 | − enable_irq(client->irq); | |
| 187 | − | |
| 188 | − mutex_unlock(lock); | |
| 175 | + return IRQ_HANDLED; | |
| 189 | 176 | } |
| 190 | 177 | |
| 191 | 178 | static int rx8025_get_time(struct device *dev, struct rtc_time *dt) |
| @@ -194,6 +181,10 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt) · 2 unmodified lines | ||
| 194 | 181 | u8 date[7]; |
| 195 | 182 | int err; |
| 196 | 183 | |
| 184 | + err = rx8025_check_validity(dev); | |
| 185 | + if (err) | |
| 186 | + return err; | |
| 187 | + | |
| 197 | 188 | err = rx8025_read_regs(rx8025->client, RX8025_REG_SEC, 7, date); |
| 198 | 189 | if (err) |
| 199 | 190 | return err; |
| @@ -213,10 +204,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt) · 13 unmodified lines | ||
| 213 | 204 | |
| 214 | 205 | dt->tm_mday = bcd2bin(date[RX8025_REG_MDAY] & 0x3f); |
| 215 | 206 | dt->tm_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1; |
| 216 | − dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]); | |
| 217 | − | |
| 218 | − if (dt->tm_year < 70) | |
| 219 | − dt->tm_year += 100; | |
| 207 | + dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100; | |
| 220 | 208 | |
| 221 | 209 | dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, |
| 222 | 210 | dt->tm_sec, dt->tm_min, dt->tm_hour, |
| @@ -229,12 +217,10 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt) · 6 unmodified lines | ||
| 229 | 217 | { |
| 230 | 218 | struct rx8025_data *rx8025 = dev_get_drvdata(dev); |
| 231 | 219 | u8 date[7]; |
| 220 | + int ret; | |
| 232 | 221 | |
| 233 | − /* | |
| 234 | − * BUG: The HW assumes every year that is a multiple of 4 to be a leap | |
| 235 | − * year. Next time this is wrong is 2100, which will not be a leap | |
| 236 | − * year. | |
| 237 | − */ | |
| 222 | + if ((dt->tm_year < 100) || (dt->tm_year > 199)) | |
| 223 | + return -EINVAL; | |
| 238 | 224 | |
| 239 | 225 | /* |
| 240 | 226 | * Here the read-only bits are written as "0". I'm not sure if that |
| @@ -251,17 +237,21 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt) · 10 unmodified lines | ||
| 251 | 237 | date[RX8025_REG_WDAY] = bin2bcd(dt->tm_wday); |
| 252 | 238 | date[RX8025_REG_MDAY] = bin2bcd(dt->tm_mday); |
| 253 | 239 | date[RX8025_REG_MONTH] = bin2bcd(dt->tm_mon + 1); |
| 254 | − date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year % 100); | |
| 240 | + date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year - 100); | |
| 255 | 241 | |
| 256 | 242 | dev_dbg(dev, |
| 257 | 243 | "%s: write 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", |
| 258 | 244 | __func__, |
| 259 | 245 | date[0], date[1], date[2], date[3], date[4], date[5], date[6]); |
| 260 | 246 | |
| 261 | − return rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date); | |
| 247 | + ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date); | |
| 248 | + if (ret < 0) | |
| 249 | + return ret; | |
| 250 | + | |
| 251 | + return rx8025_reset_validity(rx8025->client); | |
| 262 | 252 | } |
| 263 | 253 | |
| 264 | −static int rx8025_init_client(struct i2c_client *client, int *need_reset) | |
| 254 | +static int rx8025_init_client(struct i2c_client *client) | |
| 265 | 255 | { |
| 266 | 256 | struct rx8025_data *rx8025 = i2c_get_clientdata(client); |
| 267 | 257 | u8 ctrl[2], ctrl2; |
| @@ -275,38 +265,18 @@ static int rx8025_init_client(struct i2c_client *client, int *need_reset) · 7 unmodified lines | ||
| 275 | 265 | /* Keep test bit zero ! */ |
| 276 | 266 | rx8025->ctrl1 = ctrl[0] & ~RX8025_BIT_CTRL1_TEST; |
| 277 | 267 | |
| 278 | − if (ctrl[1] & RX8025_BIT_CTRL2_PON) { | |
| 279 | − dev_warn(&client->dev, "power-on reset was detected, " | |
| 280 | − "you may have to readjust the clock\n"); | |
| 281 | − *need_reset = 1; | |
| 282 | − } | |
| 283 | − | |
| 284 | − if (ctrl[1] & RX8025_BIT_CTRL2_VDET) { | |
| 285 | − dev_warn(&client->dev, "a power voltage drop was detected, " | |
| 286 | − "you may have to readjust the clock\n"); | |
| 287 | − *need_reset = 1; | |
| 288 | − } | |
| 289 | − | |
| 290 | − if (!(ctrl[1] & RX8025_BIT_CTRL2_XST)) { | |
| 291 | − dev_warn(&client->dev, "Oscillation stop was detected," | |
| 292 | − "you may have to readjust the clock\n"); | |
| 293 | − *need_reset = 1; | |
| 294 | − } | |
| 295 | − | |
| 296 | 268 | if (ctrl[1] & (RX8025_BIT_CTRL2_DAFG | RX8025_BIT_CTRL2_WAFG)) { |
| 297 | 269 | dev_warn(&client->dev, "Alarm was detected\n"); |
| 298 | 270 | need_clear = 1; |
| 299 | 271 | } |
| 300 | 272 | |
| 301 | − if (!(ctrl[1] & RX8025_BIT_CTRL2_CTFG)) | |
| 273 | + if (ctrl[1] & RX8025_BIT_CTRL2_CTFG) | |
| 302 | 274 | need_clear = 1; |
| 303 | 275 | |
| 304 | − if (*need_reset || need_clear) { | |
| 305 | − ctrl2 = ctrl[0]; | |
| 306 | − ctrl2 &= ~(RX8025_BIT_CTRL2_PON | RX8025_BIT_CTRL2_VDET | | |
| 307 | − RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG | | |
| 276 | + if (need_clear) { | |
| 277 | + ctrl2 = ctrl[1]; | |
| 278 | + ctrl2 &= ~(RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG | | |
| 308 | 279 | RX8025_BIT_CTRL2_DAFG); |
| 309 | − ctrl2 |= RX8025_BIT_CTRL2_XST; | |
| 310 | 280 | |
| 311 | 281 | err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2); |
| 312 | 282 | } |
| @@ -319,8 +289,8 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) · 6 unmodified lines | ||
| 319 | 289 | { |
| 320 | 290 | struct rx8025_data *rx8025 = dev_get_drvdata(dev); |
| 321 | 291 | struct i2c_client *client = rx8025->client; |
| 322 | − u8 ctrl2, ald[2]; | |
| 323 | − int err; | |
| 292 | + u8 ald[2]; | |
| 293 | + int ctrl2, err; | |
| 324 | 294 | |
| 325 | 295 | if (client->irq <= 0) |
| 326 | 296 | return -EINVAL; |
| @@ -329,9 +299,9 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) · 2 unmodified lines | ||
| 329 | 299 | if (err) |
| 330 | 300 | return err; |
| 331 | 301 | |
| 332 | − err = rx8025_read_reg(client, RX8025_REG_CTRL2, &ctrl2); | |
| 333 | − if (err) | |
| 334 | − return err; | |
| 302 | + ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2); | |
| 303 | + if (ctrl2 < 0) | |
| 304 | + return ctrl2; | |
| 335 | 305 | |
| 336 | 306 | dev_dbg(dev, "%s: read alarm 0x%02x 0x%02x ctrl2 %02x\n", |
| 337 | 307 | __func__, ald[0], ald[1], ctrl2); |
| @@ -452,12 +422,11 @@ static struct rtc_class_ops rx8025_rtc_ops = { · 114 unmodified lines | ||
| 452 | 422 | static int rx8025_get_clock_adjust(struct device *dev, int *adj) |
| 453 | 423 | { |
| 454 | 424 | struct i2c_client *client = to_i2c_client(dev); |
| 455 | − u8 digoff; | |
| 456 | − int err; | |
| 425 | + int digoff; | |
| 457 | 426 | |
| 458 | − err = rx8025_read_reg(client, RX8025_REG_DIGOFF, &digoff); | |
| 459 | − if (err) | |
| 460 | − return err; | |
| 427 | + digoff = rx8025_read_reg(client, RX8025_REG_DIGOFF); | |
| 428 | + if (digoff < 0) | |
| 429 | + return digoff; | |
| 461 | 430 | |
| 462 | 431 | *adj = digoff >= 64 ? digoff - 128 : digoff; |
| 463 | 432 | if (*adj > 0) |
| @@ -539,88 +508,53 @@ static int rx8025_probe(struct i2c_client *client, · 75 unmodified lines | ||
| 539 | 508 | { |
| 540 | 509 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 541 | 510 | struct rx8025_data *rx8025; |
| 542 | − int err, need_reset = 0; | |
| 511 | + int err = 0; | |
| 543 | 512 | |
| 544 | 513 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
| 545 | 514 | | I2C_FUNC_SMBUS_I2C_BLOCK)) { |
| 546 | 515 | dev_err(&adapter->dev, |
| 547 | 516 | "doesn't support required functionality\n"); |
| 548 | − err = -EIO; | |
| 549 | − goto errout; | |
| 517 | + return -EIO; | |
| 550 | 518 | } |
| 551 | 519 | |
| 552 | 520 | rx8025 = devm_kzalloc(&client->dev, sizeof(*rx8025), GFP_KERNEL); |
| 553 | 521 | if (!rx8025) { |
| 554 | − err = -ENOMEM; | |
| 555 | − goto errout; | |
| 522 | + return -ENOMEM; | |
| 556 | 523 | } |
| 557 | 524 | |
| 558 | 525 | rx8025->client = client; |
| 559 | 526 | i2c_set_clientdata(client, rx8025); |
| 560 | − INIT_WORK(&rx8025->work, rx8025_work); | |
| 561 | 527 | |
| 562 | − err = rx8025_init_client(client, &need_reset); | |
| 528 | + err = rx8025_init_client(client); | |
| 563 | 529 | if (err) |
| 564 | − goto errout; | |
| 565 | − | |
| 566 | − if (need_reset) { | |
| 567 | − struct rtc_time tm; | |
| 568 | − dev_info(&client->dev, | |
| 569 | − "bad conditions detected, resetting date\n"); | |
| 570 | − rtc_time_to_tm(0, &tm); /* 1970/1/1 */ | |
| 571 | − rx8025_set_time(&client->dev, &tm); | |
| 572 | − } | |
| 530 | + return err; | |
| 573 | 531 | |
| 574 | 532 | rx8025->rtc = devm_rtc_device_register(&client->dev, client->name, |
| 575 | 533 | &rx8025_rtc_ops, THIS_MODULE); |
| 576 | 534 | if (IS_ERR(rx8025->rtc)) { |
| 577 | − err = PTR_ERR(rx8025->rtc); | |
| 578 | 535 | dev_err(&client->dev, "unable to register the class device\n"); |
| 579 | − goto errout; | |
| 536 | + return PTR_ERR(rx8025->rtc); | |
| 580 | 537 | } |
| 581 | 538 | |
| 582 | 539 | if (client->irq > 0) { |
| 583 | 540 | dev_info(&client->dev, "IRQ %d supplied\n", client->irq); |
| 584 | − err = request_irq(client->irq, rx8025_irq, | |
| 585 | − 0, "rx8025", client); | |
| 541 | + err = devm_request_threaded_irq(&client->dev, client->irq, NULL, | |
| 542 | + rx8025_handle_irq, 0, "rx8025", | |
| 543 | + client); | |
| 586 | 544 | if (err) { |
| 587 | − dev_err(&client->dev, "unable to request IRQ\n"); | |
| 588 | − goto errout; | |
| 545 | + dev_err(&client->dev, "unable to request IRQ, alarms disabled\n"); | |
| 546 | + client->irq = 0; | |
| 589 | 547 | } |
| 590 | 548 | } |
| 591 | 549 | |
| 592 | − rx8025->rtc->irq_freq = 1; | |
| 593 | 550 | rx8025->rtc->max_user_freq = 1; |
| 594 | 551 | |
| 595 | 552 | err = rx8025_sysfs_register(&client->dev); |
| 596 | − if (err) | |
| 597 | − goto errout_irq; | |
| 598 | − | |
| 599 | − return 0; | |
| 600 | − | |
| 601 | −errout_irq: | |
| 602 | − if (client->irq > 0) | |
| 603 | − free_irq(client->irq, client); | |
| 604 | − | |
| 605 | −errout: | |
| 606 | − dev_err(&adapter->dev, "probing for rx8025 failed\n"); | |
| 607 | 553 | return err; |
| 608 | 554 | } |
| 609 | 555 | |
| 610 | 556 | static int rx8025_remove(struct i2c_client *client) |
| 611 | 557 | { |
| 612 | − struct rx8025_data *rx8025 = i2c_get_clientdata(client); | |
| 613 | − struct mutex *lock = &rx8025->rtc->ops_lock; | |
| 614 | − | |
| 615 | − if (client->irq > 0) { | |
| 616 | − mutex_lock(lock); | |
| 617 | − rx8025->exiting = 1; | |
| 618 | − mutex_unlock(lock); | |
| 619 | − | |
| 620 | − free_irq(client->irq, client); | |
| 621 | − cancel_work_sync(&rx8025->work); | |
| 622 | − } | |
| 623 | − | |
| 624 | 558 | rx8025_sysfs_unregister(&client->dev); |
| 625 | 559 | return 0; |
| 626 | 560 | } |
| @@ -628,7 +562,6 @@ static int rx8025_remove(struct i2c_client *client) · 1 unmodified line | ||
| 628 | 562 | static struct i2c_driver rx8025_driver = { |
| 629 | 563 | .driver = { |
| 630 | 564 | .name = "rtc-rx8025", |
| 631 | − .owner = THIS_MODULE, | |
| 632 | 565 | }, |
| 633 | 566 | .probe = rx8025_probe, |
| 634 | 567 | .remove = rx8025_remove, |
| @@ -315,7 +315,6 @@ MODULE_DEVICE_TABLE(i2c, rx8581_id); · 314 unmodified lines | ||
| 315 | 315 | static struct i2c_driver rx8581_driver = { |
| 316 | 316 | .driver = { |
| 317 | 317 | .name = "rtc-rx8581", |
| 318 | − .owner = THIS_MODULE, | |
| 319 | 318 | }, |
| 320 | 319 | .probe = rx8581_probe, |
| 321 | 320 | .id_table = rx8581_id, |
| @@ -39,6 +39,7 @@ struct s3c_rtc { · 38 unmodified lines | ||
| 39 | 39 | void __iomem *base; |
| 40 | 40 | struct clk *rtc_clk; |
| 41 | 41 | struct clk *rtc_src_clk; |
| 42 | + bool clk_disabled; | |
| 42 | 43 | |
| 43 | 44 | struct s3c_rtc_data *data; |
| 44 | 45 | |
| @@ -71,9 +72,12 @@ static void s3c_rtc_enable_clk(struct s3c_rtc *info) · 26 unmodified lines | ||
| 71 | 72 | unsigned long irq_flags; |
| 72 | 73 | |
| 73 | 74 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); |
| 74 | − clk_enable(info->rtc_clk); | |
| 75 | − if (info->data->needs_src_clk) | |
| 76 | − clk_enable(info->rtc_src_clk); | |
| 75 | + if (info->clk_disabled) { | |
| 76 | + clk_enable(info->rtc_clk); | |
| 77 | + if (info->data->needs_src_clk) | |
| 78 | + clk_enable(info->rtc_src_clk); | |
| 79 | + info->clk_disabled = false; | |
| 80 | + } | |
| 77 | 81 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); |
| 78 | 82 | } |
| 79 | 83 | |
| @@ -82,9 +86,12 @@ static void s3c_rtc_disable_clk(struct s3c_rtc *info) · 2 unmodified lines | ||
| 82 | 86 | unsigned long irq_flags; |
| 83 | 87 | |
| 84 | 88 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); |
| 85 | − if (info->data->needs_src_clk) | |
| 86 | − clk_disable(info->rtc_src_clk); | |
| 87 | − clk_disable(info->rtc_clk); | |
| 89 | + if (!info->clk_disabled) { | |
| 90 | + if (info->data->needs_src_clk) | |
| 91 | + clk_disable(info->rtc_src_clk); | |
| 92 | + clk_disable(info->rtc_clk); | |
| 93 | + info->clk_disabled = true; | |
| 94 | + } | |
| 88 | 95 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); |
| 89 | 96 | } |
| 90 | 97 | |
| @@ -128,6 +135,11 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) · 37 unmodified lines | ||
| 128 | 135 | |
| 129 | 136 | s3c_rtc_disable_clk(info); |
| 130 | 137 | |
| 138 | + if (enabled) | |
| 139 | + s3c_rtc_enable_clk(info); | |
| 140 | + else | |
| 141 | + s3c_rtc_disable_clk(info); | |
| 142 | + | |
| 131 | 143 | return 0; |
| 132 | 144 | } |
| 133 | 145 | |
| @@ -410,8 +422,9 @@ static int s3c_rtc_remove(struct platform_device *pdev) · 276 unmodified lines | ||
| 410 | 422 | |
| 411 | 423 | s3c_rtc_setaie(info->dev, 0); |
| 412 | 424 | |
| 425 | + if (info->data->needs_src_clk) | |
| 426 | + clk_unprepare(info->rtc_src_clk); | |
| 413 | 427 | clk_unprepare(info->rtc_clk); |
| 414 | − info->rtc_clk = NULL; | |
| 415 | 428 | |
| 416 | 429 | return 0; |
| 417 | 430 | } |
| @@ -482,6 +495,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) · 64 unmodified lines | ||
| 482 | 495 | if (IS_ERR(info->rtc_src_clk)) { |
| 483 | 496 | dev_err(&pdev->dev, |
| 484 | 497 | "failed to find rtc source clock\n"); |
| 498 | + clk_disable_unprepare(info->rtc_clk); | |
| 485 | 499 | return PTR_ERR(info->rtc_src_clk); |
| 486 | 500 | } |
| 487 | 501 | clk_prepare_enable(info->rtc_src_clk); |
| @@ -635,6 +635,16 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) · 634 unmodified lines | ||
| 635 | 635 | case S2MPS13X: |
| 636 | 636 | data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); |
| 637 | 637 | ret = regmap_write(info->regmap, info->regs->ctrl, data[0]); |
| 638 | + if (ret < 0) | |
| 639 | + break; | |
| 640 | + | |
| 641 | + /* | |
| 642 | + * Should set WUDR & (RUDR or AUDR) bits to high after writing | |
| 643 | + * RTC_CTRL register like writing Alarm registers. We can't find | |
| 644 | + * the description from datasheet but vendor code does that | |
| 645 | + * really. | |
| 646 | + */ | |
| 647 | + ret = s5m8767_rtc_set_alarm_reg(info); | |
| 638 | 648 | break; |
| 639 | 649 | |
| 640 | 650 | default: |
| @@ -797,6 +807,7 @@ static const struct platform_device_id s5m_rtc_id[] = { · 156 unmodified lines | ||
| 797 | 807 | { "s2mps14-rtc", S2MPS14X }, |
| 798 | 808 | { }, |
| 799 | 809 | }; |
| 810 | +MODULE_DEVICE_TABLE(platform, s5m_rtc_id); | |
| 800 | 811 | |
| 801 | 812 | static struct platform_driver s5m_rtc_driver = { |
| 802 | 813 | .driver = { |
| @@ -35,24 +35,17 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <linux/bitops.h> |
| 36 | 36 | #include <linux/io.h> |
| 37 | 37 | |
| 38 | −#include <mach/hardware.h> | |
| 39 | −#include <mach/irqs.h> | |
| 38 | +#define RTSR_HZE BIT(3) /* HZ interrupt enable */ | |
| 39 | +#define RTSR_ALE BIT(2) /* RTC alarm interrupt enable */ | |
| 40 | +#define RTSR_HZ BIT(1) /* HZ rising-edge detected */ | |
| 41 | +#define RTSR_AL BIT(0) /* RTC alarm detected */ | |
| 40 | 42 | |
| 41 | −#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) | |
| 42 | −#include <mach/regs-rtc.h> | |
| 43 | −#endif | |
| 43 | +#include "rtc-sa1100.h" | |
| 44 | 44 | |
| 45 | 45 | #define RTC_DEF_DIVIDER (32768 - 1) |
| 46 | 46 | #define RTC_DEF_TRIM 0 |
| 47 | 47 | #define RTC_FREQ 1024 |
| 48 | 48 | |
| 49 | −struct sa1100_rtc { | |
| 50 | − spinlock_t lock; | |
| 51 | − int irq_1hz; | |
| 52 | − int irq_alarm; | |
| 53 | − struct rtc_device *rtc; | |
| 54 | − struct clk *clk; | |
| 55 | −}; | |
| 56 | 49 | |
| 57 | 50 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) |
| 58 | 51 | { |
| @@ -63,16 +56,16 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) · 4 unmodified lines | ||
| 63 | 56 | |
| 64 | 57 | spin_lock(&info->lock); |
| 65 | 58 | |
| 66 | − rtsr = RTSR; | |
| 59 | + rtsr = readl_relaxed(info->rtsr); | |
| 67 | 60 | /* clear interrupt sources */ |
| 68 | − RTSR = 0; | |
| 61 | + writel_relaxed(0, info->rtsr); | |
| 69 | 62 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
| 70 | 63 | * See also the comments in sa1100_rtc_probe(). */ |
| 71 | 64 | if (rtsr & (RTSR_ALE | RTSR_HZE)) { |
| 72 | 65 | /* This is the original code, before there was the if test |
| 73 | 66 | * above. This code does not clear interrupts that were not |
| 74 | 67 | * enabled. */ |
| 75 | − RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | |
| 68 | + writel_relaxed((RTSR_AL | RTSR_HZ) & (rtsr >> 2), info->rtsr); | |
| 76 | 69 | } else { |
| 77 | 70 | /* For some reason, it is possible to enter this routine |
| 78 | 71 | * without interruptions enabled, it has been tested with |
| @@ -81,13 +74,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) · 2 unmodified lines | ||
| 81 | 74 | * This situation leads to an infinite "loop" of interrupt |
| 82 | 75 | * routine calling and as a result the processor seems to |
| 83 | 76 | * lock on its first call to open(). */ |
| 84 | − RTSR = RTSR_AL | RTSR_HZ; | |
| 77 | + writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr); | |
| 85 | 78 | } |
| 86 | 79 | |
| 87 | 80 | /* clear alarm interrupt if it has occurred */ |
| 88 | 81 | if (rtsr & RTSR_AL) |
| 89 | 82 | rtsr &= ~RTSR_ALE; |
| 90 | − RTSR = rtsr & (RTSR_ALE | RTSR_HZE); | |
| 83 | + writel_relaxed(rtsr & (RTSR_ALE | RTSR_HZE), info->rtsr); | |
| 91 | 84 | |
| 92 | 85 | /* update irq data & counter */ |
| 93 | 86 | if (rtsr & RTSR_AL) |
| @@ -135,7 +128,7 @@ static void sa1100_rtc_release(struct device *dev) · 41 unmodified lines | ||
| 135 | 128 | struct sa1100_rtc *info = dev_get_drvdata(dev); |
| 136 | 129 | |
| 137 | 130 | spin_lock_irq(&info->lock); |
| 138 | − RTSR = 0; | |
| 131 | + writel_relaxed(0, info->rtsr); | |
| 139 | 132 | spin_unlock_irq(&info->lock); |
| 140 | 133 | |
| 141 | 134 | free_irq(info->irq_alarm, dev); |
| @@ -144,39 +137,46 @@ static void sa1100_rtc_release(struct device *dev) · 2 unmodified lines | ||
| 144 | 137 | |
| 145 | 138 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
| 146 | 139 | { |
| 140 | + u32 rtsr; | |
| 147 | 141 | struct sa1100_rtc *info = dev_get_drvdata(dev); |
| 148 | 142 | |
| 149 | 143 | spin_lock_irq(&info->lock); |
| 144 | + rtsr = readl_relaxed(info->rtsr); | |
| 150 | 145 | if (enabled) |
| 151 | − RTSR |= RTSR_ALE; | |
| 146 | + rtsr |= RTSR_ALE; | |
| 152 | 147 | else |
| 153 | − RTSR &= ~RTSR_ALE; | |
| 148 | + rtsr &= ~RTSR_ALE; | |
| 149 | + writel_relaxed(rtsr, info->rtsr); | |
| 154 | 150 | spin_unlock_irq(&info->lock); |
| 155 | 151 | return 0; |
| 156 | 152 | } |
| 157 | 153 | |
| 158 | 154 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| 159 | 155 | { |
| 160 | − rtc_time_to_tm(RCNR, tm); | |
| 156 | + struct sa1100_rtc *info = dev_get_drvdata(dev); | |
| 157 | + | |
| 158 | + rtc_time_to_tm(readl_relaxed(info->rcnr), tm); | |
| 161 | 159 | return 0; |
| 162 | 160 | } |
| 163 | 161 | |
| 164 | 162 | static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) |
| 165 | 163 | { |
| 164 | + struct sa1100_rtc *info = dev_get_drvdata(dev); | |
| 166 | 165 | unsigned long time; |
| 167 | 166 | int ret; |
| 168 | 167 | |
| 169 | 168 | ret = rtc_tm_to_time(tm, &time); |
| 170 | 169 | if (ret == 0) |
| 171 | − RCNR = time; | |
| 170 | + writel_relaxed(time, info->rcnr); | |
| 172 | 171 | return ret; |
| 173 | 172 | } |
| 174 | 173 | |
| 175 | 174 | static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| 176 | 175 | { |
| 177 | 176 | u32 rtsr; |
| 177 | + struct sa1100_rtc *info = dev_get_drvdata(dev); | |
| 178 | 178 | |
| 179 | − rtsr = RTSR; | |
| 179 | + rtsr = readl_relaxed(info->rtsr); | |
| 180 | 180 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; |
| 181 | 181 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; |
| 182 | 182 | return 0; |
| @@ -192,12 +192,13 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) · 9 unmodified lines | ||
| 192 | 192 | ret = rtc_tm_to_time(&alrm->time, &time); |
| 193 | 193 | if (ret != 0) |
| 194 | 194 | goto out; |
| 195 | − RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); | |
| 196 | − RTAR = time; | |
| 195 | + writel_relaxed(readl_relaxed(info->rtsr) & | |
| 196 | + (RTSR_HZE | RTSR_ALE | RTSR_AL), info->rtsr); | |
| 197 | + writel_relaxed(time, info->rtar); | |
| 197 | 198 | if (alrm->enabled) |
| 198 | − RTSR |= RTSR_ALE; | |
| 199 | + writel_relaxed(readl_relaxed(info->rtsr) | RTSR_ALE, info->rtsr); | |
| 199 | 200 | else |
| 200 | − RTSR &= ~RTSR_ALE; | |
| 201 | + writel_relaxed(readl_relaxed(info->rtsr) & ~RTSR_ALE, info->rtsr); | |
| 201 | 202 | out: |
| 202 | 203 | spin_unlock_irq(&info->lock); |
| 203 | 204 | |
| @@ -206,8 +207,10 @@ out: · 2 unmodified lines | ||
| 206 | 207 | |
| 207 | 208 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) |
| 208 | 209 | { |
| 209 | − seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); | |
| 210 | − seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); | |
| 210 | + struct sa1100_rtc *info = dev_get_drvdata(dev); | |
| 211 | + | |
| 212 | + seq_printf(seq, "trim/divider\t\t: 0x%08x\n", readl_relaxed(info->rttr)); | |
| 213 | + seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", readl_relaxed(info->rtsr)); | |
| 211 | 214 | |
| 212 | 215 | return 0; |
| 213 | 216 | } |
| @@ -223,29 +226,18 @@ static const struct rtc_class_ops sa1100_rtc_ops = { · 9 unmodified lines | ||
| 223 | 226 | .alarm_irq_enable = sa1100_rtc_alarm_irq_enable, |
| 224 | 227 | }; |
| 225 | 228 | |
| 226 | −static int sa1100_rtc_probe(struct platform_device *pdev) | |
| 229 | +int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info) | |
| 227 | 230 | { |
| 228 | 231 | struct rtc_device *rtc; |
| 229 | − struct sa1100_rtc *info; | |
| 230 | − int irq_1hz, irq_alarm, ret = 0; | |
| 232 | + int ret; | |
| 231 | 233 | |
| 232 | − irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); | |
| 233 | − irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); | |
| 234 | − if (irq_1hz < 0 || irq_alarm < 0) | |
| 235 | − return -ENODEV; | |
| 234 | + spin_lock_init(&info->lock); | |
| 236 | 235 | |
| 237 | − info = devm_kzalloc(&pdev->dev, sizeof(struct sa1100_rtc), GFP_KERNEL); | |
| 238 | − if (!info) | |
| 239 | − return -ENOMEM; | |
| 240 | 236 | info->clk = devm_clk_get(&pdev->dev, NULL); |
| 241 | 237 | if (IS_ERR(info->clk)) { |
| 242 | 238 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); |
| 243 | 239 | return PTR_ERR(info->clk); |
| 244 | 240 | } |
| 245 | − info->irq_1hz = irq_1hz; | |
| 246 | − info->irq_alarm = irq_alarm; | |
| 247 | − spin_lock_init(&info->lock); | |
| 248 | − platform_set_drvdata(pdev, info); | |
| 249 | 241 | |
| 250 | 242 | ret = clk_prepare_enable(info->clk); |
| 251 | 243 | if (ret) |
| @@ -257,22 +249,19 @@ static int sa1100_rtc_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 257 | 249 | * If the clock divider is uninitialized then reset it to the |
| 258 | 250 | * default value to get the 1Hz clock. |
| 259 | 251 | */ |
| 260 | − if (RTTR == 0) { | |
| 261 | − RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | |
| 252 | + if (readl_relaxed(info->rttr) == 0) { | |
| 253 | + writel_relaxed(RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16), info->rttr); | |
| 262 | 254 | dev_warn(&pdev->dev, "warning: " |
| 263 | 255 | "initializing default clock divider/trim value\n"); |
| 264 | 256 | /* The current RTC value probably doesn't make sense either */ |
| 265 | − RCNR = 0; | |
| 257 | + writel_relaxed(0, info->rcnr); | |
| 266 | 258 | } |
| 267 | 259 | |
| 268 | − device_init_wakeup(&pdev->dev, 1); | |
| 269 | − | |
| 270 | 260 | rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops, |
| 271 | 261 | THIS_MODULE); |
| 272 | − | |
| 273 | 262 | if (IS_ERR(rtc)) { |
| 274 | − ret = PTR_ERR(rtc); | |
| 275 | − goto err_dev; | |
| 263 | + clk_disable_unprepare(info->clk); | |
| 264 | + return PTR_ERR(rtc); | |
| 276 | 265 | } |
| 277 | 266 | info->rtc = rtc; |
| 278 | 267 | |
| @@ -298,12 +287,52 @@ static int sa1100_rtc_probe(struct platform_device *pdev) · 19 unmodified lines | ||
| 298 | 287 | * |
| 299 | 288 | * Notice that clearing bit 1 and 0 is accomplished by writting ONES to |
| 300 | 289 | * the corresponding bits in RTSR. */ |
| 301 | − RTSR = RTSR_AL | RTSR_HZ; | |
| 290 | + writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr); | |
| 302 | 291 | |
| 303 | 292 | return 0; |
| 304 | −err_dev: | |
| 305 | − clk_disable_unprepare(info->clk); | |
| 306 | − return ret; | |
| 293 | +} | |
| 294 | +EXPORT_SYMBOL_GPL(sa1100_rtc_init); | |
| 295 | + | |
| 296 | +static int sa1100_rtc_probe(struct platform_device *pdev) | |
| 297 | +{ | |
| 298 | + struct sa1100_rtc *info; | |
| 299 | + struct resource *iores; | |
| 300 | + void __iomem *base; | |
| 301 | + int irq_1hz, irq_alarm; | |
| 302 | + | |
| 303 | + irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); | |
| 304 | + irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); | |
| 305 | + if (irq_1hz < 0 || irq_alarm < 0) | |
| 306 | + return -ENODEV; | |
| 307 | + | |
| 308 | + info = devm_kzalloc(&pdev->dev, sizeof(struct sa1100_rtc), GFP_KERNEL); | |
| 309 | + if (!info) | |
| 310 | + return -ENOMEM; | |
| 311 | + info->irq_1hz = irq_1hz; | |
| 312 | + info->irq_alarm = irq_alarm; | |
| 313 | + | |
| 314 | + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 315 | + base = devm_ioremap_resource(&pdev->dev, iores); | |
| 316 | + if (IS_ERR(base)) | |
| 317 | + return PTR_ERR(base); | |
| 318 | + | |
| 319 | + if (IS_ENABLED(CONFIG_ARCH_SA1100) || | |
| 320 | + of_device_is_compatible(pdev->dev.of_node, "mrvl,sa1100-rtc")) { | |
| 321 | + info->rcnr = base + 0x04; | |
| 322 | + info->rtsr = base + 0x10; | |
| 323 | + info->rtar = base + 0x00; | |
| 324 | + info->rttr = base + 0x08; | |
| 325 | + } else { | |
| 326 | + info->rcnr = base + 0x0; | |
| 327 | + info->rtsr = base + 0x8; | |
| 328 | + info->rtar = base + 0x4; | |
| 329 | + info->rttr = base + 0xc; | |
| 330 | + } | |
| 331 | + | |
| 332 | + platform_set_drvdata(pdev, info); | |
| 333 | + device_init_wakeup(&pdev->dev, 1); | |
| 334 | + | |
| 335 | + return sa1100_rtc_init(pdev, info); | |
| 307 | 336 | } |
| 308 | 337 | |
| 309 | 338 | static int sa1100_rtc_remove(struct platform_device *pdev) |
| @@ -0,0 +1,23 @@ | ||
| 1 | +#ifndef __RTC_SA1100_H__ | |
| 2 | +#define __RTC_SA1100_H__ | |
| 3 | + | |
| 4 | +#include <linux/kernel.h> | |
| 5 | + | |
| 6 | +struct clk; | |
| 7 | +struct platform_device; | |
| 8 | + | |
| 9 | +struct sa1100_rtc { | |
| 10 | + spinlock_t lock; | |
| 11 | + void __iomem *rcnr; | |
| 12 | + void __iomem *rtar; | |
| 13 | + void __iomem *rtsr; | |
| 14 | + void __iomem *rttr; | |
| 15 | + int irq_1hz; | |
| 16 | + int irq_alarm; | |
| 17 | + struct rtc_device *rtc; | |
| 18 | + struct clk *clk; | |
| 19 | +}; | |
| 20 | + | |
| 21 | +int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info); | |
| 22 | + | |
| 23 | +#endif | |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/slab.h> |
| 14 | 14 | #include <linux/io.h> |
| 15 | 15 | #include <linux/of.h> |
| 16 | +#include <linux/regmap.h> | |
| 16 | 17 | #include <linux/rtc/sirfsoc_rtciobrg.h> |
| 17 | 18 | |
| 18 | 19 | |
| @@ -48,12 +49,27 @@ struct sirfsoc_rtc_drv { · 29 unmodified lines | ||
| 48 | 49 | /* Overflow for every 8 years extra time */ |
| 49 | 50 | u32 overflow_rtc; |
| 50 | 51 | spinlock_t lock; |
| 52 | + struct regmap *regmap; | |
| 51 | 53 | #ifdef CONFIG_PM |
| 52 | 54 | u32 saved_counter; |
| 53 | 55 | u32 saved_overflow_rtc; |
| 54 | 56 | #endif |
| 55 | 57 | }; |
| 56 | 58 | |
| 59 | +static u32 sirfsoc_rtc_readl(struct sirfsoc_rtc_drv *rtcdrv, u32 offset) | |
| 60 | +{ | |
| 61 | + u32 val; | |
| 62 | + | |
| 63 | + regmap_read(rtcdrv->regmap, rtcdrv->rtc_base + offset, &val); | |
| 64 | + return val; | |
| 65 | +} | |
| 66 | + | |
| 67 | +static void sirfsoc_rtc_writel(struct sirfsoc_rtc_drv *rtcdrv, | |
| 68 | + u32 offset, u32 val) | |
| 69 | +{ | |
| 70 | + regmap_write(rtcdrv->regmap, rtcdrv->rtc_base + offset, val); | |
| 71 | +} | |
| 72 | + | |
| 57 | 73 | static int sirfsoc_rtc_read_alarm(struct device *dev, |
| 58 | 74 | struct rtc_wkalrm *alrm) |
| 59 | 75 | { |
| @@ -64,9 +80,9 @@ static int sirfsoc_rtc_read_alarm(struct device *dev, · 4 unmodified lines | ||
| 64 | 80 | |
| 65 | 81 | spin_lock_irq(&rtcdrv->lock); |
| 66 | 82 | |
| 67 | − rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); | |
| 83 | + rtc_count = sirfsoc_rtc_readl(rtcdrv, RTC_CN); | |
| 68 | 84 | |
| 69 | − rtc_alarm = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_ALARM0); | |
| 85 | + rtc_alarm = sirfsoc_rtc_readl(rtcdrv, RTC_ALARM0); | |
| 70 | 86 | memset(alrm, 0, sizeof(struct rtc_wkalrm)); |
| 71 | 87 | |
| 72 | 88 | /* |
| @@ -82,8 +98,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev, · 9 unmodified lines | ||
| 82 | 98 | rtc_time_to_tm(rtcdrv->overflow_rtc |
| 83 | 99 | << (BITS_PER_LONG - RTC_SHIFT) |
| 84 | 100 | | rtc_alarm >> RTC_SHIFT, &(alrm->time)); |
| 85 | − if (sirfsoc_rtc_iobrg_readl( | |
| 86 | − rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E) | |
| 101 | + if (sirfsoc_rtc_readl(rtcdrv, RTC_STATUS) & SIRFSOC_RTC_AL0E) | |
| 87 | 102 | alrm->enabled = 1; |
| 88 | 103 | |
| 89 | 104 | spin_unlock_irq(&rtcdrv->lock); |
| @@ -103,8 +118,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, · 13 unmodified lines | ||
| 103 | 118 | |
| 104 | 119 | spin_lock_irq(&rtcdrv->lock); |
| 105 | 120 | |
| 106 | − rtc_status_reg = sirfsoc_rtc_iobrg_readl( | |
| 107 | − rtcdrv->rtc_base + RTC_STATUS); | |
| 121 | + rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); | |
| 108 | 122 | if (rtc_status_reg & SIRFSOC_RTC_AL0E) { |
| 109 | 123 | /* |
| 110 | 124 | * An ongoing alarm in progress - ingore it and not |
| @@ -113,8 +127,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, · 2 unmodified lines | ||
| 113 | 127 | dev_info(dev, "An old alarm was set, will be replaced by a new one\n"); |
| 114 | 128 | } |
| 115 | 129 | |
| 116 | − sirfsoc_rtc_iobrg_writel( | |
| 117 | − rtc_alarm << RTC_SHIFT, rtcdrv->rtc_base + RTC_ALARM0); | |
| 130 | + sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, rtc_alarm << RTC_SHIFT); | |
| 118 | 131 | rtc_status_reg &= ~0x07; /* mask out the lower status bits */ |
| 119 | 132 | /* |
| 120 | 133 | * This bit RTC_AL sets it as a wake-up source for Sleep Mode |
| @@ -123,8 +136,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, · 2 unmodified lines | ||
| 123 | 136 | rtc_status_reg |= SIRFSOC_RTC_AL0; |
| 124 | 137 | /* enable the RTC alarm interrupt */ |
| 125 | 138 | rtc_status_reg |= SIRFSOC_RTC_AL0E; |
| 126 | − sirfsoc_rtc_iobrg_writel( | |
| 127 | − rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); | |
| 139 | + sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg); | |
| 128 | 140 | |
| 129 | 141 | spin_unlock_irq(&rtcdrv->lock); |
| 130 | 142 | } else { |
| @@ -135,8 +147,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, · 4 unmodified lines | ||
| 135 | 147 | */ |
| 136 | 148 | spin_lock_irq(&rtcdrv->lock); |
| 137 | 149 | |
| 138 | − rtc_status_reg = sirfsoc_rtc_iobrg_readl( | |
| 139 | − rtcdrv->rtc_base + RTC_STATUS); | |
| 150 | + rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); | |
| 140 | 151 | if (rtc_status_reg & SIRFSOC_RTC_AL0E) { |
| 141 | 152 | /* clear the RTC status register's alarm bit */ |
| 142 | 153 | rtc_status_reg &= ~0x07; |
| @@ -145,8 +156,8 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, · 2 unmodified lines | ||
| 145 | 156 | /* Clear the Alarm enable bit */ |
| 146 | 157 | rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); |
| 147 | 158 | |
| 148 | − sirfsoc_rtc_iobrg_writel(rtc_status_reg, | |
| 149 | − rtcdrv->rtc_base + RTC_STATUS); | |
| 159 | + sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, | |
| 160 | + rtc_status_reg); | |
| 150 | 161 | } |
| 151 | 162 | |
| 152 | 163 | spin_unlock_irq(&rtcdrv->lock); |
| @@ -167,9 +178,9 @@ static int sirfsoc_rtc_read_time(struct device *dev, · 14 unmodified lines | ||
| 167 | 178 | * fail, read several times to make sure get stable value. |
| 168 | 179 | */ |
| 169 | 180 | do { |
| 170 | − tmp_rtc = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); | |
| 181 | + tmp_rtc = sirfsoc_rtc_readl(rtcdrv, RTC_CN); | |
| 171 | 182 | cpu_relax(); |
| 172 | − } while (tmp_rtc != sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN)); | |
| 183 | + } while (tmp_rtc != sirfsoc_rtc_readl(rtcdrv, RTC_CN)); | |
| 173 | 184 | |
| 174 | 185 | rtc_time_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) | |
| 175 | 186 | tmp_rtc >> RTC_SHIFT, tm); |
| @@ -187,10 +198,8 @@ static int sirfsoc_rtc_set_time(struct device *dev, · 11 unmodified lines | ||
| 187 | 198 | |
| 188 | 199 | rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT); |
| 189 | 200 | |
| 190 | − sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc, | |
| 191 | − rtcdrv->rtc_base + RTC_SW_VALUE); | |
| 192 | − sirfsoc_rtc_iobrg_writel( | |
| 193 | − rtc_time << RTC_SHIFT, rtcdrv->rtc_base + RTC_CN); | |
| 201 | + sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc); | |
| 202 | + sirfsoc_rtc_writel(rtcdrv, RTC_CN, rtc_time << RTC_SHIFT); | |
| 194 | 203 | |
| 195 | 204 | return 0; |
| 196 | 205 | } |
| @@ -222,14 +231,13 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev, · 25 unmodified lines | ||
| 222 | 231 | |
| 223 | 232 | spin_lock_irq(&rtcdrv->lock); |
| 224 | 233 | |
| 225 | − rtc_status_reg = sirfsoc_rtc_iobrg_readl( | |
| 226 | − rtcdrv->rtc_base + RTC_STATUS); | |
| 234 | + rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); | |
| 227 | 235 | if (enabled) |
| 228 | 236 | rtc_status_reg |= SIRFSOC_RTC_AL0E; |
| 229 | 237 | else |
| 230 | 238 | rtc_status_reg &= ~SIRFSOC_RTC_AL0E; |
| 231 | 239 | |
| 232 | − sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); | |
| 240 | + sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg); | |
| 233 | 241 | |
| 234 | 242 | spin_unlock_irq(&rtcdrv->lock); |
| 235 | 243 | |
| @@ -254,7 +262,7 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata) · 18 unmodified lines | ||
| 254 | 262 | |
| 255 | 263 | spin_lock(&rtcdrv->lock); |
| 256 | 264 | |
| 257 | − rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS); | |
| 265 | + rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS); | |
| 258 | 266 | /* this bit will be set ONLY if an alarm was active |
| 259 | 267 | * and it expired NOW |
| 260 | 268 | * So this is being used as an ASSERT |
| @@ -270,7 +278,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata) · 9 unmodified lines | ||
| 270 | 278 | /* Clear the Alarm enable bit */ |
| 271 | 279 | rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); |
| 272 | 280 | } |
| 273 | − sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); | |
| 281 | + | |
| 282 | + sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg); | |
| 274 | 283 | |
| 275 | 284 | spin_unlock(&rtcdrv->lock); |
| 276 | 285 | |
| @@ -287,6 +296,13 @@ static const struct of_device_id sirfsoc_rtc_of_match[] = { · 10 unmodified lines | ||
| 287 | 296 | { .compatible = "sirf,prima2-sysrtc"}, |
| 288 | 297 | {}, |
| 289 | 298 | }; |
| 299 | + | |
| 300 | +const struct regmap_config sysrtc_regmap_config = { | |
| 301 | + .reg_bits = 32, | |
| 302 | + .val_bits = 32, | |
| 303 | + .fast_io = true, | |
| 304 | +}; | |
| 305 | + | |
| 290 | 306 | MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match); |
| 291 | 307 | |
| 292 | 308 | static int sirfsoc_rtc_probe(struct platform_device *pdev) |
| @@ -314,27 +330,35 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev) · 21 unmodified lines | ||
| 314 | 330 | /* Register rtc alarm as a wakeup source */ |
| 315 | 331 | device_init_wakeup(&pdev->dev, 1); |
| 316 | 332 | |
| 333 | + rtcdrv->regmap = devm_regmap_init_iobg(&pdev->dev, | |
| 334 | + &sysrtc_regmap_config); | |
| 335 | + if (IS_ERR(rtcdrv->regmap)) { | |
| 336 | + err = PTR_ERR(rtcdrv->regmap); | |
| 337 | + dev_err(&pdev->dev, "Failed to allocate register map: %d\n", | |
| 338 | + err); | |
| 339 | + return err; | |
| 340 | + } | |
| 341 | + | |
| 317 | 342 | /* |
| 318 | 343 | * Set SYS_RTC counter in RTC_HZ HZ Units |
| 319 | 344 | * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1 |
| 320 | 345 | * If 16HZ, therefore RTC_DIV = 1023; |
| 321 | 346 | */ |
| 322 | 347 | rtc_div = ((32768 / RTC_HZ) / 2) - 1; |
| 323 | − sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV); | |
| 348 | + sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div); | |
| 324 | 349 | |
| 325 | 350 | /* 0x3 -> RTC_CLK */ |
| 326 | − sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK, | |
| 327 | − rtcdrv->rtc_base + RTC_CLOCK_SWITCH); | |
| 351 | + sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK); | |
| 328 | 352 | |
| 329 | 353 | /* reset SYS RTC ALARM0 */ |
| 330 | − sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0); | |
| 354 | + sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0); | |
| 331 | 355 | |
| 332 | 356 | /* reset SYS RTC ALARM1 */ |
| 333 | − sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1); | |
| 357 | + sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0); | |
| 334 | 358 | |
| 335 | 359 | /* Restore RTC Overflow From Register After Command Reboot */ |
| 336 | 360 | rtcdrv->overflow_rtc = |
| 337 | − sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); | |
| 361 | + sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE); | |
| 338 | 362 | |
| 339 | 363 | rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, |
| 340 | 364 | &sirfsoc_rtc_ops, THIS_MODULE); |
| @@ -372,10 +396,10 @@ static int sirfsoc_rtc_suspend(struct device *dev) · 31 unmodified lines | ||
| 372 | 396 | { |
| 373 | 397 | struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev); |
| 374 | 398 | rtcdrv->overflow_rtc = |
| 375 | − sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); | |
| 399 | + sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE); | |
| 376 | 400 | |
| 377 | 401 | rtcdrv->saved_counter = |
| 378 | − sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); | |
| 402 | + sirfsoc_rtc_readl(rtcdrv, RTC_CN); | |
| 379 | 403 | rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc; |
| 380 | 404 | if (device_may_wakeup(dev) && !enable_irq_wake(rtcdrv->irq)) |
| 381 | 405 | rtcdrv->irq_wake = 1; |
| @@ -392,12 +416,10 @@ static int sirfsoc_rtc_resume(struct device *dev) · 10 unmodified lines | ||
| 392 | 416 | * if resume from snapshot and the rtc power is lost, |
| 393 | 417 | * restroe the rtc settings |
| 394 | 418 | */ |
| 395 | − if (SIRFSOC_RTC_CLK != sirfsoc_rtc_iobrg_readl( | |
| 396 | − rtcdrv->rtc_base + RTC_CLOCK_SWITCH)) { | |
| 419 | + if (SIRFSOC_RTC_CLK != sirfsoc_rtc_readl(rtcdrv, RTC_CLOCK_SWITCH)) { | |
| 397 | 420 | u32 rtc_div; |
| 398 | 421 | /* 0x3 -> RTC_CLK */ |
| 399 | − sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK, | |
| 400 | − rtcdrv->rtc_base + RTC_CLOCK_SWITCH); | |
| 422 | + sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK); | |
| 401 | 423 | /* |
| 402 | 424 | * Set SYS_RTC counter in RTC_HZ HZ Units |
| 403 | 425 | * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1 |
| @@ -405,13 +427,13 @@ static int sirfsoc_rtc_resume(struct device *dev) · 1 unmodified line | ||
| 405 | 427 | */ |
| 406 | 428 | rtc_div = ((32768 / RTC_HZ) / 2) - 1; |
| 407 | 429 | |
| 408 | − sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV); | |
| 430 | + sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div); | |
| 409 | 431 | |
| 410 | 432 | /* reset SYS RTC ALARM0 */ |
| 411 | − sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0); | |
| 433 | + sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0); | |
| 412 | 434 | |
| 413 | 435 | /* reset SYS RTC ALARM1 */ |
| 414 | − sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1); | |
| 436 | + sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0); | |
| 415 | 437 | } |
| 416 | 438 | rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc; |
| 417 | 439 | |
| @@ -419,15 +441,14 @@ static int sirfsoc_rtc_resume(struct device *dev) · 1 unmodified line | ||
| 419 | 441 | * if current counter is small than previous, |
| 420 | 442 | * it means overflow in sleep |
| 421 | 443 | */ |
| 422 | − tmp = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); | |
| 444 | + tmp = sirfsoc_rtc_readl(rtcdrv, RTC_CN); | |
| 423 | 445 | if (tmp <= rtcdrv->saved_counter) |
| 424 | 446 | rtcdrv->overflow_rtc++; |
| 425 | 447 | /* |
| 426 | 448 | *PWRC Value Be Changed When Suspend, Restore Overflow |
| 427 | 449 | * In Memory To Register |
| 428 | 450 | */ |
| 429 | − sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc, | |
| 430 | − rtcdrv->rtc_base + RTC_SW_VALUE); | |
| 451 | + sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc); | |
| 431 | 452 | |
| 432 | 453 | if (device_may_wakeup(dev) && rtcdrv->irq_wake) { |
| 433 | 454 | disable_irq_wake(rtcdrv->irq); |
| @@ -254,7 +254,7 @@ static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj, · 253 unmodified lines | ||
| 254 | 254 | void __iomem *ioaddr = pdata->ioaddr; |
| 255 | 255 | ssize_t count; |
| 256 | 256 | |
| 257 | − for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) | |
| 257 | + for (count = 0; count < size; count++) | |
| 258 | 258 | *buf++ = readb(ioaddr + pos++); |
| 259 | 259 | return count; |
| 260 | 260 | } |
| @@ -269,7 +269,7 @@ static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj, · 8 unmodified lines | ||
| 269 | 269 | void __iomem *ioaddr = pdata->ioaddr; |
| 270 | 270 | ssize_t count; |
| 271 | 271 | |
| 272 | − for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) | |
| 272 | + for (count = 0; count < size; count++) | |
| 273 | 273 | writeb(*buf++, ioaddr + pos++); |
| 274 | 274 | return count; |
| 275 | 275 | } |
| @@ -122,20 +122,8 @@ hctosys_show(struct device *dev, struct device_attribute *attr, char *buf) · 121 unmodified lines | ||
| 122 | 122 | } |
| 123 | 123 | static DEVICE_ATTR_RO(hctosys); |
| 124 | 124 | |
| 125 | −static struct attribute *rtc_attrs[] = { | |
| 126 | − &dev_attr_name.attr, | |
| 127 | − &dev_attr_date.attr, | |
| 128 | − &dev_attr_time.attr, | |
| 129 | − &dev_attr_since_epoch.attr, | |
| 130 | − &dev_attr_max_user_freq.attr, | |
| 131 | − &dev_attr_hctosys.attr, | |
| 132 | − NULL, | |
| 133 | −}; | |
| 134 | −ATTRIBUTE_GROUPS(rtc); | |
| 135 | − | |
| 136 | 125 | static ssize_t |
| 137 | −rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, | |
| 138 | − char *buf) | |
| 126 | +wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf) | |
| 139 | 127 | { |
| 140 | 128 | ssize_t retval; |
| 141 | 129 | unsigned long alarm; |
| @@ -159,7 +147,7 @@ rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, · 17 unmodified lines | ||
| 159 | 147 | } |
| 160 | 148 | |
| 161 | 149 | static ssize_t |
| 162 | −rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, | |
| 150 | +wakealarm_store(struct device *dev, struct device_attribute *attr, | |
| 163 | 151 | const char *buf, size_t n) |
| 164 | 152 | { |
| 165 | 153 | ssize_t retval; |
| @@ -221,45 +209,57 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, · 55 unmodified lines | ||
| 221 | 209 | retval = rtc_set_alarm(rtc, &alm); |
| 222 | 210 | return (retval < 0) ? retval : n; |
| 223 | 211 | } |
| 224 | −static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, | |
| 225 | − rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm); | |
| 212 | +static DEVICE_ATTR_RW(wakealarm); | |
| 226 | 213 | |
| 214 | +static struct attribute *rtc_attrs[] = { | |
| 215 | + &dev_attr_name.attr, | |
| 216 | + &dev_attr_date.attr, | |
| 217 | + &dev_attr_time.attr, | |
| 218 | + &dev_attr_since_epoch.attr, | |
| 219 | + &dev_attr_max_user_freq.attr, | |
| 220 | + &dev_attr_hctosys.attr, | |
| 221 | + &dev_attr_wakealarm.attr, | |
| 222 | + NULL, | |
| 223 | +}; | |
| 227 | 224 | |
| 228 | 225 | /* The reason to trigger an alarm with no process watching it (via sysfs) |
| 229 | 226 | * is its side effect: waking from a system state like suspend-to-RAM or |
| 230 | 227 | * suspend-to-disk. So: no attribute unless that side effect is possible. |
| 231 | 228 | * (Userspace may disable that mechanism later.) |
| 232 | 229 | */ |
| 233 | −static inline int rtc_does_wakealarm(struct rtc_device *rtc) | |
| 230 | +static bool rtc_does_wakealarm(struct rtc_device *rtc) | |
| 234 | 231 | { |
| 235 | 232 | if (!device_can_wakeup(rtc->dev.parent)) |
| 236 | − return 0; | |
| 233 | + return false; | |
| 234 | + | |
| 237 | 235 | return rtc->ops->set_alarm != NULL; |
| 238 | 236 | } |
| 239 | 237 | |
| 240 | − | |
| 241 | −void rtc_sysfs_add_device(struct rtc_device *rtc) | |
| 238 | +static umode_t rtc_attr_is_visible(struct kobject *kobj, | |
| 239 | + struct attribute *attr, int n) | |
| 242 | 240 | { |
| 243 | − int err; | |
| 241 | + struct device *dev = container_of(kobj, struct device, kobj); | |
| 242 | + struct rtc_device *rtc = to_rtc_device(dev); | |
| 243 | + umode_t mode = attr->mode; | |
| 244 | 244 | |
| 245 | − /* not all RTCs support both alarms and wakeup */ | |
| 246 | − if (!rtc_does_wakealarm(rtc)) | |
| 247 | − return; | |
| 245 | + if (attr == &dev_attr_wakealarm.attr) | |
| 246 | + if (!rtc_does_wakealarm(rtc)) | |
| 247 | + mode = 0; | |
| 248 | 248 | |
| 249 | − err = device_create_file(&rtc->dev, &dev_attr_wakealarm); | |
| 250 | − if (err) | |
| 251 | − dev_err(rtc->dev.parent, | |
| 252 | − "failed to create alarm attribute, %d\n", err); | |
| 249 | + return mode; | |
| 253 | 250 | } |
| 254 | 251 | |
| 255 | −void rtc_sysfs_del_device(struct rtc_device *rtc) | |
| 256 | −{ | |
| 257 | − /* REVISIT did we add it successfully? */ | |
| 258 | − if (rtc_does_wakealarm(rtc)) | |
| 259 | − device_remove_file(&rtc->dev, &dev_attr_wakealarm); | |
| 260 | −} | |
| 252 | +static struct attribute_group rtc_attr_group = { | |
| 253 | + .is_visible = rtc_attr_is_visible, | |
| 254 | + .attrs = rtc_attrs, | |
| 255 | +}; | |
| 256 | + | |
| 257 | +static const struct attribute_group *rtc_attr_groups[] = { | |
| 258 | + &rtc_attr_group, | |
| 259 | + NULL | |
| 260 | +}; | |
| 261 | 261 | |
| 262 | −void __init rtc_sysfs_init(struct class *rtc_class) | |
| 262 | +const struct attribute_group **rtc_get_dev_attribute_groups(void) | |
| 263 | 263 | { |
| 264 | − rtc_class->dev_groups = rtc_groups; | |
| 264 | + return rtc_attr_groups; | |
| 265 | 265 | } |
| @@ -199,8 +199,7 @@ static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, · 198 unmodified lines | ||
| 199 | 199 | ssize_t count; |
| 200 | 200 | |
| 201 | 201 | spin_lock_irq(&pdata->lock); |
| 202 | − for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; | |
| 203 | − count++, size--) { | |
| 202 | + for (count = 0; count < size; count++) { | |
| 204 | 203 | __raw_writel(pos++, &rtcreg->adr); |
| 205 | 204 | *buf++ = __raw_readl(&rtcreg->dat); |
| 206 | 205 | } |
| @@ -218,8 +217,7 @@ static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, · 11 unmodified lines | ||
| 218 | 217 | ssize_t count; |
| 219 | 218 | |
| 220 | 219 | spin_lock_irq(&pdata->lock); |
| 221 | − for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; | |
| 222 | − count++, size--) { | |
| 220 | + for (count = 0; count < size; count++) { | |
| 223 | 221 | __raw_writel(pos++, &rtcreg->adr); |
| 224 | 222 | __raw_writel(*buf++, &rtcreg->dat); |
| 225 | 223 | } |
| @@ -271,6 +271,7 @@ static const struct of_device_id wmt_dt_ids[] = { · 270 unmodified lines | ||
| 271 | 271 | { .compatible = "via,vt8500-rtc", }, |
| 272 | 272 | {} |
| 273 | 273 | }; |
| 274 | +MODULE_DEVICE_TABLE(of, wmt_dt_ids); | |
| 274 | 275 | |
| 275 | 276 | static struct platform_driver vt8500_rtc_driver = { |
| 276 | 277 | .probe = vt8500_rtc_probe, |
| @@ -0,0 +1,279 @@ | ||
| 1 | +/* | |
| 2 | + * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015 Xilinx, Inc. | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify it | |
| 7 | + * under the terms and conditions of the GNU General Public License, | |
| 8 | + * version 2, as published by the Free Software Foundation. | |
| 9 | + * | |
| 10 | + * This program is distributed in the hope it will be useful, but WITHOUT | |
| 11 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 12 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 13 | + * more details. | |
| 14 | + * | |
| 15 | + * You should have received a copy of the GNU General Public License along with | |
| 16 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
| 17 | + * | |
| 18 | + */ | |
| 19 | + | |
| 20 | +#include <linux/delay.h> | |
| 21 | +#include <linux/init.h> | |
| 22 | +#include <linux/io.h> | |
| 23 | +#include <linux/module.h> | |
| 24 | +#include <linux/of.h> | |
| 25 | +#include <linux/platform_device.h> | |
| 26 | +#include <linux/rtc.h> | |
| 27 | + | |
| 28 | +/* RTC Registers */ | |
| 29 | +#define RTC_SET_TM_WR 0x00 | |
| 30 | +#define RTC_SET_TM_RD 0x04 | |
| 31 | +#define RTC_CALIB_WR 0x08 | |
| 32 | +#define RTC_CALIB_RD 0x0C | |
| 33 | +#define RTC_CUR_TM 0x10 | |
| 34 | +#define RTC_CUR_TICK 0x14 | |
| 35 | +#define RTC_ALRM 0x18 | |
| 36 | +#define RTC_INT_STS 0x20 | |
| 37 | +#define RTC_INT_MASK 0x24 | |
| 38 | +#define RTC_INT_EN 0x28 | |
| 39 | +#define RTC_INT_DIS 0x2C | |
| 40 | +#define RTC_CTRL 0x40 | |
| 41 | + | |
| 42 | +#define RTC_FR_EN BIT(20) | |
| 43 | +#define RTC_FR_DATSHIFT 16 | |
| 44 | +#define RTC_TICK_MASK 0xFFFF | |
| 45 | +#define RTC_INT_SEC BIT(0) | |
| 46 | +#define RTC_INT_ALRM BIT(1) | |
| 47 | +#define RTC_OSC_EN BIT(24) | |
| 48 | + | |
| 49 | +#define RTC_CALIB_DEF 0x198233 | |
| 50 | +#define RTC_CALIB_MASK 0x1FFFFF | |
| 51 | +#define RTC_SEC_MAX_VAL 0xFFFFFFFF | |
| 52 | + | |
| 53 | +struct xlnx_rtc_dev { | |
| 54 | + struct rtc_device *rtc; | |
| 55 | + void __iomem *reg_base; | |
| 56 | + int alarm_irq; | |
| 57 | + int sec_irq; | |
| 58 | +}; | |
| 59 | + | |
| 60 | +static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm) | |
| 61 | +{ | |
| 62 | + struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); | |
| 63 | + unsigned long new_time; | |
| 64 | + | |
| 65 | + new_time = rtc_tm_to_time64(tm); | |
| 66 | + | |
| 67 | + if (new_time > RTC_SEC_MAX_VAL) | |
| 68 | + return -EINVAL; | |
| 69 | + | |
| 70 | + writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR); | |
| 71 | + | |
| 72 | + return 0; | |
| 73 | +} | |
| 74 | + | |
| 75 | +static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm) | |
| 76 | +{ | |
| 77 | + struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); | |
| 78 | + | |
| 79 | + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm); | |
| 80 | + | |
| 81 | + return rtc_valid_tm(tm); | |
| 82 | +} | |
| 83 | + | |
| 84 | +static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |
| 85 | +{ | |
| 86 | + struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); | |
| 87 | + | |
| 88 | + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time); | |
| 89 | + alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM; | |
| 90 | + | |
| 91 | + return 0; | |
| 92 | +} | |
| 93 | + | |
| 94 | +static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled) | |
| 95 | +{ | |
| 96 | + struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); | |
| 97 | + | |
| 98 | + if (enabled) | |
| 99 | + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN); | |
| 100 | + else | |
| 101 | + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS); | |
| 102 | + | |
| 103 | + return 0; | |
| 104 | +} | |
| 105 | + | |
| 106 | +static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |
| 107 | +{ | |
| 108 | + struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); | |
| 109 | + unsigned long alarm_time; | |
| 110 | + | |
| 111 | + alarm_time = rtc_tm_to_time64(&alrm->time); | |
| 112 | + | |
| 113 | + if (alarm_time > RTC_SEC_MAX_VAL) | |
| 114 | + return -EINVAL; | |
| 115 | + | |
| 116 | + writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM)); | |
| 117 | + | |
| 118 | + xlnx_rtc_alarm_irq_enable(dev, alrm->enabled); | |
| 119 | + | |
| 120 | + return 0; | |
| 121 | +} | |
| 122 | + | |
| 123 | +static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval) | |
| 124 | +{ | |
| 125 | + /* | |
| 126 | + * Based on crystal freq of 33.330 KHz | |
| 127 | + * set the seconds counter and enable, set fractions counter | |
| 128 | + * to default value suggested as per design spec | |
| 129 | + * to correct RTC delay in frequency over period of time. | |
| 130 | + */ | |
| 131 | + calibval &= RTC_CALIB_MASK; | |
| 132 | + writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); | |
| 133 | +} | |
| 134 | + | |
| 135 | +static const struct rtc_class_ops xlnx_rtc_ops = { | |
| 136 | + .set_time = xlnx_rtc_set_time, | |
| 137 | + .read_time = xlnx_rtc_read_time, | |
| 138 | + .read_alarm = xlnx_rtc_read_alarm, | |
| 139 | + .set_alarm = xlnx_rtc_set_alarm, | |
| 140 | + .alarm_irq_enable = xlnx_rtc_alarm_irq_enable, | |
| 141 | +}; | |
| 142 | + | |
| 143 | +static irqreturn_t xlnx_rtc_interrupt(int irq, void *id) | |
| 144 | +{ | |
| 145 | + struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id; | |
| 146 | + unsigned int status; | |
| 147 | + | |
| 148 | + status = readl(xrtcdev->reg_base + RTC_INT_STS); | |
| 149 | + /* Check if interrupt asserted */ | |
| 150 | + if (!(status & (RTC_INT_SEC | RTC_INT_ALRM))) | |
| 151 | + return IRQ_NONE; | |
| 152 | + | |
| 153 | + /* Clear interrupt */ | |
| 154 | + writel(status, xrtcdev->reg_base + RTC_INT_STS); | |
| 155 | + | |
| 156 | + if (status & RTC_INT_SEC) | |
| 157 | + rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF); | |
| 158 | + if (status & RTC_INT_ALRM) | |
| 159 | + rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF); | |
| 160 | + | |
| 161 | + return IRQ_HANDLED; | |
| 162 | +} | |
| 163 | + | |
| 164 | +static int xlnx_rtc_probe(struct platform_device *pdev) | |
| 165 | +{ | |
| 166 | + struct xlnx_rtc_dev *xrtcdev; | |
| 167 | + struct resource *res; | |
| 168 | + int ret; | |
| 169 | + unsigned int calibvalue; | |
| 170 | + | |
| 171 | + xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL); | |
| 172 | + if (!xrtcdev) | |
| 173 | + return -ENOMEM; | |
| 174 | + | |
| 175 | + platform_set_drvdata(pdev, xrtcdev); | |
| 176 | + | |
| 177 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 178 | + | |
| 179 | + xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res); | |
| 180 | + if (IS_ERR(xrtcdev->reg_base)) | |
| 181 | + return PTR_ERR(xrtcdev->reg_base); | |
| 182 | + | |
| 183 | + xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm"); | |
| 184 | + if (xrtcdev->alarm_irq < 0) { | |
| 185 | + dev_err(&pdev->dev, "no irq resource\n"); | |
| 186 | + return xrtcdev->alarm_irq; | |
| 187 | + } | |
| 188 | + ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq, | |
| 189 | + xlnx_rtc_interrupt, 0, | |
| 190 | + dev_name(&pdev->dev), xrtcdev); | |
| 191 | + if (ret) { | |
| 192 | + dev_err(&pdev->dev, "request irq failed\n"); | |
| 193 | + return ret; | |
| 194 | + } | |
| 195 | + | |
| 196 | + xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec"); | |
| 197 | + if (xrtcdev->sec_irq < 0) { | |
| 198 | + dev_err(&pdev->dev, "no irq resource\n"); | |
| 199 | + return xrtcdev->sec_irq; | |
| 200 | + } | |
| 201 | + ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq, | |
| 202 | + xlnx_rtc_interrupt, 0, | |
| 203 | + dev_name(&pdev->dev), xrtcdev); | |
| 204 | + if (ret) { | |
| 205 | + dev_err(&pdev->dev, "request irq failed\n"); | |
| 206 | + return ret; | |
| 207 | + } | |
| 208 | + | |
| 209 | + ret = of_property_read_u32(pdev->dev.of_node, "calibration", | |
| 210 | + &calibvalue); | |
| 211 | + if (ret) | |
| 212 | + calibvalue = RTC_CALIB_DEF; | |
| 213 | + | |
| 214 | + xlnx_init_rtc(xrtcdev, calibvalue); | |
| 215 | + | |
| 216 | + device_init_wakeup(&pdev->dev, 1); | |
| 217 | + | |
| 218 | + xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | |
| 219 | + &xlnx_rtc_ops, THIS_MODULE); | |
| 220 | + return PTR_ERR_OR_ZERO(xrtcdev->rtc); | |
| 221 | +} | |
| 222 | + | |
| 223 | +static int xlnx_rtc_remove(struct platform_device *pdev) | |
| 224 | +{ | |
| 225 | + xlnx_rtc_alarm_irq_enable(&pdev->dev, 0); | |
| 226 | + device_init_wakeup(&pdev->dev, 0); | |
| 227 | + | |
| 228 | + return 0; | |
| 229 | +} | |
| 230 | + | |
| 231 | +static int __maybe_unused xlnx_rtc_suspend(struct device *dev) | |
| 232 | +{ | |
| 233 | + struct platform_device *pdev = to_platform_device(dev); | |
| 234 | + struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev); | |
| 235 | + | |
| 236 | + if (device_may_wakeup(&pdev->dev)) | |
| 237 | + enable_irq_wake(xrtcdev->alarm_irq); | |
| 238 | + else | |
| 239 | + xlnx_rtc_alarm_irq_enable(dev, 0); | |
| 240 | + | |
| 241 | + return 0; | |
| 242 | +} | |
| 243 | + | |
| 244 | +static int __maybe_unused xlnx_rtc_resume(struct device *dev) | |
| 245 | +{ | |
| 246 | + struct platform_device *pdev = to_platform_device(dev); | |
| 247 | + struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev); | |
| 248 | + | |
| 249 | + if (device_may_wakeup(&pdev->dev)) | |
| 250 | + disable_irq_wake(xrtcdev->alarm_irq); | |
| 251 | + else | |
| 252 | + xlnx_rtc_alarm_irq_enable(dev, 1); | |
| 253 | + | |
| 254 | + return 0; | |
| 255 | +} | |
| 256 | + | |
| 257 | +static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend, xlnx_rtc_resume); | |
| 258 | + | |
| 259 | +static const struct of_device_id xlnx_rtc_of_match[] = { | |
| 260 | + {.compatible = "xlnx,zynqmp-rtc" }, | |
| 261 | + { } | |
| 262 | +}; | |
| 263 | +MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match); | |
| 264 | + | |
| 265 | +static struct platform_driver xlnx_rtc_driver = { | |
| 266 | + .probe = xlnx_rtc_probe, | |
| 267 | + .remove = xlnx_rtc_remove, | |
| 268 | + .driver = { | |
| 269 | + .name = KBUILD_MODNAME, | |
| 270 | + .pm = &xlnx_rtc_pm_ops, | |
| 271 | + .of_match_table = xlnx_rtc_of_match, | |
| 272 | + }, | |
| 273 | +}; | |
| 274 | + | |
| 275 | +module_platform_driver(xlnx_rtc_driver); | |
| 276 | + | |
| 277 | +MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver"); | |
| 278 | +MODULE_AUTHOR("Xilinx Inc."); | |
| 279 | +MODULE_LICENSE("GPL v2"); | |
| @@ -16,6 +16,9 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/rtc.h> |
| 17 | 17 | #include <linux/bcd.h> |
| 18 | 18 | #include <linux/delay.h> |
| 19 | +#ifdef CONFIG_ACPI | |
| 20 | +#include <linux/acpi.h> | |
| 21 | +#endif | |
| 19 | 22 | |
| 20 | 23 | #define RTC_PIE 0x40 /* periodic interrupt enable */ |
| 21 | 24 | #define RTC_AIE 0x20 /* alarm interrupt enable */ |
| @@ -46,6 +49,7 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) · 24 unmodified lines | ||
| 46 | 49 | { |
| 47 | 50 | unsigned char ctrl; |
| 48 | 51 | unsigned long flags; |
| 52 | + unsigned char century = 0; | |
| 49 | 53 | |
| 50 | 54 | #ifdef CONFIG_MACH_DECSTATION |
| 51 | 55 | unsigned int real_year; |
| @@ -78,6 +82,11 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) · 26 unmodified lines | ||
| 78 | 82 | time->tm_year = CMOS_READ(RTC_YEAR); |
| 79 | 83 | #ifdef CONFIG_MACH_DECSTATION |
| 80 | 84 | real_year = CMOS_READ(RTC_DEC_YEAR); |
| 85 | +#endif | |
| 86 | +#ifdef CONFIG_ACPI | |
| 87 | + if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && | |
| 88 | + acpi_gbl_FADT.century) | |
| 89 | + century = CMOS_READ(acpi_gbl_FADT.century); | |
| 81 | 90 | #endif |
| 82 | 91 | ctrl = CMOS_READ(RTC_CONTROL); |
| 83 | 92 | spin_unlock_irqrestore(&rtc_lock, flags); |
| @@ -90,12 +99,16 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) · 6 unmodified lines | ||
| 90 | 99 | time->tm_mday = bcd2bin(time->tm_mday); |
| 91 | 100 | time->tm_mon = bcd2bin(time->tm_mon); |
| 92 | 101 | time->tm_year = bcd2bin(time->tm_year); |
| 102 | + century = bcd2bin(century); | |
| 93 | 103 | } |
| 94 | 104 | |
| 95 | 105 | #ifdef CONFIG_MACH_DECSTATION |
| 96 | 106 | time->tm_year += real_year - 72; |
| 97 | 107 | #endif |
| 98 | 108 | |
| 109 | + if (century) | |
| 110 | + time->tm_year += (century - 19) * 100; | |
| 111 | + | |
| 99 | 112 | /* |
| 100 | 113 | * Account for differences between how the RTC uses the values |
| 101 | 114 | * and how they are defined in a struct rtc_time; |
| @@ -122,6 +135,7 @@ static inline int __set_rtc_time(struct rtc_time *time) · 20 unmodified lines | ||
| 122 | 135 | #ifdef CONFIG_MACH_DECSTATION |
| 123 | 136 | unsigned int real_yrs, leap_yr; |
| 124 | 137 | #endif |
| 138 | + unsigned char century = 0; | |
| 125 | 139 | |
| 126 | 140 | yrs = time->tm_year; |
| 127 | 141 | mon = time->tm_mon + 1; /* tm_mon starts at zero */ |
| @@ -150,6 +164,15 @@ static inline int __set_rtc_time(struct rtc_time *time) · 22 unmodified lines | ||
| 150 | 164 | yrs = 73; |
| 151 | 165 | } |
| 152 | 166 | #endif |
| 167 | + | |
| 168 | +#ifdef CONFIG_ACPI | |
| 169 | + if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && | |
| 170 | + acpi_gbl_FADT.century) { | |
| 171 | + century = (yrs + 1900) / 100; | |
| 172 | + yrs %= 100; | |
| 173 | + } | |
| 174 | +#endif | |
| 175 | + | |
| 153 | 176 | /* These limits and adjustments are independent of |
| 154 | 177 | * whether the chip is in binary mode or not. |
| 155 | 178 | */ |
| @@ -169,6 +192,7 @@ static inline int __set_rtc_time(struct rtc_time *time) · 13 unmodified lines | ||
| 169 | 192 | day = bin2bcd(day); |
| 170 | 193 | mon = bin2bcd(mon); |
| 171 | 194 | yrs = bin2bcd(yrs); |
| 195 | + century = bin2bcd(century); | |
| 172 | 196 | } |
| 173 | 197 | |
| 174 | 198 | save_control = CMOS_READ(RTC_CONTROL); |
| @@ -185,6 +209,11 @@ static inline int __set_rtc_time(struct rtc_time *time) · 10 unmodified lines | ||
| 185 | 209 | CMOS_WRITE(hrs, RTC_HOURS); |
| 186 | 210 | CMOS_WRITE(min, RTC_MINUTES); |
| 187 | 211 | CMOS_WRITE(sec, RTC_SECONDS); |
| 212 | +#ifdef CONFIG_ACPI | |
| 213 | + if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && | |
| 214 | + acpi_gbl_FADT.century) | |
| 215 | + CMOS_WRITE(century, acpi_gbl_FADT.century); | |
| 216 | +#endif | |
| 188 | 217 | |
| 189 | 218 | CMOS_WRITE(save_control, RTC_CONTROL); |
| 190 | 219 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); |