diff options
Diffstat (limited to 'drivers/rtc')
47 files changed, 3171 insertions, 250 deletions
| diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 923a9da9c829..79fbe3832dfc 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -20,14 +20,24 @@ if RTC_CLASS | |||
| 20 | config RTC_HCTOSYS | 20 | config RTC_HCTOSYS | 
| 21 | bool "Set system time from RTC on startup and resume" | 21 | bool "Set system time from RTC on startup and resume" | 
| 22 | default y | 22 | default y | 
| 23 | depends on !ALWAYS_USE_PERSISTENT_CLOCK | ||
| 23 | help | 24 | help | 
| 24 | If you say yes here, the system time (wall clock) will be set using | 25 | If you say yes here, the system time (wall clock) will be set using | 
| 25 | the value read from a specified RTC device. This is useful to avoid | 26 | the value read from a specified RTC device. This is useful to avoid | 
| 26 | unnecessary fsck runs at boot time, and to network better. | 27 | unnecessary fsck runs at boot time, and to network better. | 
| 27 | 28 | ||
| 29 | config RTC_SYSTOHC | ||
| 30 | bool "Set the RTC time based on NTP synchronization" | ||
| 31 | default y | ||
| 32 | depends on !ALWAYS_USE_PERSISTENT_CLOCK | ||
| 33 | help | ||
| 34 | If you say yes here, the system time (wall clock) will be stored | ||
| 35 | in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11 | ||
| 36 | minutes if userspace reports synchronized NTP status. | ||
| 37 | |||
| 28 | config RTC_HCTOSYS_DEVICE | 38 | config RTC_HCTOSYS_DEVICE | 
| 29 | string "RTC used to set the system time" | 39 | string "RTC used to set the system time" | 
| 30 | depends on RTC_HCTOSYS = y | 40 | depends on RTC_HCTOSYS = y || RTC_SYSTOHC = y | 
| 31 | default "rtc0" | 41 | default "rtc0" | 
| 32 | help | 42 | help | 
| 33 | The RTC device that will be used to (re)initialize the system | 43 | The RTC device that will be used to (re)initialize the system | 
| @@ -194,6 +204,12 @@ config RTC_DRV_DS3232 | |||
| 194 | This driver can also be built as a module. If so, the module | 204 | This driver can also be built as a module. If so, the module | 
| 195 | will be called rtc-ds3232. | 205 | will be called rtc-ds3232. | 
| 196 | 206 | ||
| 207 | config RTC_DRV_LP8788 | ||
| 208 | tristate "TI LP8788 RTC driver" | ||
| 209 | depends on MFD_LP8788 | ||
| 210 | help | ||
| 211 | Say Y to enable support for the LP8788 RTC/ALARM driver. | ||
| 212 | |||
| 197 | config RTC_DRV_MAX6900 | 213 | config RTC_DRV_MAX6900 | 
| 198 | tristate "Maxim MAX6900" | 214 | tristate "Maxim MAX6900" | 
| 199 | help | 215 | help | 
| @@ -233,6 +249,26 @@ config RTC_DRV_MAX8998 | |||
| 233 | This driver can also be built as a module. If so, the module | 249 | This driver can also be built as a module. If so, the module | 
| 234 | will be called rtc-max8998. | 250 | will be called rtc-max8998. | 
| 235 | 251 | ||
| 252 | config RTC_DRV_MAX8997 | ||
| 253 | tristate "Maxim MAX8997" | ||
| 254 | depends on MFD_MAX8997 | ||
| 255 | help | ||
| 256 | If you say yes here you will get support for the | ||
| 257 | RTC of Maxim MAX8997 PMIC. | ||
| 258 | |||
| 259 | This driver can also be built as a module. If so, the module | ||
| 260 | will be called rtc-max8997. | ||
| 261 | |||
| 262 | config RTC_DRV_MAX77686 | ||
| 263 | tristate "Maxim MAX77686" | ||
| 264 | depends on MFD_MAX77686 | ||
| 265 | help | ||
| 266 | If you say yes here you will get support for the | ||
| 267 | RTC of Maxim MAX77686 PMIC. | ||
| 268 | |||
| 269 | This driver can also be built as a module. If so, the module | ||
| 270 | will be called rtc-max77686. | ||
| 271 | |||
| 236 | config RTC_DRV_RS5C372 | 272 | config RTC_DRV_RS5C372 | 
| 237 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" | 273 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" | 
| 238 | help | 274 | help | 
| @@ -269,6 +305,16 @@ config RTC_DRV_X1205 | |||
| 269 | This driver can also be built as a module. If so, the module | 305 | This driver can also be built as a module. If so, the module | 
| 270 | will be called rtc-x1205. | 306 | will be called rtc-x1205. | 
| 271 | 307 | ||
| 308 | config RTC_DRV_PALMAS | ||
| 309 | tristate "TI Palmas RTC driver" | ||
| 310 | depends on MFD_PALMAS | ||
| 311 | help | ||
| 312 | If you say yes here you get support for the RTC of TI PALMA series PMIC | ||
| 313 | chips. | ||
| 314 | |||
| 315 | This driver can also be built as a module. If so, the module | ||
| 316 | will be called rtc-palma. | ||
| 317 | |||
| 272 | config RTC_DRV_PCF8523 | 318 | config RTC_DRV_PCF8523 | 
| 273 | tristate "NXP PCF8523" | 319 | tristate "NXP PCF8523" | 
| 274 | help | 320 | help | 
| @@ -370,6 +416,14 @@ config RTC_DRV_TPS65910 | |||
| 370 | This driver can also be built as a module. If so, the module | 416 | This driver can also be built as a module. If so, the module | 
| 371 | will be called rtc-tps65910. | 417 | will be called rtc-tps65910. | 
| 372 | 418 | ||
| 419 | config RTC_DRV_TPS80031 | ||
| 420 | tristate "TI TPS80031/TPS80032 RTC driver" | ||
| 421 | depends on MFD_TPS80031 | ||
| 422 | help | ||
| 423 | TI Power Managment IC TPS80031 supports RTC functionality | ||
| 424 | along with alarm. This driver supports the RTC driver for | ||
| 425 | the TPS80031 RTC module. | ||
| 426 | |||
| 373 | config RTC_DRV_RC5T583 | 427 | config RTC_DRV_RC5T583 | 
| 374 | tristate "RICOH 5T583 RTC driver" | 428 | tristate "RICOH 5T583 RTC driver" | 
| 375 | depends on MFD_RC5T583 | 429 | depends on MFD_RC5T583 | 
| @@ -527,6 +581,14 @@ config RTC_DRV_PCF2123 | |||
| 527 | This driver can also be built as a module. If so, the module | 581 | This driver can also be built as a module. If so, the module | 
| 528 | will be called rtc-pcf2123. | 582 | will be called rtc-pcf2123. | 
| 529 | 583 | ||
| 584 | config RTC_DRV_RX4581 | ||
| 585 | tristate "Epson RX-4581" | ||
| 586 | help | ||
| 587 | If you say yes here you will get support for the Epson RX-4581. | ||
| 588 | |||
| 589 | This driver can also be built as a module. If so the module | ||
| 590 | will be called rtc-rx4581. | ||
| 591 | |||
| 530 | endif # SPI_MASTER | 592 | endif # SPI_MASTER | 
| 531 | 593 | ||
| 532 | comment "Platform RTC drivers" | 594 | comment "Platform RTC drivers" | 
| @@ -1023,7 +1085,7 @@ config RTC_DRV_TX4939 | |||
| 1023 | 1085 | ||
| 1024 | config RTC_DRV_MV | 1086 | config RTC_DRV_MV | 
| 1025 | tristate "Marvell SoC RTC" | 1087 | tristate "Marvell SoC RTC" | 
| 1026 | depends on ARCH_KIRKWOOD || ARCH_DOVE | 1088 | depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU | 
| 1027 | help | 1089 | help | 
| 1028 | If you say yes here you will get support for the in-chip RTC | 1090 | If you say yes here you will get support for the in-chip RTC | 
| 1029 | that can be found in some of Marvell's SoC devices, such as | 1091 | that can be found in some of Marvell's SoC devices, such as | 
| @@ -1173,4 +1235,20 @@ config RTC_DRV_SNVS | |||
| 1173 | This driver can also be built as a module, if so, the module | 1235 | This driver can also be built as a module, if so, the module | 
| 1174 | will be called "rtc-snvs". | 1236 | will be called "rtc-snvs". | 
| 1175 | 1237 | ||
| 1238 | comment "HID Sensor RTC drivers" | ||
| 1239 | |||
| 1240 | config RTC_DRV_HID_SENSOR_TIME | ||
| 1241 | tristate "HID Sensor Time" | ||
| 1242 | depends on USB_HID | ||
| 1243 | select IIO | ||
| 1244 | select HID_SENSOR_HUB | ||
| 1245 | select HID_SENSOR_IIO_COMMON | ||
| 1246 | help | ||
| 1247 | Say yes here to build support for the HID Sensors of type Time. | ||
| 1248 | This drivers makes such sensors available as RTCs. | ||
| 1249 | |||
| 1250 | If this driver is compiled as a module, it will be named | ||
| 1251 | rtc-hid-sensor-time. | ||
| 1252 | |||
| 1253 | |||
| 1176 | endif # RTC_CLASS | 1254 | endif # RTC_CLASS | 
| diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 4418ef3f9ecc..c33f86f1a69b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -6,6 +6,7 @@ ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG | |||
| 6 | 6 | ||
| 7 | obj-$(CONFIG_RTC_LIB) += rtc-lib.o | 7 | obj-$(CONFIG_RTC_LIB) += rtc-lib.o | 
| 8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | 8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | 
| 9 | obj-$(CONFIG_RTC_SYSTOHC) += systohc.o | ||
| 9 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 
| 10 | rtc-core-y := class.o interface.o | 11 | rtc-core-y := class.o interface.o | 
| 11 | 12 | ||
| @@ -52,10 +53,12 @@ obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o | |||
| 52 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 53 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 
| 53 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | 54 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | 
| 54 | obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o | 55 | obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o | 
| 56 | obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o | ||
| 55 | obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o | 57 | obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o | 
| 56 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 58 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 
| 57 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o | 59 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o | 
| 58 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o | 60 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o | 
| 61 | obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o | ||
| 59 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o | 62 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o | 
| 60 | obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o | 63 | obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o | 
| 61 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 64 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 
| @@ -69,13 +72,16 @@ obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | |||
| 69 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o | 72 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o | 
| 70 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 73 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 
| 71 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | 74 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | 
| 75 | obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o | ||
| 72 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 76 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 
| 77 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o | ||
| 73 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o | 78 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o | 
| 74 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 79 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 
| 75 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o | 80 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o | 
| 76 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | 81 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | 
| 77 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o | 82 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o | 
| 78 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 83 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 
| 84 | obj-$(CONFIG_RTC_DRV_PALMAS) += rtc-palmas.o | ||
| 79 | obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o | 85 | obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o | 
| 80 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o | 86 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o | 
| 81 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 87 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 
| @@ -95,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | |||
| 95 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 101 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 
| 96 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 102 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 
| 97 | obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o | 103 | obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o | 
| 104 | obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o | ||
| 98 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o | 105 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o | 
| 99 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o | 106 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o | 
| 100 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | 107 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | 
| @@ -113,6 +120,7 @@ obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o | |||
| 113 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | 120 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | 
| 114 | obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o | 121 | obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o | 
| 115 | obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o | 122 | obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o | 
| 123 | obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o | ||
| 116 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | 124 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | 
| 117 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 125 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 
| 118 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 126 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 
| diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 5143629dedbd..9b742d3ffb94 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. | 
| 12 | */ | 12 | */ | 
| 13 | 13 | ||
| 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 15 | |||
| 14 | #include <linux/module.h> | 16 | #include <linux/module.h> | 
| 15 | #include <linux/rtc.h> | 17 | #include <linux/rtc.h> | 
| 16 | #include <linux/kdev_t.h> | 18 | #include <linux/kdev_t.h> | 
| @@ -50,6 +52,10 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) | |||
| 50 | struct rtc_device *rtc = to_rtc_device(dev); | 52 | struct rtc_device *rtc = to_rtc_device(dev); | 
| 51 | struct rtc_time tm; | 53 | struct rtc_time tm; | 
| 52 | struct timespec delta, delta_delta; | 54 | struct timespec delta, delta_delta; | 
| 55 | |||
| 56 | if (has_persistent_clock()) | ||
| 57 | return 0; | ||
| 58 | |||
| 53 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 59 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 
| 54 | return 0; | 60 | return 0; | 
| 55 | 61 | ||
| @@ -88,6 +94,9 @@ static int rtc_resume(struct device *dev) | |||
| 88 | struct timespec new_system, new_rtc; | 94 | struct timespec new_system, new_rtc; | 
| 89 | struct timespec sleep_time; | 95 | struct timespec sleep_time; | 
| 90 | 96 | ||
| 97 | if (has_persistent_clock()) | ||
| 98 | return 0; | ||
| 99 | |||
| 91 | rtc_hctosys_ret = -ENODEV; | 100 | rtc_hctosys_ret = -ENODEV; | 
| 92 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 101 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 
| 93 | return 0; | 102 | return 0; | 
| @@ -254,7 +263,7 @@ static int __init rtc_init(void) | |||
| 254 | { | 263 | { | 
| 255 | rtc_class = class_create(THIS_MODULE, "rtc"); | 264 | rtc_class = class_create(THIS_MODULE, "rtc"); | 
| 256 | if (IS_ERR(rtc_class)) { | 265 | if (IS_ERR(rtc_class)) { | 
| 257 | printk(KERN_ERR "%s: couldn't create class\n", __FILE__); | 266 | pr_err("couldn't create class\n"); | 
| 258 | return PTR_ERR(rtc_class); | 267 | return PTR_ERR(rtc_class); | 
| 259 | } | 268 | } | 
| 260 | rtc_class->suspend = rtc_suspend; | 269 | rtc_class->suspend = rtc_suspend; | 
| diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9592b936b71b..42bd57da239d 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
| @@ -587,16 +587,16 @@ void rtc_update_irq(struct rtc_device *rtc, | |||
| 587 | } | 587 | } | 
| 588 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 588 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 
| 589 | 589 | ||
| 590 | static int __rtc_match(struct device *dev, void *data) | 590 | static int __rtc_match(struct device *dev, const void *data) | 
| 591 | { | 591 | { | 
| 592 | char *name = (char *)data; | 592 | const char *name = data; | 
| 593 | 593 | ||
| 594 | if (strcmp(dev_name(dev), name) == 0) | 594 | if (strcmp(dev_name(dev), name) == 0) | 
| 595 | return 1; | 595 | return 1; | 
| 596 | return 0; | 596 | return 0; | 
| 597 | } | 597 | } | 
| 598 | 598 | ||
| 599 | struct rtc_device *rtc_class_open(char *name) | 599 | struct rtc_device *rtc_class_open(const char *name) | 
| 600 | { | 600 | { | 
| 601 | struct device *dev; | 601 | struct device *dev; | 
| 602 | struct rtc_device *rtc = NULL; | 602 | struct rtc_device *rtc = NULL; | 
| diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index b6469e2cae89..434ebc3a99dc 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
| @@ -86,7 +86,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) | |||
| 86 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | 86 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | 
| 87 | tm->tm_year = tm->tm_year - 1900; | 87 | tm->tm_year = tm->tm_year - 1900; | 
| 88 | 88 | ||
| 89 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 89 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 
| 90 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 90 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 
| 91 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 91 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 
| 92 | 92 | ||
| @@ -100,7 +100,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
| 100 | { | 100 | { | 
| 101 | unsigned long cr; | 101 | unsigned long cr; | 
| 102 | 102 | ||
| 103 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 103 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 
| 104 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 104 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 
| 105 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 105 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 
| 106 | 106 | ||
| @@ -145,7 +145,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 145 | alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) | 145 | alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) | 
| 146 | ? 1 : 0; | 146 | ? 1 : 0; | 
| 147 | 147 | ||
| 148 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 148 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 
| 149 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 149 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 
| 150 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 150 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 
| 151 | 151 | ||
| @@ -183,7 +183,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 183 | at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); | 183 | at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); | 
| 184 | } | 184 | } | 
| 185 | 185 | ||
| 186 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 186 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 
| 187 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, | 187 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, | 
| 188 | tm.tm_min, tm.tm_sec); | 188 | tm.tm_min, tm.tm_sec); | 
| 189 | 189 | ||
| @@ -192,7 +192,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 192 | 192 | ||
| 193 | static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 193 | static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 
| 194 | { | 194 | { | 
| 195 | pr_debug("%s(): cmd=%08x\n", __func__, enabled); | 195 | dev_dbg(dev, "%s(): cmd=%08x\n", __func__, enabled); | 
| 196 | 196 | ||
| 197 | if (enabled) { | 197 | if (enabled) { | 
| 198 | at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | 198 | at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | 
| @@ -240,7 +240,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
| 240 | 240 | ||
| 241 | rtc_update_irq(rtc, 1, events); | 241 | rtc_update_irq(rtc, 1, events); | 
| 242 | 242 | ||
| 243 | pr_debug("%s(): num=%ld, events=0x%02lx\n", __func__, | 243 | dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", __func__, | 
| 244 | events >> 8, events & 0x000000FF); | 244 | events >> 8, events & 0x000000FF); | 
| 245 | 245 | ||
| 246 | return IRQ_HANDLED; | 246 | return IRQ_HANDLED; | 
| @@ -296,8 +296,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
| 296 | IRQF_SHARED, | 296 | IRQF_SHARED, | 
| 297 | "at91_rtc", pdev); | 297 | "at91_rtc", pdev); | 
| 298 | if (ret) { | 298 | if (ret) { | 
| 299 | printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", | 299 | dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); | 
| 300 | irq); | ||
| 301 | return ret; | 300 | return ret; | 
| 302 | } | 301 | } | 
| 303 | 302 | ||
| @@ -315,7 +314,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
| 315 | } | 314 | } | 
| 316 | platform_set_drvdata(pdev, rtc); | 315 | platform_set_drvdata(pdev, rtc); | 
| 317 | 316 | ||
| 318 | printk(KERN_INFO "AT91 Real Time Clock driver.\n"); | 317 | dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); | 
| 319 | return 0; | 318 | return 0; | 
| 320 | } | 319 | } | 
| 321 | 320 | ||
| diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 16630aa87f45..af97c94e8a3a 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
| @@ -706,7 +706,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 706 | rtc_cmos_int_handler = hpet_rtc_interrupt; | 706 | rtc_cmos_int_handler = hpet_rtc_interrupt; | 
| 707 | err = hpet_register_irq_handler(cmos_interrupt); | 707 | err = hpet_register_irq_handler(cmos_interrupt); | 
| 708 | if (err != 0) { | 708 | if (err != 0) { | 
| 709 | printk(KERN_WARNING "hpet_register_irq_handler " | 709 | dev_warn(dev, "hpet_register_irq_handler " | 
| 710 | " failed in rtc_init()."); | 710 | " failed in rtc_init()."); | 
| 711 | goto cleanup1; | 711 | goto cleanup1; | 
| 712 | } | 712 | } | 
| @@ -731,8 +731,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 731 | goto cleanup2; | 731 | goto cleanup2; | 
| 732 | } | 732 | } | 
| 733 | 733 | ||
| 734 | pr_info("%s: %s%s, %zd bytes nvram%s\n", | 734 | dev_info(dev, "%s%s, %zd bytes nvram%s\n", | 
| 735 | dev_name(&cmos_rtc.rtc->dev), | ||
| 736 | !is_valid_irq(rtc_irq) ? "no alarms" : | 735 | !is_valid_irq(rtc_irq) ? "no alarms" : | 
| 737 | cmos_rtc.mon_alrm ? "alarms up to one year" : | 736 | cmos_rtc.mon_alrm ? "alarms up to one year" : | 
| 738 | cmos_rtc.day_alrm ? "alarms up to one month" : | 737 | cmos_rtc.day_alrm ? "alarms up to one month" : | 
| @@ -820,8 +819,7 @@ static int cmos_suspend(struct device *dev) | |||
| 820 | enable_irq_wake(cmos->irq); | 819 | enable_irq_wake(cmos->irq); | 
| 821 | } | 820 | } | 
| 822 | 821 | ||
| 823 | pr_debug("%s: suspend%s, ctrl %02x\n", | 822 | dev_dbg(dev, "suspend%s, ctrl %02x\n", | 
| 824 | dev_name(&cmos_rtc.rtc->dev), | ||
| 825 | (tmp & RTC_AIE) ? ", alarm may wake" : "", | 823 | (tmp & RTC_AIE) ? ", alarm may wake" : "", | 
| 826 | tmp); | 824 | tmp); | 
| 827 | 825 | ||
| @@ -876,9 +874,7 @@ static int cmos_resume(struct device *dev) | |||
| 876 | spin_unlock_irq(&rtc_lock); | 874 | spin_unlock_irq(&rtc_lock); | 
| 877 | } | 875 | } | 
| 878 | 876 | ||
| 879 | pr_debug("%s: resume, ctrl %02x\n", | 877 | dev_dbg(dev, "resume, ctrl %02x\n", tmp); | 
| 880 | dev_name(&cmos_rtc.rtc->dev), | ||
| 881 | tmp); | ||
| 882 | 878 | ||
| 883 | return 0; | 879 | return 0; | 
| 884 | } | 880 | } | 
| @@ -1098,7 +1094,6 @@ static __init void cmos_of_init(struct platform_device *pdev) | |||
| 1098 | } | 1094 | } | 
| 1099 | #else | 1095 | #else | 
| 1100 | static inline void cmos_of_init(struct platform_device *pdev) {} | 1096 | static inline void cmos_of_init(struct platform_device *pdev) {} | 
| 1101 | #define of_cmos_match NULL | ||
| 1102 | #endif | 1097 | #endif | 
| 1103 | /*----------------------------------------------------------------*/ | 1098 | /*----------------------------------------------------------------*/ | 
| 1104 | 1099 | ||
| @@ -1140,7 +1135,7 @@ static struct platform_driver cmos_platform_driver = { | |||
| 1140 | #ifdef CONFIG_PM | 1135 | #ifdef CONFIG_PM | 
| 1141 | .pm = &cmos_pm_ops, | 1136 | .pm = &cmos_pm_ops, | 
| 1142 | #endif | 1137 | #endif | 
| 1143 | .of_match_table = of_cmos_match, | 1138 | .of_match_table = of_match_ptr(of_cmos_match), | 
| 1144 | } | 1139 | } | 
| 1145 | }; | 1140 | }; | 
| 1146 | 1141 | ||
| diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index c8115b83e5ab..2d28ec1aa1cd 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c | |||
| @@ -157,7 +157,6 @@ static int __exit coh901331_remove(struct platform_device *pdev) | |||
| 157 | if (rtap) { | 157 | if (rtap) { | 
| 158 | rtc_device_unregister(rtap->rtc); | 158 | rtc_device_unregister(rtap->rtc); | 
| 159 | clk_unprepare(rtap->clk); | 159 | clk_unprepare(rtap->clk); | 
| 160 | clk_put(rtap->clk); | ||
| 161 | platform_set_drvdata(pdev, NULL); | 160 | platform_set_drvdata(pdev, NULL); | 
| 162 | } | 161 | } | 
| 163 | 162 | ||
| @@ -196,7 +195,7 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
| 196 | "RTC COH 901 331 Alarm", rtap)) | 195 | "RTC COH 901 331 Alarm", rtap)) | 
| 197 | return -EIO; | 196 | return -EIO; | 
| 198 | 197 | ||
| 199 | rtap->clk = clk_get(&pdev->dev, NULL); | 198 | rtap->clk = devm_clk_get(&pdev->dev, NULL); | 
| 200 | if (IS_ERR(rtap->clk)) { | 199 | if (IS_ERR(rtap->clk)) { | 
| 201 | ret = PTR_ERR(rtap->clk); | 200 | ret = PTR_ERR(rtap->clk); | 
| 202 | dev_err(&pdev->dev, "could not get clock\n"); | 201 | dev_err(&pdev->dev, "could not get clock\n"); | 
| @@ -207,7 +206,7 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
| 207 | ret = clk_prepare_enable(rtap->clk); | 206 | ret = clk_prepare_enable(rtap->clk); | 
| 208 | if (ret) { | 207 | if (ret) { | 
| 209 | dev_err(&pdev->dev, "could not enable clock\n"); | 208 | dev_err(&pdev->dev, "could not enable clock\n"); | 
| 210 | goto out_no_clk_prepenable; | 209 | return ret; | 
| 211 | } | 210 | } | 
| 212 | clk_disable(rtap->clk); | 211 | clk_disable(rtap->clk); | 
| 213 | 212 | ||
| @@ -224,8 +223,6 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
| 224 | out_no_rtc: | 223 | out_no_rtc: | 
| 225 | platform_set_drvdata(pdev, NULL); | 224 | platform_set_drvdata(pdev, NULL); | 
| 226 | clk_unprepare(rtap->clk); | 225 | clk_unprepare(rtap->clk); | 
| 227 | out_no_clk_prepenable: | ||
| 228 | clk_put(rtap->clk); | ||
| 229 | return ret; | 226 | return ret; | 
| 230 | } | 227 | } | 
| 231 | 228 | ||
| diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 60b826e520e2..0dde688ca09b 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c | |||
| @@ -240,9 +240,10 @@ static int da9052_rtc_probe(struct platform_device *pdev) | |||
| 240 | rtc->da9052 = dev_get_drvdata(pdev->dev.parent); | 240 | rtc->da9052 = dev_get_drvdata(pdev->dev.parent); | 
| 241 | platform_set_drvdata(pdev, rtc); | 241 | platform_set_drvdata(pdev, rtc); | 
| 242 | rtc->irq = platform_get_irq_byname(pdev, "ALM"); | 242 | rtc->irq = platform_get_irq_byname(pdev, "ALM"); | 
| 243 | ret = request_threaded_irq(rtc->irq, NULL, da9052_rtc_irq, | 243 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | 
| 244 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 244 | da9052_rtc_irq, | 
| 245 | "ALM", rtc); | 245 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 
| 246 | "ALM", rtc); | ||
| 246 | if (ret != 0) { | 247 | if (ret != 0) { | 
| 247 | rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); | 248 | rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); | 
| 248 | return ret; | 249 | return ret; | 
| @@ -250,16 +251,10 @@ static int da9052_rtc_probe(struct platform_device *pdev) | |||
| 250 | 251 | ||
| 251 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 252 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 
| 252 | &da9052_rtc_ops, THIS_MODULE); | 253 | &da9052_rtc_ops, THIS_MODULE); | 
| 253 | if (IS_ERR(rtc->rtc)) { | 254 | if (IS_ERR(rtc->rtc)) | 
| 254 | ret = PTR_ERR(rtc->rtc); | 255 | return PTR_ERR(rtc->rtc); | 
| 255 | goto err_free_irq; | ||
| 256 | } | ||
| 257 | 256 | ||
| 258 | return 0; | 257 | return 0; | 
| 259 | |||
| 260 | err_free_irq: | ||
| 261 | free_irq(rtc->irq, rtc); | ||
| 262 | return ret; | ||
| 263 | } | 258 | } | 
| 264 | 259 | ||
| 265 | static int da9052_rtc_remove(struct platform_device *pdev) | 260 | static int da9052_rtc_remove(struct platform_device *pdev) | 
| @@ -267,7 +262,6 @@ static int da9052_rtc_remove(struct platform_device *pdev) | |||
| 267 | struct da9052_rtc *rtc = pdev->dev.platform_data; | 262 | struct da9052_rtc *rtc = pdev->dev.platform_data; | 
| 268 | 263 | ||
| 269 | rtc_device_unregister(rtc->rtc); | 264 | rtc_device_unregister(rtc->rtc); | 
| 270 | free_irq(rtc->irq, rtc); | ||
| 271 | platform_set_drvdata(pdev, NULL); | 265 | platform_set_drvdata(pdev, NULL); | 
| 272 | 266 | ||
| 273 | return 0; | 267 | return 0; | 
| diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 5f7982f7c1b5..56b73089bb29 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c | |||
| @@ -506,19 +506,19 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
| 506 | davinci_rtc->pbase = res->start; | 506 | davinci_rtc->pbase = res->start; | 
| 507 | davinci_rtc->base_size = resource_size(res); | 507 | davinci_rtc->base_size = resource_size(res); | 
| 508 | 508 | ||
| 509 | mem = request_mem_region(davinci_rtc->pbase, davinci_rtc->base_size, | 509 | mem = devm_request_mem_region(dev, davinci_rtc->pbase, | 
| 510 | pdev->name); | 510 | davinci_rtc->base_size, pdev->name); | 
| 511 | if (!mem) { | 511 | if (!mem) { | 
| 512 | dev_err(dev, "RTC registers at %08x are not free\n", | 512 | dev_err(dev, "RTC registers at %08x are not free\n", | 
| 513 | davinci_rtc->pbase); | 513 | davinci_rtc->pbase); | 
| 514 | return -EBUSY; | 514 | return -EBUSY; | 
| 515 | } | 515 | } | 
| 516 | 516 | ||
| 517 | davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size); | 517 | davinci_rtc->base = devm_ioremap(dev, davinci_rtc->pbase, | 
| 518 | davinci_rtc->base_size); | ||
| 518 | if (!davinci_rtc->base) { | 519 | if (!davinci_rtc->base) { | 
| 519 | dev_err(dev, "unable to ioremap MEM resource\n"); | 520 | dev_err(dev, "unable to ioremap MEM resource\n"); | 
| 520 | ret = -ENOMEM; | 521 | return -ENOMEM; | 
| 521 | goto fail2; | ||
| 522 | } | 522 | } | 
| 523 | 523 | ||
| 524 | platform_set_drvdata(pdev, davinci_rtc); | 524 | platform_set_drvdata(pdev, davinci_rtc); | 
| @@ -529,7 +529,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
| 529 | ret = PTR_ERR(davinci_rtc->rtc); | 529 | ret = PTR_ERR(davinci_rtc->rtc); | 
| 530 | dev_err(dev, "unable to register RTC device, err %d\n", | 530 | dev_err(dev, "unable to register RTC device, err %d\n", | 
| 531 | ret); | 531 | ret); | 
| 532 | goto fail3; | 532 | goto fail1; | 
| 533 | } | 533 | } | 
| 534 | 534 | ||
| 535 | rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); | 535 | rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); | 
| @@ -539,11 +539,11 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
| 539 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL); | 539 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL); | 
| 540 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); | 540 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); | 
| 541 | 541 | ||
| 542 | ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt, | 542 | ret = devm_request_irq(dev, davinci_rtc->irq, davinci_rtc_interrupt, | 
| 543 | 0, "davinci_rtc", davinci_rtc); | 543 | 0, "davinci_rtc", davinci_rtc); | 
| 544 | if (ret < 0) { | 544 | if (ret < 0) { | 
| 545 | dev_err(dev, "unable to register davinci RTC interrupt\n"); | 545 | dev_err(dev, "unable to register davinci RTC interrupt\n"); | 
| 546 | goto fail4; | 546 | goto fail2; | 
| 547 | } | 547 | } | 
| 548 | 548 | ||
| 549 | /* Enable interrupts */ | 549 | /* Enable interrupts */ | 
| @@ -557,13 +557,10 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
| 557 | 557 | ||
| 558 | return 0; | 558 | return 0; | 
| 559 | 559 | ||
| 560 | fail4: | 560 | fail2: | 
| 561 | rtc_device_unregister(davinci_rtc->rtc); | 561 | rtc_device_unregister(davinci_rtc->rtc); | 
| 562 | fail3: | 562 | fail1: | 
| 563 | platform_set_drvdata(pdev, NULL); | 563 | platform_set_drvdata(pdev, NULL); | 
| 564 | iounmap(davinci_rtc->base); | ||
| 565 | fail2: | ||
| 566 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | ||
| 567 | return ret; | 564 | return ret; | 
| 568 | } | 565 | } | 
| 569 | 566 | ||
| @@ -575,13 +572,8 @@ static int davinci_rtc_remove(struct platform_device *pdev) | |||
| 575 | 572 | ||
| 576 | rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); | 573 | rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); | 
| 577 | 574 | ||
| 578 | free_irq(davinci_rtc->irq, davinci_rtc); | ||
| 579 | |||
| 580 | rtc_device_unregister(davinci_rtc->rtc); | 575 | rtc_device_unregister(davinci_rtc->rtc); | 
| 581 | 576 | ||
| 582 | iounmap(davinci_rtc->base); | ||
| 583 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | ||
| 584 | |||
| 585 | platform_set_drvdata(pdev, NULL); | 577 | platform_set_drvdata(pdev, NULL); | 
| 586 | 578 | ||
| 587 | return 0; | 579 | return 0; | 
| diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 9a86b4bd8699..d04939369251 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. | 
| 12 | */ | 12 | */ | 
| 13 | 13 | ||
| 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 15 | |||
| 14 | #include <linux/module.h> | 16 | #include <linux/module.h> | 
| 15 | #include <linux/rtc.h> | 17 | #include <linux/rtc.h> | 
| 16 | #include <linux/sched.h> | 18 | #include <linux/sched.h> | 
| @@ -462,7 +464,7 @@ void rtc_dev_prepare(struct rtc_device *rtc) | |||
| 462 | return; | 464 | return; | 
| 463 | 465 | ||
| 464 | if (rtc->id >= RTC_DEV_MAX) { | 466 | if (rtc->id >= RTC_DEV_MAX) { | 
| 465 | pr_debug("%s: too many RTC devices\n", rtc->name); | 467 | dev_dbg(&rtc->dev, "%s: too many RTC devices\n", rtc->name); | 
| 466 | return; | 468 | return; | 
| 467 | } | 469 | } | 
| 468 | 470 | ||
| @@ -480,10 +482,10 @@ void rtc_dev_prepare(struct rtc_device *rtc) | |||
| 480 | void rtc_dev_add_device(struct rtc_device *rtc) | 482 | void rtc_dev_add_device(struct rtc_device *rtc) | 
| 481 | { | 483 | { | 
| 482 | if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1)) | 484 | if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1)) | 
| 483 | printk(KERN_WARNING "%s: failed to add char device %d:%d\n", | 485 | dev_warn(&rtc->dev, "%s: failed to add char device %d:%d\n", | 
| 484 | rtc->name, MAJOR(rtc_devt), rtc->id); | 486 | rtc->name, MAJOR(rtc_devt), rtc->id); | 
| 485 | else | 487 | else | 
| 486 | pr_debug("%s: dev (%d:%d)\n", rtc->name, | 488 | dev_dbg(&rtc->dev, "%s: dev (%d:%d)\n", rtc->name, | 
| 487 | MAJOR(rtc_devt), rtc->id); | 489 | MAJOR(rtc_devt), rtc->id); | 
| 488 | } | 490 | } | 
| 489 | 491 | ||
| @@ -499,8 +501,7 @@ void __init rtc_dev_init(void) | |||
| 499 | 501 | ||
| 500 | err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); | 502 | err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); | 
| 501 | if (err < 0) | 503 | if (err < 0) | 
| 502 | printk(KERN_ERR "%s: failed to allocate char dev region\n", | 504 | pr_err("failed to allocate char dev region\n"); | 
| 503 | __FILE__); | ||
| 504 | } | 505 | } | 
| 505 | 506 | ||
| 506 | void __exit rtc_dev_exit(void) | 507 | void __exit rtc_dev_exit(void) | 
| diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index d578773f5ce2..b05a6dc96405 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
| @@ -635,9 +635,7 @@ static int ds1305_probe(struct spi_device *spi) | |||
| 635 | goto fail0; | 635 | goto fail0; | 
| 636 | } | 636 | } | 
| 637 | 637 | ||
| 638 | dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", | 638 | dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "read", ds1305->ctrl); | 
| 639 | "read", ds1305->ctrl[0], | ||
| 640 | ds1305->ctrl[1], ds1305->ctrl[2]); | ||
| 641 | 639 | ||
| 642 | /* Sanity check register values ... partially compensating for the | 640 | /* Sanity check register values ... partially compensating for the | 
| 643 | * fact that SPI has no device handshake. A pullup on MISO would | 641 | * fact that SPI has no device handshake. A pullup on MISO would | 
| @@ -723,9 +721,7 @@ static int ds1305_probe(struct spi_device *spi) | |||
| 723 | goto fail0; | 721 | goto fail0; | 
| 724 | } | 722 | } | 
| 725 | 723 | ||
| 726 | dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", | 724 | dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "write", ds1305->ctrl); | 
| 727 | "write", ds1305->ctrl[0], | ||
| 728 | ds1305->ctrl[1], ds1305->ctrl[2]); | ||
| 729 | } | 725 | } | 
| 730 | 726 | ||
| 731 | /* see if non-Linux software set up AM/PM mode */ | 727 | /* see if non-Linux software set up AM/PM mode */ | 
| diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index e0d0ba4de03f..970a236b147a 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
| @@ -322,12 +322,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) | |||
| 322 | return -EIO; | 322 | return -EIO; | 
| 323 | } | 323 | } | 
| 324 | 324 | ||
| 325 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", | 325 | dev_dbg(dev, "%s: %7ph\n", "read", ds1307->regs); | 
| 326 | "read", | ||
| 327 | ds1307->regs[0], ds1307->regs[1], | ||
| 328 | ds1307->regs[2], ds1307->regs[3], | ||
| 329 | ds1307->regs[4], ds1307->regs[5], | ||
| 330 | ds1307->regs[6]); | ||
| 331 | 326 | ||
| 332 | t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f); | 327 | t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f); | 
| 333 | t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); | 328 | t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); | 
| @@ -398,9 +393,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
| 398 | break; | 393 | break; | 
| 399 | } | 394 | } | 
| 400 | 395 | ||
| 401 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", | 396 | dev_dbg(dev, "%s: %7ph\n", "write", buf); | 
| 402 | "write", buf[0], buf[1], buf[2], buf[3], | ||
| 403 | buf[4], buf[5], buf[6]); | ||
| 404 | 397 | ||
| 405 | result = ds1307->write_block_data(ds1307->client, | 398 | result = ds1307->write_block_data(ds1307->client, | 
| 406 | ds1307->offset, 7, buf); | 399 | ds1307->offset, 7, buf); | 
| diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index 5ea9df7c8c31..b04fc4272fb3 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c | |||
| @@ -70,7 +70,7 @@ static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev, | |||
| 70 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) { | 70 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) { | 
| 71 | err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name); | 71 | err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name); | 
| 72 | if (err) { | 72 | if (err) { | 
| 73 | printk(KERN_ERR "error mapping gpio %s: %d\n", | 73 | dev_err(&pdev->dev, "error mapping gpio %s: %d\n", | 
| 74 | ds2404_gpio[i].name, err); | 74 | ds2404_gpio[i].name, err); | 
| 75 | goto err_request; | 75 | goto err_request; | 
| 76 | } | 76 | } | 
| @@ -177,7 +177,7 @@ static void ds2404_write_memory(struct device *dev, u16 offset, | |||
| 177 | 177 | ||
| 178 | for (i = 0; i < length; i++) { | 178 | for (i = 0; i < length; i++) { | 
| 179 | if (out[i] != ds2404_read_byte(dev)) { | 179 | if (out[i] != ds2404_read_byte(dev)) { | 
| 180 | printk(KERN_ERR "read invalid data\n"); | 180 | dev_err(dev, "read invalid data\n"); | 
| 181 | return; | 181 | return; | 
| 182 | } | 182 | } | 
| 183 | } | 183 | } | 
| @@ -283,19 +283,7 @@ static struct platform_driver rtc_device_driver = { | |||
| 283 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, | 
| 284 | }, | 284 | }, | 
| 285 | }; | 285 | }; | 
| 286 | 286 | module_platform_driver(rtc_device_driver); | |
| 287 | static __init int ds2404_init(void) | ||
| 288 | { | ||
| 289 | return platform_driver_register(&rtc_device_driver); | ||
| 290 | } | ||
| 291 | |||
| 292 | static __exit void ds2404_exit(void) | ||
| 293 | { | ||
| 294 | platform_driver_unregister(&rtc_device_driver); | ||
| 295 | } | ||
| 296 | |||
| 297 | module_init(ds2404_init); | ||
| 298 | module_exit(ds2404_exit); | ||
| 299 | 287 | ||
| 300 | MODULE_DESCRIPTION("DS2404 RTC"); | 288 | MODULE_DESCRIPTION("DS2404 RTC"); | 
| 301 | MODULE_AUTHOR("Sven Schnelle"); | 289 | MODULE_AUTHOR("Sven Schnelle"); | 
| diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index c9f890b088da..1a0c37c9152b 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | * | 13 | * | 
| 14 | */ | 14 | */ | 
| 15 | 15 | ||
| 16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 17 | |||
| 16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> | 
| 17 | #include <linux/module.h> | 19 | #include <linux/module.h> | 
| 18 | #include <linux/time.h> | 20 | #include <linux/time.h> | 
| @@ -47,7 +49,7 @@ compute_wday(efi_time_t *eft) | |||
| 47 | int ndays = 0; | 49 | int ndays = 0; | 
| 48 | 50 | ||
| 49 | if (eft->year < 1998) { | 51 | if (eft->year < 1998) { | 
| 50 | printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n"); | 52 | pr_err("EFI year < 1998, invalid date\n"); | 
| 51 | return -1; | 53 | return -1; | 
| 52 | } | 54 | } | 
| 53 | 55 | ||
| @@ -70,7 +72,7 @@ convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft) | |||
| 70 | eft->day = wtime->tm_mday; | 72 | eft->day = wtime->tm_mday; | 
| 71 | eft->hour = wtime->tm_hour; | 73 | eft->hour = wtime->tm_hour; | 
| 72 | eft->minute = wtime->tm_min; | 74 | eft->minute = wtime->tm_min; | 
| 73 | eft->second = wtime->tm_sec; | 75 | eft->second = wtime->tm_sec; | 
| 74 | eft->nanosecond = 0; | 76 | eft->nanosecond = 0; | 
| 75 | eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0; | 77 | eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0; | 
| 76 | eft->timezone = EFI_UNSPECIFIED_TIMEZONE; | 78 | eft->timezone = EFI_UNSPECIFIED_TIMEZONE; | 
| @@ -142,7 +144,7 @@ static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
| 142 | */ | 144 | */ | 
| 143 | status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft); | 145 | status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft); | 
| 144 | 146 | ||
| 145 | printk(KERN_WARNING "write status is %d\n", (int)status); | 147 | dev_warn(dev, "write status is %d\n", (int)status); | 
| 146 | 148 | ||
| 147 | return status == EFI_SUCCESS ? 0 : -EINVAL; | 149 | return status == EFI_SUCCESS ? 0 : -EINVAL; | 
| 148 | } | 150 | } | 
| @@ -157,7 +159,7 @@ static int efi_read_time(struct device *dev, struct rtc_time *tm) | |||
| 157 | 159 | ||
| 158 | if (status != EFI_SUCCESS) { | 160 | if (status != EFI_SUCCESS) { | 
| 159 | /* should never happen */ | 161 | /* should never happen */ | 
| 160 | printk(KERN_ERR "efitime: can't read time\n"); | 162 | dev_err(dev, "can't read time\n"); | 
| 161 | return -EINVAL; | 163 | return -EINVAL; | 
| 162 | } | 164 | } | 
| 163 | 165 | ||
| diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 04e93c6597f8..bff3cdc5140e 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c | |||
| @@ -116,17 +116,7 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t) | |||
| 116 | 116 | ||
| 117 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | 117 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | 
| 118 | 118 | ||
| 119 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | 119 | dev_dbg(dev, "%s: %15ph\n", "read", fm3130->regs); | 
| 120 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
| 121 | "read", | ||
| 122 | fm3130->regs[0], fm3130->regs[1], | ||
| 123 | fm3130->regs[2], fm3130->regs[3], | ||
| 124 | fm3130->regs[4], fm3130->regs[5], | ||
| 125 | fm3130->regs[6], fm3130->regs[7], | ||
| 126 | fm3130->regs[8], fm3130->regs[9], | ||
| 127 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
| 128 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
| 129 | fm3130->regs[0xe]); | ||
| 130 | 120 | ||
| 131 | t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); | 121 | t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); | 
| 132 | t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | 122 | t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | 
| @@ -175,12 +165,7 @@ static int fm3130_set_time(struct device *dev, struct rtc_time *t) | |||
| 175 | tmp = t->tm_year - 100; | 165 | tmp = t->tm_year - 100; | 
| 176 | buf[FM3130_RTC_YEARS] = bin2bcd(tmp); | 166 | buf[FM3130_RTC_YEARS] = bin2bcd(tmp); | 
| 177 | 167 | ||
| 178 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" | 168 | dev_dbg(dev, "%s: %15ph\n", "write", buf); | 
| 179 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
| 180 | "write", buf[0], buf[1], buf[2], buf[3], | ||
| 181 | buf[4], buf[5], buf[6], buf[7], | ||
| 182 | buf[8], buf[9], buf[0xa], buf[0xb], | ||
| 183 | buf[0xc], buf[0xd], buf[0xe]); | ||
| 184 | 169 | ||
| 185 | fm3130_rtc_mode(dev, FM3130_MODE_WRITE); | 170 | fm3130_rtc_mode(dev, FM3130_MODE_WRITE); | 
| 186 | 171 | ||
| @@ -517,18 +502,8 @@ bad_alarm: | |||
| 517 | bad_clock: | 502 | bad_clock: | 
| 518 | 503 | ||
| 519 | if (!fm3130->data_valid || !fm3130->alarm_valid) | 504 | if (!fm3130->data_valid || !fm3130->alarm_valid) | 
| 520 | dev_dbg(&client->dev, | 505 | dev_dbg(&client->dev, "%s: %15ph\n", "bogus registers", | 
| 521 | "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | 506 | fm3130->regs); | 
| 522 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
| 523 | "bogus registers", | ||
| 524 | fm3130->regs[0], fm3130->regs[1], | ||
| 525 | fm3130->regs[2], fm3130->regs[3], | ||
| 526 | fm3130->regs[4], fm3130->regs[5], | ||
| 527 | fm3130->regs[6], fm3130->regs[7], | ||
| 528 | fm3130->regs[8], fm3130->regs[9], | ||
| 529 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
| 530 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
| 531 | fm3130->regs[0xe]); | ||
| 532 | 507 | ||
| 533 | /* We won't bail out here because we just got invalid data. | 508 | /* We won't bail out here because we just got invalid data. | 
| 534 | Time setting from u-boot doesn't work anyway */ | 509 | Time setting from u-boot doesn't work anyway */ | 
| diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c new file mode 100644 index 000000000000..31c5728ef629 --- /dev/null +++ b/drivers/rtc/rtc-hid-sensor-time.c | |||
| @@ -0,0 +1,292 @@ | |||
| 1 | /* | ||
| 2 | * HID Sensor Time Driver | ||
| 3 | * Copyright (c) 2012, Alexander Holler. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | #include <linux/device.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/hid-sensor-hub.h> | ||
| 23 | #include <linux/iio/iio.h> | ||
| 24 | #include <linux/rtc.h> | ||
| 25 | |||
| 26 | /* Format: HID-SENSOR-usage_id_in_hex */ | ||
| 27 | /* Usage ID from spec for Time: 0x2000A0 */ | ||
| 28 | #define DRIVER_NAME "HID-SENSOR-2000a0" /* must be lowercase */ | ||
| 29 | |||
| 30 | enum hid_time_channel { | ||
| 31 | CHANNEL_SCAN_INDEX_YEAR, | ||
| 32 | CHANNEL_SCAN_INDEX_MONTH, | ||
| 33 | CHANNEL_SCAN_INDEX_DAY, | ||
| 34 | CHANNEL_SCAN_INDEX_HOUR, | ||
| 35 | CHANNEL_SCAN_INDEX_MINUTE, | ||
| 36 | CHANNEL_SCAN_INDEX_SECOND, | ||
| 37 | TIME_RTC_CHANNEL_MAX, | ||
| 38 | }; | ||
| 39 | |||
| 40 | struct hid_time_state { | ||
| 41 | struct hid_sensor_hub_callbacks callbacks; | ||
| 42 | struct hid_sensor_common common_attributes; | ||
| 43 | struct hid_sensor_hub_attribute_info info[TIME_RTC_CHANNEL_MAX]; | ||
| 44 | struct rtc_time last_time; | ||
| 45 | spinlock_t lock_last_time; | ||
| 46 | struct completion comp_last_time; | ||
| 47 | struct rtc_time time_buf; | ||
| 48 | struct rtc_device *rtc; | ||
| 49 | }; | ||
| 50 | |||
| 51 | static const u32 hid_time_addresses[TIME_RTC_CHANNEL_MAX] = { | ||
| 52 | HID_USAGE_SENSOR_TIME_YEAR, | ||
| 53 | HID_USAGE_SENSOR_TIME_MONTH, | ||
| 54 | HID_USAGE_SENSOR_TIME_DAY, | ||
| 55 | HID_USAGE_SENSOR_TIME_HOUR, | ||
| 56 | HID_USAGE_SENSOR_TIME_MINUTE, | ||
| 57 | HID_USAGE_SENSOR_TIME_SECOND, | ||
| 58 | }; | ||
| 59 | |||
| 60 | /* Channel names for verbose error messages */ | ||
| 61 | static const char * const hid_time_channel_names[TIME_RTC_CHANNEL_MAX] = { | ||
| 62 | "year", "month", "day", "hour", "minute", "second", | ||
| 63 | }; | ||
| 64 | |||
| 65 | /* Callback handler to send event after all samples are received and captured */ | ||
| 66 | static int hid_time_proc_event(struct hid_sensor_hub_device *hsdev, | ||
| 67 | unsigned usage_id, void *priv) | ||
| 68 | { | ||
| 69 | unsigned long flags; | ||
| 70 | struct hid_time_state *time_state = platform_get_drvdata(priv); | ||
| 71 | |||
| 72 | spin_lock_irqsave(&time_state->lock_last_time, flags); | ||
| 73 | time_state->last_time = time_state->time_buf; | ||
| 74 | spin_unlock_irqrestore(&time_state->lock_last_time, flags); | ||
| 75 | complete(&time_state->comp_last_time); | ||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static int hid_time_capture_sample(struct hid_sensor_hub_device *hsdev, | ||
| 80 | unsigned usage_id, size_t raw_len, | ||
| 81 | char *raw_data, void *priv) | ||
| 82 | { | ||
| 83 | struct hid_time_state *time_state = platform_get_drvdata(priv); | ||
| 84 | struct rtc_time *time_buf = &time_state->time_buf; | ||
| 85 | |||
| 86 | switch (usage_id) { | ||
| 87 | case HID_USAGE_SENSOR_TIME_YEAR: | ||
| 88 | time_buf->tm_year = *(u8 *)raw_data; | ||
| 89 | if (time_buf->tm_year < 70) | ||
| 90 | /* assume we are in 1970...2069 */ | ||
| 91 | time_buf->tm_year += 100; | ||
| 92 | break; | ||
| 93 | case HID_USAGE_SENSOR_TIME_MONTH: | ||
| 94 | /* sensor sending the month as 1-12, we need 0-11 */ | ||
| 95 | time_buf->tm_mon = *(u8 *)raw_data-1; | ||
| 96 | break; | ||
| 97 | case HID_USAGE_SENSOR_TIME_DAY: | ||
| 98 | time_buf->tm_mday = *(u8 *)raw_data; | ||
| 99 | break; | ||
| 100 | case HID_USAGE_SENSOR_TIME_HOUR: | ||
| 101 | time_buf->tm_hour = *(u8 *)raw_data; | ||
| 102 | break; | ||
| 103 | case HID_USAGE_SENSOR_TIME_MINUTE: | ||
| 104 | time_buf->tm_min = *(u8 *)raw_data; | ||
| 105 | break; | ||
| 106 | case HID_USAGE_SENSOR_TIME_SECOND: | ||
| 107 | time_buf->tm_sec = *(u8 *)raw_data; | ||
| 108 | break; | ||
| 109 | default: | ||
| 110 | return -EINVAL; | ||
| 111 | } | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | /* small helper, haven't found any other way */ | ||
| 116 | static const char *hid_time_attrib_name(u32 attrib_id) | ||
| 117 | { | ||
| 118 | static const char unknown[] = "unknown"; | ||
| 119 | unsigned i; | ||
| 120 | |||
| 121 | for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) { | ||
| 122 | if (hid_time_addresses[i] == attrib_id) | ||
| 123 | return hid_time_channel_names[i]; | ||
| 124 | } | ||
| 125 | return unknown; /* should never happen */ | ||
| 126 | } | ||
| 127 | |||
| 128 | static int hid_time_parse_report(struct platform_device *pdev, | ||
| 129 | struct hid_sensor_hub_device *hsdev, | ||
| 130 | unsigned usage_id, | ||
| 131 | struct hid_time_state *time_state) | ||
| 132 | { | ||
| 133 | int report_id, i; | ||
| 134 | |||
| 135 | for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) | ||
| 136 | if (sensor_hub_input_get_attribute_info(hsdev, | ||
| 137 | HID_INPUT_REPORT, usage_id, | ||
| 138 | hid_time_addresses[i], | ||
| 139 | &time_state->info[i]) < 0) | ||
| 140 | return -EINVAL; | ||
| 141 | /* Check the (needed) attributes for sanity */ | ||
| 142 | report_id = time_state->info[0].report_id; | ||
| 143 | if (report_id < 0) { | ||
| 144 | dev_err(&pdev->dev, "bad report ID!\n"); | ||
| 145 | return -EINVAL; | ||
| 146 | } | ||
| 147 | for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) { | ||
| 148 | if (time_state->info[i].report_id != report_id) { | ||
| 149 | dev_err(&pdev->dev, | ||
| 150 | "not all needed attributes inside the same report!\n"); | ||
| 151 | return -EINVAL; | ||
| 152 | } | ||
| 153 | if (time_state->info[i].size != 1) { | ||
| 154 | dev_err(&pdev->dev, | ||
| 155 | "attribute '%s' not 8 bits wide!\n", | ||
| 156 | hid_time_attrib_name( | ||
| 157 | time_state->info[i].attrib_id)); | ||
| 158 | return -EINVAL; | ||
| 159 | } | ||
| 160 | if (time_state->info[i].units != | ||
| 161 | HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED && | ||
| 162 | /* allow attribute seconds with unit seconds */ | ||
| 163 | !(time_state->info[i].attrib_id == | ||
| 164 | HID_USAGE_SENSOR_TIME_SECOND && | ||
| 165 | time_state->info[i].units == | ||
| 166 | HID_USAGE_SENSOR_UNITS_SECOND)) { | ||
| 167 | dev_err(&pdev->dev, | ||
| 168 | "attribute '%s' hasn't a unit of type 'none'!\n", | ||
| 169 | hid_time_attrib_name( | ||
| 170 | time_state->info[i].attrib_id)); | ||
| 171 | return -EINVAL; | ||
| 172 | } | ||
| 173 | if (time_state->info[i].unit_expo) { | ||
| 174 | dev_err(&pdev->dev, | ||
| 175 | "attribute '%s' hasn't a unit exponent of 1!\n", | ||
| 176 | hid_time_attrib_name( | ||
| 177 | time_state->info[i].attrib_id)); | ||
| 178 | return -EINVAL; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 186 | { | ||
| 187 | unsigned long flags; | ||
| 188 | struct hid_time_state *time_state = | ||
| 189 | platform_get_drvdata(to_platform_device(dev)); | ||
| 190 | int ret; | ||
| 191 | |||
| 192 | INIT_COMPLETION(time_state->comp_last_time); | ||
| 193 | /* get a report with all values through requesting one value */ | ||
| 194 | sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev, | ||
| 195 | HID_USAGE_SENSOR_TIME, hid_time_addresses[0], | ||
| 196 | time_state->info[0].report_id); | ||
| 197 | /* wait for all values (event) */ | ||
| 198 | ret = wait_for_completion_killable_timeout( | ||
| 199 | &time_state->comp_last_time, HZ*6); | ||
| 200 | if (ret > 0) { | ||
| 201 | /* no error */ | ||
| 202 | spin_lock_irqsave(&time_state->lock_last_time, flags); | ||
| 203 | *tm = time_state->last_time; | ||
| 204 | spin_unlock_irqrestore(&time_state->lock_last_time, flags); | ||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | if (!ret) | ||
| 208 | return -EIO; /* timeouted */ | ||
| 209 | return ret; /* killed (-ERESTARTSYS) */ | ||
| 210 | } | ||
| 211 | |||
| 212 | static const struct rtc_class_ops hid_time_rtc_ops = { | ||
| 213 | .read_time = hid_rtc_read_time, | ||
| 214 | }; | ||
| 215 | |||
| 216 | static int hid_time_probe(struct platform_device *pdev) | ||
| 217 | { | ||
| 218 | int ret = 0; | ||
| 219 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; | ||
| 220 | struct hid_time_state *time_state = devm_kzalloc(&pdev->dev, | ||
| 221 | sizeof(struct hid_time_state), GFP_KERNEL); | ||
| 222 | |||
| 223 | if (time_state == NULL) | ||
| 224 | return -ENOMEM; | ||
| 225 | |||
| 226 | platform_set_drvdata(pdev, time_state); | ||
| 227 | |||
| 228 | spin_lock_init(&time_state->lock_last_time); | ||
| 229 | init_completion(&time_state->comp_last_time); | ||
| 230 | time_state->common_attributes.hsdev = hsdev; | ||
| 231 | time_state->common_attributes.pdev = pdev; | ||
| 232 | |||
| 233 | ret = hid_sensor_parse_common_attributes(hsdev, | ||
| 234 | HID_USAGE_SENSOR_TIME, | ||
| 235 | &time_state->common_attributes); | ||
| 236 | if (ret) { | ||
| 237 | dev_err(&pdev->dev, "failed to setup common attributes!\n"); | ||
| 238 | return ret; | ||
| 239 | } | ||
| 240 | |||
| 241 | ret = hid_time_parse_report(pdev, hsdev, HID_USAGE_SENSOR_TIME, | ||
| 242 | time_state); | ||
| 243 | if (ret) { | ||
| 244 | dev_err(&pdev->dev, "failed to setup attributes!\n"); | ||
| 245 | return ret; | ||
| 246 | } | ||
| 247 | |||
| 248 | time_state->callbacks.send_event = hid_time_proc_event; | ||
| 249 | time_state->callbacks.capture_sample = hid_time_capture_sample; | ||
| 250 | time_state->callbacks.pdev = pdev; | ||
| 251 | ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_TIME, | ||
| 252 | &time_state->callbacks); | ||
| 253 | if (ret < 0) { | ||
| 254 | dev_err(&pdev->dev, "register callback failed!\n"); | ||
| 255 | return ret; | ||
| 256 | } | ||
| 257 | |||
| 258 | time_state->rtc = rtc_device_register("hid-sensor-time", | ||
| 259 | &pdev->dev, &hid_time_rtc_ops, THIS_MODULE); | ||
| 260 | |||
| 261 | if (IS_ERR(time_state->rtc)) { | ||
| 262 | dev_err(&pdev->dev, "rtc device register failed!\n"); | ||
| 263 | return PTR_ERR(time_state->rtc); | ||
| 264 | } | ||
| 265 | |||
| 266 | return ret; | ||
| 267 | } | ||
| 268 | |||
| 269 | static int hid_time_remove(struct platform_device *pdev) | ||
| 270 | { | ||
| 271 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; | ||
| 272 | struct hid_time_state *time_state = platform_get_drvdata(pdev); | ||
| 273 | |||
| 274 | rtc_device_unregister(time_state->rtc); | ||
| 275 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME); | ||
| 276 | |||
| 277 | return 0; | ||
| 278 | } | ||
| 279 | |||
| 280 | static struct platform_driver hid_time_platform_driver = { | ||
| 281 | .driver = { | ||
| 282 | .name = DRIVER_NAME, | ||
| 283 | .owner = THIS_MODULE, | ||
| 284 | }, | ||
| 285 | .probe = hid_time_probe, | ||
| 286 | .remove = hid_time_remove, | ||
| 287 | }; | ||
| 288 | module_platform_driver(hid_time_platform_driver); | ||
| 289 | |||
| 290 | MODULE_DESCRIPTION("HID Sensor Time"); | ||
| 291 | MODULE_AUTHOR("Alexander Holler <holler@ahsoftware.de>"); | ||
| 292 | MODULE_LICENSE("GPL"); | ||
| diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 75d307ab37f4..82aad695979e 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
| @@ -406,7 +406,7 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
| 406 | 406 | ||
| 407 | mutex_init(&imxdi->write_mutex); | 407 | mutex_init(&imxdi->write_mutex); | 
| 408 | 408 | ||
| 409 | imxdi->clk = clk_get(&pdev->dev, NULL); | 409 | imxdi->clk = devm_clk_get(&pdev->dev, NULL); | 
| 410 | if (IS_ERR(imxdi->clk)) | 410 | if (IS_ERR(imxdi->clk)) | 
| 411 | return PTR_ERR(imxdi->clk); | 411 | return PTR_ERR(imxdi->clk); | 
| 412 | clk_prepare_enable(imxdi->clk); | 412 | clk_prepare_enable(imxdi->clk); | 
| @@ -475,7 +475,6 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
| 475 | 475 | ||
| 476 | err: | 476 | err: | 
| 477 | clk_disable_unprepare(imxdi->clk); | 477 | clk_disable_unprepare(imxdi->clk); | 
| 478 | clk_put(imxdi->clk); | ||
| 479 | 478 | ||
| 480 | return rc; | 479 | return rc; | 
| 481 | } | 480 | } | 
| @@ -492,7 +491,6 @@ static int dryice_rtc_remove(struct platform_device *pdev) | |||
| 492 | rtc_device_unregister(imxdi->rtc); | 491 | rtc_device_unregister(imxdi->rtc); | 
| 493 | 492 | ||
| 494 | clk_disable_unprepare(imxdi->clk); | 493 | clk_disable_unprepare(imxdi->clk); | 
| 495 | clk_put(imxdi->clk); | ||
| 496 | 494 | ||
| 497 | return 0; | 495 | return 0; | 
| 498 | } | 496 | } | 
| diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 1850104705c0..6b4298ea683d 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c | |||
| @@ -227,7 +227,7 @@ static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
| 227 | buf[ISL12022_REG_SC + i]); | 227 | buf[ISL12022_REG_SC + i]); | 
| 228 | if (ret) | 228 | if (ret) | 
| 229 | return -EIO; | 229 | return -EIO; | 
| 230 | }; | 230 | } | 
| 231 | 231 | ||
| 232 | return 0; | 232 | return 0; | 
| 233 | } | 233 | } | 
| diff --git a/drivers/rtc/rtc-lp8788.c b/drivers/rtc/rtc-lp8788.c new file mode 100644 index 000000000000..9a4631218f41 --- /dev/null +++ b/drivers/rtc/rtc-lp8788.c | |||
| @@ -0,0 +1,338 @@ | |||
| 1 | /* | ||
| 2 | * TI LP8788 MFD - rtc driver | ||
| 3 | * | ||
| 4 | * Copyright 2012 Texas Instruments | ||
| 5 | * | ||
| 6 | * Author: Milo(Woogyom) Kim <milo.kim@ti.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/err.h> | ||
| 15 | #include <linux/irqdomain.h> | ||
| 16 | #include <linux/mfd/lp8788.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/rtc.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | |||
| 22 | /* register address */ | ||
| 23 | #define LP8788_INTEN_3 0x05 | ||
| 24 | #define LP8788_RTC_UNLOCK 0x64 | ||
| 25 | #define LP8788_RTC_SEC 0x70 | ||
| 26 | #define LP8788_ALM1_SEC 0x77 | ||
| 27 | #define LP8788_ALM1_EN 0x7D | ||
| 28 | #define LP8788_ALM2_SEC 0x7E | ||
| 29 | #define LP8788_ALM2_EN 0x84 | ||
| 30 | |||
| 31 | /* mask/shift bits */ | ||
| 32 | #define LP8788_INT_RTC_ALM1_M BIT(1) /* Addr 05h */ | ||
| 33 | #define LP8788_INT_RTC_ALM1_S 1 | ||
| 34 | #define LP8788_INT_RTC_ALM2_M BIT(2) /* Addr 05h */ | ||
| 35 | #define LP8788_INT_RTC_ALM2_S 2 | ||
| 36 | #define LP8788_ALM_EN_M BIT(7) /* Addr 7Dh or 84h */ | ||
| 37 | #define LP8788_ALM_EN_S 7 | ||
| 38 | |||
| 39 | #define DEFAULT_ALARM_SEL LP8788_ALARM_1 | ||
| 40 | #define LP8788_MONTH_OFFSET 1 | ||
| 41 | #define LP8788_BASE_YEAR 2000 | ||
| 42 | #define MAX_WDAY_BITS 7 | ||
| 43 | #define LP8788_WDAY_SET 1 | ||
| 44 | #define RTC_UNLOCK 0x1 | ||
| 45 | #define RTC_LATCH 0x2 | ||
| 46 | #define ALARM_IRQ_FLAG (RTC_IRQF | RTC_AF) | ||
| 47 | |||
| 48 | enum lp8788_time { | ||
| 49 | LPTIME_SEC, | ||
| 50 | LPTIME_MIN, | ||
| 51 | LPTIME_HOUR, | ||
| 52 | LPTIME_MDAY, | ||
| 53 | LPTIME_MON, | ||
| 54 | LPTIME_YEAR, | ||
| 55 | LPTIME_WDAY, | ||
| 56 | LPTIME_MAX, | ||
| 57 | }; | ||
| 58 | |||
| 59 | struct lp8788_rtc { | ||
| 60 | struct lp8788 *lp; | ||
| 61 | struct rtc_device *rdev; | ||
| 62 | enum lp8788_alarm_sel alarm; | ||
| 63 | int irq; | ||
| 64 | }; | ||
| 65 | |||
| 66 | static const u8 addr_alarm_sec[LP8788_ALARM_MAX] = { | ||
| 67 | LP8788_ALM1_SEC, | ||
| 68 | LP8788_ALM2_SEC, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static const u8 addr_alarm_en[LP8788_ALARM_MAX] = { | ||
| 72 | LP8788_ALM1_EN, | ||
| 73 | LP8788_ALM2_EN, | ||
| 74 | }; | ||
| 75 | |||
| 76 | static const u8 mask_alarm_en[LP8788_ALARM_MAX] = { | ||
| 77 | LP8788_INT_RTC_ALM1_M, | ||
| 78 | LP8788_INT_RTC_ALM2_M, | ||
| 79 | }; | ||
| 80 | |||
| 81 | static const u8 shift_alarm_en[LP8788_ALARM_MAX] = { | ||
| 82 | LP8788_INT_RTC_ALM1_S, | ||
| 83 | LP8788_INT_RTC_ALM2_S, | ||
| 84 | }; | ||
| 85 | |||
| 86 | static int _to_tm_wday(u8 lp8788_wday) | ||
| 87 | { | ||
| 88 | int i; | ||
| 89 | |||
| 90 | if (lp8788_wday == 0) | ||
| 91 | return 0; | ||
| 92 | |||
| 93 | /* lookup defined weekday from read register value */ | ||
| 94 | for (i = 0; i < MAX_WDAY_BITS; i++) { | ||
| 95 | if ((lp8788_wday >> i) == LP8788_WDAY_SET) | ||
| 96 | break; | ||
| 97 | } | ||
| 98 | |||
| 99 | return i + 1; | ||
| 100 | } | ||
| 101 | |||
| 102 | static inline int _to_lp8788_wday(int tm_wday) | ||
| 103 | { | ||
| 104 | return LP8788_WDAY_SET << (tm_wday - 1); | ||
| 105 | } | ||
| 106 | |||
| 107 | static void lp8788_rtc_unlock(struct lp8788 *lp) | ||
| 108 | { | ||
| 109 | lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_UNLOCK); | ||
| 110 | lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_LATCH); | ||
| 111 | } | ||
| 112 | |||
| 113 | static int lp8788_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 114 | { | ||
| 115 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
| 116 | struct lp8788 *lp = rtc->lp; | ||
| 117 | u8 data[LPTIME_MAX]; | ||
| 118 | int ret; | ||
| 119 | |||
| 120 | lp8788_rtc_unlock(lp); | ||
| 121 | |||
| 122 | ret = lp8788_read_multi_bytes(lp, LP8788_RTC_SEC, data, LPTIME_MAX); | ||
| 123 | if (ret) | ||
| 124 | return ret; | ||
| 125 | |||
| 126 | tm->tm_sec = data[LPTIME_SEC]; | ||
| 127 | tm->tm_min = data[LPTIME_MIN]; | ||
| 128 | tm->tm_hour = data[LPTIME_HOUR]; | ||
| 129 | tm->tm_mday = data[LPTIME_MDAY]; | ||
| 130 | tm->tm_mon = data[LPTIME_MON] - LP8788_MONTH_OFFSET; | ||
| 131 | tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900; | ||
| 132 | tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]); | ||
| 133 | |||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | static int lp8788_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 138 | { | ||
| 139 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
| 140 | struct lp8788 *lp = rtc->lp; | ||
| 141 | u8 data[LPTIME_MAX - 1]; | ||
| 142 | int ret, i, year; | ||
| 143 | |||
| 144 | year = tm->tm_year + 1900 - LP8788_BASE_YEAR; | ||
| 145 | if (year < 0) { | ||
| 146 | dev_err(lp->dev, "invalid year: %d\n", year); | ||
| 147 | return -EINVAL; | ||
| 148 | } | ||
| 149 | |||
| 150 | /* because rtc weekday is a readonly register, do not update */ | ||
| 151 | data[LPTIME_SEC] = tm->tm_sec; | ||
| 152 | data[LPTIME_MIN] = tm->tm_min; | ||
| 153 | data[LPTIME_HOUR] = tm->tm_hour; | ||
| 154 | data[LPTIME_MDAY] = tm->tm_mday; | ||
| 155 | data[LPTIME_MON] = tm->tm_mon + LP8788_MONTH_OFFSET; | ||
| 156 | data[LPTIME_YEAR] = year; | ||
| 157 | |||
| 158 | for (i = 0; i < ARRAY_SIZE(data); i++) { | ||
| 159 | ret = lp8788_write_byte(lp, LP8788_RTC_SEC + i, data[i]); | ||
| 160 | if (ret) | ||
| 161 | return ret; | ||
| 162 | } | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int lp8788_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
| 168 | { | ||
| 169 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
| 170 | struct lp8788 *lp = rtc->lp; | ||
| 171 | struct rtc_time *tm = &alarm->time; | ||
| 172 | u8 addr, data[LPTIME_MAX]; | ||
| 173 | int ret; | ||
| 174 | |||
| 175 | addr = addr_alarm_sec[rtc->alarm]; | ||
| 176 | ret = lp8788_read_multi_bytes(lp, addr, data, LPTIME_MAX); | ||
| 177 | if (ret) | ||
| 178 | return ret; | ||
| 179 | |||
| 180 | tm->tm_sec = data[LPTIME_SEC]; | ||
| 181 | tm->tm_min = data[LPTIME_MIN]; | ||
| 182 | tm->tm_hour = data[LPTIME_HOUR]; | ||
| 183 | tm->tm_mday = data[LPTIME_MDAY]; | ||
| 184 | tm->tm_mon = data[LPTIME_MON] - LP8788_MONTH_OFFSET; | ||
| 185 | tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900; | ||
| 186 | tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]); | ||
| 187 | alarm->enabled = data[LPTIME_WDAY] & LP8788_ALM_EN_M; | ||
| 188 | |||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | static int lp8788_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
| 193 | { | ||
| 194 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
| 195 | struct lp8788 *lp = rtc->lp; | ||
| 196 | struct rtc_time *tm = &alarm->time; | ||
| 197 | u8 addr, data[LPTIME_MAX]; | ||
| 198 | int ret, i, year; | ||
| 199 | |||
| 200 | year = tm->tm_year + 1900 - LP8788_BASE_YEAR; | ||
| 201 | if (year < 0) { | ||
| 202 | dev_err(lp->dev, "invalid year: %d\n", year); | ||
| 203 | return -EINVAL; | ||
| 204 | } | ||
| 205 | |||
| 206 | data[LPTIME_SEC] = tm->tm_sec; | ||
| 207 | data[LPTIME_MIN] = tm->tm_min; | ||
| 208 | data[LPTIME_HOUR] = tm->tm_hour; | ||
| 209 | data[LPTIME_MDAY] = tm->tm_mday; | ||
| 210 | data[LPTIME_MON] = tm->tm_mon + LP8788_MONTH_OFFSET; | ||
| 211 | data[LPTIME_YEAR] = year; | ||
| 212 | data[LPTIME_WDAY] = _to_lp8788_wday(tm->tm_wday); | ||
| 213 | |||
| 214 | for (i = 0; i < ARRAY_SIZE(data); i++) { | ||
| 215 | addr = addr_alarm_sec[rtc->alarm] + i; | ||
| 216 | ret = lp8788_write_byte(lp, addr, data[i]); | ||
| 217 | if (ret) | ||
| 218 | return ret; | ||
| 219 | } | ||
| 220 | |||
| 221 | alarm->enabled = 1; | ||
| 222 | addr = addr_alarm_en[rtc->alarm]; | ||
| 223 | |||
| 224 | return lp8788_update_bits(lp, addr, LP8788_ALM_EN_M, | ||
| 225 | alarm->enabled << LP8788_ALM_EN_S); | ||
| 226 | } | ||
| 227 | |||
| 228 | static int lp8788_alarm_irq_enable(struct device *dev, unsigned int enable) | ||
| 229 | { | ||
| 230 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
| 231 | struct lp8788 *lp = rtc->lp; | ||
| 232 | u8 mask, shift; | ||
| 233 | |||
| 234 | if (!rtc->irq) | ||
| 235 | return -EIO; | ||
| 236 | |||
| 237 | mask = mask_alarm_en[rtc->alarm]; | ||
| 238 | shift = shift_alarm_en[rtc->alarm]; | ||
| 239 | |||
| 240 | return lp8788_update_bits(lp, LP8788_INTEN_3, mask, enable << shift); | ||
| 241 | } | ||
| 242 | |||
| 243 | static const struct rtc_class_ops lp8788_rtc_ops = { | ||
| 244 | .read_time = lp8788_rtc_read_time, | ||
| 245 | .set_time = lp8788_rtc_set_time, | ||
| 246 | .read_alarm = lp8788_read_alarm, | ||
| 247 | .set_alarm = lp8788_set_alarm, | ||
| 248 | .alarm_irq_enable = lp8788_alarm_irq_enable, | ||
| 249 | }; | ||
| 250 | |||
| 251 | static irqreturn_t lp8788_alarm_irq_handler(int irq, void *ptr) | ||
| 252 | { | ||
| 253 | struct lp8788_rtc *rtc = ptr; | ||
| 254 | |||
| 255 | rtc_update_irq(rtc->rdev, 1, ALARM_IRQ_FLAG); | ||
| 256 | return IRQ_HANDLED; | ||
| 257 | } | ||
| 258 | |||
| 259 | static int lp8788_alarm_irq_register(struct platform_device *pdev, | ||
| 260 | struct lp8788_rtc *rtc) | ||
| 261 | { | ||
| 262 | struct resource *r; | ||
| 263 | struct lp8788 *lp = rtc->lp; | ||
| 264 | struct irq_domain *irqdm = lp->irqdm; | ||
| 265 | int irq; | ||
| 266 | |||
| 267 | rtc->irq = 0; | ||
| 268 | |||
| 269 | /* even the alarm IRQ number is not specified, rtc time should work */ | ||
| 270 | r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, LP8788_ALM_IRQ); | ||
| 271 | if (!r) | ||
| 272 | return 0; | ||
| 273 | |||
| 274 | if (rtc->alarm == LP8788_ALARM_1) | ||
| 275 | irq = r->start; | ||
| 276 | else | ||
| 277 | irq = r->end; | ||
| 278 | |||
| 279 | rtc->irq = irq_create_mapping(irqdm, irq); | ||
| 280 | |||
| 281 | return devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | ||
| 282 | lp8788_alarm_irq_handler, | ||
| 283 | 0, LP8788_ALM_IRQ, rtc); | ||
| 284 | } | ||
| 285 | |||
| 286 | static int lp8788_rtc_probe(struct platform_device *pdev) | ||
| 287 | { | ||
| 288 | struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); | ||
| 289 | struct lp8788_rtc *rtc; | ||
| 290 | struct device *dev = &pdev->dev; | ||
| 291 | |||
| 292 | rtc = devm_kzalloc(dev, sizeof(struct lp8788_rtc), GFP_KERNEL); | ||
| 293 | if (!rtc) | ||
| 294 | return -ENOMEM; | ||
| 295 | |||
| 296 | rtc->lp = lp; | ||
| 297 | rtc->alarm = lp->pdata ? lp->pdata->alarm_sel : DEFAULT_ALARM_SEL; | ||
| 298 | platform_set_drvdata(pdev, rtc); | ||
| 299 | |||
| 300 | device_init_wakeup(dev, 1); | ||
| 301 | |||
| 302 | rtc->rdev = rtc_device_register("lp8788_rtc", dev, | ||
| 303 | &lp8788_rtc_ops, THIS_MODULE); | ||
| 304 | if (IS_ERR(rtc->rdev)) { | ||
| 305 | dev_err(dev, "can not register rtc device\n"); | ||
| 306 | return PTR_ERR(rtc->rdev); | ||
| 307 | } | ||
| 308 | |||
| 309 | if (lp8788_alarm_irq_register(pdev, rtc)) | ||
| 310 | dev_warn(lp->dev, "no rtc irq handler\n"); | ||
| 311 | |||
| 312 | return 0; | ||
| 313 | } | ||
| 314 | |||
| 315 | static int lp8788_rtc_remove(struct platform_device *pdev) | ||
| 316 | { | ||
| 317 | struct lp8788_rtc *rtc = platform_get_drvdata(pdev); | ||
| 318 | |||
| 319 | rtc_device_unregister(rtc->rdev); | ||
| 320 | platform_set_drvdata(pdev, NULL); | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | static struct platform_driver lp8788_rtc_driver = { | ||
| 326 | .probe = lp8788_rtc_probe, | ||
| 327 | .remove = lp8788_rtc_remove, | ||
| 328 | .driver = { | ||
| 329 | .name = LP8788_DEV_RTC, | ||
| 330 | .owner = THIS_MODULE, | ||
| 331 | }, | ||
| 332 | }; | ||
| 333 | module_platform_driver(lp8788_rtc_driver); | ||
| 334 | |||
| 335 | MODULE_DESCRIPTION("Texas Instruments LP8788 RTC Driver"); | ||
| 336 | MODULE_AUTHOR("Milo Kim"); | ||
| 337 | MODULE_LICENSE("GPL"); | ||
| 338 | MODULE_ALIAS("platform:lp8788-rtc"); | ||
| diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c new file mode 100644 index 000000000000..6b1337f9baf4 --- /dev/null +++ b/drivers/rtc/rtc-max77686.c | |||
| @@ -0,0 +1,641 @@ | |||
| 1 | /* | ||
| 2 | * RTC driver for Maxim MAX77686 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
| 5 | * | ||
| 6 | * based on rtc-max8997.c | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/rtc.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/mutex.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/mfd/max77686-private.h> | ||
| 22 | #include <linux/irqdomain.h> | ||
| 23 | #include <linux/regmap.h> | ||
| 24 | |||
| 25 | /* RTC Control Register */ | ||
| 26 | #define BCD_EN_SHIFT 0 | ||
| 27 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) | ||
| 28 | #define MODEL24_SHIFT 1 | ||
| 29 | #define MODEL24_MASK (1 << MODEL24_SHIFT) | ||
| 30 | /* RTC Update Register1 */ | ||
| 31 | #define RTC_UDR_SHIFT 0 | ||
| 32 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | ||
| 33 | #define RTC_RBUDR_SHIFT 4 | ||
| 34 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) | ||
| 35 | /* WTSR and SMPL Register */ | ||
| 36 | #define WTSRT_SHIFT 0 | ||
| 37 | #define SMPLT_SHIFT 2 | ||
| 38 | #define WTSR_EN_SHIFT 6 | ||
| 39 | #define SMPL_EN_SHIFT 7 | ||
| 40 | #define WTSRT_MASK (3 << WTSRT_SHIFT) | ||
| 41 | #define SMPLT_MASK (3 << SMPLT_SHIFT) | ||
| 42 | #define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) | ||
| 43 | #define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) | ||
| 44 | /* RTC Hour register */ | ||
| 45 | #define HOUR_PM_SHIFT 6 | ||
| 46 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | ||
| 47 | /* RTC Alarm Enable */ | ||
| 48 | #define ALARM_ENABLE_SHIFT 7 | ||
| 49 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | ||
| 50 | |||
| 51 | #define MAX77686_RTC_UPDATE_DELAY 16 | ||
| 52 | #undef MAX77686_RTC_WTSR_SMPL | ||
| 53 | |||
| 54 | enum { | ||
| 55 | RTC_SEC = 0, | ||
| 56 | RTC_MIN, | ||
| 57 | RTC_HOUR, | ||
| 58 | RTC_WEEKDAY, | ||
| 59 | RTC_MONTH, | ||
| 60 | RTC_YEAR, | ||
| 61 | RTC_DATE, | ||
| 62 | RTC_NR_TIME | ||
| 63 | }; | ||
| 64 | |||
| 65 | struct max77686_rtc_info { | ||
| 66 | struct device *dev; | ||
| 67 | struct max77686_dev *max77686; | ||
| 68 | struct i2c_client *rtc; | ||
| 69 | struct rtc_device *rtc_dev; | ||
| 70 | struct mutex lock; | ||
| 71 | |||
| 72 | struct regmap *regmap; | ||
| 73 | |||
| 74 | int virq; | ||
| 75 | int rtc_24hr_mode; | ||
| 76 | }; | ||
| 77 | |||
| 78 | enum MAX77686_RTC_OP { | ||
| 79 | MAX77686_RTC_WRITE, | ||
| 80 | MAX77686_RTC_READ, | ||
| 81 | }; | ||
| 82 | |||
| 83 | static inline int max77686_rtc_calculate_wday(u8 shifted) | ||
| 84 | { | ||
| 85 | int counter = -1; | ||
| 86 | while (shifted) { | ||
| 87 | shifted >>= 1; | ||
| 88 | counter++; | ||
| 89 | } | ||
| 90 | return counter; | ||
| 91 | } | ||
| 92 | |||
| 93 | static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | ||
| 94 | int rtc_24hr_mode) | ||
| 95 | { | ||
| 96 | tm->tm_sec = data[RTC_SEC] & 0x7f; | ||
| 97 | tm->tm_min = data[RTC_MIN] & 0x7f; | ||
| 98 | if (rtc_24hr_mode) | ||
| 99 | tm->tm_hour = data[RTC_HOUR] & 0x1f; | ||
| 100 | else { | ||
| 101 | tm->tm_hour = data[RTC_HOUR] & 0x0f; | ||
| 102 | if (data[RTC_HOUR] & HOUR_PM_MASK) | ||
| 103 | tm->tm_hour += 12; | ||
| 104 | } | ||
| 105 | |||
| 106 | tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f); | ||
| 107 | tm->tm_mday = data[RTC_DATE] & 0x1f; | ||
| 108 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | ||
| 109 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; | ||
| 110 | tm->tm_yday = 0; | ||
| 111 | tm->tm_isdst = 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data) | ||
| 115 | { | ||
| 116 | data[RTC_SEC] = tm->tm_sec; | ||
| 117 | data[RTC_MIN] = tm->tm_min; | ||
| 118 | data[RTC_HOUR] = tm->tm_hour; | ||
| 119 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; | ||
| 120 | data[RTC_DATE] = tm->tm_mday; | ||
| 121 | data[RTC_MONTH] = tm->tm_mon + 1; | ||
| 122 | data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0 ; | ||
| 123 | |||
| 124 | if (tm->tm_year < 100) { | ||
| 125 | pr_warn("%s: MAX77686 RTC cannot handle the year %d." | ||
| 126 | "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); | ||
| 127 | return -EINVAL; | ||
| 128 | } | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int max77686_rtc_update(struct max77686_rtc_info *info, | ||
| 133 | enum MAX77686_RTC_OP op) | ||
| 134 | { | ||
| 135 | int ret; | ||
| 136 | unsigned int data; | ||
| 137 | |||
| 138 | if (op == MAX77686_RTC_WRITE) | ||
| 139 | data = 1 << RTC_UDR_SHIFT; | ||
| 140 | else | ||
| 141 | data = 1 << RTC_RBUDR_SHIFT; | ||
| 142 | |||
| 143 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
| 144 | MAX77686_RTC_UPDATE0, data, data); | ||
| 145 | if (ret < 0) | ||
| 146 | dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n", | ||
| 147 | __func__, ret, data); | ||
| 148 | else { | ||
| 149 | /* Minimum 16ms delay required before RTC update. */ | ||
| 150 | msleep(MAX77686_RTC_UPDATE_DELAY); | ||
| 151 | } | ||
| 152 | |||
| 153 | return ret; | ||
| 154 | } | ||
| 155 | |||
| 156 | static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 157 | { | ||
| 158 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
| 159 | u8 data[RTC_NR_TIME]; | ||
| 160 | int ret; | ||
| 161 | |||
| 162 | mutex_lock(&info->lock); | ||
| 163 | |||
| 164 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
| 165 | if (ret < 0) | ||
| 166 | goto out; | ||
| 167 | |||
| 168 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
| 169 | MAX77686_RTC_SEC, data, RTC_NR_TIME); | ||
| 170 | if (ret < 0) { | ||
| 171 | dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, ret); | ||
| 172 | goto out; | ||
| 173 | } | ||
| 174 | |||
| 175 | max77686_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); | ||
| 176 | |||
| 177 | ret = rtc_valid_tm(tm); | ||
| 178 | |||
| 179 | out: | ||
| 180 | mutex_unlock(&info->lock); | ||
| 181 | return ret; | ||
| 182 | } | ||
| 183 | |||
| 184 | static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 185 | { | ||
| 186 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
| 187 | u8 data[RTC_NR_TIME]; | ||
| 188 | int ret; | ||
| 189 | |||
| 190 | ret = max77686_rtc_tm_to_data(tm, data); | ||
| 191 | if (ret < 0) | ||
| 192 | return ret; | ||
| 193 | |||
| 194 | mutex_lock(&info->lock); | ||
| 195 | |||
| 196 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
| 197 | MAX77686_RTC_SEC, data, RTC_NR_TIME); | ||
| 198 | if (ret < 0) { | ||
| 199 | dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__, | ||
| 200 | ret); | ||
| 201 | goto out; | ||
| 202 | } | ||
| 203 | |||
| 204 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
| 205 | |||
| 206 | out: | ||
| 207 | mutex_unlock(&info->lock); | ||
| 208 | return ret; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int max77686_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 212 | { | ||
| 213 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
| 214 | u8 data[RTC_NR_TIME]; | ||
| 215 | unsigned int val; | ||
| 216 | int i, ret; | ||
| 217 | |||
| 218 | mutex_lock(&info->lock); | ||
| 219 | |||
| 220 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
| 221 | if (ret < 0) | ||
| 222 | goto out; | ||
| 223 | |||
| 224 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
| 225 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
| 226 | if (ret < 0) { | ||
| 227 | dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n", | ||
| 228 | __func__, __LINE__, ret); | ||
| 229 | goto out; | ||
| 230 | } | ||
| 231 | |||
| 232 | max77686_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); | ||
| 233 | |||
| 234 | alrm->enabled = 0; | ||
| 235 | for (i = 0; i < RTC_NR_TIME; i++) { | ||
| 236 | if (data[i] & ALARM_ENABLE_MASK) { | ||
| 237 | alrm->enabled = 1; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | alrm->pending = 0; | ||
| 243 | ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS1, &val); | ||
| 244 | if (ret < 0) { | ||
| 245 | dev_err(info->dev, "%s:%d fail to read status1 reg(%d)\n", | ||
| 246 | __func__, __LINE__, ret); | ||
| 247 | goto out; | ||
| 248 | } | ||
| 249 | |||
| 250 | if (val & (1 << 4)) /* RTCA1 */ | ||
| 251 | alrm->pending = 1; | ||
| 252 | |||
| 253 | out: | ||
| 254 | mutex_unlock(&info->lock); | ||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | |||
| 258 | static int max77686_rtc_stop_alarm(struct max77686_rtc_info *info) | ||
| 259 | { | ||
| 260 | u8 data[RTC_NR_TIME]; | ||
| 261 | int ret, i; | ||
| 262 | struct rtc_time tm; | ||
| 263 | |||
| 264 | if (!mutex_is_locked(&info->lock)) | ||
| 265 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
| 266 | |||
| 267 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
| 268 | if (ret < 0) | ||
| 269 | goto out; | ||
| 270 | |||
| 271 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
| 272 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
| 273 | if (ret < 0) { | ||
| 274 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
| 275 | __func__, ret); | ||
| 276 | goto out; | ||
| 277 | } | ||
| 278 | |||
| 279 | max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode); | ||
| 280 | |||
| 281 | for (i = 0; i < RTC_NR_TIME; i++) | ||
| 282 | data[i] &= ~ALARM_ENABLE_MASK; | ||
| 283 | |||
| 284 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
| 285 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
| 286 | if (ret < 0) { | ||
| 287 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
| 288 | __func__, ret); | ||
| 289 | goto out; | ||
| 290 | } | ||
| 291 | |||
| 292 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
| 293 | out: | ||
| 294 | return ret; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int max77686_rtc_start_alarm(struct max77686_rtc_info *info) | ||
| 298 | { | ||
| 299 | u8 data[RTC_NR_TIME]; | ||
| 300 | int ret; | ||
| 301 | struct rtc_time tm; | ||
| 302 | |||
| 303 | if (!mutex_is_locked(&info->lock)) | ||
| 304 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
| 305 | |||
| 306 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
| 307 | if (ret < 0) | ||
| 308 | goto out; | ||
| 309 | |||
| 310 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
| 311 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
| 312 | if (ret < 0) { | ||
| 313 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
| 314 | __func__, ret); | ||
| 315 | goto out; | ||
| 316 | } | ||
| 317 | |||
| 318 | max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode); | ||
| 319 | |||
| 320 | data[RTC_SEC] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 321 | data[RTC_MIN] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 322 | data[RTC_HOUR] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 323 | data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK; | ||
| 324 | if (data[RTC_MONTH] & 0xf) | ||
| 325 | data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 326 | if (data[RTC_YEAR] & 0x7f) | ||
| 327 | data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 328 | if (data[RTC_DATE] & 0x1f) | ||
| 329 | data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 330 | |||
| 331 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
| 332 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
| 333 | if (ret < 0) { | ||
| 334 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
| 335 | __func__, ret); | ||
| 336 | goto out; | ||
| 337 | } | ||
| 338 | |||
| 339 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
| 340 | out: | ||
| 341 | return ret; | ||
| 342 | } | ||
| 343 | |||
| 344 | static int max77686_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 345 | { | ||
| 346 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
| 347 | u8 data[RTC_NR_TIME]; | ||
| 348 | int ret; | ||
| 349 | |||
| 350 | ret = max77686_rtc_tm_to_data(&alrm->time, data); | ||
| 351 | if (ret < 0) | ||
| 352 | return ret; | ||
| 353 | |||
| 354 | mutex_lock(&info->lock); | ||
| 355 | |||
| 356 | ret = max77686_rtc_stop_alarm(info); | ||
| 357 | if (ret < 0) | ||
| 358 | goto out; | ||
| 359 | |||
| 360 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
| 361 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
| 362 | |||
| 363 | if (ret < 0) { | ||
| 364 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
| 365 | __func__, ret); | ||
| 366 | goto out; | ||
| 367 | } | ||
| 368 | |||
| 369 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
| 370 | if (ret < 0) | ||
| 371 | goto out; | ||
| 372 | |||
| 373 | if (alrm->enabled) | ||
| 374 | ret = max77686_rtc_start_alarm(info); | ||
| 375 | out: | ||
| 376 | mutex_unlock(&info->lock); | ||
| 377 | return ret; | ||
| 378 | } | ||
| 379 | |||
| 380 | static int max77686_rtc_alarm_irq_enable(struct device *dev, | ||
| 381 | unsigned int enabled) | ||
| 382 | { | ||
| 383 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
| 384 | int ret; | ||
| 385 | |||
| 386 | mutex_lock(&info->lock); | ||
| 387 | if (enabled) | ||
| 388 | ret = max77686_rtc_start_alarm(info); | ||
| 389 | else | ||
| 390 | ret = max77686_rtc_stop_alarm(info); | ||
| 391 | mutex_unlock(&info->lock); | ||
| 392 | |||
| 393 | return ret; | ||
| 394 | } | ||
| 395 | |||
| 396 | static irqreturn_t max77686_rtc_alarm_irq(int irq, void *data) | ||
| 397 | { | ||
| 398 | struct max77686_rtc_info *info = data; | ||
| 399 | |||
| 400 | dev_info(info->dev, "%s:irq(%d)\n", __func__, irq); | ||
| 401 | |||
| 402 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
| 403 | |||
| 404 | return IRQ_HANDLED; | ||
| 405 | } | ||
| 406 | |||
| 407 | static const struct rtc_class_ops max77686_rtc_ops = { | ||
| 408 | .read_time = max77686_rtc_read_time, | ||
| 409 | .set_time = max77686_rtc_set_time, | ||
| 410 | .read_alarm = max77686_rtc_read_alarm, | ||
| 411 | .set_alarm = max77686_rtc_set_alarm, | ||
| 412 | .alarm_irq_enable = max77686_rtc_alarm_irq_enable, | ||
| 413 | }; | ||
| 414 | |||
| 415 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
| 416 | static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable) | ||
| 417 | { | ||
| 418 | int ret; | ||
| 419 | unsigned int val, mask; | ||
| 420 | |||
| 421 | if (enable) | ||
| 422 | val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); | ||
| 423 | else | ||
| 424 | val = 0; | ||
| 425 | |||
| 426 | mask = WTSR_EN_MASK | WTSRT_MASK; | ||
| 427 | |||
| 428 | dev_info(info->dev, "%s: %s WTSR\n", __func__, | ||
| 429 | enable ? "enable" : "disable"); | ||
| 430 | |||
| 431 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
| 432 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
| 433 | if (ret < 0) { | ||
| 434 | dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", | ||
| 435 | __func__, ret); | ||
| 436 | return; | ||
| 437 | } | ||
| 438 | |||
| 439 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
| 440 | } | ||
| 441 | |||
| 442 | static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable) | ||
| 443 | { | ||
| 444 | int ret; | ||
| 445 | unsigned int val, mask; | ||
| 446 | |||
| 447 | if (enable) | ||
| 448 | val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); | ||
| 449 | else | ||
| 450 | val = 0; | ||
| 451 | |||
| 452 | mask = SMPL_EN_MASK | SMPLT_MASK; | ||
| 453 | |||
| 454 | dev_info(info->dev, "%s: %s SMPL\n", __func__, | ||
| 455 | enable ? "enable" : "disable"); | ||
| 456 | |||
| 457 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
| 458 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
| 459 | if (ret < 0) { | ||
| 460 | dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", | ||
| 461 | __func__, ret); | ||
| 462 | return; | ||
| 463 | } | ||
| 464 | |||
| 465 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
| 466 | |||
| 467 | val = 0; | ||
| 468 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
| 469 | pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val); | ||
| 470 | } | ||
| 471 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
| 472 | |||
| 473 | static int max77686_rtc_init_reg(struct max77686_rtc_info *info) | ||
| 474 | { | ||
| 475 | u8 data[2]; | ||
| 476 | int ret; | ||
| 477 | |||
| 478 | /* Set RTC control register : Binary mode, 24hour mdoe */ | ||
| 479 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
| 480 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
| 481 | |||
| 482 | info->rtc_24hr_mode = 1; | ||
| 483 | |||
| 484 | ret = regmap_bulk_write(info->max77686->rtc_regmap, MAX77686_RTC_CONTROLM, data, 2); | ||
| 485 | if (ret < 0) { | ||
| 486 | dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", | ||
| 487 | __func__, ret); | ||
| 488 | return ret; | ||
| 489 | } | ||
| 490 | |||
| 491 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
| 492 | return ret; | ||
| 493 | } | ||
| 494 | |||
| 495 | static struct regmap_config max77686_rtc_regmap_config = { | ||
| 496 | .reg_bits = 8, | ||
| 497 | .val_bits = 8, | ||
| 498 | }; | ||
| 499 | |||
| 500 | static int max77686_rtc_probe(struct platform_device *pdev) | ||
| 501 | { | ||
| 502 | struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent); | ||
| 503 | struct max77686_rtc_info *info; | ||
| 504 | int ret, virq; | ||
| 505 | |||
| 506 | dev_info(&pdev->dev, "%s\n", __func__); | ||
| 507 | |||
| 508 | info = kzalloc(sizeof(struct max77686_rtc_info), GFP_KERNEL); | ||
| 509 | if (!info) | ||
| 510 | return -ENOMEM; | ||
| 511 | |||
| 512 | mutex_init(&info->lock); | ||
| 513 | info->dev = &pdev->dev; | ||
| 514 | info->max77686 = max77686; | ||
| 515 | info->rtc = max77686->rtc; | ||
| 516 | info->max77686->rtc_regmap = regmap_init_i2c(info->max77686->rtc, | ||
| 517 | &max77686_rtc_regmap_config); | ||
| 518 | if (IS_ERR(info->max77686->rtc_regmap)) { | ||
| 519 | ret = PTR_ERR(info->max77686->rtc_regmap); | ||
| 520 | dev_err(info->max77686->dev, "Failed to allocate register map: %d\n", | ||
| 521 | ret); | ||
| 522 | kfree(info); | ||
| 523 | return ret; | ||
| 524 | } | ||
| 525 | platform_set_drvdata(pdev, info); | ||
| 526 | |||
| 527 | ret = max77686_rtc_init_reg(info); | ||
| 528 | |||
| 529 | if (ret < 0) { | ||
| 530 | dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret); | ||
| 531 | goto err_rtc; | ||
| 532 | } | ||
| 533 | |||
| 534 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
| 535 | max77686_rtc_enable_wtsr(info, true); | ||
| 536 | max77686_rtc_enable_smpl(info, true); | ||
| 537 | #endif | ||
| 538 | |||
| 539 | device_init_wakeup(&pdev->dev, 1); | ||
| 540 | |||
| 541 | info->rtc_dev = rtc_device_register("max77686-rtc", &pdev->dev, | ||
| 542 | &max77686_rtc_ops, THIS_MODULE); | ||
| 543 | |||
| 544 | if (IS_ERR(info->rtc_dev)) { | ||
| 545 | dev_info(&pdev->dev, "%s: fail\n", __func__); | ||
| 546 | |||
| 547 | ret = PTR_ERR(info->rtc_dev); | ||
| 548 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
| 549 | if (ret == 0) | ||
| 550 | ret = -EINVAL; | ||
| 551 | goto err_rtc; | ||
| 552 | } | ||
| 553 | virq = irq_create_mapping(max77686->irq_domain, MAX77686_RTCIRQ_RTCA1); | ||
| 554 | if (!virq) | ||
| 555 | goto err_rtc; | ||
| 556 | info->virq = virq; | ||
| 557 | |||
| 558 | ret = request_threaded_irq(virq, NULL, max77686_rtc_alarm_irq, 0, | ||
| 559 | "rtc-alarm0", info); | ||
| 560 | if (ret < 0) { | ||
| 561 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | ||
| 562 | info->virq, ret); | ||
| 563 | goto err_rtc; | ||
| 564 | } | ||
| 565 | |||
| 566 | goto out; | ||
| 567 | err_rtc: | ||
| 568 | kfree(info); | ||
| 569 | return ret; | ||
| 570 | out: | ||
| 571 | return ret; | ||
| 572 | } | ||
| 573 | |||
| 574 | static int max77686_rtc_remove(struct platform_device *pdev) | ||
| 575 | { | ||
| 576 | struct max77686_rtc_info *info = platform_get_drvdata(pdev); | ||
| 577 | |||
| 578 | if (info) { | ||
| 579 | free_irq(info->virq, info); | ||
| 580 | rtc_device_unregister(info->rtc_dev); | ||
| 581 | kfree(info); | ||
| 582 | } | ||
| 583 | |||
| 584 | return 0; | ||
| 585 | } | ||
| 586 | |||
| 587 | static void max77686_rtc_shutdown(struct platform_device *pdev) | ||
| 588 | { | ||
| 589 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
| 590 | struct max77686_rtc_info *info = platform_get_drvdata(pdev); | ||
| 591 | int i; | ||
| 592 | u8 val = 0; | ||
| 593 | |||
| 594 | for (i = 0; i < 3; i++) { | ||
| 595 | max77686_rtc_enable_wtsr(info, false); | ||
| 596 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
| 597 | pr_info("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val); | ||
| 598 | if (val & WTSR_EN_MASK) | ||
| 599 | pr_emerg("%s: fail to disable WTSR\n", __func__); | ||
| 600 | else { | ||
| 601 | pr_info("%s: success to disable WTSR\n", __func__); | ||
| 602 | break; | ||
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | /* Disable SMPL when power off */ | ||
| 607 | max77686_rtc_enable_smpl(info, false); | ||
| 608 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
| 609 | } | ||
| 610 | |||
| 611 | static const struct platform_device_id rtc_id[] = { | ||
| 612 | { "max77686-rtc", 0 }, | ||
| 613 | {}, | ||
| 614 | }; | ||
| 615 | |||
| 616 | static struct platform_driver max77686_rtc_driver = { | ||
| 617 | .driver = { | ||
| 618 | .name = "max77686-rtc", | ||
| 619 | .owner = THIS_MODULE, | ||
| 620 | }, | ||
| 621 | .probe = max77686_rtc_probe, | ||
| 622 | .remove = max77686_rtc_remove, | ||
| 623 | .shutdown = max77686_rtc_shutdown, | ||
| 624 | .id_table = rtc_id, | ||
| 625 | }; | ||
| 626 | |||
| 627 | static int __init max77686_rtc_init(void) | ||
| 628 | { | ||
| 629 | return platform_driver_register(&max77686_rtc_driver); | ||
| 630 | } | ||
| 631 | module_init(max77686_rtc_init); | ||
| 632 | |||
| 633 | static void __exit max77686_rtc_exit(void) | ||
| 634 | { | ||
| 635 | platform_driver_unregister(&max77686_rtc_driver); | ||
| 636 | } | ||
| 637 | module_exit(max77686_rtc_exit); | ||
| 638 | |||
| 639 | MODULE_DESCRIPTION("Maxim MAX77686 RTC driver"); | ||
| 640 | MODULE_AUTHOR("<woong.byun@samsung.com>"); | ||
| 641 | MODULE_LICENSE("GPL"); | ||
| diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c index 1d049da16c85..31ca8faf9f05 100644 --- a/drivers/rtc/rtc-max8907.c +++ b/drivers/rtc/rtc-max8907.c | |||
| @@ -205,8 +205,9 @@ static int max8907_rtc_probe(struct platform_device *pdev) | |||
| 205 | goto err_unregister; | 205 | goto err_unregister; | 
| 206 | } | 206 | } | 
| 207 | 207 | ||
| 208 | ret = request_threaded_irq(rtc->irq, NULL, max8907_irq_handler, | 208 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | 
| 209 | IRQF_ONESHOT, "max8907-alarm0", rtc); | 209 | max8907_irq_handler, | 
| 210 | IRQF_ONESHOT, "max8907-alarm0", rtc); | ||
| 210 | if (ret < 0) { | 211 | if (ret < 0) { | 
| 211 | dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n", | 212 | dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n", | 
| 212 | rtc->irq, ret); | 213 | rtc->irq, ret); | 
| @@ -224,7 +225,6 @@ static int max8907_rtc_remove(struct platform_device *pdev) | |||
| 224 | { | 225 | { | 
| 225 | struct max8907_rtc *rtc = platform_get_drvdata(pdev); | 226 | struct max8907_rtc *rtc = platform_get_drvdata(pdev); | 
| 226 | 227 | ||
| 227 | free_irq(rtc->irq, rtc); | ||
| 228 | rtc_device_unregister(rtc->rtc_dev); | 228 | rtc_device_unregister(rtc->rtc_dev); | 
| 229 | 229 | ||
| 230 | return 0; | 230 | return 0; | 
| diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c new file mode 100644 index 000000000000..00e505b6bee3 --- /dev/null +++ b/drivers/rtc/rtc-max8997.c | |||
| @@ -0,0 +1,552 @@ | |||
| 1 | /* | ||
| 2 | * RTC driver for Maxim MAX8997 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013 Samsung Electronics Co.Ltd | ||
| 5 | * | ||
| 6 | * based on rtc-max8998.c | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/rtc.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/mutex.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/mfd/max8997-private.h> | ||
| 22 | #include <linux/irqdomain.h> | ||
| 23 | |||
| 24 | /* Module parameter for WTSR function control */ | ||
| 25 | static int wtsr_en = 1; | ||
| 26 | module_param(wtsr_en, int, 0444); | ||
| 27 | MODULE_PARM_DESC(wtsr_en, "Wachdog Timeout & Sofware Reset (default=on)"); | ||
| 28 | /* Module parameter for SMPL function control */ | ||
| 29 | static int smpl_en = 1; | ||
| 30 | module_param(smpl_en, int, 0444); | ||
| 31 | MODULE_PARM_DESC(smpl_en, "Sudden Momentary Power Loss (default=on)"); | ||
| 32 | |||
| 33 | /* RTC Control Register */ | ||
| 34 | #define BCD_EN_SHIFT 0 | ||
| 35 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) | ||
| 36 | #define MODEL24_SHIFT 1 | ||
| 37 | #define MODEL24_MASK (1 << MODEL24_SHIFT) | ||
| 38 | /* RTC Update Register1 */ | ||
| 39 | #define RTC_UDR_SHIFT 0 | ||
| 40 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | ||
| 41 | /* WTSR and SMPL Register */ | ||
| 42 | #define WTSRT_SHIFT 0 | ||
| 43 | #define SMPLT_SHIFT 2 | ||
| 44 | #define WTSR_EN_SHIFT 6 | ||
| 45 | #define SMPL_EN_SHIFT 7 | ||
| 46 | #define WTSRT_MASK (3 << WTSRT_SHIFT) | ||
| 47 | #define SMPLT_MASK (3 << SMPLT_SHIFT) | ||
| 48 | #define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) | ||
| 49 | #define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) | ||
| 50 | /* RTC Hour register */ | ||
| 51 | #define HOUR_PM_SHIFT 6 | ||
| 52 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | ||
| 53 | /* RTC Alarm Enable */ | ||
| 54 | #define ALARM_ENABLE_SHIFT 7 | ||
| 55 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | ||
| 56 | |||
| 57 | enum { | ||
| 58 | RTC_SEC = 0, | ||
| 59 | RTC_MIN, | ||
| 60 | RTC_HOUR, | ||
| 61 | RTC_WEEKDAY, | ||
| 62 | RTC_MONTH, | ||
| 63 | RTC_YEAR, | ||
| 64 | RTC_DATE, | ||
| 65 | RTC_NR_TIME | ||
| 66 | }; | ||
| 67 | |||
| 68 | struct max8997_rtc_info { | ||
| 69 | struct device *dev; | ||
| 70 | struct max8997_dev *max8997; | ||
| 71 | struct i2c_client *rtc; | ||
| 72 | struct rtc_device *rtc_dev; | ||
| 73 | struct mutex lock; | ||
| 74 | int virq; | ||
| 75 | int rtc_24hr_mode; | ||
| 76 | }; | ||
| 77 | |||
| 78 | static void max8997_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | ||
| 79 | int rtc_24hr_mode) | ||
| 80 | { | ||
| 81 | tm->tm_sec = data[RTC_SEC] & 0x7f; | ||
| 82 | tm->tm_min = data[RTC_MIN] & 0x7f; | ||
| 83 | if (rtc_24hr_mode) | ||
| 84 | tm->tm_hour = data[RTC_HOUR] & 0x1f; | ||
| 85 | else { | ||
| 86 | tm->tm_hour = data[RTC_HOUR] & 0x0f; | ||
| 87 | if (data[RTC_HOUR] & HOUR_PM_MASK) | ||
| 88 | tm->tm_hour += 12; | ||
| 89 | } | ||
| 90 | |||
| 91 | tm->tm_wday = fls(data[RTC_WEEKDAY] & 0x7f) - 1; | ||
| 92 | tm->tm_mday = data[RTC_DATE] & 0x1f; | ||
| 93 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | ||
| 94 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; | ||
| 95 | tm->tm_yday = 0; | ||
| 96 | tm->tm_isdst = 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int max8997_rtc_tm_to_data(struct rtc_time *tm, u8 *data) | ||
| 100 | { | ||
| 101 | data[RTC_SEC] = tm->tm_sec; | ||
| 102 | data[RTC_MIN] = tm->tm_min; | ||
| 103 | data[RTC_HOUR] = tm->tm_hour; | ||
| 104 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; | ||
| 105 | data[RTC_DATE] = tm->tm_mday; | ||
| 106 | data[RTC_MONTH] = tm->tm_mon + 1; | ||
| 107 | data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0 ; | ||
| 108 | |||
| 109 | if (tm->tm_year < 100) { | ||
| 110 | pr_warn("%s: MAX8997 RTC cannot handle the year %d." | ||
| 111 | "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); | ||
| 112 | return -EINVAL; | ||
| 113 | } | ||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | static inline int max8997_rtc_set_update_reg(struct max8997_rtc_info *info) | ||
| 118 | { | ||
| 119 | int ret; | ||
| 120 | |||
| 121 | ret = max8997_write_reg(info->rtc, MAX8997_RTC_UPDATE1, | ||
| 122 | RTC_UDR_MASK); | ||
| 123 | if (ret < 0) | ||
| 124 | dev_err(info->dev, "%s: fail to write update reg(%d)\n", | ||
| 125 | __func__, ret); | ||
| 126 | else { | ||
| 127 | /* Minimum 16ms delay required before RTC update. | ||
| 128 | * Otherwise, we may read and update based on out-of-date | ||
| 129 | * value */ | ||
| 130 | msleep(20); | ||
| 131 | } | ||
| 132 | |||
| 133 | return ret; | ||
| 134 | } | ||
| 135 | |||
| 136 | static int max8997_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 137 | { | ||
| 138 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
| 139 | u8 data[RTC_NR_TIME]; | ||
| 140 | int ret; | ||
| 141 | |||
| 142 | mutex_lock(&info->lock); | ||
| 143 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_SEC, RTC_NR_TIME, data); | ||
| 144 | mutex_unlock(&info->lock); | ||
| 145 | |||
| 146 | if (ret < 0) { | ||
| 147 | dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, | ||
| 148 | ret); | ||
| 149 | return ret; | ||
| 150 | } | ||
| 151 | |||
| 152 | max8997_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); | ||
| 153 | |||
| 154 | return rtc_valid_tm(tm); | ||
| 155 | } | ||
| 156 | |||
| 157 | static int max8997_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 158 | { | ||
| 159 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
| 160 | u8 data[RTC_NR_TIME]; | ||
| 161 | int ret; | ||
| 162 | |||
| 163 | ret = max8997_rtc_tm_to_data(tm, data); | ||
| 164 | if (ret < 0) | ||
| 165 | return ret; | ||
| 166 | |||
| 167 | mutex_lock(&info->lock); | ||
| 168 | |||
| 169 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_SEC, RTC_NR_TIME, data); | ||
| 170 | if (ret < 0) { | ||
| 171 | dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__, | ||
| 172 | ret); | ||
| 173 | goto out; | ||
| 174 | } | ||
| 175 | |||
| 176 | ret = max8997_rtc_set_update_reg(info); | ||
| 177 | out: | ||
| 178 | mutex_unlock(&info->lock); | ||
| 179 | return ret; | ||
| 180 | } | ||
| 181 | |||
| 182 | static int max8997_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 183 | { | ||
| 184 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
| 185 | u8 data[RTC_NR_TIME]; | ||
| 186 | u8 val; | ||
| 187 | int i, ret; | ||
| 188 | |||
| 189 | mutex_lock(&info->lock); | ||
| 190 | |||
| 191 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
| 192 | data); | ||
| 193 | if (ret < 0) { | ||
| 194 | dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n", | ||
| 195 | __func__, __LINE__, ret); | ||
| 196 | goto out; | ||
| 197 | } | ||
| 198 | |||
| 199 | max8997_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); | ||
| 200 | |||
| 201 | alrm->enabled = 0; | ||
| 202 | for (i = 0; i < RTC_NR_TIME; i++) { | ||
| 203 | if (data[i] & ALARM_ENABLE_MASK) { | ||
| 204 | alrm->enabled = 1; | ||
| 205 | break; | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | alrm->pending = 0; | ||
| 210 | ret = max8997_read_reg(info->max8997->i2c, MAX8997_REG_STATUS1, &val); | ||
| 211 | if (ret < 0) { | ||
| 212 | dev_err(info->dev, "%s:%d fail to read status1 reg(%d)\n", | ||
| 213 | __func__, __LINE__, ret); | ||
| 214 | goto out; | ||
| 215 | } | ||
| 216 | |||
| 217 | if (val & (1 << 4)) /* RTCA1 */ | ||
| 218 | alrm->pending = 1; | ||
| 219 | |||
| 220 | out: | ||
| 221 | mutex_unlock(&info->lock); | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int max8997_rtc_stop_alarm(struct max8997_rtc_info *info) | ||
| 226 | { | ||
| 227 | u8 data[RTC_NR_TIME]; | ||
| 228 | int ret, i; | ||
| 229 | |||
| 230 | if (!mutex_is_locked(&info->lock)) | ||
| 231 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
| 232 | |||
| 233 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
| 234 | data); | ||
| 235 | if (ret < 0) { | ||
| 236 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
| 237 | __func__, ret); | ||
| 238 | goto out; | ||
| 239 | } | ||
| 240 | |||
| 241 | for (i = 0; i < RTC_NR_TIME; i++) | ||
| 242 | data[i] &= ~ALARM_ENABLE_MASK; | ||
| 243 | |||
| 244 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
| 245 | data); | ||
| 246 | if (ret < 0) { | ||
| 247 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
| 248 | __func__, ret); | ||
| 249 | goto out; | ||
| 250 | } | ||
| 251 | |||
| 252 | ret = max8997_rtc_set_update_reg(info); | ||
| 253 | out: | ||
| 254 | return ret; | ||
| 255 | } | ||
| 256 | |||
| 257 | static int max8997_rtc_start_alarm(struct max8997_rtc_info *info) | ||
| 258 | { | ||
| 259 | u8 data[RTC_NR_TIME]; | ||
| 260 | int ret; | ||
| 261 | |||
| 262 | if (!mutex_is_locked(&info->lock)) | ||
| 263 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
| 264 | |||
| 265 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
| 266 | data); | ||
| 267 | if (ret < 0) { | ||
| 268 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
| 269 | __func__, ret); | ||
| 270 | goto out; | ||
| 271 | } | ||
| 272 | |||
| 273 | data[RTC_SEC] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 274 | data[RTC_MIN] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 275 | data[RTC_HOUR] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 276 | data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK; | ||
| 277 | if (data[RTC_MONTH] & 0xf) | ||
| 278 | data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 279 | if (data[RTC_YEAR] & 0x7f) | ||
| 280 | data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 281 | if (data[RTC_DATE] & 0x1f) | ||
| 282 | data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT); | ||
| 283 | |||
| 284 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
| 285 | data); | ||
| 286 | if (ret < 0) { | ||
| 287 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
| 288 | __func__, ret); | ||
| 289 | goto out; | ||
| 290 | } | ||
| 291 | |||
| 292 | ret = max8997_rtc_set_update_reg(info); | ||
| 293 | out: | ||
| 294 | return ret; | ||
| 295 | } | ||
| 296 | static int max8997_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 297 | { | ||
| 298 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
| 299 | u8 data[RTC_NR_TIME]; | ||
| 300 | int ret; | ||
| 301 | |||
| 302 | ret = max8997_rtc_tm_to_data(&alrm->time, data); | ||
| 303 | if (ret < 0) | ||
| 304 | return ret; | ||
| 305 | |||
| 306 | dev_info(info->dev, "%s: %d-%02d-%02d %02d:%02d:%02d\n", __func__, | ||
| 307 | data[RTC_YEAR] + 2000, data[RTC_MONTH], data[RTC_DATE], | ||
| 308 | data[RTC_HOUR], data[RTC_MIN], data[RTC_SEC]); | ||
| 309 | |||
| 310 | mutex_lock(&info->lock); | ||
| 311 | |||
| 312 | ret = max8997_rtc_stop_alarm(info); | ||
| 313 | if (ret < 0) | ||
| 314 | goto out; | ||
| 315 | |||
| 316 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
| 317 | data); | ||
| 318 | if (ret < 0) { | ||
| 319 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
| 320 | __func__, ret); | ||
| 321 | goto out; | ||
| 322 | } | ||
| 323 | |||
| 324 | ret = max8997_rtc_set_update_reg(info); | ||
| 325 | if (ret < 0) | ||
| 326 | goto out; | ||
| 327 | |||
| 328 | if (alrm->enabled) | ||
| 329 | ret = max8997_rtc_start_alarm(info); | ||
| 330 | out: | ||
| 331 | mutex_unlock(&info->lock); | ||
| 332 | return ret; | ||
| 333 | } | ||
| 334 | |||
| 335 | static int max8997_rtc_alarm_irq_enable(struct device *dev, | ||
| 336 | unsigned int enabled) | ||
| 337 | { | ||
| 338 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
| 339 | int ret; | ||
| 340 | |||
| 341 | mutex_lock(&info->lock); | ||
| 342 | if (enabled) | ||
| 343 | ret = max8997_rtc_start_alarm(info); | ||
| 344 | else | ||
| 345 | ret = max8997_rtc_stop_alarm(info); | ||
| 346 | mutex_unlock(&info->lock); | ||
| 347 | |||
| 348 | return ret; | ||
| 349 | } | ||
| 350 | |||
| 351 | static irqreturn_t max8997_rtc_alarm_irq(int irq, void *data) | ||
| 352 | { | ||
| 353 | struct max8997_rtc_info *info = data; | ||
| 354 | |||
| 355 | dev_info(info->dev, "%s:irq(%d)\n", __func__, irq); | ||
| 356 | |||
| 357 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
| 358 | |||
| 359 | return IRQ_HANDLED; | ||
| 360 | } | ||
| 361 | |||
| 362 | static const struct rtc_class_ops max8997_rtc_ops = { | ||
| 363 | .read_time = max8997_rtc_read_time, | ||
| 364 | .set_time = max8997_rtc_set_time, | ||
| 365 | .read_alarm = max8997_rtc_read_alarm, | ||
| 366 | .set_alarm = max8997_rtc_set_alarm, | ||
| 367 | .alarm_irq_enable = max8997_rtc_alarm_irq_enable, | ||
| 368 | }; | ||
| 369 | |||
| 370 | static void max8997_rtc_enable_wtsr(struct max8997_rtc_info *info, bool enable) | ||
| 371 | { | ||
| 372 | int ret; | ||
| 373 | u8 val, mask; | ||
| 374 | |||
| 375 | if (!wtsr_en) | ||
| 376 | return; | ||
| 377 | |||
| 378 | if (enable) | ||
| 379 | val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); | ||
| 380 | else | ||
| 381 | val = 0; | ||
| 382 | |||
| 383 | mask = WTSR_EN_MASK | WTSRT_MASK; | ||
| 384 | |||
| 385 | dev_info(info->dev, "%s: %s WTSR\n", __func__, | ||
| 386 | enable ? "enable" : "disable"); | ||
| 387 | |||
| 388 | ret = max8997_update_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, val, mask); | ||
| 389 | if (ret < 0) { | ||
| 390 | dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", | ||
| 391 | __func__, ret); | ||
| 392 | return; | ||
| 393 | } | ||
| 394 | |||
| 395 | max8997_rtc_set_update_reg(info); | ||
| 396 | } | ||
| 397 | |||
| 398 | static void max8997_rtc_enable_smpl(struct max8997_rtc_info *info, bool enable) | ||
| 399 | { | ||
| 400 | int ret; | ||
| 401 | u8 val, mask; | ||
| 402 | |||
| 403 | if (!smpl_en) | ||
| 404 | return; | ||
| 405 | |||
| 406 | if (enable) | ||
| 407 | val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); | ||
| 408 | else | ||
| 409 | val = 0; | ||
| 410 | |||
| 411 | mask = SMPL_EN_MASK | SMPLT_MASK; | ||
| 412 | |||
| 413 | dev_info(info->dev, "%s: %s SMPL\n", __func__, | ||
| 414 | enable ? "enable" : "disable"); | ||
| 415 | |||
| 416 | ret = max8997_update_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, val, mask); | ||
| 417 | if (ret < 0) { | ||
| 418 | dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", | ||
| 419 | __func__, ret); | ||
| 420 | return; | ||
| 421 | } | ||
| 422 | |||
| 423 | max8997_rtc_set_update_reg(info); | ||
| 424 | |||
| 425 | val = 0; | ||
| 426 | max8997_read_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, &val); | ||
| 427 | pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val); | ||
| 428 | } | ||
| 429 | |||
| 430 | static int max8997_rtc_init_reg(struct max8997_rtc_info *info) | ||
| 431 | { | ||
| 432 | u8 data[2]; | ||
| 433 | int ret; | ||
| 434 | |||
| 435 | /* Set RTC control register : Binary mode, 24hour mdoe */ | ||
| 436 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
| 437 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
| 438 | |||
| 439 | info->rtc_24hr_mode = 1; | ||
| 440 | |||
| 441 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_CTRLMASK, 2, data); | ||
| 442 | if (ret < 0) { | ||
| 443 | dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", | ||
| 444 | __func__, ret); | ||
| 445 | return ret; | ||
| 446 | } | ||
| 447 | |||
| 448 | ret = max8997_rtc_set_update_reg(info); | ||
| 449 | return ret; | ||
| 450 | } | ||
| 451 | |||
| 452 | static int max8997_rtc_probe(struct platform_device *pdev) | ||
| 453 | { | ||
| 454 | struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); | ||
| 455 | struct max8997_rtc_info *info; | ||
| 456 | int ret, virq; | ||
| 457 | |||
| 458 | info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_rtc_info), | ||
| 459 | GFP_KERNEL); | ||
| 460 | if (!info) | ||
| 461 | return -ENOMEM; | ||
| 462 | |||
| 463 | mutex_init(&info->lock); | ||
| 464 | info->dev = &pdev->dev; | ||
| 465 | info->max8997 = max8997; | ||
| 466 | info->rtc = max8997->rtc; | ||
| 467 | |||
| 468 | platform_set_drvdata(pdev, info); | ||
| 469 | |||
| 470 | ret = max8997_rtc_init_reg(info); | ||
| 471 | |||
| 472 | if (ret < 0) { | ||
| 473 | dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret); | ||
| 474 | return ret; | ||
| 475 | } | ||
| 476 | |||
| 477 | max8997_rtc_enable_wtsr(info, true); | ||
| 478 | max8997_rtc_enable_smpl(info, true); | ||
| 479 | |||
| 480 | device_init_wakeup(&pdev->dev, 1); | ||
| 481 | |||
| 482 | info->rtc_dev = rtc_device_register("max8997-rtc", &pdev->dev, | ||
| 483 | &max8997_rtc_ops, THIS_MODULE); | ||
| 484 | |||
| 485 | if (IS_ERR(info->rtc_dev)) { | ||
| 486 | ret = PTR_ERR(info->rtc_dev); | ||
| 487 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
| 488 | return ret; | ||
| 489 | } | ||
| 490 | |||
| 491 | virq = irq_create_mapping(max8997->irq_domain, MAX8997_PMICIRQ_RTCA1); | ||
| 492 | if (!virq) { | ||
| 493 | dev_err(&pdev->dev, "Failed to create mapping alarm IRQ\n"); | ||
| 494 | goto err_out; | ||
| 495 | } | ||
| 496 | info->virq = virq; | ||
| 497 | |||
| 498 | ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, | ||
| 499 | max8997_rtc_alarm_irq, 0, | ||
| 500 | "rtc-alarm0", info); | ||
| 501 | if (ret < 0) { | ||
| 502 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | ||
| 503 | info->virq, ret); | ||
| 504 | goto err_out; | ||
| 505 | } | ||
| 506 | |||
| 507 | return ret; | ||
| 508 | |||
| 509 | err_out: | ||
| 510 | rtc_device_unregister(info->rtc_dev); | ||
| 511 | return ret; | ||
| 512 | } | ||
| 513 | |||
| 514 | static int max8997_rtc_remove(struct platform_device *pdev) | ||
| 515 | { | ||
| 516 | struct max8997_rtc_info *info = platform_get_drvdata(pdev); | ||
| 517 | |||
| 518 | if (info) | ||
| 519 | rtc_device_unregister(info->rtc_dev); | ||
| 520 | |||
| 521 | return 0; | ||
| 522 | } | ||
| 523 | |||
| 524 | static void max8997_rtc_shutdown(struct platform_device *pdev) | ||
| 525 | { | ||
| 526 | struct max8997_rtc_info *info = platform_get_drvdata(pdev); | ||
| 527 | |||
| 528 | max8997_rtc_enable_wtsr(info, false); | ||
| 529 | max8997_rtc_enable_smpl(info, false); | ||
| 530 | } | ||
| 531 | |||
| 532 | static const struct platform_device_id rtc_id[] = { | ||
| 533 | { "max8997-rtc", 0 }, | ||
| 534 | {}, | ||
| 535 | }; | ||
| 536 | |||
| 537 | static struct platform_driver max8997_rtc_driver = { | ||
| 538 | .driver = { | ||
| 539 | .name = "max8997-rtc", | ||
| 540 | .owner = THIS_MODULE, | ||
| 541 | }, | ||
| 542 | .probe = max8997_rtc_probe, | ||
| 543 | .remove = max8997_rtc_remove, | ||
| 544 | .shutdown = max8997_rtc_shutdown, | ||
| 545 | .id_table = rtc_id, | ||
| 546 | }; | ||
| 547 | |||
| 548 | module_platform_driver(max8997_rtc_driver); | ||
| 549 | |||
| 550 | MODULE_DESCRIPTION("Maxim MAX8997 RTC driver"); | ||
| 551 | MODULE_AUTHOR("<ms925.kim@samsung.com>"); | ||
| 552 | MODULE_LICENSE("GPL"); | ||
| diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index bec10be96f84..bdcc60830aec 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> | 
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> | 
| 15 | #include <linux/rtc.h> | 15 | #include <linux/rtc.h> | 
| 16 | #include <linux/of.h> | ||
| 16 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> | 
| 17 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> | 
| 18 | #include <linux/io.h> | 19 | #include <linux/io.h> | 
| @@ -403,17 +404,19 @@ static int mpc5121_rtc_remove(struct platform_device *op) | |||
| 403 | return 0; | 404 | return 0; | 
| 404 | } | 405 | } | 
| 405 | 406 | ||
| 407 | #ifdef CONFIG_OF | ||
| 406 | static struct of_device_id mpc5121_rtc_match[] = { | 408 | static struct of_device_id mpc5121_rtc_match[] = { | 
| 407 | { .compatible = "fsl,mpc5121-rtc", }, | 409 | { .compatible = "fsl,mpc5121-rtc", }, | 
| 408 | { .compatible = "fsl,mpc5200-rtc", }, | 410 | { .compatible = "fsl,mpc5200-rtc", }, | 
| 409 | {}, | 411 | {}, | 
| 410 | }; | 412 | }; | 
| 413 | #endif | ||
| 411 | 414 | ||
| 412 | static struct platform_driver mpc5121_rtc_driver = { | 415 | static struct platform_driver mpc5121_rtc_driver = { | 
| 413 | .driver = { | 416 | .driver = { | 
| 414 | .name = "mpc5121-rtc", | 417 | .name = "mpc5121-rtc", | 
| 415 | .owner = THIS_MODULE, | 418 | .owner = THIS_MODULE, | 
| 416 | .of_match_table = mpc5121_rtc_match, | 419 | .of_match_table = of_match_ptr(mpc5121_rtc_match), | 
| 417 | }, | 420 | }, | 
| 418 | .probe = mpc5121_rtc_probe, | 421 | .probe = mpc5121_rtc_probe, | 
| 419 | .remove = mpc5121_rtc_remove, | 422 | .remove = mpc5121_rtc_remove, | 
| diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c new file mode 100644 index 000000000000..59c42986254e --- /dev/null +++ b/drivers/rtc/rtc-palmas.c | |||
| @@ -0,0 +1,339 @@ | |||
| 1 | /* | ||
| 2 | * rtc-palmas.c -- Palmas Real Time Clock driver. | ||
| 3 | |||
| 4 | * RTC driver for TI Palma series devices like TPS65913, | ||
| 5 | * TPS65914 power management IC. | ||
| 6 | * | ||
| 7 | * Copyright (c) 2012, NVIDIA Corporation. | ||
| 8 | * | ||
| 9 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or | ||
| 12 | * modify it under the terms of the GNU General Public License as | ||
| 13 | * published by the Free Software Foundation version 2. | ||
| 14 | * | ||
| 15 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
| 16 | * whether express or implied; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/bcd.h> | ||
| 27 | #include <linux/errno.h> | ||
| 28 | #include <linux/init.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/mfd/palmas.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | #include <linux/rtc.h> | ||
| 34 | #include <linux/types.h> | ||
| 35 | #include <linux/platform_device.h> | ||
| 36 | #include <linux/pm.h> | ||
| 37 | |||
| 38 | struct palmas_rtc { | ||
| 39 | struct rtc_device *rtc; | ||
| 40 | struct device *dev; | ||
| 41 | unsigned int irq; | ||
| 42 | }; | ||
| 43 | |||
| 44 | /* Total number of RTC registers needed to set time*/ | ||
| 45 | #define PALMAS_NUM_TIME_REGS (PALMAS_YEARS_REG - PALMAS_SECONDS_REG + 1) | ||
| 46 | |||
| 47 | static int palmas_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 48 | { | ||
| 49 | unsigned char rtc_data[PALMAS_NUM_TIME_REGS]; | ||
| 50 | struct palmas *palmas = dev_get_drvdata(dev->parent); | ||
| 51 | int ret; | ||
| 52 | |||
| 53 | /* Copy RTC counting registers to static registers or latches */ | ||
| 54 | ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, | ||
| 55 | PALMAS_RTC_CTRL_REG_GET_TIME, PALMAS_RTC_CTRL_REG_GET_TIME); | ||
| 56 | if (ret < 0) { | ||
| 57 | dev_err(dev, "RTC CTRL reg update failed, err: %d\n", ret); | ||
| 58 | return ret; | ||
| 59 | } | ||
| 60 | |||
| 61 | ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG, | ||
| 62 | rtc_data, PALMAS_NUM_TIME_REGS); | ||
| 63 | if (ret < 0) { | ||
| 64 | dev_err(dev, "RTC_SECONDS reg read failed, err = %d\n", ret); | ||
| 65 | return ret; | ||
| 66 | } | ||
| 67 | |||
| 68 | tm->tm_sec = bcd2bin(rtc_data[0]); | ||
| 69 | tm->tm_min = bcd2bin(rtc_data[1]); | ||
| 70 | tm->tm_hour = bcd2bin(rtc_data[2]); | ||
| 71 | tm->tm_mday = bcd2bin(rtc_data[3]); | ||
| 72 | tm->tm_mon = bcd2bin(rtc_data[4]) - 1; | ||
| 73 | tm->tm_year = bcd2bin(rtc_data[5]) + 100; | ||
| 74 | |||
| 75 | return ret; | ||
| 76 | } | ||
| 77 | |||
| 78 | static int palmas_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 79 | { | ||
| 80 | unsigned char rtc_data[PALMAS_NUM_TIME_REGS]; | ||
| 81 | struct palmas *palmas = dev_get_drvdata(dev->parent); | ||
| 82 | int ret; | ||
| 83 | |||
| 84 | rtc_data[0] = bin2bcd(tm->tm_sec); | ||
| 85 | rtc_data[1] = bin2bcd(tm->tm_min); | ||
| 86 | rtc_data[2] = bin2bcd(tm->tm_hour); | ||
| 87 | rtc_data[3] = bin2bcd(tm->tm_mday); | ||
| 88 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); | ||
| 89 | rtc_data[5] = bin2bcd(tm->tm_year - 100); | ||
| 90 | |||
| 91 | /* Stop RTC while updating the RTC time registers */ | ||
| 92 | ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, | ||
| 93 | PALMAS_RTC_CTRL_REG_STOP_RTC, 0); | ||
| 94 | if (ret < 0) { | ||
| 95 | dev_err(dev, "RTC stop failed, err = %d\n", ret); | ||
| 96 | return ret; | ||
| 97 | } | ||
| 98 | |||
| 99 | ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG, | ||
| 100 | rtc_data, PALMAS_NUM_TIME_REGS); | ||
| 101 | if (ret < 0) { | ||
| 102 | dev_err(dev, "RTC_SECONDS reg write failed, err = %d\n", ret); | ||
| 103 | return ret; | ||
| 104 | } | ||
| 105 | |||
| 106 | /* Start back RTC */ | ||
| 107 | ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, | ||
| 108 | PALMAS_RTC_CTRL_REG_STOP_RTC, PALMAS_RTC_CTRL_REG_STOP_RTC); | ||
| 109 | if (ret < 0) | ||
| 110 | dev_err(dev, "RTC start failed, err = %d\n", ret); | ||
| 111 | return ret; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int palmas_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | ||
| 115 | { | ||
| 116 | struct palmas *palmas = dev_get_drvdata(dev->parent); | ||
| 117 | u8 val; | ||
| 118 | |||
| 119 | val = enabled ? PALMAS_RTC_INTERRUPTS_REG_IT_ALARM : 0; | ||
| 120 | return palmas_write(palmas, PALMAS_RTC_BASE, | ||
| 121 | PALMAS_RTC_INTERRUPTS_REG, val); | ||
| 122 | } | ||
| 123 | |||
| 124 | static int palmas_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
| 125 | { | ||
| 126 | unsigned char alarm_data[PALMAS_NUM_TIME_REGS]; | ||
| 127 | u32 int_val; | ||
| 128 | struct palmas *palmas = dev_get_drvdata(dev->parent); | ||
| 129 | int ret; | ||
| 130 | |||
| 131 | ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE, | ||
| 132 | PALMAS_ALARM_SECONDS_REG, | ||
| 133 | alarm_data, PALMAS_NUM_TIME_REGS); | ||
| 134 | if (ret < 0) { | ||
| 135 | dev_err(dev, "RTC_ALARM_SECONDS read failed, err = %d\n", ret); | ||
| 136 | return ret; | ||
| 137 | } | ||
| 138 | |||
| 139 | alm->time.tm_sec = bcd2bin(alarm_data[0]); | ||
| 140 | alm->time.tm_min = bcd2bin(alarm_data[1]); | ||
| 141 | alm->time.tm_hour = bcd2bin(alarm_data[2]); | ||
| 142 | alm->time.tm_mday = bcd2bin(alarm_data[3]); | ||
| 143 | alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1; | ||
| 144 | alm->time.tm_year = bcd2bin(alarm_data[5]) + 100; | ||
| 145 | |||
| 146 | ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_INTERRUPTS_REG, | ||
| 147 | &int_val); | ||
| 148 | if (ret < 0) { | ||
| 149 | dev_err(dev, "RTC_INTERRUPTS reg read failed, err = %d\n", ret); | ||
| 150 | return ret; | ||
| 151 | } | ||
| 152 | |||
| 153 | if (int_val & PALMAS_RTC_INTERRUPTS_REG_IT_ALARM) | ||
| 154 | alm->enabled = 1; | ||
| 155 | return ret; | ||
| 156 | } | ||
| 157 | |||
| 158 | static int palmas_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
| 159 | { | ||
| 160 | unsigned char alarm_data[PALMAS_NUM_TIME_REGS]; | ||
| 161 | struct palmas *palmas = dev_get_drvdata(dev->parent); | ||
| 162 | int ret; | ||
| 163 | |||
| 164 | ret = palmas_rtc_alarm_irq_enable(dev, 0); | ||
| 165 | if (ret < 0) { | ||
| 166 | dev_err(dev, "Disable RTC alarm failed\n"); | ||
| 167 | return ret; | ||
| 168 | } | ||
| 169 | |||
| 170 | alarm_data[0] = bin2bcd(alm->time.tm_sec); | ||
| 171 | alarm_data[1] = bin2bcd(alm->time.tm_min); | ||
| 172 | alarm_data[2] = bin2bcd(alm->time.tm_hour); | ||
| 173 | alarm_data[3] = bin2bcd(alm->time.tm_mday); | ||
| 174 | alarm_data[4] = bin2bcd(alm->time.tm_mon + 1); | ||
| 175 | alarm_data[5] = bin2bcd(alm->time.tm_year - 100); | ||
| 176 | |||
| 177 | ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE, | ||
| 178 | PALMAS_ALARM_SECONDS_REG, alarm_data, PALMAS_NUM_TIME_REGS); | ||
| 179 | if (ret < 0) { | ||
| 180 | dev_err(dev, "ALARM_SECONDS_REG write failed, err = %d\n", ret); | ||
| 181 | return ret; | ||
| 182 | } | ||
| 183 | |||
| 184 | if (alm->enabled) | ||
| 185 | ret = palmas_rtc_alarm_irq_enable(dev, 1); | ||
| 186 | return ret; | ||
| 187 | } | ||
| 188 | |||
| 189 | static int palmas_clear_interrupts(struct device *dev) | ||
| 190 | { | ||
| 191 | struct palmas *palmas = dev_get_drvdata(dev->parent); | ||
| 192 | unsigned int rtc_reg; | ||
| 193 | int ret; | ||
| 194 | |||
| 195 | ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG, | ||
| 196 | &rtc_reg); | ||
| 197 | if (ret < 0) { | ||
| 198 | dev_err(dev, "RTC_STATUS read failed, err = %d\n", ret); | ||
| 199 | return ret; | ||
| 200 | } | ||
| 201 | |||
| 202 | ret = palmas_write(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG, | ||
| 203 | rtc_reg); | ||
| 204 | if (ret < 0) { | ||
| 205 | dev_err(dev, "RTC_STATUS write failed, err = %d\n", ret); | ||
| 206 | return ret; | ||
| 207 | } | ||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | |||
| 211 | static irqreturn_t palmas_rtc_interrupt(int irq, void *context) | ||
| 212 | { | ||
| 213 | struct palmas_rtc *palmas_rtc = context; | ||
| 214 | struct device *dev = palmas_rtc->dev; | ||
| 215 | int ret; | ||
| 216 | |||
| 217 | ret = palmas_clear_interrupts(dev); | ||
| 218 | if (ret < 0) { | ||
| 219 | dev_err(dev, "RTC interrupt clear failed, err = %d\n", ret); | ||
| 220 | return IRQ_NONE; | ||
| 221 | } | ||
| 222 | |||
| 223 | rtc_update_irq(palmas_rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
| 224 | return IRQ_HANDLED; | ||
| 225 | } | ||
| 226 | |||
| 227 | static struct rtc_class_ops palmas_rtc_ops = { | ||
| 228 | .read_time = palmas_rtc_read_time, | ||
| 229 | .set_time = palmas_rtc_set_time, | ||
| 230 | .read_alarm = palmas_rtc_read_alarm, | ||
| 231 | .set_alarm = palmas_rtc_set_alarm, | ||
| 232 | .alarm_irq_enable = palmas_rtc_alarm_irq_enable, | ||
| 233 | }; | ||
| 234 | |||
| 235 | static int palmas_rtc_probe(struct platform_device *pdev) | ||
| 236 | { | ||
| 237 | struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); | ||
| 238 | struct palmas_rtc *palmas_rtc = NULL; | ||
| 239 | int ret; | ||
| 240 | |||
| 241 | palmas_rtc = devm_kzalloc(&pdev->dev, sizeof(struct palmas_rtc), | ||
| 242 | GFP_KERNEL); | ||
| 243 | if (!palmas_rtc) | ||
| 244 | return -ENOMEM; | ||
| 245 | |||
| 246 | /* Clear pending interrupts */ | ||
| 247 | ret = palmas_clear_interrupts(&pdev->dev); | ||
| 248 | if (ret < 0) { | ||
| 249 | dev_err(&pdev->dev, "clear RTC int failed, err = %d\n", ret); | ||
| 250 | return ret; | ||
| 251 | } | ||
| 252 | |||
| 253 | palmas_rtc->dev = &pdev->dev; | ||
| 254 | platform_set_drvdata(pdev, palmas_rtc); | ||
| 255 | |||
| 256 | /* Start RTC */ | ||
| 257 | ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, | ||
| 258 | PALMAS_RTC_CTRL_REG_STOP_RTC, | ||
| 259 | PALMAS_RTC_CTRL_REG_STOP_RTC); | ||
| 260 | if (ret < 0) { | ||
| 261 | dev_err(&pdev->dev, "RTC_CTRL write failed, err = %d\n", ret); | ||
| 262 | return ret; | ||
| 263 | } | ||
| 264 | |||
| 265 | palmas_rtc->irq = platform_get_irq(pdev, 0); | ||
| 266 | |||
| 267 | palmas_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
| 268 | &palmas_rtc_ops, THIS_MODULE); | ||
| 269 | if (IS_ERR(palmas_rtc->rtc)) { | ||
| 270 | ret = PTR_ERR(palmas_rtc->rtc); | ||
| 271 | dev_err(&pdev->dev, "RTC register failed, err = %d\n", ret); | ||
| 272 | return ret; | ||
| 273 | } | ||
| 274 | |||
| 275 | ret = request_threaded_irq(palmas_rtc->irq, NULL, | ||
| 276 | palmas_rtc_interrupt, | ||
| 277 | IRQF_TRIGGER_LOW | IRQF_ONESHOT | | ||
| 278 | IRQF_EARLY_RESUME, | ||
| 279 | dev_name(&pdev->dev), palmas_rtc); | ||
| 280 | if (ret < 0) { | ||
| 281 | dev_err(&pdev->dev, "IRQ request failed, err = %d\n", ret); | ||
| 282 | rtc_device_unregister(palmas_rtc->rtc); | ||
| 283 | return ret; | ||
| 284 | } | ||
| 285 | |||
| 286 | device_set_wakeup_capable(&pdev->dev, 1); | ||
| 287 | return 0; | ||
| 288 | } | ||
| 289 | |||
| 290 | static int palmas_rtc_remove(struct platform_device *pdev) | ||
| 291 | { | ||
| 292 | struct palmas_rtc *palmas_rtc = platform_get_drvdata(pdev); | ||
| 293 | |||
| 294 | palmas_rtc_alarm_irq_enable(&pdev->dev, 0); | ||
| 295 | free_irq(palmas_rtc->irq, palmas_rtc); | ||
| 296 | rtc_device_unregister(palmas_rtc->rtc); | ||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | #ifdef CONFIG_PM_SLEEP | ||
| 301 | static int palmas_rtc_suspend(struct device *dev) | ||
| 302 | { | ||
| 303 | struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev); | ||
| 304 | |||
| 305 | if (device_may_wakeup(dev)) | ||
| 306 | enable_irq_wake(palmas_rtc->irq); | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | static int palmas_rtc_resume(struct device *dev) | ||
| 311 | { | ||
| 312 | struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev); | ||
| 313 | |||
| 314 | if (device_may_wakeup(dev)) | ||
| 315 | disable_irq_wake(palmas_rtc->irq); | ||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | #endif | ||
| 319 | |||
| 320 | static const struct dev_pm_ops palmas_rtc_pm_ops = { | ||
| 321 | SET_SYSTEM_SLEEP_PM_OPS(palmas_rtc_suspend, palmas_rtc_resume) | ||
| 322 | }; | ||
| 323 | |||
| 324 | static struct platform_driver palmas_rtc_driver = { | ||
| 325 | .probe = palmas_rtc_probe, | ||
| 326 | .remove = palmas_rtc_remove, | ||
| 327 | .driver = { | ||
| 328 | .owner = THIS_MODULE, | ||
| 329 | .name = "palmas-rtc", | ||
| 330 | .pm = &palmas_rtc_pm_ops, | ||
| 331 | }, | ||
| 332 | }; | ||
| 333 | |||
| 334 | module_platform_driver(palmas_rtc_driver); | ||
| 335 | |||
| 336 | MODULE_ALIAS("platform:palmas_rtc"); | ||
| 337 | MODULE_DESCRIPTION("TI PALMAS series RTC driver"); | ||
| 338 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
| 339 | MODULE_LICENSE("GPL v2"); | ||
| diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index be05a645f99e..889e3160e701 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */ | 23 | #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */ | 
| 24 | #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */ | 24 | #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */ | 
| 25 | #define REG_CONTROL3_PM_MASK 0xe0 | 25 | #define REG_CONTROL3_PM_MASK 0xe0 | 
| 26 | #define REG_CONTROL3_BLF (1 << 2) /* battery low bit, read-only */ | ||
| 26 | 27 | ||
| 27 | #define REG_SECONDS 0x03 | 28 | #define REG_SECONDS 0x03 | 
| 28 | #define REG_SECONDS_OS (1 << 7) | 29 | #define REG_SECONDS_OS (1 << 7) | 
| @@ -250,9 +251,39 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
| 250 | return pcf8523_start_rtc(client); | 251 | return pcf8523_start_rtc(client); | 
| 251 | } | 252 | } | 
| 252 | 253 | ||
| 254 | #ifdef CONFIG_RTC_INTF_DEV | ||
| 255 | static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
| 256 | unsigned long arg) | ||
| 257 | { | ||
| 258 | struct i2c_client *client = to_i2c_client(dev); | ||
| 259 | u8 value; | ||
| 260 | int ret = 0, err; | ||
| 261 | |||
| 262 | switch (cmd) { | ||
| 263 | case RTC_VL_READ: | ||
| 264 | err = pcf8523_read(client, REG_CONTROL3, &value); | ||
| 265 | if (err < 0) | ||
| 266 | return err; | ||
| 267 | |||
| 268 | if (value & REG_CONTROL3_BLF) | ||
| 269 | ret = 1; | ||
| 270 | |||
| 271 | if (copy_to_user((void __user *)arg, &ret, sizeof(int))) | ||
| 272 | return -EFAULT; | ||
| 273 | |||
| 274 | return 0; | ||
| 275 | default: | ||
| 276 | return -ENOIOCTLCMD; | ||
| 277 | } | ||
| 278 | } | ||
| 279 | #else | ||
| 280 | #define pcf8523_rtc_ioctl NULL | ||
| 281 | #endif | ||
| 282 | |||
| 253 | static const struct rtc_class_ops pcf8523_rtc_ops = { | 283 | static const struct rtc_class_ops pcf8523_rtc_ops = { | 
| 254 | .read_time = pcf8523_rtc_read_time, | 284 | .read_time = pcf8523_rtc_read_time, | 
| 255 | .set_time = pcf8523_rtc_set_time, | 285 | .set_time = pcf8523_rtc_set_time, | 
| 286 | .ioctl = pcf8523_rtc_ioctl, | ||
| 256 | }; | 287 | }; | 
| 257 | 288 | ||
| 258 | static int pcf8523_probe(struct i2c_client *client, | 289 | static int pcf8523_probe(struct i2c_client *client, | 
| diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 7098ee89bd29..f7daf18a112e 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
| @@ -181,7 +181,7 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
| 181 | __func__, err, data[0], data[1]); | 181 | __func__, err, data[0], data[1]); | 
| 182 | return -EIO; | 182 | return -EIO; | 
| 183 | } | 183 | } | 
| 184 | }; | 184 | } | 
| 185 | 185 | ||
| 186 | return 0; | 186 | return 0; | 
| 187 | } | 187 | } | 
| diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 3415b8f18555..5f97c61247d5 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
| @@ -185,8 +185,8 @@ static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
| 185 | if (ctrl & (CTRL_STOP | CTRL_HOLD)) { | 185 | if (ctrl & (CTRL_STOP | CTRL_HOLD)) { | 
| 186 | unsigned char new_ctrl = ctrl & ~(CTRL_STOP | CTRL_HOLD); | 186 | unsigned char new_ctrl = ctrl & ~(CTRL_STOP | CTRL_HOLD); | 
| 187 | 187 | ||
| 188 | printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n", | 188 | dev_warn(dev, "resetting control %02x -> %02x\n", | 
| 189 | ctrl, new_ctrl); | 189 | ctrl, new_ctrl); | 
| 190 | 190 | ||
| 191 | if ((err = pcf8583_set_ctrl(client, &new_ctrl)) < 0) | 191 | if ((err = pcf8583_set_ctrl(client, &new_ctrl)) < 0) | 
| 192 | return err; | 192 | return err; | 
| diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 10c1a3454e48..8900ea784817 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
| @@ -350,7 +350,9 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 350 | /* Enable the clockwatch on ST Variants */ | 350 | /* Enable the clockwatch on ST Variants */ | 
| 351 | if (vendor->clockwatch) | 351 | if (vendor->clockwatch) | 
| 352 | data |= RTC_CR_CWEN; | 352 | data |= RTC_CR_CWEN; | 
| 353 | writel(data | RTC_CR_EN, ldata->base + RTC_CR); | 353 | else | 
| 354 | data |= RTC_CR_EN; | ||
| 355 | writel(data, ldata->base + RTC_CR); | ||
| 354 | 356 | ||
| 355 | /* | 357 | /* | 
| 356 | * On ST PL031 variants, the RTC reset value does not provide correct | 358 | * On ST PL031 variants, the RTC reset value does not provide correct | 
| @@ -382,6 +384,8 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 382 | goto out_no_irq; | 384 | goto out_no_irq; | 
| 383 | } | 385 | } | 
| 384 | 386 | ||
| 387 | device_init_wakeup(&adev->dev, 1); | ||
| 388 | |||
| 385 | return 0; | 389 | return 0; | 
| 386 | 390 | ||
| 387 | out_no_irq: | 391 | out_no_irq: | 
| diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index f771b2ee4b18..03c85ee719a7 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c | |||
| @@ -62,6 +62,10 @@ | |||
| 62 | #define RYxR_MONTH_S 5 | 62 | #define RYxR_MONTH_S 5 | 
| 63 | #define RYxR_MONTH_MASK (0xf << RYxR_MONTH_S) | 63 | #define RYxR_MONTH_MASK (0xf << RYxR_MONTH_S) | 
| 64 | #define RYxR_DAY_MASK 0x1f | 64 | #define RYxR_DAY_MASK 0x1f | 
| 65 | #define RDxR_WOM_S 20 | ||
| 66 | #define RDxR_WOM_MASK (0x7 << RDxR_WOM_S) | ||
| 67 | #define RDxR_DOW_S 17 | ||
| 68 | #define RDxR_DOW_MASK (0x7 << RDxR_DOW_S) | ||
| 65 | #define RDxR_HOUR_S 12 | 69 | #define RDxR_HOUR_S 12 | 
| 66 | #define RDxR_HOUR_MASK (0x1f << RDxR_HOUR_S) | 70 | #define RDxR_HOUR_MASK (0x1f << RDxR_HOUR_S) | 
| 67 | #define RDxR_MIN_S 6 | 71 | #define RDxR_MIN_S 6 | 
| @@ -91,6 +95,7 @@ struct pxa_rtc { | |||
| 91 | spinlock_t lock; /* Protects this structure */ | 95 | spinlock_t lock; /* Protects this structure */ | 
| 92 | }; | 96 | }; | 
| 93 | 97 | ||
| 98 | |||
| 94 | static u32 ryxr_calc(struct rtc_time *tm) | 99 | static u32 ryxr_calc(struct rtc_time *tm) | 
| 95 | { | 100 | { | 
| 96 | return ((tm->tm_year + 1900) << RYxR_YEAR_S) | 101 | return ((tm->tm_year + 1900) << RYxR_YEAR_S) | 
| @@ -100,7 +105,10 @@ static u32 ryxr_calc(struct rtc_time *tm) | |||
| 100 | 105 | ||
| 101 | static u32 rdxr_calc(struct rtc_time *tm) | 106 | static u32 rdxr_calc(struct rtc_time *tm) | 
| 102 | { | 107 | { | 
| 103 | return (tm->tm_hour << RDxR_HOUR_S) | (tm->tm_min << RDxR_MIN_S) | 108 | return ((((tm->tm_mday + 6) / 7) << RDxR_WOM_S) & RDxR_WOM_MASK) | 
| 109 | | (((tm->tm_wday + 1) << RDxR_DOW_S) & RDxR_DOW_MASK) | ||
| 110 | | (tm->tm_hour << RDxR_HOUR_S) | ||
| 111 | | (tm->tm_min << RDxR_MIN_S) | ||
| 104 | | tm->tm_sec; | 112 | | tm->tm_sec; | 
| 105 | } | 113 | } | 
| 106 | 114 | ||
| @@ -109,6 +117,7 @@ static void tm_calc(u32 rycr, u32 rdcr, struct rtc_time *tm) | |||
| 109 | tm->tm_year = ((rycr & RYxR_YEAR_MASK) >> RYxR_YEAR_S) - 1900; | 117 | tm->tm_year = ((rycr & RYxR_YEAR_MASK) >> RYxR_YEAR_S) - 1900; | 
| 110 | tm->tm_mon = (((rycr & RYxR_MONTH_MASK) >> RYxR_MONTH_S)) - 1; | 118 | tm->tm_mon = (((rycr & RYxR_MONTH_MASK) >> RYxR_MONTH_S)) - 1; | 
| 111 | tm->tm_mday = (rycr & RYxR_DAY_MASK); | 119 | tm->tm_mday = (rycr & RYxR_DAY_MASK); | 
| 120 | tm->tm_wday = ((rycr & RDxR_DOW_MASK) >> RDxR_DOW_S) - 1; | ||
| 112 | tm->tm_hour = (rdcr & RDxR_HOUR_MASK) >> RDxR_HOUR_S; | 121 | tm->tm_hour = (rdcr & RDxR_HOUR_MASK) >> RDxR_HOUR_S; | 
| 113 | tm->tm_min = (rdcr & RDxR_MIN_MASK) >> RDxR_MIN_S; | 122 | tm->tm_min = (rdcr & RDxR_MIN_MASK) >> RDxR_MIN_S; | 
| 114 | tm->tm_sec = rdcr & RDxR_SEC_MASK; | 123 | tm->tm_sec = rdcr & RDxR_SEC_MASK; | 
| @@ -300,8 +309,6 @@ static int pxa_rtc_proc(struct device *dev, struct seq_file *seq) | |||
| 300 | } | 309 | } | 
| 301 | 310 | ||
| 302 | static const struct rtc_class_ops pxa_rtc_ops = { | 311 | static const struct rtc_class_ops pxa_rtc_ops = { | 
| 303 | .open = pxa_rtc_open, | ||
| 304 | .release = pxa_rtc_release, | ||
| 305 | .read_time = pxa_rtc_read_time, | 312 | .read_time = pxa_rtc_read_time, | 
| 306 | .set_time = pxa_rtc_set_time, | 313 | .set_time = pxa_rtc_set_time, | 
| 307 | .read_alarm = pxa_rtc_read_alarm, | 314 | .read_alarm = pxa_rtc_read_alarm, | 
| @@ -341,7 +348,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) | |||
| 341 | dev_err(dev, "No alarm IRQ resource defined\n"); | 348 | dev_err(dev, "No alarm IRQ resource defined\n"); | 
| 342 | goto err_ress; | 349 | goto err_ress; | 
| 343 | } | 350 | } | 
| 344 | 351 | pxa_rtc_open(dev); | |
| 345 | ret = -ENOMEM; | 352 | ret = -ENOMEM; | 
| 346 | pxa_rtc->base = ioremap(pxa_rtc->ress->start, | 353 | pxa_rtc->base = ioremap(pxa_rtc->ress->start, | 
| 347 | resource_size(pxa_rtc->ress)); | 354 | resource_size(pxa_rtc->ress)); | 
| @@ -387,6 +394,9 @@ static int __exit pxa_rtc_remove(struct platform_device *pdev) | |||
| 387 | { | 394 | { | 
| 388 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | 395 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | 
| 389 | 396 | ||
| 397 | struct device *dev = &pdev->dev; | ||
| 398 | pxa_rtc_release(dev); | ||
| 399 | |||
| 390 | rtc_device_unregister(pxa_rtc->rtc); | 400 | rtc_device_unregister(pxa_rtc->rtc); | 
| 391 | 401 | ||
| 392 | spin_lock_irq(&pxa_rtc->lock); | 402 | spin_lock_irq(&pxa_rtc->lock); | 
| @@ -444,10 +454,7 @@ static struct platform_driver pxa_rtc_driver = { | |||
| 444 | 454 | ||
| 445 | static int __init pxa_rtc_init(void) | 455 | static int __init pxa_rtc_init(void) | 
| 446 | { | 456 | { | 
| 447 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) | 457 | return platform_driver_probe(&pxa_rtc_driver, pxa_rtc_probe); | 
| 448 | return platform_driver_probe(&pxa_rtc_driver, pxa_rtc_probe); | ||
| 449 | |||
| 450 | return -ENODEV; | ||
| 451 | } | 458 | } | 
| 452 | 459 | ||
| 453 | static void __exit pxa_rtc_exit(void) | 460 | static void __exit pxa_rtc_exit(void) | 
| diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index d1aee793ecc8..d98ea5b759c8 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c | |||
| @@ -39,6 +39,8 @@ | |||
| 39 | * 1.13 Nobuhiro Iwamatsu: Updata driver. | 39 | * 1.13 Nobuhiro Iwamatsu: Updata driver. | 
| 40 | */ | 40 | */ | 
| 41 | 41 | ||
| 42 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 43 | |||
| 42 | #include <linux/module.h> | 44 | #include <linux/module.h> | 
| 43 | #include <linux/err.h> | 45 | #include <linux/err.h> | 
| 44 | #include <linux/rtc.h> | 46 | #include <linux/rtc.h> | 
| @@ -352,8 +354,7 @@ static void rs5c313_check_xstp_bit(void) | |||
| 352 | tm.tm_year = 2000 - 1900; | 354 | tm.tm_year = 2000 - 1900; | 
| 353 | 355 | ||
| 354 | rs5c313_rtc_set_time(NULL, &tm); | 356 | rs5c313_rtc_set_time(NULL, &tm); | 
| 355 | printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to " | 357 | pr_err("invalid value, resetting to 1 Jan 2000\n"); | 
| 356 | "1 Jan 2000\n"); | ||
| 357 | } | 358 | } | 
| 358 | RS5C313_CEDISABLE; | 359 | RS5C313_CEDISABLE; | 
| 359 | ndelay(700); /* CE:L */ | 360 | ndelay(700); /* CE:L */ | 
| diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 76f565ae384d..581739f40097 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
| @@ -311,8 +311,7 @@ static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
| 311 | buf &= ~RS5C_CTRL1_AALE; | 311 | buf &= ~RS5C_CTRL1_AALE; | 
| 312 | 312 | ||
| 313 | if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { | 313 | if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { | 
| 314 | printk(KERN_WARNING "%s: can't update alarm\n", | 314 | dev_warn(dev, "can't update alarm\n"); | 
| 315 | rs5c->rtc->name); | ||
| 316 | status = -EIO; | 315 | status = -EIO; | 
| 317 | } else | 316 | } else | 
| 318 | rs5c->regs[RS5C_REG_CTRL1] = buf; | 317 | rs5c->regs[RS5C_REG_CTRL1] = buf; | 
| @@ -381,7 +380,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 381 | addr = RS5C_ADDR(RS5C_REG_CTRL1); | 380 | addr = RS5C_ADDR(RS5C_REG_CTRL1); | 
| 382 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; | 381 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; | 
| 383 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) { | 382 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) { | 
| 384 | pr_debug("%s: can't disable alarm\n", rs5c->rtc->name); | 383 | dev_dbg(dev, "can't disable alarm\n"); | 
| 385 | return -EIO; | 384 | return -EIO; | 
| 386 | } | 385 | } | 
| 387 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; | 386 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; | 
| @@ -395,7 +394,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 395 | for (i = 0; i < sizeof(buf); i++) { | 394 | for (i = 0; i < sizeof(buf); i++) { | 
| 396 | addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); | 395 | addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); | 
| 397 | if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) { | 396 | if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) { | 
| 398 | pr_debug("%s: can't set alarm time\n", rs5c->rtc->name); | 397 | dev_dbg(dev, "can't set alarm time\n"); | 
| 399 | return -EIO; | 398 | return -EIO; | 
| 400 | } | 399 | } | 
| 401 | } | 400 | } | 
| @@ -405,8 +404,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 405 | addr = RS5C_ADDR(RS5C_REG_CTRL1); | 404 | addr = RS5C_ADDR(RS5C_REG_CTRL1); | 
| 406 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; | 405 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; | 
| 407 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) | 406 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) | 
| 408 | printk(KERN_WARNING "%s: can't enable alarm\n", | 407 | dev_warn(dev, "can't enable alarm\n"); | 
| 409 | rs5c->rtc->name); | ||
| 410 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; | 408 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; | 
| 411 | } | 409 | } | 
| 412 | 410 | ||
| diff --git a/drivers/rtc/rtc-rx4581.c b/drivers/rtc/rtc-rx4581.c new file mode 100644 index 000000000000..599ec73ec886 --- /dev/null +++ b/drivers/rtc/rtc-rx4581.c | |||
| @@ -0,0 +1,314 @@ | |||
| 1 | /* drivers/rtc/rtc-rx4581.c | ||
| 2 | * | ||
| 3 | * written by Torben Hohn <torbenh@linutronix.de> | ||
| 4 | * | ||
| 5 | * Based on: | ||
| 6 | * drivers/rtc/rtc-max6902.c | ||
| 7 | * | ||
| 8 | * Copyright (C) 2006 8D Technologies inc. | ||
| 9 | * Copyright (C) 2004 Compulab Ltd. | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * Driver for MAX6902 spi RTC | ||
| 16 | * | ||
| 17 | * and based on: | ||
| 18 | * drivers/rtc/rtc-rx8581.c | ||
| 19 | * | ||
| 20 | * An I2C driver for the Epson RX8581 RTC | ||
| 21 | * | ||
| 22 | * Author: Martyn Welch <martyn.welch@ge.com> | ||
| 23 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
| 24 | * | ||
| 25 | * This program is free software; you can redistribute it and/or modify | ||
| 26 | * it under the terms of the GNU General Public License version 2 as | ||
| 27 | * published by the Free Software Foundation. | ||
| 28 | * | ||
| 29 | * Based on: rtc-pcf8563.c (An I2C driver for the Philips PCF8563 RTC) | ||
| 30 | * Copyright 2005-06 Tower Technologies | ||
| 31 | * | ||
| 32 | */ | ||
| 33 | |||
| 34 | #include <linux/module.h> | ||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/platform_device.h> | ||
| 37 | #include <linux/init.h> | ||
| 38 | #include <linux/rtc.h> | ||
| 39 | #include <linux/spi/spi.h> | ||
| 40 | #include <linux/bcd.h> | ||
| 41 | |||
| 42 | #define RX4581_REG_SC 0x00 /* Second in BCD */ | ||
| 43 | #define RX4581_REG_MN 0x01 /* Minute in BCD */ | ||
| 44 | #define RX4581_REG_HR 0x02 /* Hour in BCD */ | ||
| 45 | #define RX4581_REG_DW 0x03 /* Day of Week */ | ||
| 46 | #define RX4581_REG_DM 0x04 /* Day of Month in BCD */ | ||
| 47 | #define RX4581_REG_MO 0x05 /* Month in BCD */ | ||
| 48 | #define RX4581_REG_YR 0x06 /* Year in BCD */ | ||
| 49 | #define RX4581_REG_RAM 0x07 /* RAM */ | ||
| 50 | #define RX4581_REG_AMN 0x08 /* Alarm Min in BCD*/ | ||
| 51 | #define RX4581_REG_AHR 0x09 /* Alarm Hour in BCD */ | ||
| 52 | #define RX4581_REG_ADM 0x0A | ||
| 53 | #define RX4581_REG_ADW 0x0A | ||
| 54 | #define RX4581_REG_TMR0 0x0B | ||
| 55 | #define RX4581_REG_TMR1 0x0C | ||
| 56 | #define RX4581_REG_EXT 0x0D /* Extension Register */ | ||
| 57 | #define RX4581_REG_FLAG 0x0E /* Flag Register */ | ||
| 58 | #define RX4581_REG_CTRL 0x0F /* Control Register */ | ||
| 59 | |||
| 60 | |||
| 61 | /* Flag Register bit definitions */ | ||
| 62 | #define RX4581_FLAG_UF 0x20 /* Update */ | ||
| 63 | #define RX4581_FLAG_TF 0x10 /* Timer */ | ||
| 64 | #define RX4581_FLAG_AF 0x08 /* Alarm */ | ||
| 65 | #define RX4581_FLAG_VLF 0x02 /* Voltage Low */ | ||
| 66 | |||
| 67 | /* Control Register bit definitions */ | ||
| 68 | #define RX4581_CTRL_UIE 0x20 /* Update Interrupt Enable */ | ||
| 69 | #define RX4581_CTRL_TIE 0x10 /* Timer Interrupt Enable */ | ||
| 70 | #define RX4581_CTRL_AIE 0x08 /* Alarm Interrupt Enable */ | ||
| 71 | #define RX4581_CTRL_STOP 0x02 /* STOP bit */ | ||
| 72 | #define RX4581_CTRL_RESET 0x01 /* RESET bit */ | ||
| 73 | |||
| 74 | static int rx4581_set_reg(struct device *dev, unsigned char address, | ||
| 75 | unsigned char data) | ||
| 76 | { | ||
| 77 | struct spi_device *spi = to_spi_device(dev); | ||
| 78 | unsigned char buf[2]; | ||
| 79 | |||
| 80 | /* high nibble must be '0' to write */ | ||
| 81 | buf[0] = address & 0x0f; | ||
| 82 | buf[1] = data; | ||
| 83 | |||
| 84 | return spi_write_then_read(spi, buf, 2, NULL, 0); | ||
| 85 | } | ||
| 86 | |||
| 87 | static int rx4581_get_reg(struct device *dev, unsigned char address, | ||
| 88 | unsigned char *data) | ||
| 89 | { | ||
| 90 | struct spi_device *spi = to_spi_device(dev); | ||
| 91 | |||
| 92 | /* Set MSB to indicate read */ | ||
| 93 | *data = address | 0x80; | ||
| 94 | |||
| 95 | return spi_write_then_read(spi, data, 1, data, 1); | ||
| 96 | } | ||
| 97 | |||
| 98 | /* | ||
| 99 | * In the routines that deal directly with the rx8581 hardware, we use | ||
| 100 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | ||
| 101 | */ | ||
| 102 | static int rx4581_get_datetime(struct device *dev, struct rtc_time *tm) | ||
| 103 | { | ||
| 104 | struct spi_device *spi = to_spi_device(dev); | ||
| 105 | unsigned char date[7]; | ||
| 106 | unsigned char data; | ||
| 107 | int err; | ||
| 108 | |||
| 109 | /* First we ensure that the "update flag" is not set, we read the | ||
| 110 | * time and date then re-read the "update flag". If the update flag | ||
| 111 | * has been set, we know that the time has changed during the read so | ||
| 112 | * we repeat the whole process again. | ||
| 113 | */ | ||
| 114 | err = rx4581_get_reg(dev, RX4581_REG_FLAG, &data); | ||
| 115 | if (err != 0) { | ||
| 116 | dev_err(dev, "Unable to read device flags\n"); | ||
| 117 | return -EIO; | ||
| 118 | } | ||
| 119 | |||
| 120 | do { | ||
| 121 | /* If update flag set, clear it */ | ||
| 122 | if (data & RX4581_FLAG_UF) { | ||
| 123 | err = rx4581_set_reg(dev, | ||
| 124 | RX4581_REG_FLAG, (data & ~RX4581_FLAG_UF)); | ||
| 125 | if (err != 0) { | ||
| 126 | dev_err(dev, "Unable to write device " | ||
| 127 | "flags\n"); | ||
| 128 | return -EIO; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | /* Now read time and date */ | ||
| 133 | date[0] = 0x80; | ||
| 134 | err = spi_write_then_read(spi, date, 1, date, 7); | ||
| 135 | if (err < 0) { | ||
| 136 | dev_err(dev, "Unable to read date\n"); | ||
| 137 | return -EIO; | ||
| 138 | } | ||
| 139 | |||
| 140 | /* Check flag register */ | ||
| 141 | err = rx4581_get_reg(dev, RX4581_REG_FLAG, &data); | ||
| 142 | if (err != 0) { | ||
| 143 | dev_err(dev, "Unable to read device flags\n"); | ||
| 144 | return -EIO; | ||
| 145 | } | ||
| 146 | } while (data & RX4581_FLAG_UF); | ||
| 147 | |||
| 148 | if (data & RX4581_FLAG_VLF) | ||
| 149 | dev_info(dev, | ||
| 150 | "low voltage detected, date/time is not reliable.\n"); | ||
| 151 | |||
| 152 | dev_dbg(dev, | ||
| 153 | "%s: raw data is sec=%02x, min=%02x, hr=%02x, " | ||
| 154 | "wday=%02x, mday=%02x, mon=%02x, year=%02x\n", | ||
| 155 | __func__, | ||
| 156 | date[0], date[1], date[2], date[3], date[4], date[5], date[6]); | ||
| 157 | |||
| 158 | tm->tm_sec = bcd2bin(date[RX4581_REG_SC] & 0x7F); | ||
| 159 | tm->tm_min = bcd2bin(date[RX4581_REG_MN] & 0x7F); | ||
| 160 | tm->tm_hour = bcd2bin(date[RX4581_REG_HR] & 0x3F); /* rtc hr 0-23 */ | ||
| 161 | tm->tm_wday = ilog2(date[RX4581_REG_DW] & 0x7F); | ||
| 162 | tm->tm_mday = bcd2bin(date[RX4581_REG_DM] & 0x3F); | ||
| 163 | tm->tm_mon = bcd2bin(date[RX4581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ | ||
| 164 | tm->tm_year = bcd2bin(date[RX4581_REG_YR]); | ||
| 165 | if (tm->tm_year < 70) | ||
| 166 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | ||
| 167 | |||
| 168 | |||
| 169 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | ||
| 170 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
| 171 | __func__, | ||
| 172 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
| 173 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
| 174 | |||
| 175 | err = rtc_valid_tm(tm); | ||
| 176 | if (err < 0) | ||
| 177 | dev_err(dev, "retrieved date/time is not valid.\n"); | ||
| 178 | |||
| 179 | return err; | ||
| 180 | } | ||
| 181 | |||
| 182 | static int rx4581_set_datetime(struct device *dev, struct rtc_time *tm) | ||
| 183 | { | ||
| 184 | struct spi_device *spi = to_spi_device(dev); | ||
| 185 | int err; | ||
| 186 | unsigned char buf[8], data; | ||
| 187 | |||
| 188 | dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, " | ||
| 189 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
| 190 | __func__, | ||
| 191 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
| 192 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
| 193 | |||
| 194 | buf[0] = 0x00; | ||
| 195 | /* hours, minutes and seconds */ | ||
| 196 | buf[RX4581_REG_SC+1] = bin2bcd(tm->tm_sec); | ||
| 197 | buf[RX4581_REG_MN+1] = bin2bcd(tm->tm_min); | ||
| 198 | buf[RX4581_REG_HR+1] = bin2bcd(tm->tm_hour); | ||
| 199 | |||
| 200 | buf[RX4581_REG_DM+1] = bin2bcd(tm->tm_mday); | ||
| 201 | |||
| 202 | /* month, 1 - 12 */ | ||
| 203 | buf[RX4581_REG_MO+1] = bin2bcd(tm->tm_mon + 1); | ||
| 204 | |||
| 205 | /* year and century */ | ||
| 206 | buf[RX4581_REG_YR+1] = bin2bcd(tm->tm_year % 100); | ||
| 207 | buf[RX4581_REG_DW+1] = (0x1 << tm->tm_wday); | ||
| 208 | |||
| 209 | /* Stop the clock */ | ||
| 210 | err = rx4581_get_reg(dev, RX4581_REG_CTRL, &data); | ||
| 211 | if (err != 0) { | ||
| 212 | dev_err(dev, "Unable to read control register\n"); | ||
| 213 | return -EIO; | ||
| 214 | } | ||
| 215 | |||
| 216 | err = rx4581_set_reg(dev, RX4581_REG_CTRL, | ||
| 217 | (data | RX4581_CTRL_STOP)); | ||
| 218 | if (err != 0) { | ||
| 219 | dev_err(dev, "Unable to write control register\n"); | ||
| 220 | return -EIO; | ||
| 221 | } | ||
| 222 | |||
| 223 | /* write register's data */ | ||
| 224 | err = spi_write_then_read(spi, buf, 8, NULL, 0); | ||
| 225 | if (err != 0) { | ||
| 226 | dev_err(dev, "Unable to write to date registers\n"); | ||
| 227 | return -EIO; | ||
| 228 | } | ||
| 229 | |||
| 230 | /* get VLF and clear it */ | ||
| 231 | err = rx4581_get_reg(dev, RX4581_REG_FLAG, &data); | ||
| 232 | if (err != 0) { | ||
| 233 | dev_err(dev, "Unable to read flag register\n"); | ||
| 234 | return -EIO; | ||
| 235 | } | ||
| 236 | |||
| 237 | err = rx4581_set_reg(dev, RX4581_REG_FLAG, | ||
| 238 | (data & ~(RX4581_FLAG_VLF))); | ||
| 239 | if (err != 0) { | ||
| 240 | dev_err(dev, "Unable to write flag register\n"); | ||
| 241 | return -EIO; | ||
| 242 | } | ||
| 243 | |||
| 244 | /* Restart the clock */ | ||
| 245 | err = rx4581_get_reg(dev, RX4581_REG_CTRL, &data); | ||
| 246 | if (err != 0) { | ||
| 247 | dev_err(dev, "Unable to read control register\n"); | ||
| 248 | return -EIO; | ||
| 249 | } | ||
| 250 | |||
| 251 | err = rx4581_set_reg(dev, RX4581_REG_CTRL, | ||
| 252 | (data & ~(RX4581_CTRL_STOP))); | ||
| 253 | if (err != 0) { | ||
| 254 | dev_err(dev, "Unable to write control register\n"); | ||
| 255 | return -EIO; | ||
| 256 | } | ||
| 257 | |||
| 258 | return 0; | ||
| 259 | } | ||
| 260 | |||
| 261 | static const struct rtc_class_ops rx4581_rtc_ops = { | ||
| 262 | .read_time = rx4581_get_datetime, | ||
| 263 | .set_time = rx4581_set_datetime, | ||
| 264 | }; | ||
| 265 | |||
| 266 | static int rx4581_probe(struct spi_device *spi) | ||
| 267 | { | ||
| 268 | struct rtc_device *rtc; | ||
| 269 | unsigned char tmp; | ||
| 270 | int res; | ||
| 271 | |||
| 272 | res = rx4581_get_reg(&spi->dev, RX4581_REG_SC, &tmp); | ||
| 273 | if (res != 0) | ||
| 274 | return res; | ||
| 275 | |||
| 276 | rtc = rtc_device_register("rx4581", | ||
| 277 | &spi->dev, &rx4581_rtc_ops, THIS_MODULE); | ||
| 278 | if (IS_ERR(rtc)) | ||
| 279 | return PTR_ERR(rtc); | ||
| 280 | |||
| 281 | dev_set_drvdata(&spi->dev, rtc); | ||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int rx4581_remove(struct spi_device *spi) | ||
| 286 | { | ||
| 287 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); | ||
| 288 | |||
| 289 | rtc_device_unregister(rtc); | ||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | static const struct spi_device_id rx4581_id[] = { | ||
| 294 | { "rx4581", 0 }, | ||
| 295 | { } | ||
| 296 | }; | ||
| 297 | MODULE_DEVICE_TABLE(spi, rx4581_id); | ||
| 298 | |||
| 299 | static struct spi_driver rx4581_driver = { | ||
| 300 | .driver = { | ||
| 301 | .name = "rtc-rx4581", | ||
| 302 | .owner = THIS_MODULE, | ||
| 303 | }, | ||
| 304 | .probe = rx4581_probe, | ||
| 305 | .remove = rx4581_remove, | ||
| 306 | .id_table = rx4581_id, | ||
| 307 | }; | ||
| 308 | |||
| 309 | module_spi_driver(rx4581_driver); | ||
| 310 | |||
| 311 | MODULE_DESCRIPTION("rx4581 spi RTC driver"); | ||
| 312 | MODULE_AUTHOR("Torben Hohn"); | ||
| 313 | MODULE_LICENSE("GPL"); | ||
| 314 | MODULE_ALIAS("spi:rtc-rx4581"); | ||
| diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 404651464d45..fb994e9ddc15 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
| @@ -115,7 +115,7 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) | |||
| 115 | { | 115 | { | 
| 116 | unsigned int tmp; | 116 | unsigned int tmp; | 
| 117 | 117 | ||
| 118 | pr_debug("%s: aie=%d\n", __func__, enabled); | 118 | dev_dbg(dev, "%s: aie=%d\n", __func__, enabled); | 
| 119 | 119 | ||
| 120 | clk_enable(rtc_clk); | 120 | clk_enable(rtc_clk); | 
| 121 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 121 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 
| @@ -203,7 +203,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
| 203 | 203 | ||
| 204 | rtc_tm->tm_year += 100; | 204 | rtc_tm->tm_year += 100; | 
| 205 | 205 | ||
| 206 | pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", | 206 | dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n", | 
| 207 | 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, | 207 | 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, | 
| 208 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); | 208 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); | 
| 209 | 209 | ||
| @@ -218,7 +218,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
| 218 | void __iomem *base = s3c_rtc_base; | 218 | void __iomem *base = s3c_rtc_base; | 
| 219 | int year = tm->tm_year - 100; | 219 | int year = tm->tm_year - 100; | 
| 220 | 220 | ||
| 221 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", | 221 | dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", | 
| 222 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 222 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 
| 223 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 223 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 
| 224 | 224 | ||
| @@ -259,7 +259,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 259 | 259 | ||
| 260 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; | 260 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; | 
| 261 | 261 | ||
| 262 | pr_debug("read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 262 | dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 
| 263 | alm_en, | 263 | alm_en, | 
| 264 | 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, | 264 | 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, | 
| 265 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); | 265 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); | 
| @@ -310,7 +310,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 310 | unsigned int alrm_en; | 310 | unsigned int alrm_en; | 
| 311 | 311 | ||
| 312 | clk_enable(rtc_clk); | 312 | clk_enable(rtc_clk); | 
| 313 | pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 313 | dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 
| 314 | alrm->enabled, | 314 | alrm->enabled, | 
| 315 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | 315 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | 
| 316 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 316 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 
| @@ -333,7 +333,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 333 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); | 333 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); | 
| 334 | } | 334 | } | 
| 335 | 335 | ||
| 336 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); | 336 | dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); | 
| 337 | 337 | ||
| 338 | writeb(alrm_en, base + S3C2410_RTCALM); | 338 | writeb(alrm_en, base + S3C2410_RTCALM); | 
| 339 | 339 | ||
| @@ -459,7 +459,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
| 459 | int ret; | 459 | int ret; | 
| 460 | int tmp; | 460 | int tmp; | 
| 461 | 461 | ||
| 462 | pr_debug("%s: probe=%p\n", __func__, pdev); | 462 | dev_dbg(&pdev->dev, "%s: probe=%p\n", __func__, pdev); | 
| 463 | 463 | ||
| 464 | /* find the IRQs */ | 464 | /* find the IRQs */ | 
| 465 | 465 | ||
| @@ -475,7 +475,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
| 475 | return s3c_rtc_alarmno; | 475 | return s3c_rtc_alarmno; | 
| 476 | } | 476 | } | 
| 477 | 477 | ||
| 478 | pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", | 478 | dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", | 
| 479 | s3c_rtc_tickno, s3c_rtc_alarmno); | 479 | s3c_rtc_tickno, s3c_rtc_alarmno); | 
| 480 | 480 | ||
| 481 | /* get the memory region */ | 481 | /* get the memory region */ | 
| @@ -486,11 +486,9 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
| 486 | return -ENOENT; | 486 | return -ENOENT; | 
| 487 | } | 487 | } | 
| 488 | 488 | ||
| 489 | s3c_rtc_base = devm_request_and_ioremap(&pdev->dev, res); | 489 | s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); | 
| 490 | if (s3c_rtc_base == NULL) { | 490 | if (IS_ERR(s3c_rtc_base)) | 
| 491 | dev_err(&pdev->dev, "failed to ioremap memory region\n"); | 491 | return PTR_ERR(s3c_rtc_base); | 
| 492 | return -EINVAL; | ||
| 493 | } | ||
| 494 | 492 | ||
| 495 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); | 493 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); | 
| 496 | if (IS_ERR(rtc_clk)) { | 494 | if (IS_ERR(rtc_clk)) { | 
| @@ -506,7 +504,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
| 506 | 504 | ||
| 507 | s3c_rtc_enable(pdev, 1); | 505 | s3c_rtc_enable(pdev, 1); | 
| 508 | 506 | ||
| 509 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", | 507 | dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", | 
| 510 | readw(s3c_rtc_base + S3C2410_RTCCON)); | 508 | readw(s3c_rtc_base + S3C2410_RTCCON)); | 
| 511 | 509 | ||
| 512 | device_init_wakeup(&pdev->dev, 1); | 510 | device_init_wakeup(&pdev->dev, 1); | 
| diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 50a5c4adee48..5ec5036df0bc 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
| @@ -108,9 +108,6 @@ static int sa1100_rtc_open(struct device *dev) | |||
| 108 | struct rtc_device *rtc = info->rtc; | 108 | struct rtc_device *rtc = info->rtc; | 
| 109 | int ret; | 109 | int ret; | 
| 110 | 110 | ||
| 111 | ret = clk_prepare_enable(info->clk); | ||
| 112 | if (ret) | ||
| 113 | goto fail_clk; | ||
| 114 | ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); | 111 | ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); | 
| 115 | if (ret) { | 112 | if (ret) { | 
| 116 | dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz); | 113 | dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz); | 
| @@ -130,7 +127,6 @@ static int sa1100_rtc_open(struct device *dev) | |||
| 130 | free_irq(info->irq_1hz, dev); | 127 | free_irq(info->irq_1hz, dev); | 
| 131 | fail_ui: | 128 | fail_ui: | 
| 132 | clk_disable_unprepare(info->clk); | 129 | clk_disable_unprepare(info->clk); | 
| 133 | fail_clk: | ||
| 134 | return ret; | 130 | return ret; | 
| 135 | } | 131 | } | 
| 136 | 132 | ||
| @@ -144,7 +140,6 @@ static void sa1100_rtc_release(struct device *dev) | |||
| 144 | 140 | ||
| 145 | free_irq(info->irq_alarm, dev); | 141 | free_irq(info->irq_alarm, dev); | 
| 146 | free_irq(info->irq_1hz, dev); | 142 | free_irq(info->irq_1hz, dev); | 
| 147 | clk_disable_unprepare(info->clk); | ||
| 148 | } | 143 | } | 
| 149 | 144 | ||
| 150 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 145 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 
| @@ -253,6 +248,9 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
| 253 | spin_lock_init(&info->lock); | 248 | spin_lock_init(&info->lock); | 
| 254 | platform_set_drvdata(pdev, info); | 249 | platform_set_drvdata(pdev, info); | 
| 255 | 250 | ||
| 251 | ret = clk_prepare_enable(info->clk); | ||
| 252 | if (ret) | ||
| 253 | goto err_enable_clk; | ||
| 256 | /* | 254 | /* | 
| 257 | * According to the manual we should be able to let RTTR be zero | 255 | * According to the manual we should be able to let RTTR be zero | 
| 258 | * and then a default diviser for a 32.768KHz clock is used. | 256 | * and then a default diviser for a 32.768KHz clock is used. | 
| @@ -305,6 +303,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
| 305 | 303 | ||
| 306 | return 0; | 304 | return 0; | 
| 307 | err_dev: | 305 | err_dev: | 
| 306 | clk_disable_unprepare(info->clk); | ||
| 307 | err_enable_clk: | ||
| 308 | platform_set_drvdata(pdev, NULL); | 308 | platform_set_drvdata(pdev, NULL); | 
| 309 | clk_put(info->clk); | 309 | clk_put(info->clk); | 
| 310 | err_clk: | 310 | err_clk: | 
| @@ -318,6 +318,7 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
| 318 | 318 | ||
| 319 | if (info) { | 319 | if (info) { | 
| 320 | rtc_device_unregister(info->rtc); | 320 | rtc_device_unregister(info->rtc); | 
| 321 | clk_disable_unprepare(info->clk); | ||
| 321 | clk_put(info->clk); | 322 | clk_put(info->clk); | 
| 322 | platform_set_drvdata(pdev, NULL); | 323 | platform_set_drvdata(pdev, NULL); | 
| 323 | kfree(info); | 324 | kfree(info); | 
| @@ -349,12 +350,14 @@ static const struct dev_pm_ops sa1100_rtc_pm_ops = { | |||
| 349 | }; | 350 | }; | 
| 350 | #endif | 351 | #endif | 
| 351 | 352 | ||
| 353 | #ifdef CONFIG_OF | ||
| 352 | static struct of_device_id sa1100_rtc_dt_ids[] = { | 354 | static struct of_device_id sa1100_rtc_dt_ids[] = { | 
| 353 | { .compatible = "mrvl,sa1100-rtc", }, | 355 | { .compatible = "mrvl,sa1100-rtc", }, | 
| 354 | { .compatible = "mrvl,mmp-rtc", }, | 356 | { .compatible = "mrvl,mmp-rtc", }, | 
| 355 | {} | 357 | {} | 
| 356 | }; | 358 | }; | 
| 357 | MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids); | 359 | MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids); | 
| 360 | #endif | ||
| 358 | 361 | ||
| 359 | static struct platform_driver sa1100_rtc_driver = { | 362 | static struct platform_driver sa1100_rtc_driver = { | 
| 360 | .probe = sa1100_rtc_probe, | 363 | .probe = sa1100_rtc_probe, | 
| @@ -364,7 +367,7 @@ static struct platform_driver sa1100_rtc_driver = { | |||
| 364 | #ifdef CONFIG_PM | 367 | #ifdef CONFIG_PM | 
| 365 | .pm = &sa1100_rtc_pm_ops, | 368 | .pm = &sa1100_rtc_pm_ops, | 
| 366 | #endif | 369 | #endif | 
| 367 | .of_match_table = sa1100_rtc_dt_ids, | 370 | .of_match_table = of_match_ptr(sa1100_rtc_dt_ids), | 
| 368 | }, | 371 | }, | 
| 369 | }; | 372 | }; | 
| 370 | 373 | ||
| diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index d5ec7854a651..f7d90703db5e 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c | |||
| @@ -252,9 +252,9 @@ static int snvs_rtc_probe(struct platform_device *pdev) | |||
| 252 | return -ENOMEM; | 252 | return -ENOMEM; | 
| 253 | 253 | ||
| 254 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 254 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 
| 255 | data->ioaddr = devm_request_and_ioremap(&pdev->dev, res); | 255 | data->ioaddr = devm_ioremap_resource(&pdev->dev, res); | 
| 256 | if (!data->ioaddr) | 256 | if (IS_ERR(data->ioaddr)) | 
| 257 | return -EADDRNOTAVAIL; | 257 | return PTR_ERR(data->ioaddr); | 
| 258 | 258 | ||
| 259 | data->irq = platform_get_irq(pdev, 0); | 259 | data->irq = platform_get_irq(pdev, 0); | 
| 260 | if (data->irq < 0) | 260 | if (data->irq < 0) | 
| @@ -338,7 +338,7 @@ static struct platform_driver snvs_rtc_driver = { | |||
| 338 | .name = "snvs_rtc", | 338 | .name = "snvs_rtc", | 
| 339 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, | 
| 340 | .pm = &snvs_rtc_pm_ops, | 340 | .pm = &snvs_rtc_pm_ops, | 
| 341 | .of_match_table = snvs_dt_ids, | 341 | .of_match_table = of_match_ptr(snvs_dt_ids), | 
| 342 | }, | 342 | }, | 
| 343 | .probe = snvs_rtc_probe, | 343 | .probe = snvs_rtc_probe, | 
| 344 | .remove = snvs_rtc_remove, | 344 | .remove = snvs_rtc_remove, | 
| diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index c2121b5a01f2..a18c3192ed40 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c | |||
| @@ -385,11 +385,9 @@ static int spear_rtc_probe(struct platform_device *pdev) | |||
| 385 | return status; | 385 | return status; | 
| 386 | } | 386 | } | 
| 387 | 387 | ||
| 388 | config->ioaddr = devm_request_and_ioremap(&pdev->dev, res); | 388 | config->ioaddr = devm_ioremap_resource(&pdev->dev, res); | 
| 389 | if (!config->ioaddr) { | 389 | if (IS_ERR(config->ioaddr)) | 
| 390 | dev_err(&pdev->dev, "request-ioremap fail\n"); | 390 | return PTR_ERR(config->ioaddr); | 
| 391 | return -ENOMEM; | ||
| 392 | } | ||
| 393 | 391 | ||
| 394 | config->clk = devm_clk_get(&pdev->dev, NULL); | 392 | config->clk = devm_clk_get(&pdev->dev, NULL); | 
| 395 | if (IS_ERR(config->clk)) | 393 | if (IS_ERR(config->clk)) | 
| diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 739ef55694f4..b2a8ed99b2bf 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/rtc.h> | 26 | #include <linux/rtc.h> | 
| 27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> | 
| 28 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> | 
| 29 | #include <linux/of.h> | ||
| 29 | 30 | ||
| 30 | #include <mach/common.h> | 31 | #include <mach/common.h> | 
| 31 | 32 | ||
| @@ -280,7 +281,7 @@ static struct platform_driver stmp3xxx_rtcdrv = { | |||
| 280 | .driver = { | 281 | .driver = { | 
| 281 | .name = "stmp3xxx-rtc", | 282 | .name = "stmp3xxx-rtc", | 
| 282 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, | 
| 283 | .of_match_table = rtc_dt_ids, | 284 | .of_match_table = of_match_ptr(rtc_dt_ids), | 
| 284 | }, | 285 | }, | 
| 285 | }; | 286 | }; | 
| 286 | 287 | ||
| diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c index 5b2261052a65..59b5c2dcb58c 100644 --- a/drivers/rtc/rtc-sun4v.c +++ b/drivers/rtc/rtc-sun4v.c | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | 
| 4 | */ | 4 | */ | 
| 5 | 5 | ||
| 6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 7 | |||
| 6 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> | 
| 7 | #include <linux/module.h> | 9 | #include <linux/module.h> | 
| 8 | #include <linux/delay.h> | 10 | #include <linux/delay.h> | 
| @@ -26,10 +28,10 @@ retry: | |||
| 26 | udelay(100); | 28 | udelay(100); | 
| 27 | goto retry; | 29 | goto retry; | 
| 28 | } | 30 | } | 
| 29 | printk(KERN_WARNING "SUN4V: tod_get() timed out.\n"); | 31 | pr_warn("tod_get() timed out.\n"); | 
| 30 | return 0; | 32 | return 0; | 
| 31 | } | 33 | } | 
| 32 | printk(KERN_WARNING "SUN4V: tod_get() not supported.\n"); | 34 | pr_warn("tod_get() not supported.\n"); | 
| 33 | return 0; | 35 | return 0; | 
| 34 | } | 36 | } | 
| 35 | 37 | ||
| @@ -53,10 +55,10 @@ retry: | |||
| 53 | udelay(100); | 55 | udelay(100); | 
| 54 | goto retry; | 56 | goto retry; | 
| 55 | } | 57 | } | 
| 56 | printk(KERN_WARNING "SUN4V: tod_set() timed out.\n"); | 58 | pr_warn("tod_set() timed out.\n"); | 
| 57 | return -EAGAIN; | 59 | return -EAGAIN; | 
| 58 | } | 60 | } | 
| 59 | printk(KERN_WARNING "SUN4V: tod_set() not supported.\n"); | 61 | pr_warn("tod_set() not supported.\n"); | 
| 60 | return -EOPNOTSUPP; | 62 | return -EOPNOTSUPP; | 
| 61 | } | 63 | } | 
| 62 | 64 | ||
| diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index c84ea6659f49..7c033756d6b5 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c | |||
| @@ -327,11 +327,9 @@ static int tegra_rtc_probe(struct platform_device *pdev) | |||
| 327 | return -EBUSY; | 327 | return -EBUSY; | 
| 328 | } | 328 | } | 
| 329 | 329 | ||
| 330 | info->rtc_base = devm_request_and_ioremap(&pdev->dev, res); | 330 | info->rtc_base = devm_ioremap_resource(&pdev->dev, res); | 
| 331 | if (!info->rtc_base) { | 331 | if (IS_ERR(info->rtc_base)) | 
| 332 | dev_err(&pdev->dev, "Unable to request mem region and grab IOs for device.\n"); | 332 | return PTR_ERR(info->rtc_base); | 
| 333 | return -EBUSY; | ||
| 334 | } | ||
| 335 | 333 | ||
| 336 | info->tegra_rtc_irq = platform_get_irq(pdev, 0); | 334 | info->tegra_rtc_irq = platform_get_irq(pdev, 0); | 
| 337 | if (info->tegra_rtc_irq <= 0) | 335 | if (info->tegra_rtc_irq <= 0) | 
| diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 70f61b8e9e6f..aab4e8c93622 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c | |||
| @@ -282,7 +282,8 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) | |||
| 282 | goto fail_rtc_register; | 282 | goto fail_rtc_register; | 
| 283 | } | 283 | } | 
| 284 | 284 | ||
| 285 | ret = request_threaded_irq(rtc->irq, NULL, tps6586x_rtc_irq, | 285 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | 
| 286 | tps6586x_rtc_irq, | ||
| 286 | IRQF_ONESHOT | IRQF_EARLY_RESUME, | 287 | IRQF_ONESHOT | IRQF_EARLY_RESUME, | 
| 287 | dev_name(&pdev->dev), rtc); | 288 | dev_name(&pdev->dev), rtc); | 
| 288 | if (ret < 0) { | 289 | if (ret < 0) { | 
| @@ -311,7 +312,6 @@ static int tps6586x_rtc_remove(struct platform_device *pdev) | |||
| 311 | tps6586x_update(tps_dev, RTC_CTRL, 0, | 312 | tps6586x_update(tps_dev, RTC_CTRL, 0, | 
| 312 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); | 313 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); | 
| 313 | rtc_device_unregister(rtc->rtc); | 314 | rtc_device_unregister(rtc->rtc); | 
| 314 | free_irq(rtc->irq, rtc); | ||
| 315 | return 0; | 315 | return 0; | 
| 316 | } | 316 | } | 
| 317 | 317 | ||
| diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index e5fef141a0e2..8bd8115329b5 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c | |||
| @@ -22,13 +22,13 @@ | |||
| 22 | #include <linux/rtc.h> | 22 | #include <linux/rtc.h> | 
| 23 | #include <linux/bcd.h> | 23 | #include <linux/bcd.h> | 
| 24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> | 
| 25 | #include <linux/pm_runtime.h> | ||
| 25 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> | 
| 26 | #include <linux/mfd/tps65910.h> | 27 | #include <linux/mfd/tps65910.h> | 
| 27 | 28 | ||
| 28 | struct tps65910_rtc { | 29 | struct tps65910_rtc { | 
| 29 | struct rtc_device *rtc; | 30 | struct rtc_device *rtc; | 
| 30 | /* To store the list of enabled interrupts */ | 31 | int irq; | 
| 31 | u32 irqstat; | ||
| 32 | }; | 32 | }; | 
| 33 | 33 | ||
| 34 | /* Total number of RTC registers needed to set time*/ | 34 | /* Total number of RTC registers needed to set time*/ | 
| @@ -267,13 +267,14 @@ static int tps65910_rtc_probe(struct platform_device *pdev) | |||
| 267 | } | 267 | } | 
| 268 | 268 | ||
| 269 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 269 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 
| 270 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW, | 270 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW | IRQF_EARLY_RESUME, | 
| 271 | dev_name(&pdev->dev), &pdev->dev); | 271 | dev_name(&pdev->dev), &pdev->dev); | 
| 272 | if (ret < 0) { | 272 | if (ret < 0) { | 
| 273 | dev_err(&pdev->dev, "IRQ is not free.\n"); | 273 | dev_err(&pdev->dev, "IRQ is not free.\n"); | 
| 274 | return ret; | 274 | return ret; | 
| 275 | } | 275 | } | 
| 276 | device_init_wakeup(&pdev->dev, 1); | 276 | tps_rtc->irq = irq; | 
| 277 | device_set_wakeup_capable(&pdev->dev, 1); | ||
| 277 | 278 | ||
| 278 | tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 279 | tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 
| 279 | &tps65910_rtc_ops, THIS_MODULE); | 280 | &tps65910_rtc_ops, THIS_MODULE); | 
| @@ -304,49 +305,36 @@ static int tps65910_rtc_remove(struct platform_device *pdev) | |||
| 304 | } | 305 | } | 
| 305 | 306 | ||
| 306 | #ifdef CONFIG_PM_SLEEP | 307 | #ifdef CONFIG_PM_SLEEP | 
| 307 | |||
| 308 | static int tps65910_rtc_suspend(struct device *dev) | 308 | static int tps65910_rtc_suspend(struct device *dev) | 
| 309 | { | 309 | { | 
| 310 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | 310 | struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev); | 
| 311 | u8 alarm = TPS65910_RTC_INTERRUPTS_IT_ALARM; | ||
| 312 | int ret; | ||
| 313 | |||
| 314 | /* Store current list of enabled interrupts*/ | ||
| 315 | ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, | ||
| 316 | &tps->rtc->irqstat); | ||
| 317 | if (ret < 0) | ||
| 318 | return ret; | ||
| 319 | 311 | ||
| 320 | /* Enable RTC ALARM interrupt only */ | 312 | if (device_may_wakeup(dev)) | 
| 321 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, alarm); | 313 | enable_irq_wake(tps_rtc->irq); | 
| 314 | return 0; | ||
| 322 | } | 315 | } | 
| 323 | 316 | ||
| 324 | static int tps65910_rtc_resume(struct device *dev) | 317 | static int tps65910_rtc_resume(struct device *dev) | 
| 325 | { | 318 | { | 
| 326 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | 319 | struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev); | 
| 327 | 320 | ||
| 328 | /* Restore list of enabled interrupts before suspend */ | 321 | if (device_may_wakeup(dev)) | 
| 329 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, | 322 | disable_irq_wake(tps_rtc->irq); | 
| 330 | tps->rtc->irqstat); | 323 | return 0; | 
| 331 | } | 324 | } | 
| 325 | #endif | ||
| 332 | 326 | ||
| 333 | static const struct dev_pm_ops tps65910_rtc_pm_ops = { | 327 | static const struct dev_pm_ops tps65910_rtc_pm_ops = { | 
| 334 | .suspend = tps65910_rtc_suspend, | 328 | SET_SYSTEM_SLEEP_PM_OPS(tps65910_rtc_suspend, tps65910_rtc_resume) | 
| 335 | .resume = tps65910_rtc_resume, | ||
| 336 | }; | 329 | }; | 
| 337 | 330 | ||
| 338 | #define DEV_PM_OPS (&tps65910_rtc_pm_ops) | ||
| 339 | #else | ||
| 340 | #define DEV_PM_OPS NULL | ||
| 341 | #endif | ||
| 342 | |||
| 343 | static struct platform_driver tps65910_rtc_driver = { | 331 | static struct platform_driver tps65910_rtc_driver = { | 
| 344 | .probe = tps65910_rtc_probe, | 332 | .probe = tps65910_rtc_probe, | 
| 345 | .remove = tps65910_rtc_remove, | 333 | .remove = tps65910_rtc_remove, | 
| 346 | .driver = { | 334 | .driver = { | 
| 347 | .owner = THIS_MODULE, | 335 | .owner = THIS_MODULE, | 
| 348 | .name = "tps65910-rtc", | 336 | .name = "tps65910-rtc", | 
| 349 | .pm = DEV_PM_OPS, | 337 | .pm = &tps65910_rtc_pm_ops, | 
| 350 | }, | 338 | }, | 
| 351 | }; | 339 | }; | 
| 352 | 340 | ||
| diff --git a/drivers/rtc/rtc-tps80031.c b/drivers/rtc/rtc-tps80031.c new file mode 100644 index 000000000000..9aaf8aaebae9 --- /dev/null +++ b/drivers/rtc/rtc-tps80031.c | |||
| @@ -0,0 +1,349 @@ | |||
| 1 | /* | ||
| 2 | * rtc-tps80031.c -- TI TPS80031/TPS80032 RTC driver | ||
| 3 | * | ||
| 4 | * RTC driver for TI TPS80031/TPS80032 Fully Integrated | ||
| 5 | * Power Management with Power Path and Battery Charger | ||
| 6 | * | ||
| 7 | * Copyright (c) 2012, NVIDIA Corporation. | ||
| 8 | * | ||
| 9 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or | ||
| 12 | * modify it under the terms of the GNU General Public License as | ||
| 13 | * published by the Free Software Foundation version 2. | ||
| 14 | * | ||
| 15 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
| 16 | * whether express or implied; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/bcd.h> | ||
| 27 | #include <linux/device.h> | ||
| 28 | #include <linux/err.h> | ||
| 29 | #include <linux/init.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/module.h> | ||
| 32 | #include <linux/mfd/tps80031.h> | ||
| 33 | #include <linux/platform_device.h> | ||
| 34 | #include <linux/pm.h> | ||
| 35 | #include <linux/rtc.h> | ||
| 36 | #include <linux/slab.h> | ||
| 37 | |||
| 38 | #define ENABLE_ALARM_INT 0x08 | ||
| 39 | #define ALARM_INT_STATUS 0x40 | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Setting bit to 1 in STOP_RTC will run the RTC and | ||
| 43 | * setting this bit to 0 will freeze RTC. | ||
| 44 | */ | ||
| 45 | #define STOP_RTC 0x1 | ||
| 46 | |||
| 47 | /* Power on reset Values of RTC registers */ | ||
| 48 | #define TPS80031_RTC_POR_YEAR 0 | ||
| 49 | #define TPS80031_RTC_POR_MONTH 1 | ||
| 50 | #define TPS80031_RTC_POR_DAY 1 | ||
| 51 | |||
| 52 | /* Numbers of registers for time and alarms */ | ||
| 53 | #define TPS80031_RTC_TIME_NUM_REGS 7 | ||
| 54 | #define TPS80031_RTC_ALARM_NUM_REGS 6 | ||
| 55 | |||
| 56 | /** | ||
| 57 | * PMU RTC have only 2 nibbles to store year information, so using an | ||
| 58 | * offset of 100 to set the base year as 2000 for our driver. | ||
| 59 | */ | ||
| 60 | #define RTC_YEAR_OFFSET 100 | ||
| 61 | |||
| 62 | struct tps80031_rtc { | ||
| 63 | struct rtc_device *rtc; | ||
| 64 | int irq; | ||
| 65 | }; | ||
| 66 | |||
| 67 | static int tps80031_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 68 | { | ||
| 69 | u8 buff[TPS80031_RTC_TIME_NUM_REGS]; | ||
| 70 | int ret; | ||
| 71 | |||
| 72 | ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1, | ||
| 73 | TPS80031_SECONDS_REG, TPS80031_RTC_TIME_NUM_REGS, buff); | ||
| 74 | if (ret < 0) { | ||
| 75 | dev_err(dev, "reading RTC_SECONDS_REG failed, err = %d\n", ret); | ||
| 76 | return ret; | ||
| 77 | } | ||
| 78 | |||
| 79 | tm->tm_sec = bcd2bin(buff[0]); | ||
| 80 | tm->tm_min = bcd2bin(buff[1]); | ||
| 81 | tm->tm_hour = bcd2bin(buff[2]); | ||
| 82 | tm->tm_mday = bcd2bin(buff[3]); | ||
| 83 | tm->tm_mon = bcd2bin(buff[4]) - 1; | ||
| 84 | tm->tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET; | ||
| 85 | tm->tm_wday = bcd2bin(buff[6]); | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int tps80031_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 90 | { | ||
| 91 | u8 buff[7]; | ||
| 92 | int ret; | ||
| 93 | |||
| 94 | buff[0] = bin2bcd(tm->tm_sec); | ||
| 95 | buff[1] = bin2bcd(tm->tm_min); | ||
| 96 | buff[2] = bin2bcd(tm->tm_hour); | ||
| 97 | buff[3] = bin2bcd(tm->tm_mday); | ||
| 98 | buff[4] = bin2bcd(tm->tm_mon + 1); | ||
| 99 | buff[5] = bin2bcd(tm->tm_year % RTC_YEAR_OFFSET); | ||
| 100 | buff[6] = bin2bcd(tm->tm_wday); | ||
| 101 | |||
| 102 | /* Stop RTC while updating the RTC time registers */ | ||
| 103 | ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
| 104 | TPS80031_RTC_CTRL_REG, STOP_RTC); | ||
| 105 | if (ret < 0) { | ||
| 106 | dev_err(dev->parent, "Stop RTC failed, err = %d\n", ret); | ||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1, | ||
| 111 | TPS80031_SECONDS_REG, | ||
| 112 | TPS80031_RTC_TIME_NUM_REGS, buff); | ||
| 113 | if (ret < 0) { | ||
| 114 | dev_err(dev, "writing RTC_SECONDS_REG failed, err %d\n", ret); | ||
| 115 | return ret; | ||
| 116 | } | ||
| 117 | |||
| 118 | ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
| 119 | TPS80031_RTC_CTRL_REG, STOP_RTC); | ||
| 120 | if (ret < 0) | ||
| 121 | dev_err(dev->parent, "Start RTC failed, err = %d\n", ret); | ||
| 122 | return ret; | ||
| 123 | } | ||
| 124 | |||
| 125 | static int tps80031_rtc_alarm_irq_enable(struct device *dev, | ||
| 126 | unsigned int enable) | ||
| 127 | { | ||
| 128 | int ret; | ||
| 129 | |||
| 130 | if (enable) | ||
| 131 | ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
| 132 | TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT); | ||
| 133 | else | ||
| 134 | ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
| 135 | TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT); | ||
| 136 | if (ret < 0) { | ||
| 137 | dev_err(dev, "Update on RTC_INT failed, err = %d\n", ret); | ||
| 138 | return ret; | ||
| 139 | } | ||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | static int tps80031_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 144 | { | ||
| 145 | u8 buff[TPS80031_RTC_ALARM_NUM_REGS]; | ||
| 146 | int ret; | ||
| 147 | |||
| 148 | buff[0] = bin2bcd(alrm->time.tm_sec); | ||
| 149 | buff[1] = bin2bcd(alrm->time.tm_min); | ||
| 150 | buff[2] = bin2bcd(alrm->time.tm_hour); | ||
| 151 | buff[3] = bin2bcd(alrm->time.tm_mday); | ||
| 152 | buff[4] = bin2bcd(alrm->time.tm_mon + 1); | ||
| 153 | buff[5] = bin2bcd(alrm->time.tm_year % RTC_YEAR_OFFSET); | ||
| 154 | ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1, | ||
| 155 | TPS80031_ALARM_SECONDS_REG, | ||
| 156 | TPS80031_RTC_ALARM_NUM_REGS, buff); | ||
| 157 | if (ret < 0) { | ||
| 158 | dev_err(dev, "Writing RTC_ALARM failed, err %d\n", ret); | ||
| 159 | return ret; | ||
| 160 | } | ||
| 161 | return tps80031_rtc_alarm_irq_enable(dev, alrm->enabled); | ||
| 162 | } | ||
| 163 | |||
| 164 | static int tps80031_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 165 | { | ||
| 166 | u8 buff[6]; | ||
| 167 | int ret; | ||
| 168 | |||
| 169 | ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1, | ||
| 170 | TPS80031_ALARM_SECONDS_REG, | ||
| 171 | TPS80031_RTC_ALARM_NUM_REGS, buff); | ||
| 172 | if (ret < 0) { | ||
| 173 | dev_err(dev->parent, | ||
| 174 | "reading RTC_ALARM failed, err = %d\n", ret); | ||
| 175 | return ret; | ||
| 176 | } | ||
| 177 | |||
| 178 | alrm->time.tm_sec = bcd2bin(buff[0]); | ||
| 179 | alrm->time.tm_min = bcd2bin(buff[1]); | ||
| 180 | alrm->time.tm_hour = bcd2bin(buff[2]); | ||
| 181 | alrm->time.tm_mday = bcd2bin(buff[3]); | ||
| 182 | alrm->time.tm_mon = bcd2bin(buff[4]) - 1; | ||
| 183 | alrm->time.tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET; | ||
| 184 | return 0; | ||
| 185 | } | ||
| 186 | |||
| 187 | static int clear_alarm_int_status(struct device *dev, struct tps80031_rtc *rtc) | ||
| 188 | { | ||
| 189 | int ret; | ||
| 190 | u8 buf; | ||
| 191 | |||
| 192 | /** | ||
| 193 | * As per datasheet, A dummy read of this RTC_STATUS_REG register | ||
| 194 | * is necessary before each I2C read in order to update the status | ||
| 195 | * register value. | ||
| 196 | */ | ||
| 197 | ret = tps80031_read(dev->parent, TPS80031_SLAVE_ID1, | ||
| 198 | TPS80031_RTC_STATUS_REG, &buf); | ||
| 199 | if (ret < 0) { | ||
| 200 | dev_err(dev, "reading RTC_STATUS failed. err = %d\n", ret); | ||
| 201 | return ret; | ||
| 202 | } | ||
| 203 | |||
| 204 | /* clear Alarm status bits.*/ | ||
| 205 | ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
| 206 | TPS80031_RTC_STATUS_REG, ALARM_INT_STATUS); | ||
| 207 | if (ret < 0) { | ||
| 208 | dev_err(dev, "clear Alarm INT failed, err = %d\n", ret); | ||
| 209 | return ret; | ||
| 210 | } | ||
| 211 | return 0; | ||
| 212 | } | ||
| 213 | |||
| 214 | static irqreturn_t tps80031_rtc_irq(int irq, void *data) | ||
| 215 | { | ||
| 216 | struct device *dev = data; | ||
| 217 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
| 218 | int ret; | ||
| 219 | |||
| 220 | ret = clear_alarm_int_status(dev, rtc); | ||
| 221 | if (ret < 0) | ||
| 222 | return ret; | ||
| 223 | |||
| 224 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
| 225 | return IRQ_HANDLED; | ||
| 226 | } | ||
| 227 | |||
| 228 | static const struct rtc_class_ops tps80031_rtc_ops = { | ||
| 229 | .read_time = tps80031_rtc_read_time, | ||
| 230 | .set_time = tps80031_rtc_set_time, | ||
| 231 | .set_alarm = tps80031_rtc_set_alarm, | ||
| 232 | .read_alarm = tps80031_rtc_read_alarm, | ||
| 233 | .alarm_irq_enable = tps80031_rtc_alarm_irq_enable, | ||
| 234 | }; | ||
| 235 | |||
| 236 | static int tps80031_rtc_probe(struct platform_device *pdev) | ||
| 237 | { | ||
| 238 | struct tps80031_rtc *rtc; | ||
| 239 | struct rtc_time tm; | ||
| 240 | int ret; | ||
| 241 | |||
| 242 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
| 243 | if (!rtc) | ||
| 244 | return -ENOMEM; | ||
| 245 | |||
| 246 | rtc->irq = platform_get_irq(pdev, 0); | ||
| 247 | platform_set_drvdata(pdev, rtc); | ||
| 248 | |||
| 249 | /* Start RTC */ | ||
| 250 | ret = tps80031_set_bits(pdev->dev.parent, TPS80031_SLAVE_ID1, | ||
| 251 | TPS80031_RTC_CTRL_REG, STOP_RTC); | ||
| 252 | if (ret < 0) { | ||
| 253 | dev_err(&pdev->dev, "failed to start RTC. err = %d\n", ret); | ||
| 254 | return ret; | ||
| 255 | } | ||
| 256 | |||
| 257 | /* If RTC have POR values, set time 01:01:2000 */ | ||
| 258 | tps80031_rtc_read_time(&pdev->dev, &tm); | ||
| 259 | if ((tm.tm_year == RTC_YEAR_OFFSET + TPS80031_RTC_POR_YEAR) && | ||
| 260 | (tm.tm_mon == (TPS80031_RTC_POR_MONTH - 1)) && | ||
| 261 | (tm.tm_mday == TPS80031_RTC_POR_DAY)) { | ||
| 262 | tm.tm_year = 2000; | ||
| 263 | tm.tm_mday = 1; | ||
| 264 | tm.tm_mon = 1; | ||
| 265 | ret = tps80031_rtc_set_time(&pdev->dev, &tm); | ||
| 266 | if (ret < 0) { | ||
| 267 | dev_err(&pdev->dev, | ||
| 268 | "RTC set time failed, err = %d\n", ret); | ||
| 269 | return ret; | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | /* Clear alarm intretupt status if it is there */ | ||
| 274 | ret = clear_alarm_int_status(&pdev->dev, rtc); | ||
| 275 | if (ret < 0) { | ||
| 276 | dev_err(&pdev->dev, "Clear alarm int failed, err = %d\n", ret); | ||
| 277 | return ret; | ||
| 278 | } | ||
| 279 | |||
| 280 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
| 281 | &tps80031_rtc_ops, THIS_MODULE); | ||
| 282 | if (IS_ERR(rtc->rtc)) { | ||
| 283 | ret = PTR_ERR(rtc->rtc); | ||
| 284 | dev_err(&pdev->dev, "RTC registration failed, err %d\n", ret); | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | |||
| 288 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | ||
| 289 | tps80031_rtc_irq, | ||
| 290 | IRQF_ONESHOT | IRQF_EARLY_RESUME, | ||
| 291 | dev_name(&pdev->dev), rtc); | ||
| 292 | if (ret < 0) { | ||
| 293 | dev_err(&pdev->dev, "request IRQ:%d failed, err = %d\n", | ||
| 294 | rtc->irq, ret); | ||
| 295 | rtc_device_unregister(rtc->rtc); | ||
| 296 | return ret; | ||
| 297 | } | ||
| 298 | device_set_wakeup_capable(&pdev->dev, 1); | ||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int tps80031_rtc_remove(struct platform_device *pdev) | ||
| 303 | { | ||
| 304 | struct tps80031_rtc *rtc = platform_get_drvdata(pdev); | ||
| 305 | |||
| 306 | rtc_device_unregister(rtc->rtc); | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | #ifdef CONFIG_PM_SLEEP | ||
| 311 | static int tps80031_rtc_suspend(struct device *dev) | ||
| 312 | { | ||
| 313 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
| 314 | |||
| 315 | if (device_may_wakeup(dev)) | ||
| 316 | enable_irq_wake(rtc->irq); | ||
| 317 | return 0; | ||
| 318 | } | ||
| 319 | |||
| 320 | static int tps80031_rtc_resume(struct device *dev) | ||
| 321 | { | ||
| 322 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
| 323 | |||
| 324 | if (device_may_wakeup(dev)) | ||
| 325 | disable_irq_wake(rtc->irq); | ||
| 326 | return 0; | ||
| 327 | }; | ||
| 328 | #endif | ||
| 329 | |||
| 330 | static const struct dev_pm_ops tps80031_pm_ops = { | ||
| 331 | SET_SYSTEM_SLEEP_PM_OPS(tps80031_rtc_suspend, tps80031_rtc_resume) | ||
| 332 | }; | ||
| 333 | |||
| 334 | static struct platform_driver tps80031_rtc_driver = { | ||
| 335 | .driver = { | ||
| 336 | .name = "tps80031-rtc", | ||
| 337 | .owner = THIS_MODULE, | ||
| 338 | .pm = &tps80031_pm_ops, | ||
| 339 | }, | ||
| 340 | .probe = tps80031_rtc_probe, | ||
| 341 | .remove = tps80031_rtc_remove, | ||
| 342 | }; | ||
| 343 | |||
| 344 | module_platform_driver(tps80031_rtc_driver); | ||
| 345 | |||
| 346 | MODULE_ALIAS("platform:tps80031-rtc"); | ||
| 347 | MODULE_DESCRIPTION("TI TPS80031/TPS80032 RTC driver"); | ||
| 348 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
| 349 | MODULE_LICENSE("GPL v2"); | ||
| diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index ccd4ad370b32..8bc6c80b184c 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> | 
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> | 
| 29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> | 
| 30 | #include <linux/of.h> | ||
| 30 | 31 | ||
| 31 | #include <linux/i2c/twl.h> | 32 | #include <linux/i2c/twl.h> | 
| 32 | 33 | ||
| @@ -588,11 +589,14 @@ static int twl_rtc_resume(struct platform_device *pdev) | |||
| 588 | #define twl_rtc_resume NULL | 589 | #define twl_rtc_resume NULL | 
| 589 | #endif | 590 | #endif | 
| 590 | 591 | ||
| 592 | #ifdef CONFIG_OF | ||
| 591 | static const struct of_device_id twl_rtc_of_match[] = { | 593 | static const struct of_device_id twl_rtc_of_match[] = { | 
| 592 | {.compatible = "ti,twl4030-rtc", }, | 594 | {.compatible = "ti,twl4030-rtc", }, | 
| 593 | { }, | 595 | { }, | 
| 594 | }; | 596 | }; | 
| 595 | MODULE_DEVICE_TABLE(of, twl_rtc_of_match); | 597 | MODULE_DEVICE_TABLE(of, twl_rtc_of_match); | 
| 598 | #endif | ||
| 599 | |||
| 596 | MODULE_ALIAS("platform:twl_rtc"); | 600 | MODULE_ALIAS("platform:twl_rtc"); | 
| 597 | 601 | ||
| 598 | static struct platform_driver twl4030rtc_driver = { | 602 | static struct platform_driver twl4030rtc_driver = { | 
| @@ -604,7 +608,7 @@ static struct platform_driver twl4030rtc_driver = { | |||
| 604 | .driver = { | 608 | .driver = { | 
| 605 | .owner = THIS_MODULE, | 609 | .owner = THIS_MODULE, | 
| 606 | .name = "twl_rtc", | 610 | .name = "twl_rtc", | 
| 607 | .of_match_table = twl_rtc_of_match, | 611 | .of_match_table = of_match_ptr(twl_rtc_of_match), | 
| 608 | }, | 612 | }, | 
| 609 | }; | 613 | }; | 
| 610 | 614 | ||
| diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 6c3774cf5a24..f91be04b9050 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
| @@ -352,7 +352,7 @@ static int rtc_probe(struct platform_device *pdev) | |||
| 352 | disable_irq(aie_irq); | 352 | disable_irq(aie_irq); | 
| 353 | disable_irq(pie_irq); | 353 | disable_irq(pie_irq); | 
| 354 | 354 | ||
| 355 | printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); | 355 | dev_info(&pdev->dev, "Real Time Clock of NEC VR4100 series\n"); | 
| 356 | 356 | ||
| 357 | return 0; | 357 | return 0; | 
| 358 | 358 | ||
| diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 2730533e2d2d..a000bc0a8bff 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c | |||
| @@ -231,20 +231,21 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
| 231 | return -ENXIO; | 231 | return -ENXIO; | 
| 232 | } | 232 | } | 
| 233 | 233 | ||
| 234 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, | 234 | vt8500_rtc->res = devm_request_mem_region(&pdev->dev, | 
| 235 | resource_size(vt8500_rtc->res), | 235 | vt8500_rtc->res->start, | 
| 236 | "vt8500-rtc"); | 236 | resource_size(vt8500_rtc->res), | 
| 237 | "vt8500-rtc"); | ||
| 237 | if (vt8500_rtc->res == NULL) { | 238 | if (vt8500_rtc->res == NULL) { | 
| 238 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 239 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 
| 239 | return -EBUSY; | 240 | return -EBUSY; | 
| 240 | } | 241 | } | 
| 241 | 242 | ||
| 242 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, | 243 | vt8500_rtc->regbase = devm_ioremap(&pdev->dev, vt8500_rtc->res->start, | 
| 243 | resource_size(vt8500_rtc->res)); | 244 | resource_size(vt8500_rtc->res)); | 
| 244 | if (!vt8500_rtc->regbase) { | 245 | if (!vt8500_rtc->regbase) { | 
| 245 | dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); | 246 | dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); | 
| 246 | ret = -EBUSY; | 247 | ret = -EBUSY; | 
| 247 | goto err_release; | 248 | goto err_return; | 
| 248 | } | 249 | } | 
| 249 | 250 | ||
| 250 | /* Enable RTC and set it to 24-hour mode */ | 251 | /* Enable RTC and set it to 24-hour mode */ | 
| @@ -257,11 +258,11 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
| 257 | ret = PTR_ERR(vt8500_rtc->rtc); | 258 | ret = PTR_ERR(vt8500_rtc->rtc); | 
| 258 | dev_err(&pdev->dev, | 259 | dev_err(&pdev->dev, | 
| 259 | "Failed to register RTC device -> %d\n", ret); | 260 | "Failed to register RTC device -> %d\n", ret); | 
| 260 | goto err_unmap; | 261 | goto err_return; | 
| 261 | } | 262 | } | 
| 262 | 263 | ||
| 263 | ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0, | 264 | ret = devm_request_irq(&pdev->dev, vt8500_rtc->irq_alarm, | 
| 264 | "rtc alarm", vt8500_rtc); | 265 | vt8500_rtc_irq, 0, "rtc alarm", vt8500_rtc); | 
| 265 | if (ret < 0) { | 266 | if (ret < 0) { | 
| 266 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", | 267 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", | 
| 267 | vt8500_rtc->irq_alarm, ret); | 268 | vt8500_rtc->irq_alarm, ret); | 
| @@ -272,11 +273,7 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
| 272 | 273 | ||
| 273 | err_unreg: | 274 | err_unreg: | 
| 274 | rtc_device_unregister(vt8500_rtc->rtc); | 275 | rtc_device_unregister(vt8500_rtc->rtc); | 
| 275 | err_unmap: | 276 | err_return: | 
| 276 | iounmap(vt8500_rtc->regbase); | ||
| 277 | err_release: | ||
| 278 | release_mem_region(vt8500_rtc->res->start, | ||
| 279 | resource_size(vt8500_rtc->res)); | ||
| 280 | return ret; | 277 | return ret; | 
| 281 | } | 278 | } | 
| 282 | 279 | ||
| @@ -284,15 +281,10 @@ static int vt8500_rtc_remove(struct platform_device *pdev) | |||
| 284 | { | 281 | { | 
| 285 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); | 282 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); | 
| 286 | 283 | ||
| 287 | free_irq(vt8500_rtc->irq_alarm, vt8500_rtc); | ||
| 288 | |||
| 289 | rtc_device_unregister(vt8500_rtc->rtc); | 284 | rtc_device_unregister(vt8500_rtc->rtc); | 
| 290 | 285 | ||
| 291 | /* Disable alarm matching */ | 286 | /* Disable alarm matching */ | 
| 292 | writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); | 287 | writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); | 
| 293 | iounmap(vt8500_rtc->regbase); | ||
| 294 | release_mem_region(vt8500_rtc->res->start, | ||
| 295 | resource_size(vt8500_rtc->res)); | ||
| 296 | 288 | ||
| 297 | platform_set_drvdata(pdev, NULL); | 289 | platform_set_drvdata(pdev, NULL); | 
| 298 | 290 | ||
| diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 1b0affbe2659..2f0ac7b30a0c 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
| @@ -443,9 +443,10 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
| 443 | goto err; | 443 | goto err; | 
| 444 | } | 444 | } | 
| 445 | 445 | ||
| 446 | ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, | 446 | ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL, | 
| 447 | IRQF_TRIGGER_RISING, "RTC alarm", | 447 | wm831x_alm_irq, | 
| 448 | wm831x_rtc); | 448 | IRQF_TRIGGER_RISING, "RTC alarm", | 
| 449 | wm831x_rtc); | ||
| 449 | if (ret != 0) { | 450 | if (ret != 0) { | 
| 450 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", | 451 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", | 
| 451 | alm_irq, ret); | 452 | alm_irq, ret); | 
| @@ -462,9 +463,7 @@ err: | |||
| 462 | static int wm831x_rtc_remove(struct platform_device *pdev) | 463 | static int wm831x_rtc_remove(struct platform_device *pdev) | 
| 463 | { | 464 | { | 
| 464 | struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev); | 465 | struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev); | 
| 465 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); | ||
| 466 | 466 | ||
| 467 | free_irq(alm_irq, wm831x_rtc); | ||
| 468 | rtc_device_unregister(wm831x_rtc->rtc); | 467 | rtc_device_unregister(wm831x_rtc->rtc); | 
| 469 | 468 | ||
| 470 | return 0; | 469 | return 0; | 
| diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c new file mode 100644 index 000000000000..bf3e242ccc5c --- /dev/null +++ b/drivers/rtc/systohc.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published by | ||
| 4 | * the Free Software Foundation. | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | #include <linux/rtc.h> | ||
| 8 | #include <linux/time.h> | ||
| 9 | |||
| 10 | /** | ||
| 11 | * rtc_set_ntp_time - Save NTP synchronized time to the RTC | ||
| 12 | * @now: Current time of day | ||
| 13 | * | ||
| 14 | * Replacement for the NTP platform function update_persistent_clock | ||
| 15 | * that stores time for later retrieval by rtc_hctosys. | ||
| 16 | * | ||
| 17 | * Returns 0 on successful RTC update, -ENODEV if a RTC update is not | ||
| 18 | * possible at all, and various other -errno for specific temporary failure | ||
| 19 | * cases. | ||
| 20 | * | ||
| 21 | * If temporary failure is indicated the caller should try again 'soon' | ||
| 22 | */ | ||
| 23 | int rtc_set_ntp_time(struct timespec now) | ||
| 24 | { | ||
| 25 | struct rtc_device *rtc; | ||
| 26 | struct rtc_time tm; | ||
| 27 | int err = -ENODEV; | ||
| 28 | |||
| 29 | if (now.tv_nsec < (NSEC_PER_SEC >> 1)) | ||
| 30 | rtc_time_to_tm(now.tv_sec, &tm); | ||
| 31 | else | ||
| 32 | rtc_time_to_tm(now.tv_sec + 1, &tm); | ||
| 33 | |||
| 34 | rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | ||
| 35 | if (rtc) { | ||
| 36 | /* rtc_hctosys exclusively uses UTC, so we call set_time here, | ||
| 37 | * not set_mmss. */ | ||
| 38 | if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss)) | ||
| 39 | err = rtc_set_time(rtc, &tm); | ||
| 40 | rtc_class_close(rtc); | ||
| 41 | } | ||
| 42 | |||
| 43 | return err; | ||
| 44 | } | ||
