diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-08 18:57:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-08 18:57:47 -0400 |
commit | 8065be8d032f38da25b54bf077a05a30d9ce9f2a (patch) | |
tree | 32a7baf4b40e0240ab4b9dd6f2bbe6129929bb66 /drivers/rtc | |
parent | 27d438c56009e5ae632de36fe70985d1aab5e344 (diff) | |
parent | ecc265fe9e09e32a3573b2ba26e79b2099eb8bbb (diff) |
Merge branch 'akpm' (second patchbomb from Andrew Morton)
Merge more incoming from Andrew Morton:
"Two new syscalls:
memfd_create in "shm: add memfd_create() syscall"
kexec_file_load in "kexec: implementation of new syscall kexec_file_load"
And:
- Most (all?) of the rest of MM
- Lots of the usual misc bits
- fs/autofs4
- drivers/rtc
- fs/nilfs
- procfs
- fork.c, exec.c
- more in lib/
- rapidio
- Janitorial work in filesystems: fs/ufs, fs/reiserfs, fs/adfs,
fs/cramfs, fs/romfs, fs/qnx6.
- initrd/initramfs work
- "file sealing" and the memfd_create() syscall, in tmpfs
- add pci_zalloc_consistent, use it in lots of places
- MAINTAINERS maintenance
- kexec feature work"
* emailed patches from Andrew Morton <akpm@linux-foundation.org: (193 commits)
MAINTAINERS: update nomadik patterns
MAINTAINERS: update usb/gadget patterns
MAINTAINERS: update DMA BUFFER SHARING patterns
kexec: verify the signature of signed PE bzImage
kexec: support kexec/kdump on EFI systems
kexec: support for kexec on panic using new system call
kexec-bzImage64: support for loading bzImage using 64bit entry
kexec: load and relocate purgatory at kernel load time
purgatory: core purgatory functionality
purgatory/sha256: provide implementation of sha256 in purgaotory context
kexec: implementation of new syscall kexec_file_load
kexec: new syscall kexec_file_load() declaration
kexec: make kexec_segment user buffer pointer a union
resource: provide new functions to walk through resources
kexec: use common function for kimage_normal_alloc() and kimage_crash_alloc()
kexec: move segment verification code in a separate function
kexec: rename unusebale_pages to unusable_pages
kernel: build bin2c based on config option CONFIG_BUILD_BIN2C
bin2c: move bin2c in scripts/basic
shm: wait for pins to be released when sealing
...
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 29 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 5 | ||||
-rw-r--r-- | drivers/rtc/class.c | 16 | ||||
-rw-r--r-- | drivers/rtc/interface.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1343.c | 75 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1742.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-efi-platform.c | 31 | ||||
-rw-r--r-- | drivers/rtc/rtc-efi.c | 32 | ||||
-rw-r--r-- | drivers/rtc/rtc-isl12022.c | 12 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf85063.c | 204 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf8563.c | 231 | ||||
-rw-r--r-- | drivers/rtc/rtc-tps65910.c | 4 |
12 files changed, 591 insertions, 52 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 0754f5c7cb3b..a168e96142b9 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -373,6 +373,14 @@ config RTC_DRV_PCF8563 | |||
373 | This driver can also be built as a module. If so, the module | 373 | This driver can also be built as a module. If so, the module |
374 | will be called rtc-pcf8563. | 374 | will be called rtc-pcf8563. |
375 | 375 | ||
376 | config RTC_DRV_PCF85063 | ||
377 | tristate "nxp PCF85063" | ||
378 | help | ||
379 | If you say yes here you get support for the PCF85063 RTC chip | ||
380 | |||
381 | This driver can also be built as a module. If so, the module | ||
382 | will be called rtc-pcf85063. | ||
383 | |||
376 | config RTC_DRV_PCF8583 | 384 | config RTC_DRV_PCF8583 |
377 | tristate "Philips PCF8583" | 385 | tristate "Philips PCF8583" |
378 | help | 386 | help |
@@ -760,6 +768,15 @@ config RTC_DRV_DS1742 | |||
760 | This driver can also be built as a module. If so, the module | 768 | This driver can also be built as a module. If so, the module |
761 | will be called rtc-ds1742. | 769 | will be called rtc-ds1742. |
762 | 770 | ||
771 | config RTC_DRV_DS2404 | ||
772 | tristate "Maxim/Dallas DS2404" | ||
773 | help | ||
774 | If you say yes here you get support for the | ||
775 | Dallas DS2404 RTC chip. | ||
776 | |||
777 | This driver can also be built as a module. If so, the module | ||
778 | will be called rtc-ds2404. | ||
779 | |||
763 | config RTC_DRV_DA9052 | 780 | config RTC_DRV_DA9052 |
764 | tristate "Dialog DA9052/DA9053 RTC" | 781 | tristate "Dialog DA9052/DA9053 RTC" |
765 | depends on PMIC_DA9052 | 782 | depends on PMIC_DA9052 |
@@ -789,7 +806,7 @@ config RTC_DRV_DA9063 | |||
789 | 806 | ||
790 | config RTC_DRV_EFI | 807 | config RTC_DRV_EFI |
791 | tristate "EFI RTC" | 808 | tristate "EFI RTC" |
792 | depends on IA64 | 809 | depends on EFI |
793 | help | 810 | help |
794 | If you say yes here you will get support for the EFI | 811 | If you say yes here you will get support for the EFI |
795 | Real Time Clock. | 812 | Real Time Clock. |
@@ -873,15 +890,6 @@ config RTC_DRV_V3020 | |||
873 | This driver can also be built as a module. If so, the module | 890 | This driver can also be built as a module. If so, the module |
874 | will be called rtc-v3020. | 891 | will be called rtc-v3020. |
875 | 892 | ||
876 | config RTC_DRV_DS2404 | ||
877 | tristate "Dallas DS2404" | ||
878 | help | ||
879 | If you say yes here you get support for the | ||
880 | Dallas DS2404 RTC chip. | ||
881 | |||
882 | This driver can also be built as a module. If so, the module | ||
883 | will be called rtc-ds2404. | ||
884 | |||
885 | config RTC_DRV_WM831X | 893 | config RTC_DRV_WM831X |
886 | tristate "Wolfson Microelectronics WM831x RTC" | 894 | tristate "Wolfson Microelectronics WM831x RTC" |
887 | depends on MFD_WM831X | 895 | depends on MFD_WM831X |
@@ -1349,6 +1357,7 @@ config RTC_DRV_SIRFSOC | |||
1349 | 1357 | ||
1350 | config RTC_DRV_MOXART | 1358 | config RTC_DRV_MOXART |
1351 | tristate "MOXA ART RTC" | 1359 | tristate "MOXA ART RTC" |
1360 | depends on ARCH_MOXART || COMPILE_TEST | ||
1352 | help | 1361 | help |
1353 | If you say yes here you get support for the MOXA ART | 1362 | If you say yes here you get support for the MOXA ART |
1354 | RTC module. | 1363 | RTC module. |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 70347d041d10..56f061c7c815 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -10,6 +10,10 @@ obj-$(CONFIG_RTC_SYSTOHC) += systohc.o | |||
10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o |
11 | rtc-core-y := class.o interface.o | 11 | rtc-core-y := class.o interface.o |
12 | 12 | ||
13 | ifdef CONFIG_RTC_DRV_EFI | ||
14 | rtc-core-y += rtc-efi-platform.o | ||
15 | endif | ||
16 | |||
13 | rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o | 17 | rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o |
14 | rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o | 18 | rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o |
15 | rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | 19 | rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o |
@@ -93,6 +97,7 @@ obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o | |||
93 | obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o | 97 | obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o |
94 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o | 98 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o |
95 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 99 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
100 | obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o | ||
96 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 101 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
97 | obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o | 102 | obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o |
98 | obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o | 103 | obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 589351ef75d0..38e26be705be 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -53,6 +53,7 @@ static int rtc_suspend(struct device *dev) | |||
53 | struct rtc_device *rtc = to_rtc_device(dev); | 53 | struct rtc_device *rtc = to_rtc_device(dev); |
54 | struct rtc_time tm; | 54 | struct rtc_time tm; |
55 | struct timespec delta, delta_delta; | 55 | struct timespec delta, delta_delta; |
56 | int err; | ||
56 | 57 | ||
57 | if (has_persistent_clock()) | 58 | if (has_persistent_clock()) |
58 | return 0; | 59 | return 0; |
@@ -61,7 +62,12 @@ static int rtc_suspend(struct device *dev) | |||
61 | return 0; | 62 | return 0; |
62 | 63 | ||
63 | /* snapshot the current RTC and system time at suspend*/ | 64 | /* snapshot the current RTC and system time at suspend*/ |
64 | rtc_read_time(rtc, &tm); | 65 | err = rtc_read_time(rtc, &tm); |
66 | if (err < 0) { | ||
67 | pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev)); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
65 | getnstimeofday(&old_system); | 71 | getnstimeofday(&old_system); |
66 | rtc_tm_to_time(&tm, &old_rtc.tv_sec); | 72 | rtc_tm_to_time(&tm, &old_rtc.tv_sec); |
67 | 73 | ||
@@ -94,6 +100,7 @@ static int rtc_resume(struct device *dev) | |||
94 | struct rtc_time tm; | 100 | struct rtc_time tm; |
95 | struct timespec new_system, new_rtc; | 101 | struct timespec new_system, new_rtc; |
96 | struct timespec sleep_time; | 102 | struct timespec sleep_time; |
103 | int err; | ||
97 | 104 | ||
98 | if (has_persistent_clock()) | 105 | if (has_persistent_clock()) |
99 | return 0; | 106 | return 0; |
@@ -104,7 +111,12 @@ static int rtc_resume(struct device *dev) | |||
104 | 111 | ||
105 | /* snapshot the current rtc and system time at resume */ | 112 | /* snapshot the current rtc and system time at resume */ |
106 | getnstimeofday(&new_system); | 113 | getnstimeofday(&new_system); |
107 | rtc_read_time(rtc, &tm); | 114 | err = rtc_read_time(rtc, &tm); |
115 | if (err < 0) { | ||
116 | pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev)); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
108 | if (rtc_valid_tm(&tm) != 0) { | 120 | if (rtc_valid_tm(&tm) != 0) { |
109 | pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); | 121 | pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); |
110 | return 0; | 122 | return 0; |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 5813fa52c3d4..5b2717f5dafa 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -348,6 +348,8 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
348 | 348 | ||
349 | /* Make sure we're not setting alarms in the past */ | 349 | /* Make sure we're not setting alarms in the past */ |
350 | err = __rtc_read_time(rtc, &tm); | 350 | err = __rtc_read_time(rtc, &tm); |
351 | if (err) | ||
352 | return err; | ||
351 | rtc_tm_to_time(&tm, &now); | 353 | rtc_tm_to_time(&tm, &now); |
352 | if (scheduled <= now) | 354 | if (scheduled <= now) |
353 | return -ETIME; | 355 | return -ETIME; |
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index c3719189dd96..ae9f997223b1 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Real Time Clock | 4 | * Real Time Clock |
5 | * | 5 | * |
6 | * Author : Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com> | 6 | * Author : Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com> |
7 | * Ankur Srivastava <sankurece@gmail.com> : DS1343 Nvram Support | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -45,6 +46,9 @@ | |||
45 | #define DS1343_CONTROL_REG 0x0F | 46 | #define DS1343_CONTROL_REG 0x0F |
46 | #define DS1343_STATUS_REG 0x10 | 47 | #define DS1343_STATUS_REG 0x10 |
47 | #define DS1343_TRICKLE_REG 0x11 | 48 | #define DS1343_TRICKLE_REG 0x11 |
49 | #define DS1343_NVRAM 0x20 | ||
50 | |||
51 | #define DS1343_NVRAM_LEN 96 | ||
48 | 52 | ||
49 | /* DS1343 Control Registers bits */ | 53 | /* DS1343 Control Registers bits */ |
50 | #define DS1343_EOSC 0x80 | 54 | #define DS1343_EOSC 0x80 |
@@ -149,6 +153,64 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev, | |||
149 | static DEVICE_ATTR(glitch_filter, S_IRUGO | S_IWUSR, ds1343_show_glitchfilter, | 153 | static DEVICE_ATTR(glitch_filter, S_IRUGO | S_IWUSR, ds1343_show_glitchfilter, |
150 | ds1343_store_glitchfilter); | 154 | ds1343_store_glitchfilter); |
151 | 155 | ||
156 | static ssize_t ds1343_nvram_write(struct file *filp, struct kobject *kobj, | ||
157 | struct bin_attribute *attr, | ||
158 | char *buf, loff_t off, size_t count) | ||
159 | { | ||
160 | int ret; | ||
161 | unsigned char address; | ||
162 | struct device *dev = kobj_to_dev(kobj); | ||
163 | struct ds1343_priv *priv = dev_get_drvdata(dev); | ||
164 | |||
165 | if (unlikely(!count)) | ||
166 | return count; | ||
167 | |||
168 | if ((count + off) > DS1343_NVRAM_LEN) | ||
169 | count = DS1343_NVRAM_LEN - off; | ||
170 | |||
171 | address = DS1343_NVRAM + off; | ||
172 | |||
173 | ret = regmap_bulk_write(priv->map, address, buf, count); | ||
174 | if (ret < 0) | ||
175 | dev_err(&priv->spi->dev, "Error in nvram write %d", ret); | ||
176 | |||
177 | return (ret < 0) ? ret : count; | ||
178 | } | ||
179 | |||
180 | |||
181 | static ssize_t ds1343_nvram_read(struct file *filp, struct kobject *kobj, | ||
182 | struct bin_attribute *attr, | ||
183 | char *buf, loff_t off, size_t count) | ||
184 | { | ||
185 | int ret; | ||
186 | unsigned char address; | ||
187 | struct device *dev = kobj_to_dev(kobj); | ||
188 | struct ds1343_priv *priv = dev_get_drvdata(dev); | ||
189 | |||
190 | if (unlikely(!count)) | ||
191 | return count; | ||
192 | |||
193 | if ((count + off) > DS1343_NVRAM_LEN) | ||
194 | count = DS1343_NVRAM_LEN - off; | ||
195 | |||
196 | address = DS1343_NVRAM + off; | ||
197 | |||
198 | ret = regmap_bulk_read(priv->map, address, buf, count); | ||
199 | if (ret < 0) | ||
200 | dev_err(&priv->spi->dev, "Error in nvram read %d\n", ret); | ||
201 | |||
202 | return (ret < 0) ? ret : count; | ||
203 | } | ||
204 | |||
205 | |||
206 | static struct bin_attribute nvram_attr = { | ||
207 | .attr.name = "nvram", | ||
208 | .attr.mode = S_IRUGO | S_IWUSR, | ||
209 | .read = ds1343_nvram_read, | ||
210 | .write = ds1343_nvram_write, | ||
211 | .size = DS1343_NVRAM_LEN, | ||
212 | }; | ||
213 | |||
152 | static ssize_t ds1343_show_alarmstatus(struct device *dev, | 214 | static ssize_t ds1343_show_alarmstatus(struct device *dev, |
153 | struct device_attribute *attr, char *buf) | 215 | struct device_attribute *attr, char *buf) |
154 | { | 216 | { |
@@ -274,12 +336,16 @@ static int ds1343_sysfs_register(struct device *dev) | |||
274 | if (err) | 336 | if (err) |
275 | goto error1; | 337 | goto error1; |
276 | 338 | ||
339 | err = device_create_bin_file(dev, &nvram_attr); | ||
340 | if (err) | ||
341 | goto error2; | ||
342 | |||
277 | if (priv->irq <= 0) | 343 | if (priv->irq <= 0) |
278 | return err; | 344 | return err; |
279 | 345 | ||
280 | err = device_create_file(dev, &dev_attr_alarm_mode); | 346 | err = device_create_file(dev, &dev_attr_alarm_mode); |
281 | if (err) | 347 | if (err) |
282 | goto error2; | 348 | goto error3; |
283 | 349 | ||
284 | err = device_create_file(dev, &dev_attr_alarm_status); | 350 | err = device_create_file(dev, &dev_attr_alarm_status); |
285 | if (!err) | 351 | if (!err) |
@@ -287,6 +353,9 @@ static int ds1343_sysfs_register(struct device *dev) | |||
287 | 353 | ||
288 | device_remove_file(dev, &dev_attr_alarm_mode); | 354 | device_remove_file(dev, &dev_attr_alarm_mode); |
289 | 355 | ||
356 | error3: | ||
357 | device_remove_bin_file(dev, &nvram_attr); | ||
358 | |||
290 | error2: | 359 | error2: |
291 | device_remove_file(dev, &dev_attr_trickle_charger); | 360 | device_remove_file(dev, &dev_attr_trickle_charger); |
292 | 361 | ||
@@ -302,6 +371,7 @@ static void ds1343_sysfs_unregister(struct device *dev) | |||
302 | 371 | ||
303 | device_remove_file(dev, &dev_attr_glitch_filter); | 372 | device_remove_file(dev, &dev_attr_glitch_filter); |
304 | device_remove_file(dev, &dev_attr_trickle_charger); | 373 | device_remove_file(dev, &dev_attr_trickle_charger); |
374 | device_remove_bin_file(dev, &nvram_attr); | ||
305 | 375 | ||
306 | if (priv->irq <= 0) | 376 | if (priv->irq <= 0) |
307 | return; | 377 | return; |
@@ -684,6 +754,7 @@ static struct spi_driver ds1343_driver = { | |||
684 | module_spi_driver(ds1343_driver); | 754 | module_spi_driver(ds1343_driver); |
685 | 755 | ||
686 | MODULE_DESCRIPTION("DS1343 RTC SPI Driver"); | 756 | MODULE_DESCRIPTION("DS1343 RTC SPI Driver"); |
687 | MODULE_AUTHOR("Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>"); | 757 | MODULE_AUTHOR("Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>," |
758 | "Ankur Srivastava <sankurece@gmail.com>"); | ||
688 | MODULE_LICENSE("GPL v2"); | 759 | MODULE_LICENSE("GPL v2"); |
689 | MODULE_VERSION(DS1343_DRV_VERSION); | 760 | MODULE_VERSION(DS1343_DRV_VERSION); |
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index c6b2191a4128..9822715db8ba 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c | |||
@@ -231,7 +231,7 @@ static struct platform_driver ds1742_rtc_driver = { | |||
231 | .driver = { | 231 | .driver = { |
232 | .name = "rtc-ds1742", | 232 | .name = "rtc-ds1742", |
233 | .owner = THIS_MODULE, | 233 | .owner = THIS_MODULE, |
234 | .of_match_table = ds1742_rtc_of_match, | 234 | .of_match_table = of_match_ptr(ds1742_rtc_of_match), |
235 | }, | 235 | }, |
236 | }; | 236 | }; |
237 | 237 | ||
diff --git a/drivers/rtc/rtc-efi-platform.c b/drivers/rtc/rtc-efi-platform.c new file mode 100644 index 000000000000..b40fbe332af4 --- /dev/null +++ b/drivers/rtc/rtc-efi-platform.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * Moved from arch/ia64/kernel/time.c | ||
3 | * | ||
4 | * Copyright (C) 1998-2003 Hewlett-Packard Co | ||
5 | * Stephane Eranian <eranian@hpl.hp.com> | ||
6 | * David Mosberger <davidm@hpl.hp.com> | ||
7 | * Copyright (C) 1999 Don Dugger <don.dugger@intel.com> | ||
8 | * Copyright (C) 1999-2000 VA Linux Systems | ||
9 | * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com> | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/efi.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | |||
17 | static struct platform_device rtc_efi_dev = { | ||
18 | .name = "rtc-efi", | ||
19 | .id = -1, | ||
20 | }; | ||
21 | |||
22 | static int __init rtc_init(void) | ||
23 | { | ||
24 | if (efi_enabled(EFI_RUNTIME_SERVICES)) | ||
25 | if (platform_device_register(&rtc_efi_dev) < 0) | ||
26 | pr_err("unable to register rtc device...\n"); | ||
27 | |||
28 | /* not necessarily an error */ | ||
29 | return 0; | ||
30 | } | ||
31 | module_init(rtc_init); | ||
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index c4c38431012e..8225b89de810 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/stringify.h> | ||
20 | #include <linux/time.h> | 21 | #include <linux/time.h> |
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | #include <linux/rtc.h> | 23 | #include <linux/rtc.h> |
@@ -48,8 +49,8 @@ compute_wday(efi_time_t *eft) | |||
48 | int y; | 49 | int y; |
49 | int ndays = 0; | 50 | int ndays = 0; |
50 | 51 | ||
51 | if (eft->year < 1998) { | 52 | if (eft->year < EFI_RTC_EPOCH) { |
52 | pr_err("EFI year < 1998, invalid date\n"); | 53 | pr_err("EFI year < " __stringify(EFI_RTC_EPOCH) ", invalid date\n"); |
53 | return -1; | 54 | return -1; |
54 | } | 55 | } |
55 | 56 | ||
@@ -78,19 +79,36 @@ convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft) | |||
78 | eft->timezone = EFI_UNSPECIFIED_TIMEZONE; | 79 | eft->timezone = EFI_UNSPECIFIED_TIMEZONE; |
79 | } | 80 | } |
80 | 81 | ||
81 | static void | 82 | static bool |
82 | convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) | 83 | convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) |
83 | { | 84 | { |
84 | memset(wtime, 0, sizeof(*wtime)); | 85 | memset(wtime, 0, sizeof(*wtime)); |
86 | |||
87 | if (eft->second >= 60) | ||
88 | return false; | ||
85 | wtime->tm_sec = eft->second; | 89 | wtime->tm_sec = eft->second; |
90 | |||
91 | if (eft->minute >= 60) | ||
92 | return false; | ||
86 | wtime->tm_min = eft->minute; | 93 | wtime->tm_min = eft->minute; |
94 | |||
95 | if (eft->hour >= 24) | ||
96 | return false; | ||
87 | wtime->tm_hour = eft->hour; | 97 | wtime->tm_hour = eft->hour; |
98 | |||
99 | if (!eft->day || eft->day > 31) | ||
100 | return false; | ||
88 | wtime->tm_mday = eft->day; | 101 | wtime->tm_mday = eft->day; |
102 | |||
103 | if (!eft->month || eft->month > 12) | ||
104 | return false; | ||
89 | wtime->tm_mon = eft->month - 1; | 105 | wtime->tm_mon = eft->month - 1; |
90 | wtime->tm_year = eft->year - 1900; | 106 | wtime->tm_year = eft->year - 1900; |
91 | 107 | ||
92 | /* day of the week [0-6], Sunday=0 */ | 108 | /* day of the week [0-6], Sunday=0 */ |
93 | wtime->tm_wday = compute_wday(eft); | 109 | wtime->tm_wday = compute_wday(eft); |
110 | if (wtime->tm_wday < 0) | ||
111 | return false; | ||
94 | 112 | ||
95 | /* day in the year [1-365]*/ | 113 | /* day in the year [1-365]*/ |
96 | wtime->tm_yday = compute_yday(eft); | 114 | wtime->tm_yday = compute_yday(eft); |
@@ -106,6 +124,8 @@ convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) | |||
106 | default: | 124 | default: |
107 | wtime->tm_isdst = -1; | 125 | wtime->tm_isdst = -1; |
108 | } | 126 | } |
127 | |||
128 | return true; | ||
109 | } | 129 | } |
110 | 130 | ||
111 | static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | 131 | static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) |
@@ -122,7 +142,8 @@ static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
122 | if (status != EFI_SUCCESS) | 142 | if (status != EFI_SUCCESS) |
123 | return -EINVAL; | 143 | return -EINVAL; |
124 | 144 | ||
125 | convert_from_efi_time(&eft, &wkalrm->time); | 145 | if (!convert_from_efi_time(&eft, &wkalrm->time)) |
146 | return -EIO; | ||
126 | 147 | ||
127 | return rtc_valid_tm(&wkalrm->time); | 148 | return rtc_valid_tm(&wkalrm->time); |
128 | } | 149 | } |
@@ -163,7 +184,8 @@ static int efi_read_time(struct device *dev, struct rtc_time *tm) | |||
163 | return -EINVAL; | 184 | return -EINVAL; |
164 | } | 185 | } |
165 | 186 | ||
166 | convert_from_efi_time(&eft, tm); | 187 | if (!convert_from_efi_time(&eft, tm)) |
188 | return -EIO; | ||
167 | 189 | ||
168 | return rtc_valid_tm(tm); | 190 | return rtc_valid_tm(tm); |
169 | } | 191 | } |
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 03b891129428..aa55f081c505 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/of.h> | ||
21 | #include <linux/of_device.h> | ||
20 | 22 | ||
21 | #define DRV_VERSION "0.1" | 23 | #define DRV_VERSION "0.1" |
22 | 24 | ||
@@ -271,6 +273,13 @@ static int isl12022_probe(struct i2c_client *client, | |||
271 | return PTR_ERR_OR_ZERO(isl12022->rtc); | 273 | return PTR_ERR_OR_ZERO(isl12022->rtc); |
272 | } | 274 | } |
273 | 275 | ||
276 | #ifdef CONFIG_OF | ||
277 | static struct of_device_id isl12022_dt_match[] = { | ||
278 | { .compatible = "isl,isl12022" }, | ||
279 | { }, | ||
280 | }; | ||
281 | #endif | ||
282 | |||
274 | static const struct i2c_device_id isl12022_id[] = { | 283 | static const struct i2c_device_id isl12022_id[] = { |
275 | { "isl12022", 0 }, | 284 | { "isl12022", 0 }, |
276 | { } | 285 | { } |
@@ -280,6 +289,9 @@ MODULE_DEVICE_TABLE(i2c, isl12022_id); | |||
280 | static struct i2c_driver isl12022_driver = { | 289 | static struct i2c_driver isl12022_driver = { |
281 | .driver = { | 290 | .driver = { |
282 | .name = "rtc-isl12022", | 291 | .name = "rtc-isl12022", |
292 | #ifdef CONFIG_OF | ||
293 | .of_match_table = of_match_ptr(isl12022_dt_match), | ||
294 | #endif | ||
283 | }, | 295 | }, |
284 | .probe = isl12022_probe, | 296 | .probe = isl12022_probe, |
285 | .id_table = isl12022_id, | 297 | .id_table = isl12022_id, |
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c new file mode 100644 index 000000000000..6a12bf62c504 --- /dev/null +++ b/drivers/rtc/rtc-pcf85063.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * An I2C driver for the PCF85063 RTC | ||
3 | * Copyright 2014 Rose Technology | ||
4 | * | ||
5 | * Author: Søren Andersen <san@rosetechnology.dk> | ||
6 | * Maintainers: http://www.nslu2-linux.org/ | ||
7 | * | ||
8 | * based on the other drivers in this same directory. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/bcd.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/module.h> | ||
18 | |||
19 | #define DRV_VERSION "0.0.1" | ||
20 | |||
21 | #define PCF85063_REG_CTRL1 0x00 /* status */ | ||
22 | #define PCF85063_REG_CTRL2 0x01 | ||
23 | |||
24 | #define PCF85063_REG_SC 0x04 /* datetime */ | ||
25 | #define PCF85063_REG_MN 0x05 | ||
26 | #define PCF85063_REG_HR 0x06 | ||
27 | #define PCF85063_REG_DM 0x07 | ||
28 | #define PCF85063_REG_DW 0x08 | ||
29 | #define PCF85063_REG_MO 0x09 | ||
30 | #define PCF85063_REG_YR 0x0A | ||
31 | |||
32 | #define PCF85063_MO_C 0x80 /* century */ | ||
33 | |||
34 | static struct i2c_driver pcf85063_driver; | ||
35 | |||
36 | struct pcf85063 { | ||
37 | struct rtc_device *rtc; | ||
38 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ | ||
39 | int voltage_low; /* indicates if a low_voltage was detected */ | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * In the routines that deal directly with the pcf85063 hardware, we use | ||
44 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | ||
45 | */ | ||
46 | static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
47 | { | ||
48 | struct pcf85063 *pcf85063 = i2c_get_clientdata(client); | ||
49 | unsigned char buf[13] = { PCF85063_REG_CTRL1 }; | ||
50 | struct i2c_msg msgs[] = { | ||
51 | {/* setup read ptr */ | ||
52 | .addr = client->addr, | ||
53 | .len = 1, | ||
54 | .buf = buf | ||
55 | }, | ||
56 | {/* read status + date */ | ||
57 | .addr = client->addr, | ||
58 | .flags = I2C_M_RD, | ||
59 | .len = 13, | ||
60 | .buf = buf | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | /* read registers */ | ||
65 | if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { | ||
66 | dev_err(&client->dev, "%s: read error\n", __func__); | ||
67 | return -EIO; | ||
68 | } | ||
69 | |||
70 | tm->tm_sec = bcd2bin(buf[PCF85063_REG_SC] & 0x7F); | ||
71 | tm->tm_min = bcd2bin(buf[PCF85063_REG_MN] & 0x7F); | ||
72 | tm->tm_hour = bcd2bin(buf[PCF85063_REG_HR] & 0x3F); /* rtc hr 0-23 */ | ||
73 | tm->tm_mday = bcd2bin(buf[PCF85063_REG_DM] & 0x3F); | ||
74 | tm->tm_wday = buf[PCF85063_REG_DW] & 0x07; | ||
75 | tm->tm_mon = bcd2bin(buf[PCF85063_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ | ||
76 | tm->tm_year = bcd2bin(buf[PCF85063_REG_YR]); | ||
77 | if (tm->tm_year < 70) | ||
78 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | ||
79 | /* detect the polarity heuristically. see note above. */ | ||
80 | pcf85063->c_polarity = (buf[PCF85063_REG_MO] & PCF85063_MO_C) ? | ||
81 | (tm->tm_year >= 100) : (tm->tm_year < 100); | ||
82 | |||
83 | /* the clock can give out invalid datetime, but we cannot return | ||
84 | * -EINVAL otherwise hwclock will refuse to set the time on bootup. | ||
85 | */ | ||
86 | if (rtc_valid_tm(tm) < 0) | ||
87 | dev_err(&client->dev, "retrieved date/time is not valid.\n"); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
93 | { | ||
94 | int i = 0, err = 0; | ||
95 | unsigned char buf[11]; | ||
96 | |||
97 | /* Control & status */ | ||
98 | buf[PCF85063_REG_CTRL1] = 0; | ||
99 | buf[PCF85063_REG_CTRL2] = 5; | ||
100 | |||
101 | /* hours, minutes and seconds */ | ||
102 | buf[PCF85063_REG_SC] = bin2bcd(tm->tm_sec) & 0x7F; | ||
103 | |||
104 | buf[PCF85063_REG_MN] = bin2bcd(tm->tm_min); | ||
105 | buf[PCF85063_REG_HR] = bin2bcd(tm->tm_hour); | ||
106 | |||
107 | /* Day of month, 1 - 31 */ | ||
108 | buf[PCF85063_REG_DM] = bin2bcd(tm->tm_mday); | ||
109 | |||
110 | /* Day, 0 - 6 */ | ||
111 | buf[PCF85063_REG_DW] = tm->tm_wday & 0x07; | ||
112 | |||
113 | /* month, 1 - 12 */ | ||
114 | buf[PCF85063_REG_MO] = bin2bcd(tm->tm_mon + 1); | ||
115 | |||
116 | /* year and century */ | ||
117 | buf[PCF85063_REG_YR] = bin2bcd(tm->tm_year % 100); | ||
118 | |||
119 | /* write register's data */ | ||
120 | for (i = 0; i < sizeof(buf); i++) { | ||
121 | unsigned char data[2] = { i, buf[i] }; | ||
122 | |||
123 | err = i2c_master_send(client, data, sizeof(data)); | ||
124 | if (err != sizeof(data)) { | ||
125 | dev_err(&client->dev, "%s: err=%d addr=%02x, data=%02x\n", | ||
126 | __func__, err, data[0], data[1]); | ||
127 | return -EIO; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
135 | { | ||
136 | return pcf85063_get_datetime(to_i2c_client(dev), tm); | ||
137 | } | ||
138 | |||
139 | static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
140 | { | ||
141 | return pcf85063_set_datetime(to_i2c_client(dev), tm); | ||
142 | } | ||
143 | |||
144 | static const struct rtc_class_ops pcf85063_rtc_ops = { | ||
145 | .read_time = pcf85063_rtc_read_time, | ||
146 | .set_time = pcf85063_rtc_set_time | ||
147 | }; | ||
148 | |||
149 | static int pcf85063_probe(struct i2c_client *client, | ||
150 | const struct i2c_device_id *id) | ||
151 | { | ||
152 | struct pcf85063 *pcf85063; | ||
153 | |||
154 | dev_dbg(&client->dev, "%s\n", __func__); | ||
155 | |||
156 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
157 | return -ENODEV; | ||
158 | |||
159 | pcf85063 = devm_kzalloc(&client->dev, sizeof(struct pcf85063), | ||
160 | GFP_KERNEL); | ||
161 | if (!pcf85063) | ||
162 | return -ENOMEM; | ||
163 | |||
164 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); | ||
165 | |||
166 | i2c_set_clientdata(client, pcf85063); | ||
167 | |||
168 | pcf85063->rtc = devm_rtc_device_register(&client->dev, | ||
169 | pcf85063_driver.driver.name, | ||
170 | &pcf85063_rtc_ops, THIS_MODULE); | ||
171 | |||
172 | return PTR_ERR_OR_ZERO(pcf85063->rtc); | ||
173 | } | ||
174 | |||
175 | static const struct i2c_device_id pcf85063_id[] = { | ||
176 | { "pcf85063", 0 }, | ||
177 | { } | ||
178 | }; | ||
179 | MODULE_DEVICE_TABLE(i2c, pcf85063_id); | ||
180 | |||
181 | #ifdef CONFIG_OF | ||
182 | static const struct of_device_id pcf85063_of_match[] = { | ||
183 | { .compatible = "nxp,pcf85063" }, | ||
184 | {} | ||
185 | }; | ||
186 | MODULE_DEVICE_TABLE(of, pcf85063_of_match); | ||
187 | #endif | ||
188 | |||
189 | static struct i2c_driver pcf85063_driver = { | ||
190 | .driver = { | ||
191 | .name = "rtc-pcf85063", | ||
192 | .owner = THIS_MODULE, | ||
193 | .of_match_table = of_match_ptr(pcf85063_of_match), | ||
194 | }, | ||
195 | .probe = pcf85063_probe, | ||
196 | .id_table = pcf85063_id, | ||
197 | }; | ||
198 | |||
199 | module_i2c_driver(pcf85063_driver); | ||
200 | |||
201 | MODULE_AUTHOR("Søren Andersen <san@rosetechnology.dk>"); | ||
202 | MODULE_DESCRIPTION("PCF85063 RTC driver"); | ||
203 | MODULE_LICENSE("GPL"); | ||
204 | MODULE_VERSION(DRV_VERSION); | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 63b558c48196..5a197d9dc7e7 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -26,6 +26,8 @@ | |||
26 | 26 | ||
27 | #define PCF8563_REG_ST1 0x00 /* status */ | 27 | #define PCF8563_REG_ST1 0x00 /* status */ |
28 | #define PCF8563_REG_ST2 0x01 | 28 | #define PCF8563_REG_ST2 0x01 |
29 | #define PCF8563_BIT_AIE (1 << 1) | ||
30 | #define PCF8563_BIT_AF (1 << 3) | ||
29 | 31 | ||
30 | #define PCF8563_REG_SC 0x02 /* datetime */ | 32 | #define PCF8563_REG_SC 0x02 /* datetime */ |
31 | #define PCF8563_REG_MN 0x03 | 33 | #define PCF8563_REG_MN 0x03 |
@@ -36,9 +38,6 @@ | |||
36 | #define PCF8563_REG_YR 0x08 | 38 | #define PCF8563_REG_YR 0x08 |
37 | 39 | ||
38 | #define PCF8563_REG_AMN 0x09 /* alarm */ | 40 | #define PCF8563_REG_AMN 0x09 /* alarm */ |
39 | #define PCF8563_REG_AHR 0x0A | ||
40 | #define PCF8563_REG_ADM 0x0B | ||
41 | #define PCF8563_REG_ADW 0x0C | ||
42 | 41 | ||
43 | #define PCF8563_REG_CLKO 0x0D /* clock out */ | 42 | #define PCF8563_REG_CLKO 0x0D /* clock out */ |
44 | #define PCF8563_REG_TMRC 0x0E /* timer control */ | 43 | #define PCF8563_REG_TMRC 0x0E /* timer control */ |
@@ -67,37 +66,133 @@ struct pcf8563 { | |||
67 | */ | 66 | */ |
68 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ | 67 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ |
69 | int voltage_low; /* incicates if a low_voltage was detected */ | 68 | int voltage_low; /* incicates if a low_voltage was detected */ |
69 | |||
70 | struct i2c_client *client; | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | /* | 73 | static int pcf8563_read_block_data(struct i2c_client *client, unsigned char reg, |
73 | * In the routines that deal directly with the pcf8563 hardware, we use | 74 | unsigned char length, unsigned char *buf) |
74 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | ||
75 | */ | ||
76 | static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
77 | { | 75 | { |
78 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); | ||
79 | unsigned char buf[13] = { PCF8563_REG_ST1 }; | ||
80 | |||
81 | struct i2c_msg msgs[] = { | 76 | struct i2c_msg msgs[] = { |
82 | {/* setup read ptr */ | 77 | {/* setup read ptr */ |
83 | .addr = client->addr, | 78 | .addr = client->addr, |
84 | .len = 1, | 79 | .len = 1, |
85 | .buf = buf | 80 | .buf = ®, |
86 | }, | 81 | }, |
87 | {/* read status + date */ | 82 | { |
88 | .addr = client->addr, | 83 | .addr = client->addr, |
89 | .flags = I2C_M_RD, | 84 | .flags = I2C_M_RD, |
90 | .len = 13, | 85 | .len = length, |
91 | .buf = buf | 86 | .buf = buf |
92 | }, | 87 | }, |
93 | }; | 88 | }; |
94 | 89 | ||
95 | /* read registers */ | ||
96 | if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { | 90 | if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { |
97 | dev_err(&client->dev, "%s: read error\n", __func__); | 91 | dev_err(&client->dev, "%s: read error\n", __func__); |
98 | return -EIO; | 92 | return -EIO; |
99 | } | 93 | } |
100 | 94 | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int pcf8563_write_block_data(struct i2c_client *client, | ||
99 | unsigned char reg, unsigned char length, | ||
100 | unsigned char *buf) | ||
101 | { | ||
102 | int i, err; | ||
103 | |||
104 | for (i = 0; i < length; i++) { | ||
105 | unsigned char data[2] = { reg + i, buf[i] }; | ||
106 | |||
107 | err = i2c_master_send(client, data, sizeof(data)); | ||
108 | if (err != sizeof(data)) { | ||
109 | dev_err(&client->dev, | ||
110 | "%s: err=%d addr=%02x, data=%02x\n", | ||
111 | __func__, err, data[0], data[1]); | ||
112 | return -EIO; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int pcf8563_set_alarm_mode(struct i2c_client *client, bool on) | ||
120 | { | ||
121 | unsigned char buf[2]; | ||
122 | int err; | ||
123 | |||
124 | err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, buf + 1); | ||
125 | if (err < 0) | ||
126 | return err; | ||
127 | |||
128 | if (on) | ||
129 | buf[1] |= PCF8563_BIT_AIE; | ||
130 | else | ||
131 | buf[1] &= ~PCF8563_BIT_AIE; | ||
132 | |||
133 | buf[1] &= ~PCF8563_BIT_AF; | ||
134 | buf[0] = PCF8563_REG_ST2; | ||
135 | |||
136 | err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, buf + 1); | ||
137 | if (err < 0) { | ||
138 | dev_err(&client->dev, "%s: write error\n", __func__); | ||
139 | return -EIO; | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int pcf8563_get_alarm_mode(struct i2c_client *client, unsigned char *en, | ||
146 | unsigned char *pen) | ||
147 | { | ||
148 | unsigned char buf; | ||
149 | int err; | ||
150 | |||
151 | err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, &buf); | ||
152 | if (err) | ||
153 | return err; | ||
154 | |||
155 | if (en) | ||
156 | *en = !!(buf & PCF8563_BIT_AIE); | ||
157 | if (pen) | ||
158 | *pen = !!(buf & PCF8563_BIT_AF); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static irqreturn_t pcf8563_irq(int irq, void *dev_id) | ||
164 | { | ||
165 | struct pcf8563 *pcf8563 = i2c_get_clientdata(dev_id); | ||
166 | int err; | ||
167 | char pending; | ||
168 | |||
169 | err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending); | ||
170 | if (err < 0) | ||
171 | return err; | ||
172 | |||
173 | if (pending) { | ||
174 | rtc_update_irq(pcf8563->rtc, 1, RTC_IRQF | RTC_AF); | ||
175 | pcf8563_set_alarm_mode(pcf8563->client, 1); | ||
176 | return IRQ_HANDLED; | ||
177 | } | ||
178 | |||
179 | return IRQ_NONE; | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * In the routines that deal directly with the pcf8563 hardware, we use | ||
184 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | ||
185 | */ | ||
186 | static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
187 | { | ||
188 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); | ||
189 | unsigned char buf[9]; | ||
190 | int err; | ||
191 | |||
192 | err = pcf8563_read_block_data(client, PCF8563_REG_ST1, 9, buf); | ||
193 | if (err) | ||
194 | return err; | ||
195 | |||
101 | if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { | 196 | if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { |
102 | pcf8563->voltage_low = 1; | 197 | pcf8563->voltage_low = 1; |
103 | dev_info(&client->dev, | 198 | dev_info(&client->dev, |
@@ -144,7 +239,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
144 | static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | 239 | static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
145 | { | 240 | { |
146 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); | 241 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); |
147 | int i, err; | 242 | int err; |
148 | unsigned char buf[9]; | 243 | unsigned char buf[9]; |
149 | 244 | ||
150 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " | 245 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " |
@@ -170,19 +265,10 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
170 | 265 | ||
171 | buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; | 266 | buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; |
172 | 267 | ||
173 | /* write register's data */ | 268 | err = pcf8563_write_block_data(client, PCF8563_REG_SC, |
174 | for (i = 0; i < 7; i++) { | 269 | 9 - PCF8563_REG_SC, buf + PCF8563_REG_SC); |
175 | unsigned char data[2] = { PCF8563_REG_SC + i, | 270 | if (err) |
176 | buf[PCF8563_REG_SC + i] }; | 271 | return err; |
177 | |||
178 | err = i2c_master_send(client, data, sizeof(data)); | ||
179 | if (err != sizeof(data)) { | ||
180 | dev_err(&client->dev, | ||
181 | "%s: err=%d addr=%02x, data=%02x\n", | ||
182 | __func__, err, data[0], data[1]); | ||
183 | return -EIO; | ||
184 | } | ||
185 | } | ||
186 | 272 | ||
187 | return 0; | 273 | return 0; |
188 | } | 274 | } |
@@ -235,16 +321,83 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
235 | return pcf8563_set_datetime(to_i2c_client(dev), tm); | 321 | return pcf8563_set_datetime(to_i2c_client(dev), tm); |
236 | } | 322 | } |
237 | 323 | ||
324 | static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) | ||
325 | { | ||
326 | struct i2c_client *client = to_i2c_client(dev); | ||
327 | unsigned char buf[4]; | ||
328 | int err; | ||
329 | |||
330 | err = pcf8563_read_block_data(client, PCF8563_REG_AMN, 4, buf); | ||
331 | if (err) | ||
332 | return err; | ||
333 | |||
334 | dev_dbg(&client->dev, | ||
335 | "%s: raw data is min=%02x, hr=%02x, mday=%02x, wday=%02x\n", | ||
336 | __func__, buf[0], buf[1], buf[2], buf[3]); | ||
337 | |||
338 | tm->time.tm_min = bcd2bin(buf[0] & 0x7F); | ||
339 | tm->time.tm_hour = bcd2bin(buf[1] & 0x7F); | ||
340 | tm->time.tm_mday = bcd2bin(buf[2] & 0x1F); | ||
341 | tm->time.tm_wday = bcd2bin(buf[3] & 0x7); | ||
342 | tm->time.tm_mon = -1; | ||
343 | tm->time.tm_year = -1; | ||
344 | tm->time.tm_yday = -1; | ||
345 | tm->time.tm_isdst = -1; | ||
346 | |||
347 | err = pcf8563_get_alarm_mode(client, &tm->enabled, &tm->pending); | ||
348 | if (err < 0) | ||
349 | return err; | ||
350 | |||
351 | dev_dbg(&client->dev, "%s: tm is mins=%d, hours=%d, mday=%d, wday=%d," | ||
352 | " enabled=%d, pending=%d\n", __func__, tm->time.tm_min, | ||
353 | tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_wday, | ||
354 | tm->enabled, tm->pending); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) | ||
360 | { | ||
361 | struct i2c_client *client = to_i2c_client(dev); | ||
362 | unsigned char buf[4]; | ||
363 | int err; | ||
364 | |||
365 | dev_dbg(dev, "%s, min=%d hour=%d wday=%d mday=%d " | ||
366 | "enabled=%d pending=%d\n", __func__, | ||
367 | tm->time.tm_min, tm->time.tm_hour, tm->time.tm_wday, | ||
368 | tm->time.tm_mday, tm->enabled, tm->pending); | ||
369 | |||
370 | buf[0] = bin2bcd(tm->time.tm_min); | ||
371 | buf[1] = bin2bcd(tm->time.tm_hour); | ||
372 | buf[2] = bin2bcd(tm->time.tm_mday); | ||
373 | buf[3] = tm->time.tm_wday & 0x07; | ||
374 | |||
375 | err = pcf8563_write_block_data(client, PCF8563_REG_AMN, 4, buf); | ||
376 | if (err) | ||
377 | return err; | ||
378 | |||
379 | return pcf8563_set_alarm_mode(client, 1); | ||
380 | } | ||
381 | |||
382 | static int pcf8563_irq_enable(struct device *dev, unsigned int enabled) | ||
383 | { | ||
384 | return pcf8563_set_alarm_mode(to_i2c_client(dev), !!enabled); | ||
385 | } | ||
386 | |||
238 | static const struct rtc_class_ops pcf8563_rtc_ops = { | 387 | static const struct rtc_class_ops pcf8563_rtc_ops = { |
239 | .ioctl = pcf8563_rtc_ioctl, | 388 | .ioctl = pcf8563_rtc_ioctl, |
240 | .read_time = pcf8563_rtc_read_time, | 389 | .read_time = pcf8563_rtc_read_time, |
241 | .set_time = pcf8563_rtc_set_time, | 390 | .set_time = pcf8563_rtc_set_time, |
391 | .read_alarm = pcf8563_rtc_read_alarm, | ||
392 | .set_alarm = pcf8563_rtc_set_alarm, | ||
393 | .alarm_irq_enable = pcf8563_irq_enable, | ||
242 | }; | 394 | }; |
243 | 395 | ||
244 | static int pcf8563_probe(struct i2c_client *client, | 396 | static int pcf8563_probe(struct i2c_client *client, |
245 | const struct i2c_device_id *id) | 397 | const struct i2c_device_id *id) |
246 | { | 398 | { |
247 | struct pcf8563 *pcf8563; | 399 | struct pcf8563 *pcf8563; |
400 | int err; | ||
248 | 401 | ||
249 | dev_dbg(&client->dev, "%s\n", __func__); | 402 | dev_dbg(&client->dev, "%s\n", __func__); |
250 | 403 | ||
@@ -259,12 +412,30 @@ static int pcf8563_probe(struct i2c_client *client, | |||
259 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); | 412 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); |
260 | 413 | ||
261 | i2c_set_clientdata(client, pcf8563); | 414 | i2c_set_clientdata(client, pcf8563); |
415 | pcf8563->client = client; | ||
416 | device_set_wakeup_capable(&client->dev, 1); | ||
262 | 417 | ||
263 | pcf8563->rtc = devm_rtc_device_register(&client->dev, | 418 | pcf8563->rtc = devm_rtc_device_register(&client->dev, |
264 | pcf8563_driver.driver.name, | 419 | pcf8563_driver.driver.name, |
265 | &pcf8563_rtc_ops, THIS_MODULE); | 420 | &pcf8563_rtc_ops, THIS_MODULE); |
266 | 421 | ||
267 | return PTR_ERR_OR_ZERO(pcf8563->rtc); | 422 | if (IS_ERR(pcf8563->rtc)) |
423 | return PTR_ERR(pcf8563->rtc); | ||
424 | |||
425 | if (client->irq > 0) { | ||
426 | err = devm_request_threaded_irq(&client->dev, client->irq, | ||
427 | NULL, pcf8563_irq, | ||
428 | IRQF_SHARED|IRQF_ONESHOT|IRQF_TRIGGER_FALLING, | ||
429 | pcf8563->rtc->name, client); | ||
430 | if (err) { | ||
431 | dev_err(&client->dev, "unable to request IRQ %d\n", | ||
432 | client->irq); | ||
433 | return err; | ||
434 | } | ||
435 | |||
436 | } | ||
437 | |||
438 | return 0; | ||
268 | } | 439 | } |
269 | 440 | ||
270 | static const struct i2c_device_id pcf8563_id[] = { | 441 | static const struct i2c_device_id pcf8563_id[] = { |
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index 7af00208d637..2583349fbde5 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c | |||
@@ -258,6 +258,8 @@ static int tps65910_rtc_probe(struct platform_device *pdev) | |||
258 | if (ret < 0) | 258 | if (ret < 0) |
259 | return ret; | 259 | return ret; |
260 | 260 | ||
261 | platform_set_drvdata(pdev, tps_rtc); | ||
262 | |||
261 | irq = platform_get_irq(pdev, 0); | 263 | irq = platform_get_irq(pdev, 0); |
262 | if (irq <= 0) { | 264 | if (irq <= 0) { |
263 | dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", | 265 | dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", |
@@ -283,8 +285,6 @@ static int tps65910_rtc_probe(struct platform_device *pdev) | |||
283 | return ret; | 285 | return ret; |
284 | } | 286 | } |
285 | 287 | ||
286 | platform_set_drvdata(pdev, tps_rtc); | ||
287 | |||
288 | return 0; | 288 | return 0; |
289 | } | 289 | } |
290 | 290 | ||