diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 10 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-abx80x.c | 146 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-da9063.c | 42 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1305.c | 8 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 17 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1685.c | 22 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds2404.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-efi.c | 66 | ||||
-rw-r--r-- | drivers/rtc/rtc-gemini.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-imxdi.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-lpc32xx.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-opal.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf8523.c | 11 | ||||
-rw-r--r-- | drivers/rtc/rtc-proc.c | 8 | ||||
-rw-r--r-- | drivers/rtc/rtc-rk808.c | 48 | ||||
-rw-r--r-- | drivers/rtc/rtc-rv8803.c | 3 | ||||
-rw-r--r-- | drivers/rtc/rtc-rx8010.c | 523 | ||||
-rw-r--r-- | drivers/rtc/rtc-s5m.c | 131 | ||||
-rw-r--r-- | drivers/rtc/rtc-sunxi.c | 18 | ||||
-rw-r--r-- | drivers/rtc/rtc-sysfs.c | 11 | ||||
-rw-r--r-- | drivers/rtc/rtc-v3020.c | 6 |
23 files changed, 957 insertions, 127 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 2a524244afec..376322f71fd5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -558,6 +558,16 @@ config RTC_DRV_FM3130 | |||
558 | This driver can also be built as a module. If so the module | 558 | This driver can also be built as a module. If so the module |
559 | will be called rtc-fm3130. | 559 | will be called rtc-fm3130. |
560 | 560 | ||
561 | config RTC_DRV_RX8010 | ||
562 | tristate "Epson RX8010SJ" | ||
563 | depends on I2C | ||
564 | help | ||
565 | If you say yes here you get support for the Epson RX8010SJ RTC | ||
566 | chip. | ||
567 | |||
568 | This driver can also be built as a module. If so, the module | ||
569 | will be called rtc-rx8010. | ||
570 | |||
561 | config RTC_DRV_RX8581 | 571 | config RTC_DRV_RX8581 |
562 | tristate "Epson RX-8581" | 572 | tristate "Epson RX-8581" |
563 | help | 573 | help |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 231f76451615..62d61b26ca7e 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -128,6 +128,7 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | |||
128 | obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o | 128 | obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o |
129 | obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o | 129 | obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o |
130 | obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o | 130 | obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o |
131 | obj-$(CONFIG_RTC_DRV_RX8010) += rtc-rx8010.o | ||
131 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o | 132 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o |
132 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o | 133 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o |
133 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | 134 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o |
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index afea84c7a155..d41bbcd653f6 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c | |||
@@ -27,10 +27,28 @@ | |||
27 | #define ABX8XX_REG_YR 0x06 | 27 | #define ABX8XX_REG_YR 0x06 |
28 | #define ABX8XX_REG_WD 0x07 | 28 | #define ABX8XX_REG_WD 0x07 |
29 | 29 | ||
30 | #define ABX8XX_REG_AHTH 0x08 | ||
31 | #define ABX8XX_REG_ASC 0x09 | ||
32 | #define ABX8XX_REG_AMN 0x0a | ||
33 | #define ABX8XX_REG_AHR 0x0b | ||
34 | #define ABX8XX_REG_ADA 0x0c | ||
35 | #define ABX8XX_REG_AMO 0x0d | ||
36 | #define ABX8XX_REG_AWD 0x0e | ||
37 | |||
38 | #define ABX8XX_REG_STATUS 0x0f | ||
39 | #define ABX8XX_STATUS_AF BIT(2) | ||
40 | |||
30 | #define ABX8XX_REG_CTRL1 0x10 | 41 | #define ABX8XX_REG_CTRL1 0x10 |
31 | #define ABX8XX_CTRL_WRITE BIT(0) | 42 | #define ABX8XX_CTRL_WRITE BIT(0) |
43 | #define ABX8XX_CTRL_ARST BIT(2) | ||
32 | #define ABX8XX_CTRL_12_24 BIT(6) | 44 | #define ABX8XX_CTRL_12_24 BIT(6) |
33 | 45 | ||
46 | #define ABX8XX_REG_IRQ 0x12 | ||
47 | #define ABX8XX_IRQ_AIE BIT(2) | ||
48 | #define ABX8XX_IRQ_IM_1_4 (0x3 << 5) | ||
49 | |||
50 | #define ABX8XX_REG_CD_TIMER_CTL 0x18 | ||
51 | |||
34 | #define ABX8XX_REG_CFG_KEY 0x1f | 52 | #define ABX8XX_REG_CFG_KEY 0x1f |
35 | #define ABX8XX_CFG_KEY_MISC 0x9d | 53 | #define ABX8XX_CFG_KEY_MISC 0x9d |
36 | 54 | ||
@@ -63,8 +81,6 @@ static struct abx80x_cap abx80x_caps[] = { | |||
63 | [ABX80X] = {.pn = 0} | 81 | [ABX80X] = {.pn = 0} |
64 | }; | 82 | }; |
65 | 83 | ||
66 | static struct i2c_driver abx80x_driver; | ||
67 | |||
68 | static int abx80x_enable_trickle_charger(struct i2c_client *client, | 84 | static int abx80x_enable_trickle_charger(struct i2c_client *client, |
69 | u8 trickle_cfg) | 85 | u8 trickle_cfg) |
70 | { | 86 | { |
@@ -148,9 +164,111 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
148 | return 0; | 164 | return 0; |
149 | } | 165 | } |
150 | 166 | ||
167 | static irqreturn_t abx80x_handle_irq(int irq, void *dev_id) | ||
168 | { | ||
169 | struct i2c_client *client = dev_id; | ||
170 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
171 | int status; | ||
172 | |||
173 | status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS); | ||
174 | if (status < 0) | ||
175 | return IRQ_NONE; | ||
176 | |||
177 | if (status & ABX8XX_STATUS_AF) | ||
178 | rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); | ||
179 | |||
180 | i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0); | ||
181 | |||
182 | return IRQ_HANDLED; | ||
183 | } | ||
184 | |||
185 | static int abx80x_read_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
186 | { | ||
187 | struct i2c_client *client = to_i2c_client(dev); | ||
188 | unsigned char buf[7]; | ||
189 | |||
190 | int irq_mask, err; | ||
191 | |||
192 | if (client->irq <= 0) | ||
193 | return -EINVAL; | ||
194 | |||
195 | err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ASC, | ||
196 | sizeof(buf), buf); | ||
197 | if (err) | ||
198 | return err; | ||
199 | |||
200 | irq_mask = i2c_smbus_read_byte_data(client, ABX8XX_REG_IRQ); | ||
201 | if (irq_mask < 0) | ||
202 | return irq_mask; | ||
203 | |||
204 | t->time.tm_sec = bcd2bin(buf[0] & 0x7F); | ||
205 | t->time.tm_min = bcd2bin(buf[1] & 0x7F); | ||
206 | t->time.tm_hour = bcd2bin(buf[2] & 0x3F); | ||
207 | t->time.tm_mday = bcd2bin(buf[3] & 0x3F); | ||
208 | t->time.tm_mon = bcd2bin(buf[4] & 0x1F) - 1; | ||
209 | t->time.tm_wday = buf[5] & 0x7; | ||
210 | |||
211 | t->enabled = !!(irq_mask & ABX8XX_IRQ_AIE); | ||
212 | t->pending = (buf[6] & ABX8XX_STATUS_AF) && t->enabled; | ||
213 | |||
214 | return err; | ||
215 | } | ||
216 | |||
217 | static int abx80x_set_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
218 | { | ||
219 | struct i2c_client *client = to_i2c_client(dev); | ||
220 | u8 alarm[6]; | ||
221 | int err; | ||
222 | |||
223 | if (client->irq <= 0) | ||
224 | return -EINVAL; | ||
225 | |||
226 | alarm[0] = 0x0; | ||
227 | alarm[1] = bin2bcd(t->time.tm_sec); | ||
228 | alarm[2] = bin2bcd(t->time.tm_min); | ||
229 | alarm[3] = bin2bcd(t->time.tm_hour); | ||
230 | alarm[4] = bin2bcd(t->time.tm_mday); | ||
231 | alarm[5] = bin2bcd(t->time.tm_mon + 1); | ||
232 | |||
233 | err = i2c_smbus_write_i2c_block_data(client, ABX8XX_REG_AHTH, | ||
234 | sizeof(alarm), alarm); | ||
235 | if (err < 0) { | ||
236 | dev_err(&client->dev, "Unable to write alarm registers\n"); | ||
237 | return -EIO; | ||
238 | } | ||
239 | |||
240 | if (t->enabled) { | ||
241 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ, | ||
242 | (ABX8XX_IRQ_IM_1_4 | | ||
243 | ABX8XX_IRQ_AIE)); | ||
244 | if (err) | ||
245 | return err; | ||
246 | } | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
252 | { | ||
253 | struct i2c_client *client = to_i2c_client(dev); | ||
254 | int err; | ||
255 | |||
256 | if (enabled) | ||
257 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ, | ||
258 | (ABX8XX_IRQ_IM_1_4 | | ||
259 | ABX8XX_IRQ_AIE)); | ||
260 | else | ||
261 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ, | ||
262 | ABX8XX_IRQ_IM_1_4); | ||
263 | return err; | ||
264 | } | ||
265 | |||
151 | static const struct rtc_class_ops abx80x_rtc_ops = { | 266 | static const struct rtc_class_ops abx80x_rtc_ops = { |
152 | .read_time = abx80x_rtc_read_time, | 267 | .read_time = abx80x_rtc_read_time, |
153 | .set_time = abx80x_rtc_set_time, | 268 | .set_time = abx80x_rtc_set_time, |
269 | .read_alarm = abx80x_read_alarm, | ||
270 | .set_alarm = abx80x_set_alarm, | ||
271 | .alarm_irq_enable = abx80x_alarm_irq_enable, | ||
154 | }; | 272 | }; |
155 | 273 | ||
156 | static int abx80x_dt_trickle_cfg(struct device_node *np) | 274 | static int abx80x_dt_trickle_cfg(struct device_node *np) |
@@ -225,7 +343,8 @@ static int abx80x_probe(struct i2c_client *client, | |||
225 | } | 343 | } |
226 | 344 | ||
227 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL1, | 345 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL1, |
228 | ((data & ~ABX8XX_CTRL_12_24) | | 346 | ((data & ~(ABX8XX_CTRL_12_24 | |
347 | ABX8XX_CTRL_ARST)) | | ||
229 | ABX8XX_CTRL_WRITE)); | 348 | ABX8XX_CTRL_WRITE)); |
230 | if (err < 0) { | 349 | if (err < 0) { |
231 | dev_err(&client->dev, "Unable to write control register\n"); | 350 | dev_err(&client->dev, "Unable to write control register\n"); |
@@ -260,7 +379,12 @@ static int abx80x_probe(struct i2c_client *client, | |||
260 | abx80x_enable_trickle_charger(client, trickle_cfg); | 379 | abx80x_enable_trickle_charger(client, trickle_cfg); |
261 | } | 380 | } |
262 | 381 | ||
263 | rtc = devm_rtc_device_register(&client->dev, abx80x_driver.driver.name, | 382 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CD_TIMER_CTL, |
383 | BIT(2)); | ||
384 | if (err) | ||
385 | return err; | ||
386 | |||
387 | rtc = devm_rtc_device_register(&client->dev, "abx8xx", | ||
264 | &abx80x_rtc_ops, THIS_MODULE); | 388 | &abx80x_rtc_ops, THIS_MODULE); |
265 | 389 | ||
266 | if (IS_ERR(rtc)) | 390 | if (IS_ERR(rtc)) |
@@ -268,6 +392,19 @@ static int abx80x_probe(struct i2c_client *client, | |||
268 | 392 | ||
269 | i2c_set_clientdata(client, rtc); | 393 | i2c_set_clientdata(client, rtc); |
270 | 394 | ||
395 | if (client->irq > 0) { | ||
396 | dev_info(&client->dev, "IRQ %d supplied\n", client->irq); | ||
397 | err = devm_request_threaded_irq(&client->dev, client->irq, NULL, | ||
398 | abx80x_handle_irq, | ||
399 | IRQF_SHARED | IRQF_ONESHOT, | ||
400 | "abx8xx", | ||
401 | client); | ||
402 | if (err) { | ||
403 | dev_err(&client->dev, "unable to request IRQ, alarms disabled\n"); | ||
404 | client->irq = 0; | ||
405 | } | ||
406 | } | ||
407 | |||
271 | return 0; | 408 | return 0; |
272 | } | 409 | } |
273 | 410 | ||
@@ -286,6 +423,7 @@ static const struct i2c_device_id abx80x_id[] = { | |||
286 | { "ab1803", AB1803 }, | 423 | { "ab1803", AB1803 }, |
287 | { "ab1804", AB1804 }, | 424 | { "ab1804", AB1804 }, |
288 | { "ab1805", AB1805 }, | 425 | { "ab1805", AB1805 }, |
426 | { "rv1805", AB1805 }, | ||
289 | { } | 427 | { } |
290 | }; | 428 | }; |
291 | MODULE_DEVICE_TABLE(i2c, abx80x_id); | 429 | MODULE_DEVICE_TABLE(i2c, abx80x_id); |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 8f7034ba7d9e..84fb541038be 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -725,7 +725,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
725 | rtc_cmos_int_handler = cmos_interrupt; | 725 | rtc_cmos_int_handler = cmos_interrupt; |
726 | 726 | ||
727 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, | 727 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, |
728 | 0, dev_name(&cmos_rtc.rtc->dev), | 728 | IRQF_SHARED, dev_name(&cmos_rtc.rtc->dev), |
729 | cmos_rtc.rtc); | 729 | cmos_rtc.rtc); |
730 | if (retval < 0) { | 730 | if (retval < 0) { |
731 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); | 731 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); |
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index 284b587da65c..f85cae240f12 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c | |||
@@ -191,24 +191,13 @@ static void da9063_tm_to_data(struct rtc_time *tm, u8 *data, | |||
191 | { | 191 | { |
192 | const struct da9063_compatible_rtc_regmap *config = rtc->config; | 192 | const struct da9063_compatible_rtc_regmap *config = rtc->config; |
193 | 193 | ||
194 | data[RTC_SEC] &= ~config->rtc_count_sec_mask; | 194 | data[RTC_SEC] = tm->tm_sec & config->rtc_count_sec_mask; |
195 | data[RTC_SEC] |= tm->tm_sec & config->rtc_count_sec_mask; | 195 | data[RTC_MIN] = tm->tm_min & config->rtc_count_min_mask; |
196 | 196 | data[RTC_HOUR] = tm->tm_hour & config->rtc_count_hour_mask; | |
197 | data[RTC_MIN] &= ~config->rtc_count_min_mask; | 197 | data[RTC_DAY] = tm->tm_mday & config->rtc_count_day_mask; |
198 | data[RTC_MIN] |= tm->tm_min & config->rtc_count_min_mask; | 198 | data[RTC_MONTH] = MONTHS_TO_DA9063(tm->tm_mon) & |
199 | |||
200 | data[RTC_HOUR] &= ~config->rtc_count_hour_mask; | ||
201 | data[RTC_HOUR] |= tm->tm_hour & config->rtc_count_hour_mask; | ||
202 | |||
203 | data[RTC_DAY] &= ~config->rtc_count_day_mask; | ||
204 | data[RTC_DAY] |= tm->tm_mday & config->rtc_count_day_mask; | ||
205 | |||
206 | data[RTC_MONTH] &= ~config->rtc_count_month_mask; | ||
207 | data[RTC_MONTH] |= MONTHS_TO_DA9063(tm->tm_mon) & | ||
208 | config->rtc_count_month_mask; | 199 | config->rtc_count_month_mask; |
209 | 200 | data[RTC_YEAR] = YEARS_TO_DA9063(tm->tm_year) & | |
210 | data[RTC_YEAR] &= ~config->rtc_count_year_mask; | ||
211 | data[RTC_YEAR] |= YEARS_TO_DA9063(tm->tm_year) & | ||
212 | config->rtc_count_year_mask; | 201 | config->rtc_count_year_mask; |
213 | } | 202 | } |
214 | 203 | ||
@@ -483,24 +472,23 @@ static int da9063_rtc_probe(struct platform_device *pdev) | |||
483 | 472 | ||
484 | platform_set_drvdata(pdev, rtc); | 473 | platform_set_drvdata(pdev, rtc); |
485 | 474 | ||
475 | rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC, | ||
476 | &da9063_rtc_ops, THIS_MODULE); | ||
477 | if (IS_ERR(rtc->rtc_dev)) | ||
478 | return PTR_ERR(rtc->rtc_dev); | ||
479 | |||
480 | da9063_data_to_tm(data, &rtc->alarm_time, rtc); | ||
481 | rtc->rtc_sync = false; | ||
482 | |||
486 | irq_alarm = platform_get_irq_byname(pdev, "ALARM"); | 483 | irq_alarm = platform_get_irq_byname(pdev, "ALARM"); |
487 | ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL, | 484 | ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL, |
488 | da9063_alarm_event, | 485 | da9063_alarm_event, |
489 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 486 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
490 | "ALARM", rtc); | 487 | "ALARM", rtc); |
491 | if (ret) { | 488 | if (ret) |
492 | dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n", | 489 | dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n", |
493 | irq_alarm, ret); | 490 | irq_alarm, ret); |
494 | return ret; | ||
495 | } | ||
496 | 491 | ||
497 | rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC, | ||
498 | &da9063_rtc_ops, THIS_MODULE); | ||
499 | if (IS_ERR(rtc->rtc_dev)) | ||
500 | return PTR_ERR(rtc->rtc_dev); | ||
501 | |||
502 | da9063_data_to_tm(data, &rtc->alarm_time, rtc); | ||
503 | rtc->rtc_sync = false; | ||
504 | return ret; | 492 | return ret; |
505 | } | 493 | } |
506 | 494 | ||
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 85706a9f82c9..f39691eea736 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -186,9 +186,7 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time) | |||
186 | if (status < 0) | 186 | if (status < 0) |
187 | return status; | 187 | return status; |
188 | 188 | ||
189 | dev_vdbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", | 189 | dev_vdbg(dev, "%s: %3ph, %4ph\n", "read", &buf[0], &buf[3]); |
190 | "read", buf[0], buf[1], buf[2], buf[3], | ||
191 | buf[4], buf[5], buf[6]); | ||
192 | 190 | ||
193 | /* Decode the registers */ | 191 | /* Decode the registers */ |
194 | time->tm_sec = bcd2bin(buf[DS1305_SEC]); | 192 | time->tm_sec = bcd2bin(buf[DS1305_SEC]); |
@@ -232,9 +230,7 @@ static int ds1305_set_time(struct device *dev, struct rtc_time *time) | |||
232 | *bp++ = bin2bcd(time->tm_mon + 1); | 230 | *bp++ = bin2bcd(time->tm_mon + 1); |
233 | *bp++ = bin2bcd(time->tm_year - 100); | 231 | *bp++ = bin2bcd(time->tm_year - 100); |
234 | 232 | ||
235 | dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", | 233 | dev_dbg(dev, "%s: %3ph, %4ph\n", "write", &buf[1], &buf[4]); |
236 | "write", buf[1], buf[2], buf[3], | ||
237 | buf[4], buf[5], buf[6], buf[7]); | ||
238 | 234 | ||
239 | /* use write-then-read since dma from stack is nonportable */ | 235 | /* use write-then-read since dma from stack is nonportable */ |
240 | return spi_write_then_read(ds1305->spi, buf, sizeof(buf), | 236 | return spi_write_then_read(ds1305->spi, buf, sizeof(buf), |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index aa705bb4748c..cf685f67b391 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -460,13 +460,8 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
460 | return -EIO; | 460 | return -EIO; |
461 | } | 461 | } |
462 | 462 | ||
463 | dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", | 463 | dev_dbg(dev, "%s: %4ph, %3ph, %2ph\n", "alarm read", |
464 | "alarm read", | 464 | &ds1307->regs[0], &ds1307->regs[4], &ds1307->regs[7]); |
465 | ds1307->regs[0], ds1307->regs[1], | ||
466 | ds1307->regs[2], ds1307->regs[3], | ||
467 | ds1307->regs[4], ds1307->regs[5], | ||
468 | ds1307->regs[6], ds1307->regs[7], | ||
469 | ds1307->regs[8]); | ||
470 | 465 | ||
471 | /* | 466 | /* |
472 | * report alarm time (ALARM1); assume 24 hour and day-of-month modes, | 467 | * report alarm time (ALARM1); assume 24 hour and day-of-month modes, |
@@ -522,12 +517,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
522 | control = ds1307->regs[7]; | 517 | control = ds1307->regs[7]; |
523 | status = ds1307->regs[8]; | 518 | status = ds1307->regs[8]; |
524 | 519 | ||
525 | dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", | 520 | dev_dbg(dev, "%s: %4ph, %3ph, %02x %02x\n", "alarm set (old status)", |
526 | "alarm set (old status)", | 521 | &ds1307->regs[0], &ds1307->regs[4], control, status); |
527 | ds1307->regs[0], ds1307->regs[1], | ||
528 | ds1307->regs[2], ds1307->regs[3], | ||
529 | ds1307->regs[4], ds1307->regs[5], | ||
530 | ds1307->regs[6], control, status); | ||
531 | 522 | ||
532 | /* set ALARM1, using 24 hour and day-of-month modes */ | 523 | /* set ALARM1, using 24 hour and day-of-month modes */ |
533 | buf[0] = bin2bcd(t->time.tm_sec); | 524 | buf[0] = bin2bcd(t->time.tm_sec); |
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 05a51ef52703..535050fc5e9f 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c | |||
@@ -853,7 +853,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq) | |||
853 | "Periodic Rate\t: %s\n" | 853 | "Periodic Rate\t: %s\n" |
854 | "SQW Freq\t: %s\n" | 854 | "SQW Freq\t: %s\n" |
855 | #ifdef CONFIG_RTC_DS1685_PROC_REGS | 855 | #ifdef CONFIG_RTC_DS1685_PROC_REGS |
856 | "Serial #\t: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" | 856 | "Serial #\t: %8phC\n" |
857 | "Register Status\t:\n" | 857 | "Register Status\t:\n" |
858 | " Ctrl A\t: UIP DV2 DV1 DV0 RS3 RS2 RS1 RS0\n" | 858 | " Ctrl A\t: UIP DV2 DV1 DV0 RS3 RS2 RS1 RS0\n" |
859 | "\t\t: %s\n" | 859 | "\t\t: %s\n" |
@@ -872,7 +872,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq) | |||
872 | " Ctrl 4B\t: ABE E32k CS RCE PRS RIE WIE KSE\n" | 872 | " Ctrl 4B\t: ABE E32k CS RCE PRS RIE WIE KSE\n" |
873 | "\t\t: %s\n", | 873 | "\t\t: %s\n", |
874 | #else | 874 | #else |
875 | "Serial #\t: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", | 875 | "Serial #\t: %8phC\n", |
876 | #endif | 876 | #endif |
877 | model, | 877 | model, |
878 | ((ctrla & RTC_CTRL_A_DV1) ? "enabled" : "disabled"), | 878 | ((ctrla & RTC_CTRL_A_DV1) ? "enabled" : "disabled"), |
@@ -888,7 +888,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq) | |||
888 | (!((ctrl4b & RTC_CTRL_4B_E32K)) ? | 888 | (!((ctrl4b & RTC_CTRL_4B_E32K)) ? |
889 | ds1685_rtc_sqw_freq[(ctrla & RTC_CTRL_A_RS_MASK)] : "32768Hz"), | 889 | ds1685_rtc_sqw_freq[(ctrla & RTC_CTRL_A_RS_MASK)] : "32768Hz"), |
890 | #ifdef CONFIG_RTC_DS1685_PROC_REGS | 890 | #ifdef CONFIG_RTC_DS1685_PROC_REGS |
891 | ssn[0], ssn[1], ssn[2], ssn[3], ssn[4], ssn[5], ssn[6], ssn[7], | 891 | ssn, |
892 | ds1685_rtc_print_regs(ctrla, bits[0]), | 892 | ds1685_rtc_print_regs(ctrla, bits[0]), |
893 | ds1685_rtc_print_regs(ctrlb, bits[1]), | 893 | ds1685_rtc_print_regs(ctrlb, bits[1]), |
894 | ds1685_rtc_print_regs(ctrlc, bits[2]), | 894 | ds1685_rtc_print_regs(ctrlc, bits[2]), |
@@ -896,7 +896,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq) | |||
896 | ds1685_rtc_print_regs(ctrl4a, bits[4]), | 896 | ds1685_rtc_print_regs(ctrl4a, bits[4]), |
897 | ds1685_rtc_print_regs(ctrl4b, bits[5])); | 897 | ds1685_rtc_print_regs(ctrl4b, bits[5])); |
898 | #else | 898 | #else |
899 | ssn[0], ssn[1], ssn[2], ssn[3], ssn[4], ssn[5], ssn[6], ssn[7]); | 899 | ssn); |
900 | #endif | 900 | #endif |
901 | return 0; | 901 | return 0; |
902 | } | 902 | } |
@@ -1114,7 +1114,7 @@ ds1685_rtc_sysfs_battery_show(struct device *dev, | |||
1114 | 1114 | ||
1115 | ctrld = rtc->read(rtc, RTC_CTRL_D); | 1115 | ctrld = rtc->read(rtc, RTC_CTRL_D); |
1116 | 1116 | ||
1117 | return snprintf(buf, 13, "%s\n", | 1117 | return sprintf(buf, "%s\n", |
1118 | (ctrld & RTC_CTRL_D_VRT) ? "ok" : "not ok or N/A"); | 1118 | (ctrld & RTC_CTRL_D_VRT) ? "ok" : "not ok or N/A"); |
1119 | } | 1119 | } |
1120 | static DEVICE_ATTR(battery, S_IRUGO, ds1685_rtc_sysfs_battery_show, NULL); | 1120 | static DEVICE_ATTR(battery, S_IRUGO, ds1685_rtc_sysfs_battery_show, NULL); |
@@ -1137,7 +1137,7 @@ ds1685_rtc_sysfs_auxbatt_show(struct device *dev, | |||
1137 | ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A); | 1137 | ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A); |
1138 | ds1685_rtc_switch_to_bank0(rtc); | 1138 | ds1685_rtc_switch_to_bank0(rtc); |
1139 | 1139 | ||
1140 | return snprintf(buf, 13, "%s\n", | 1140 | return sprintf(buf, "%s\n", |
1141 | (ctrl4a & RTC_CTRL_4A_VRT2) ? "ok" : "not ok or N/A"); | 1141 | (ctrl4a & RTC_CTRL_4A_VRT2) ? "ok" : "not ok or N/A"); |
1142 | } | 1142 | } |
1143 | static DEVICE_ATTR(auxbatt, S_IRUGO, ds1685_rtc_sysfs_auxbatt_show, NULL); | 1143 | static DEVICE_ATTR(auxbatt, S_IRUGO, ds1685_rtc_sysfs_auxbatt_show, NULL); |
@@ -1160,11 +1160,7 @@ ds1685_rtc_sysfs_serial_show(struct device *dev, | |||
1160 | ds1685_rtc_get_ssn(rtc, ssn); | 1160 | ds1685_rtc_get_ssn(rtc, ssn); |
1161 | ds1685_rtc_switch_to_bank0(rtc); | 1161 | ds1685_rtc_switch_to_bank0(rtc); |
1162 | 1162 | ||
1163 | return snprintf(buf, 24, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", | 1163 | return sprintf(buf, "%8phC\n", ssn); |
1164 | ssn[0], ssn[1], ssn[2], ssn[3], ssn[4], ssn[5], | ||
1165 | ssn[6], ssn[7]); | ||
1166 | |||
1167 | return 0; | ||
1168 | } | 1164 | } |
1169 | static DEVICE_ATTR(serial, S_IRUGO, ds1685_rtc_sysfs_serial_show, NULL); | 1165 | static DEVICE_ATTR(serial, S_IRUGO, ds1685_rtc_sysfs_serial_show, NULL); |
1170 | 1166 | ||
@@ -1287,7 +1283,7 @@ ds1685_rtc_sysfs_ctrl_regs_show(struct device *dev, | |||
1287 | tmp = rtc->read(rtc, reg_info->reg) & reg_info->bit; | 1283 | tmp = rtc->read(rtc, reg_info->reg) & reg_info->bit; |
1288 | ds1685_rtc_switch_to_bank0(rtc); | 1284 | ds1685_rtc_switch_to_bank0(rtc); |
1289 | 1285 | ||
1290 | return snprintf(buf, 2, "%d\n", (tmp ? 1 : 0)); | 1286 | return sprintf(buf, "%d\n", (tmp ? 1 : 0)); |
1291 | } | 1287 | } |
1292 | 1288 | ||
1293 | /** | 1289 | /** |
@@ -1623,7 +1619,7 @@ ds1685_rtc_sysfs_time_regs_show(struct device *dev, | |||
1623 | tmp = ds1685_rtc_bcd2bin(rtc, tmp, bcd_reg_info->mask, | 1619 | tmp = ds1685_rtc_bcd2bin(rtc, tmp, bcd_reg_info->mask, |
1624 | bin_reg_info->mask); | 1620 | bin_reg_info->mask); |
1625 | 1621 | ||
1626 | return snprintf(buf, 4, "%d\n", tmp); | 1622 | return sprintf(buf, "%d\n", tmp); |
1627 | } | 1623 | } |
1628 | 1624 | ||
1629 | /** | 1625 | /** |
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index 7885edd3d507..16310fe79d76 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c | |||
@@ -48,7 +48,7 @@ struct ds2404_gpio { | |||
48 | 48 | ||
49 | struct ds2404 { | 49 | struct ds2404 { |
50 | struct ds2404_gpio *gpio; | 50 | struct ds2404_gpio *gpio; |
51 | struct ds2404_chip_ops *ops; | 51 | const struct ds2404_chip_ops *ops; |
52 | struct rtc_device *rtc; | 52 | struct rtc_device *rtc; |
53 | }; | 53 | }; |
54 | 54 | ||
@@ -95,7 +95,7 @@ static void ds2404_gpio_unmap(struct ds2404 *chip) | |||
95 | gpio_free(ds2404_gpio[i].gpio); | 95 | gpio_free(ds2404_gpio[i].gpio); |
96 | } | 96 | } |
97 | 97 | ||
98 | static struct ds2404_chip_ops ds2404_gpio_ops = { | 98 | static const struct ds2404_chip_ops ds2404_gpio_ops = { |
99 | .map_io = ds2404_gpio_map, | 99 | .map_io = ds2404_gpio_map, |
100 | .unmap_io = ds2404_gpio_unmap, | 100 | .unmap_io = ds2404_gpio_unmap, |
101 | }; | 101 | }; |
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index 3806961b4348..96d38609d803 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c | |||
@@ -191,11 +191,69 @@ static int efi_set_time(struct device *dev, struct rtc_time *tm) | |||
191 | return status == EFI_SUCCESS ? 0 : -EINVAL; | 191 | return status == EFI_SUCCESS ? 0 : -EINVAL; |
192 | } | 192 | } |
193 | 193 | ||
194 | static int efi_procfs(struct device *dev, struct seq_file *seq) | ||
195 | { | ||
196 | efi_time_t eft, alm; | ||
197 | efi_time_cap_t cap; | ||
198 | efi_bool_t enabled, pending; | ||
199 | |||
200 | memset(&eft, 0, sizeof(eft)); | ||
201 | memset(&alm, 0, sizeof(alm)); | ||
202 | memset(&cap, 0, sizeof(cap)); | ||
203 | |||
204 | efi.get_time(&eft, &cap); | ||
205 | efi.get_wakeup_time(&enabled, &pending, &alm); | ||
206 | |||
207 | seq_printf(seq, | ||
208 | "Time\t\t: %u:%u:%u.%09u\n" | ||
209 | "Date\t\t: %u-%u-%u\n" | ||
210 | "Daylight\t: %u\n", | ||
211 | eft.hour, eft.minute, eft.second, eft.nanosecond, | ||
212 | eft.year, eft.month, eft.day, | ||
213 | eft.daylight); | ||
214 | |||
215 | if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) | ||
216 | seq_puts(seq, "Timezone\t: unspecified\n"); | ||
217 | else | ||
218 | /* XXX fixme: convert to string? */ | ||
219 | seq_printf(seq, "Timezone\t: %u\n", eft.timezone); | ||
220 | |||
221 | seq_printf(seq, | ||
222 | "Alarm Time\t: %u:%u:%u.%09u\n" | ||
223 | "Alarm Date\t: %u-%u-%u\n" | ||
224 | "Alarm Daylight\t: %u\n" | ||
225 | "Enabled\t\t: %s\n" | ||
226 | "Pending\t\t: %s\n", | ||
227 | alm.hour, alm.minute, alm.second, alm.nanosecond, | ||
228 | alm.year, alm.month, alm.day, | ||
229 | alm.daylight, | ||
230 | enabled == 1 ? "yes" : "no", | ||
231 | pending == 1 ? "yes" : "no"); | ||
232 | |||
233 | if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) | ||
234 | seq_puts(seq, "Timezone\t: unspecified\n"); | ||
235 | else | ||
236 | /* XXX fixme: convert to string? */ | ||
237 | seq_printf(seq, "Timezone\t: %u\n", alm.timezone); | ||
238 | |||
239 | /* | ||
240 | * now prints the capabilities | ||
241 | */ | ||
242 | seq_printf(seq, | ||
243 | "Resolution\t: %u\n" | ||
244 | "Accuracy\t: %u\n" | ||
245 | "SetstoZero\t: %u\n", | ||
246 | cap.resolution, cap.accuracy, cap.sets_to_zero); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
194 | static const struct rtc_class_ops efi_rtc_ops = { | 251 | static const struct rtc_class_ops efi_rtc_ops = { |
195 | .read_time = efi_read_time, | 252 | .read_time = efi_read_time, |
196 | .set_time = efi_set_time, | 253 | .set_time = efi_set_time, |
197 | .read_alarm = efi_read_alarm, | 254 | .read_alarm = efi_read_alarm, |
198 | .set_alarm = efi_set_alarm, | 255 | .set_alarm = efi_set_alarm, |
256 | .proc = efi_procfs, | ||
199 | }; | 257 | }; |
200 | 258 | ||
201 | static int __init efi_rtc_probe(struct platform_device *dev) | 259 | static int __init efi_rtc_probe(struct platform_device *dev) |
diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c index e84184647d15..f46b6d46a51b 100644 --- a/drivers/rtc/rtc-gemini.c +++ b/drivers/rtc/rtc-gemini.c | |||
@@ -156,7 +156,6 @@ static int gemini_rtc_remove(struct platform_device *pdev) | |||
156 | struct gemini_rtc *rtc = platform_get_drvdata(pdev); | 156 | struct gemini_rtc *rtc = platform_get_drvdata(pdev); |
157 | 157 | ||
158 | rtc_device_unregister(rtc->rtc_dev); | 158 | rtc_device_unregister(rtc->rtc_dev); |
159 | platform_set_drvdata(pdev, NULL); | ||
160 | 159 | ||
161 | return 0; | 160 | return 0; |
162 | } | 161 | } |
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 7bffd7f0e306..8d8049bdfaf6 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
@@ -303,7 +303,7 @@ static int di_handle_invalid_state(struct imxdi_dev *imxdi, u32 dsr) | |||
303 | sec = readl(imxdi->ioaddr + DTCMR); | 303 | sec = readl(imxdi->ioaddr + DTCMR); |
304 | if (sec != 0) | 304 | if (sec != 0) |
305 | dev_warn(&imxdi->pdev->dev, | 305 | dev_warn(&imxdi->pdev->dev, |
306 | "The security violation has happend at %u seconds\n", | 306 | "The security violation has happened at %u seconds\n", |
307 | sec); | 307 | sec); |
308 | /* | 308 | /* |
309 | * the timer cannot be set/modified if | 309 | * the timer cannot be set/modified if |
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index f923f7324788..887871c3d526 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c | |||
@@ -205,7 +205,7 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev) | |||
205 | u32 tmp; | 205 | u32 tmp; |
206 | 206 | ||
207 | rtcirq = platform_get_irq(pdev, 0); | 207 | rtcirq = platform_get_irq(pdev, 0); |
208 | if (rtcirq < 0 || rtcirq >= NR_IRQS) { | 208 | if (rtcirq < 0) { |
209 | dev_warn(&pdev->dev, "Can't get interrupt resource\n"); | 209 | dev_warn(&pdev->dev, "Can't get interrupt resource\n"); |
210 | rtcirq = -1; | 210 | rtcirq = -1; |
211 | } | 211 | } |
diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index df39ce02a99d..9c18d6fd8107 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c | |||
@@ -40,7 +40,7 @@ static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm) | |||
40 | tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff); | 40 | tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff); |
41 | tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff); | 41 | tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff); |
42 | 42 | ||
43 | GregorianDay(tm); | 43 | tm->tm_wday = -1; |
44 | } | 44 | } |
45 | 45 | ||
46 | static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms) | 46 | static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms) |
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index e7ebcc0b7e59..988566caaaa6 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c | |||
@@ -219,6 +219,17 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
219 | u8 regs[8]; | 219 | u8 regs[8]; |
220 | int err; | 220 | int err; |
221 | 221 | ||
222 | /* | ||
223 | * The hardware can only store values between 0 and 99 in it's YEAR | ||
224 | * register (with 99 overflowing to 0 on increment). | ||
225 | * After 2100-02-28 we could start interpreting the year to be in the | ||
226 | * interval [2100, 2199], but there is no path to switch in a smooth way | ||
227 | * because the chip handles YEAR=0x00 (and the out-of-spec | ||
228 | * YEAR=0xa0) as a leap year, but 2100 isn't. | ||
229 | */ | ||
230 | if (tm->tm_year < 100 || tm->tm_year >= 200) | ||
231 | return -EINVAL; | ||
232 | |||
222 | err = pcf8523_stop_rtc(client); | 233 | err = pcf8523_stop_rtc(client); |
223 | if (err < 0) | 234 | if (err < 0) |
224 | return err; | 235 | return err; |
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index ffa69e1c9245..31e7e23cc5be 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -112,19 +112,21 @@ static int rtc_proc_open(struct inode *inode, struct file *file) | |||
112 | int ret; | 112 | int ret; |
113 | struct rtc_device *rtc = PDE_DATA(inode); | 113 | struct rtc_device *rtc = PDE_DATA(inode); |
114 | 114 | ||
115 | if (!try_module_get(THIS_MODULE)) | 115 | if (!try_module_get(rtc->owner)) |
116 | return -ENODEV; | 116 | return -ENODEV; |
117 | 117 | ||
118 | ret = single_open(file, rtc_proc_show, rtc); | 118 | ret = single_open(file, rtc_proc_show, rtc); |
119 | if (ret) | 119 | if (ret) |
120 | module_put(THIS_MODULE); | 120 | module_put(rtc->owner); |
121 | return ret; | 121 | return ret; |
122 | } | 122 | } |
123 | 123 | ||
124 | static int rtc_proc_release(struct inode *inode, struct file *file) | 124 | static int rtc_proc_release(struct inode *inode, struct file *file) |
125 | { | 125 | { |
126 | int res = single_release(inode, file); | 126 | int res = single_release(inode, file); |
127 | module_put(THIS_MODULE); | 127 | struct rtc_device *rtc = PDE_DATA(inode); |
128 | |||
129 | module_put(rtc->owner); | ||
128 | return res; | 130 | return res; |
129 | } | 131 | } |
130 | 132 | ||
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c index 91ca0bc1b484..35c9aada07c8 100644 --- a/drivers/rtc/rtc-rk808.c +++ b/drivers/rtc/rtc-rk808.c | |||
@@ -56,6 +56,42 @@ struct rk808_rtc { | |||
56 | int irq; | 56 | int irq; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | /* | ||
60 | * The Rockchip calendar used by the RK808 counts November with 31 days. We use | ||
61 | * these translation functions to convert its dates to/from the Gregorian | ||
62 | * calendar used by the rest of the world. We arbitrarily define Jan 1st, 2016 | ||
63 | * as the day when both calendars were in sync, and treat all other dates | ||
64 | * relative to that. | ||
65 | * NOTE: Other system software (e.g. firmware) that reads the same hardware must | ||
66 | * implement this exact same conversion algorithm, with the same anchor date. | ||
67 | */ | ||
68 | static time64_t nov2dec_transitions(struct rtc_time *tm) | ||
69 | { | ||
70 | return (tm->tm_year + 1900) - 2016 + (tm->tm_mon + 1 > 11 ? 1 : 0); | ||
71 | } | ||
72 | |||
73 | static void rockchip_to_gregorian(struct rtc_time *tm) | ||
74 | { | ||
75 | /* If it's Nov 31st, rtc_tm_to_time64() will count that like Dec 1st */ | ||
76 | time64_t time = rtc_tm_to_time64(tm); | ||
77 | rtc_time64_to_tm(time + nov2dec_transitions(tm) * 86400, tm); | ||
78 | } | ||
79 | |||
80 | static void gregorian_to_rockchip(struct rtc_time *tm) | ||
81 | { | ||
82 | time64_t extra_days = nov2dec_transitions(tm); | ||
83 | time64_t time = rtc_tm_to_time64(tm); | ||
84 | rtc_time64_to_tm(time - extra_days * 86400, tm); | ||
85 | |||
86 | /* Compensate if we went back over Nov 31st (will work up to 2381) */ | ||
87 | if (nov2dec_transitions(tm) < extra_days) { | ||
88 | if (tm->tm_mon + 1 == 11) | ||
89 | tm->tm_mday++; /* This may result in 31! */ | ||
90 | else | ||
91 | rtc_time64_to_tm(time - (extra_days - 1) * 86400, tm); | ||
92 | } | ||
93 | } | ||
94 | |||
59 | /* Read current time and date in RTC */ | 95 | /* Read current time and date in RTC */ |
60 | static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) | 96 | static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) |
61 | { | 97 | { |
@@ -101,9 +137,10 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) | |||
101 | tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1; | 137 | tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1; |
102 | tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100; | 138 | tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100; |
103 | tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK); | 139 | tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK); |
140 | rockchip_to_gregorian(tm); | ||
104 | dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | 141 | dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", |
105 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | 142 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, |
106 | tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); | 143 | tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec); |
107 | 144 | ||
108 | return ret; | 145 | return ret; |
109 | } | 146 | } |
@@ -116,6 +153,10 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
116 | u8 rtc_data[NUM_TIME_REGS]; | 153 | u8 rtc_data[NUM_TIME_REGS]; |
117 | int ret; | 154 | int ret; |
118 | 155 | ||
156 | dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
157 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | ||
158 | tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
159 | gregorian_to_rockchip(tm); | ||
119 | rtc_data[0] = bin2bcd(tm->tm_sec); | 160 | rtc_data[0] = bin2bcd(tm->tm_sec); |
120 | rtc_data[1] = bin2bcd(tm->tm_min); | 161 | rtc_data[1] = bin2bcd(tm->tm_min); |
121 | rtc_data[2] = bin2bcd(tm->tm_hour); | 162 | rtc_data[2] = bin2bcd(tm->tm_hour); |
@@ -123,9 +164,6 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
123 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); | 164 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); |
124 | rtc_data[5] = bin2bcd(tm->tm_year - 100); | 165 | rtc_data[5] = bin2bcd(tm->tm_year - 100); |
125 | rtc_data[6] = bin2bcd(tm->tm_wday); | 166 | rtc_data[6] = bin2bcd(tm->tm_wday); |
126 | dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
127 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | ||
128 | tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); | ||
129 | 167 | ||
130 | /* Stop RTC while updating the RTC registers */ | 168 | /* Stop RTC while updating the RTC registers */ |
131 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | 169 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, |
@@ -170,6 +208,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
170 | alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK); | 208 | alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK); |
171 | alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1; | 209 | alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1; |
172 | alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100; | 210 | alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100; |
211 | rockchip_to_gregorian(&alrm->time); | ||
173 | 212 | ||
174 | ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg); | 213 | ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg); |
175 | if (ret) { | 214 | if (ret) { |
@@ -227,6 +266,7 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
227 | alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, | 266 | alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, |
228 | alrm->time.tm_min, alrm->time.tm_sec); | 267 | alrm->time.tm_min, alrm->time.tm_sec); |
229 | 268 | ||
269 | gregorian_to_rockchip(&alrm->time); | ||
230 | alrm_data[0] = bin2bcd(alrm->time.tm_sec); | 270 | alrm_data[0] = bin2bcd(alrm->time.tm_sec); |
231 | alrm_data[1] = bin2bcd(alrm->time.tm_min); | 271 | alrm_data[1] = bin2bcd(alrm->time.tm_min); |
232 | alrm_data[2] = bin2bcd(alrm->time.tm_hour); | 272 | alrm_data[2] = bin2bcd(alrm->time.tm_hour); |
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index e7329e21bfe3..7155c0816aa6 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c | |||
@@ -61,7 +61,7 @@ static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) | |||
61 | struct i2c_client *client = dev_id; | 61 | struct i2c_client *client = dev_id; |
62 | struct rv8803_data *rv8803 = i2c_get_clientdata(client); | 62 | struct rv8803_data *rv8803 = i2c_get_clientdata(client); |
63 | unsigned long events = 0; | 63 | unsigned long events = 0; |
64 | u8 flags; | 64 | int flags; |
65 | 65 | ||
66 | spin_lock(&rv8803->flags_lock); | 66 | spin_lock(&rv8803->flags_lock); |
67 | 67 | ||
@@ -502,6 +502,7 @@ static int rv8803_remove(struct i2c_client *client) | |||
502 | 502 | ||
503 | static const struct i2c_device_id rv8803_id[] = { | 503 | static const struct i2c_device_id rv8803_id[] = { |
504 | { "rv8803", 0 }, | 504 | { "rv8803", 0 }, |
505 | { "rx8900", 0 }, | ||
505 | { } | 506 | { } |
506 | }; | 507 | }; |
507 | MODULE_DEVICE_TABLE(i2c, rv8803_id); | 508 | MODULE_DEVICE_TABLE(i2c, rv8803_id); |
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c new file mode 100644 index 000000000000..772d221ec2d9 --- /dev/null +++ b/drivers/rtc/rtc-rx8010.c | |||
@@ -0,0 +1,523 @@ | |||
1 | /* | ||
2 | * Driver for the Epson RTC module RX-8010 SJ | ||
3 | * | ||
4 | * Copyright(C) Timesys Corporation 2015 | ||
5 | * Copyright(C) General Electric Company 2015 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/bcd.h> | ||
14 | #include <linux/bitops.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/rtc.h> | ||
19 | |||
20 | #define RX8010_SEC 0x10 | ||
21 | #define RX8010_MIN 0x11 | ||
22 | #define RX8010_HOUR 0x12 | ||
23 | #define RX8010_WDAY 0x13 | ||
24 | #define RX8010_MDAY 0x14 | ||
25 | #define RX8010_MONTH 0x15 | ||
26 | #define RX8010_YEAR 0x16 | ||
27 | #define RX8010_YEAR 0x16 | ||
28 | #define RX8010_RESV17 0x17 | ||
29 | #define RX8010_ALMIN 0x18 | ||
30 | #define RX8010_ALHOUR 0x19 | ||
31 | #define RX8010_ALWDAY 0x1A | ||
32 | #define RX8010_TCOUNT0 0x1B | ||
33 | #define RX8010_TCOUNT1 0x1C | ||
34 | #define RX8010_EXT 0x1D | ||
35 | #define RX8010_FLAG 0x1E | ||
36 | #define RX8010_CTRL 0x1F | ||
37 | /* 0x20 to 0x2F are user registers */ | ||
38 | #define RX8010_RESV30 0x30 | ||
39 | #define RX8010_RESV31 0x32 | ||
40 | #define RX8010_IRQ 0x32 | ||
41 | |||
42 | #define RX8010_EXT_WADA BIT(3) | ||
43 | |||
44 | #define RX8010_FLAG_VLF BIT(1) | ||
45 | #define RX8010_FLAG_AF BIT(3) | ||
46 | #define RX8010_FLAG_TF BIT(4) | ||
47 | #define RX8010_FLAG_UF BIT(5) | ||
48 | |||
49 | #define RX8010_CTRL_AIE BIT(3) | ||
50 | #define RX8010_CTRL_UIE BIT(5) | ||
51 | #define RX8010_CTRL_STOP BIT(6) | ||
52 | #define RX8010_CTRL_TEST BIT(7) | ||
53 | |||
54 | #define RX8010_ALARM_AE BIT(7) | ||
55 | |||
56 | static const struct i2c_device_id rx8010_id[] = { | ||
57 | { "rx8010", 0 }, | ||
58 | { } | ||
59 | }; | ||
60 | MODULE_DEVICE_TABLE(i2c, rx8010_id); | ||
61 | |||
62 | struct rx8010_data { | ||
63 | struct i2c_client *client; | ||
64 | struct rtc_device *rtc; | ||
65 | u8 ctrlreg; | ||
66 | spinlock_t flags_lock; | ||
67 | }; | ||
68 | |||
69 | static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id) | ||
70 | { | ||
71 | struct i2c_client *client = dev_id; | ||
72 | struct rx8010_data *rx8010 = i2c_get_clientdata(client); | ||
73 | int flagreg; | ||
74 | |||
75 | spin_lock(&rx8010->flags_lock); | ||
76 | |||
77 | flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG); | ||
78 | |||
79 | if (flagreg <= 0) { | ||
80 | spin_unlock(&rx8010->flags_lock); | ||
81 | return IRQ_NONE; | ||
82 | } | ||
83 | |||
84 | if (flagreg & RX8010_FLAG_VLF) | ||
85 | dev_warn(&client->dev, "Frequency stop detected\n"); | ||
86 | |||
87 | if (flagreg & RX8010_FLAG_TF) { | ||
88 | flagreg &= ~RX8010_FLAG_TF; | ||
89 | rtc_update_irq(rx8010->rtc, 1, RTC_PF | RTC_IRQF); | ||
90 | } | ||
91 | |||
92 | if (flagreg & RX8010_FLAG_AF) { | ||
93 | flagreg &= ~RX8010_FLAG_AF; | ||
94 | rtc_update_irq(rx8010->rtc, 1, RTC_AF | RTC_IRQF); | ||
95 | } | ||
96 | |||
97 | if (flagreg & RX8010_FLAG_UF) { | ||
98 | flagreg &= ~RX8010_FLAG_UF; | ||
99 | rtc_update_irq(rx8010->rtc, 1, RTC_UF | RTC_IRQF); | ||
100 | } | ||
101 | |||
102 | i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg); | ||
103 | |||
104 | spin_unlock(&rx8010->flags_lock); | ||
105 | return IRQ_HANDLED; | ||
106 | } | ||
107 | |||
108 | static int rx8010_get_time(struct device *dev, struct rtc_time *dt) | ||
109 | { | ||
110 | struct rx8010_data *rx8010 = dev_get_drvdata(dev); | ||
111 | u8 date[7]; | ||
112 | int flagreg; | ||
113 | int err; | ||
114 | |||
115 | flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG); | ||
116 | if (flagreg < 0) | ||
117 | return flagreg; | ||
118 | |||
119 | if (flagreg & RX8010_FLAG_VLF) { | ||
120 | dev_warn(dev, "Frequency stop detected\n"); | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | err = i2c_smbus_read_i2c_block_data(rx8010->client, RX8010_SEC, | ||
125 | 7, date); | ||
126 | if (err != 7) | ||
127 | return err < 0 ? err : -EIO; | ||
128 | |||
129 | dt->tm_sec = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f); | ||
130 | dt->tm_min = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f); | ||
131 | dt->tm_hour = bcd2bin(date[RX8010_HOUR - RX8010_SEC] & 0x3f); | ||
132 | dt->tm_mday = bcd2bin(date[RX8010_MDAY - RX8010_SEC] & 0x3f); | ||
133 | dt->tm_mon = bcd2bin(date[RX8010_MONTH - RX8010_SEC] & 0x1f) - 1; | ||
134 | dt->tm_year = bcd2bin(date[RX8010_YEAR - RX8010_SEC]) + 100; | ||
135 | dt->tm_wday = ffs(date[RX8010_WDAY - RX8010_SEC] & 0x7f); | ||
136 | |||
137 | return rtc_valid_tm(dt); | ||
138 | } | ||
139 | |||
140 | static int rx8010_set_time(struct device *dev, struct rtc_time *dt) | ||
141 | { | ||
142 | struct rx8010_data *rx8010 = dev_get_drvdata(dev); | ||
143 | u8 date[7]; | ||
144 | int ctrl, flagreg; | ||
145 | int ret; | ||
146 | unsigned long irqflags; | ||
147 | |||
148 | if ((dt->tm_year < 100) || (dt->tm_year > 199)) | ||
149 | return -EINVAL; | ||
150 | |||
151 | /* set STOP bit before changing clock/calendar */ | ||
152 | ctrl = i2c_smbus_read_byte_data(rx8010->client, RX8010_CTRL); | ||
153 | if (ctrl < 0) | ||
154 | return ctrl; | ||
155 | rx8010->ctrlreg = ctrl | RX8010_CTRL_STOP; | ||
156 | ret = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL, | ||
157 | rx8010->ctrlreg); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | |||
161 | date[RX8010_SEC - RX8010_SEC] = bin2bcd(dt->tm_sec); | ||
162 | date[RX8010_MIN - RX8010_SEC] = bin2bcd(dt->tm_min); | ||
163 | date[RX8010_HOUR - RX8010_SEC] = bin2bcd(dt->tm_hour); | ||
164 | date[RX8010_MDAY - RX8010_SEC] = bin2bcd(dt->tm_mday); | ||
165 | date[RX8010_MONTH - RX8010_SEC] = bin2bcd(dt->tm_mon + 1); | ||
166 | date[RX8010_YEAR - RX8010_SEC] = bin2bcd(dt->tm_year - 100); | ||
167 | date[RX8010_WDAY - RX8010_SEC] = bin2bcd(1 << dt->tm_wday); | ||
168 | |||
169 | ret = i2c_smbus_write_i2c_block_data(rx8010->client, | ||
170 | RX8010_SEC, 7, date); | ||
171 | if (ret < 0) | ||
172 | return ret; | ||
173 | |||
174 | /* clear STOP bit after changing clock/calendar */ | ||
175 | ctrl = i2c_smbus_read_byte_data(rx8010->client, RX8010_CTRL); | ||
176 | if (ctrl < 0) | ||
177 | return ctrl; | ||
178 | rx8010->ctrlreg = ctrl & ~RX8010_CTRL_STOP; | ||
179 | ret = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL, | ||
180 | rx8010->ctrlreg); | ||
181 | if (ret < 0) | ||
182 | return ret; | ||
183 | |||
184 | spin_lock_irqsave(&rx8010->flags_lock, irqflags); | ||
185 | |||
186 | flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG); | ||
187 | if (flagreg < 0) { | ||
188 | spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); | ||
189 | return flagreg; | ||
190 | } | ||
191 | |||
192 | if (flagreg & RX8010_FLAG_VLF) | ||
193 | ret = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, | ||
194 | flagreg & ~RX8010_FLAG_VLF); | ||
195 | |||
196 | spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static int rx8010_init_client(struct i2c_client *client) | ||
202 | { | ||
203 | struct rx8010_data *rx8010 = i2c_get_clientdata(client); | ||
204 | u8 ctrl[2]; | ||
205 | int need_clear = 0, err = 0; | ||
206 | |||
207 | /* Initialize reserved registers as specified in datasheet */ | ||
208 | err = i2c_smbus_write_byte_data(client, RX8010_RESV17, 0xD8); | ||
209 | if (err < 0) | ||
210 | return err; | ||
211 | |||
212 | err = i2c_smbus_write_byte_data(client, RX8010_RESV30, 0x00); | ||
213 | if (err < 0) | ||
214 | return err; | ||
215 | |||
216 | err = i2c_smbus_write_byte_data(client, RX8010_RESV31, 0x08); | ||
217 | if (err < 0) | ||
218 | return err; | ||
219 | |||
220 | err = i2c_smbus_write_byte_data(client, RX8010_IRQ, 0x00); | ||
221 | if (err < 0) | ||
222 | return err; | ||
223 | |||
224 | err = i2c_smbus_read_i2c_block_data(rx8010->client, RX8010_FLAG, | ||
225 | 2, ctrl); | ||
226 | if (err != 2) | ||
227 | return err < 0 ? err : -EIO; | ||
228 | |||
229 | if (ctrl[0] & RX8010_FLAG_VLF) | ||
230 | dev_warn(&client->dev, "Frequency stop was detected\n"); | ||
231 | |||
232 | if (ctrl[0] & RX8010_FLAG_AF) { | ||
233 | dev_warn(&client->dev, "Alarm was detected\n"); | ||
234 | need_clear = 1; | ||
235 | } | ||
236 | |||
237 | if (ctrl[0] & RX8010_FLAG_TF) | ||
238 | need_clear = 1; | ||
239 | |||
240 | if (ctrl[0] & RX8010_FLAG_UF) | ||
241 | need_clear = 1; | ||
242 | |||
243 | if (need_clear) { | ||
244 | ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF); | ||
245 | err = i2c_smbus_write_byte_data(client, RX8010_FLAG, ctrl[0]); | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | rx8010->ctrlreg = (ctrl[1] & ~RX8010_CTRL_TEST); | ||
251 | |||
252 | return err; | ||
253 | } | ||
254 | |||
255 | static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
256 | { | ||
257 | struct rx8010_data *rx8010 = dev_get_drvdata(dev); | ||
258 | struct i2c_client *client = rx8010->client; | ||
259 | u8 alarmvals[3]; | ||
260 | int flagreg; | ||
261 | int err; | ||
262 | |||
263 | err = i2c_smbus_read_i2c_block_data(client, RX8010_ALMIN, 3, alarmvals); | ||
264 | if (err != 3) | ||
265 | return err < 0 ? err : -EIO; | ||
266 | |||
267 | flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG); | ||
268 | if (flagreg < 0) | ||
269 | return flagreg; | ||
270 | |||
271 | t->time.tm_sec = 0; | ||
272 | t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); | ||
273 | t->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); | ||
274 | |||
275 | if (alarmvals[2] & RX8010_ALARM_AE) | ||
276 | t->time.tm_mday = -1; | ||
277 | else | ||
278 | t->time.tm_mday = bcd2bin(alarmvals[2] & 0x7f); | ||
279 | |||
280 | t->time.tm_wday = -1; | ||
281 | t->time.tm_mon = -1; | ||
282 | t->time.tm_year = -1; | ||
283 | |||
284 | t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE); | ||
285 | t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled; | ||
286 | |||
287 | return err; | ||
288 | } | ||
289 | |||
290 | static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
291 | { | ||
292 | struct i2c_client *client = to_i2c_client(dev); | ||
293 | struct rx8010_data *rx8010 = dev_get_drvdata(dev); | ||
294 | u8 alarmvals[3]; | ||
295 | int extreg, flagreg; | ||
296 | int err; | ||
297 | unsigned long irqflags; | ||
298 | |||
299 | spin_lock_irqsave(&rx8010->flags_lock, irqflags); | ||
300 | flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG); | ||
301 | if (flagreg < 0) { | ||
302 | spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); | ||
303 | return flagreg; | ||
304 | } | ||
305 | |||
306 | if (rx8010->ctrlreg & (RX8010_CTRL_AIE | RX8010_CTRL_UIE)) { | ||
307 | rx8010->ctrlreg &= ~(RX8010_CTRL_AIE | RX8010_CTRL_UIE); | ||
308 | err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL, | ||
309 | rx8010->ctrlreg); | ||
310 | if (err < 0) { | ||
311 | spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); | ||
312 | return err; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | flagreg &= ~RX8010_FLAG_AF; | ||
317 | err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg); | ||
318 | spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); | ||
319 | if (err < 0) | ||
320 | return err; | ||
321 | |||
322 | alarmvals[0] = bin2bcd(t->time.tm_min); | ||
323 | alarmvals[1] = bin2bcd(t->time.tm_hour); | ||
324 | alarmvals[2] = bin2bcd(t->time.tm_mday); | ||
325 | |||
326 | err = i2c_smbus_write_i2c_block_data(rx8010->client, RX8010_ALMIN, | ||
327 | 2, alarmvals); | ||
328 | if (err < 0) | ||
329 | return err; | ||
330 | |||
331 | extreg = i2c_smbus_read_byte_data(client, RX8010_EXT); | ||
332 | if (extreg < 0) | ||
333 | return extreg; | ||
334 | |||
335 | extreg |= RX8010_EXT_WADA; | ||
336 | err = i2c_smbus_write_byte_data(rx8010->client, RX8010_EXT, extreg); | ||
337 | if (err < 0) | ||
338 | return err; | ||
339 | |||
340 | if (alarmvals[2] == 0) | ||
341 | alarmvals[2] |= RX8010_ALARM_AE; | ||
342 | |||
343 | err = i2c_smbus_write_byte_data(rx8010->client, RX8010_ALWDAY, | ||
344 | alarmvals[2]); | ||
345 | if (err < 0) | ||
346 | return err; | ||
347 | |||
348 | if (t->enabled) { | ||
349 | if (rx8010->rtc->uie_rtctimer.enabled) | ||
350 | rx8010->ctrlreg |= RX8010_CTRL_UIE; | ||
351 | if (rx8010->rtc->aie_timer.enabled) | ||
352 | rx8010->ctrlreg |= | ||
353 | (RX8010_CTRL_AIE | RX8010_CTRL_UIE); | ||
354 | |||
355 | err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL, | ||
356 | rx8010->ctrlreg); | ||
357 | if (err < 0) | ||
358 | return err; | ||
359 | } | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static int rx8010_alarm_irq_enable(struct device *dev, | ||
365 | unsigned int enabled) | ||
366 | { | ||
367 | struct i2c_client *client = to_i2c_client(dev); | ||
368 | struct rx8010_data *rx8010 = dev_get_drvdata(dev); | ||
369 | int flagreg; | ||
370 | u8 ctrl; | ||
371 | int err; | ||
372 | |||
373 | ctrl = rx8010->ctrlreg; | ||
374 | |||
375 | if (enabled) { | ||
376 | if (rx8010->rtc->uie_rtctimer.enabled) | ||
377 | ctrl |= RX8010_CTRL_UIE; | ||
378 | if (rx8010->rtc->aie_timer.enabled) | ||
379 | ctrl |= (RX8010_CTRL_AIE | RX8010_CTRL_UIE); | ||
380 | } else { | ||
381 | if (!rx8010->rtc->uie_rtctimer.enabled) | ||
382 | ctrl &= ~RX8010_CTRL_UIE; | ||
383 | if (!rx8010->rtc->aie_timer.enabled) | ||
384 | ctrl &= ~RX8010_CTRL_AIE; | ||
385 | } | ||
386 | |||
387 | flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG); | ||
388 | if (flagreg < 0) | ||
389 | return flagreg; | ||
390 | |||
391 | flagreg &= ~RX8010_FLAG_AF; | ||
392 | err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg); | ||
393 | if (err < 0) | ||
394 | return err; | ||
395 | |||
396 | if (ctrl != rx8010->ctrlreg) { | ||
397 | rx8010->ctrlreg = ctrl; | ||
398 | err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL, | ||
399 | rx8010->ctrlreg); | ||
400 | if (err < 0) | ||
401 | return err; | ||
402 | } | ||
403 | |||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
408 | { | ||
409 | struct i2c_client *client = to_i2c_client(dev); | ||
410 | struct rx8010_data *rx8010 = dev_get_drvdata(dev); | ||
411 | int ret, tmp; | ||
412 | int flagreg; | ||
413 | unsigned long irqflags; | ||
414 | |||
415 | switch (cmd) { | ||
416 | case RTC_VL_READ: | ||
417 | flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG); | ||
418 | if (flagreg < 0) | ||
419 | return flagreg; | ||
420 | |||
421 | tmp = !!(flagreg & RX8010_FLAG_VLF); | ||
422 | if (copy_to_user((void __user *)arg, &tmp, sizeof(int))) | ||
423 | return -EFAULT; | ||
424 | |||
425 | return 0; | ||
426 | |||
427 | case RTC_VL_CLR: | ||
428 | spin_lock_irqsave(&rx8010->flags_lock, irqflags); | ||
429 | flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG); | ||
430 | if (flagreg < 0) { | ||
431 | spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); | ||
432 | return flagreg; | ||
433 | } | ||
434 | |||
435 | flagreg &= ~RX8010_FLAG_VLF; | ||
436 | ret = i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg); | ||
437 | spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); | ||
438 | if (ret < 0) | ||
439 | return ret; | ||
440 | |||
441 | return 0; | ||
442 | |||
443 | default: | ||
444 | return -ENOIOCTLCMD; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static struct rtc_class_ops rx8010_rtc_ops = { | ||
449 | .read_time = rx8010_get_time, | ||
450 | .set_time = rx8010_set_time, | ||
451 | .ioctl = rx8010_ioctl, | ||
452 | }; | ||
453 | |||
454 | static int rx8010_probe(struct i2c_client *client, | ||
455 | const struct i2c_device_id *id) | ||
456 | { | ||
457 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
458 | struct rx8010_data *rx8010; | ||
459 | int err = 0; | ||
460 | |||
461 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | ||
462 | | I2C_FUNC_SMBUS_I2C_BLOCK)) { | ||
463 | dev_err(&adapter->dev, "doesn't support required functionality\n"); | ||
464 | return -EIO; | ||
465 | } | ||
466 | |||
467 | rx8010 = devm_kzalloc(&client->dev, sizeof(struct rx8010_data), | ||
468 | GFP_KERNEL); | ||
469 | if (!rx8010) | ||
470 | return -ENOMEM; | ||
471 | |||
472 | rx8010->client = client; | ||
473 | i2c_set_clientdata(client, rx8010); | ||
474 | |||
475 | spin_lock_init(&rx8010->flags_lock); | ||
476 | |||
477 | err = rx8010_init_client(client); | ||
478 | if (err) | ||
479 | return err; | ||
480 | |||
481 | if (client->irq > 0) { | ||
482 | dev_info(&client->dev, "IRQ %d supplied\n", client->irq); | ||
483 | err = devm_request_threaded_irq(&client->dev, client->irq, NULL, | ||
484 | rx8010_irq_1_handler, | ||
485 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
486 | "rx8010", client); | ||
487 | |||
488 | if (err) { | ||
489 | dev_err(&client->dev, "unable to request IRQ\n"); | ||
490 | client->irq = 0; | ||
491 | } else { | ||
492 | rx8010_rtc_ops.read_alarm = rx8010_read_alarm; | ||
493 | rx8010_rtc_ops.set_alarm = rx8010_set_alarm; | ||
494 | rx8010_rtc_ops.alarm_irq_enable = rx8010_alarm_irq_enable; | ||
495 | } | ||
496 | } | ||
497 | |||
498 | rx8010->rtc = devm_rtc_device_register(&client->dev, client->name, | ||
499 | &rx8010_rtc_ops, THIS_MODULE); | ||
500 | |||
501 | if (IS_ERR(rx8010->rtc)) { | ||
502 | dev_err(&client->dev, "unable to register the class device\n"); | ||
503 | return PTR_ERR(rx8010->rtc); | ||
504 | } | ||
505 | |||
506 | rx8010->rtc->max_user_freq = 1; | ||
507 | |||
508 | return err; | ||
509 | } | ||
510 | |||
511 | static struct i2c_driver rx8010_driver = { | ||
512 | .driver = { | ||
513 | .name = "rtc-rx8010", | ||
514 | }, | ||
515 | .probe = rx8010_probe, | ||
516 | .id_table = rx8010_id, | ||
517 | }; | ||
518 | |||
519 | module_i2c_driver(rx8010_driver); | ||
520 | |||
521 | MODULE_AUTHOR("Akshay Bhat <akshay.bhat@timesys.com>"); | ||
522 | MODULE_DESCRIPTION("Epson RX8010SJ RTC driver"); | ||
523 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index f2504b4eef34..7407d7394bb4 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c | |||
@@ -38,7 +38,22 @@ | |||
38 | */ | 38 | */ |
39 | #define UDR_READ_RETRY_CNT 5 | 39 | #define UDR_READ_RETRY_CNT 5 |
40 | 40 | ||
41 | /* Registers used by the driver which are different between chipsets. */ | 41 | /* |
42 | * Registers used by the driver which are different between chipsets. | ||
43 | * | ||
44 | * Operations like read time and write alarm/time require updating | ||
45 | * specific fields in UDR register. These fields usually are auto-cleared | ||
46 | * (with some exceptions). | ||
47 | * | ||
48 | * Table of operations per device: | ||
49 | * | ||
50 | * Device | Write time | Read time | Write alarm | ||
51 | * ================================================= | ||
52 | * S5M8767 | UDR + TIME | | UDR | ||
53 | * S2MPS11/14 | WUDR | RUDR | WUDR + RUDR | ||
54 | * S2MPS13 | WUDR | RUDR | WUDR + AUDR | ||
55 | * S2MPS15 | WUDR | RUDR | AUDR | ||
56 | */ | ||
42 | struct s5m_rtc_reg_config { | 57 | struct s5m_rtc_reg_config { |
43 | /* Number of registers used for setting time/alarm0/alarm1 */ | 58 | /* Number of registers used for setting time/alarm0/alarm1 */ |
44 | unsigned int regs_count; | 59 | unsigned int regs_count; |
@@ -55,9 +70,16 @@ struct s5m_rtc_reg_config { | |||
55 | * will enable update of time or alarm register. Then it will be | 70 | * will enable update of time or alarm register. Then it will be |
56 | * auto-cleared after successful update. | 71 | * auto-cleared after successful update. |
57 | */ | 72 | */ |
58 | unsigned int rtc_udr_update; | 73 | unsigned int udr_update; |
59 | /* Mask for UDR field in 'rtc_udr_update' register */ | 74 | /* Auto-cleared mask in UDR field for writing time and alarm */ |
60 | unsigned int rtc_udr_mask; | 75 | unsigned int autoclear_udr_mask; |
76 | /* | ||
77 | * Masks in UDR field for time and alarm operations. | ||
78 | * The read time mask can be 0. Rest should not. | ||
79 | */ | ||
80 | unsigned int read_time_udr_mask; | ||
81 | unsigned int write_time_udr_mask; | ||
82 | unsigned int write_alarm_udr_mask; | ||
61 | }; | 83 | }; |
62 | 84 | ||
63 | /* Register map for S5M8763 and S5M8767 */ | 85 | /* Register map for S5M8763 and S5M8767 */ |
@@ -67,22 +89,56 @@ static const struct s5m_rtc_reg_config s5m_rtc_regs = { | |||
67 | .ctrl = S5M_ALARM1_CONF, | 89 | .ctrl = S5M_ALARM1_CONF, |
68 | .alarm0 = S5M_ALARM0_SEC, | 90 | .alarm0 = S5M_ALARM0_SEC, |
69 | .alarm1 = S5M_ALARM1_SEC, | 91 | .alarm1 = S5M_ALARM1_SEC, |
70 | .rtc_udr_update = S5M_RTC_UDR_CON, | 92 | .udr_update = S5M_RTC_UDR_CON, |
71 | .rtc_udr_mask = S5M_RTC_UDR_MASK, | 93 | .autoclear_udr_mask = S5M_RTC_UDR_MASK, |
94 | .read_time_udr_mask = 0, /* Not needed */ | ||
95 | .write_time_udr_mask = S5M_RTC_UDR_MASK | S5M_RTC_TIME_EN_MASK, | ||
96 | .write_alarm_udr_mask = S5M_RTC_UDR_MASK, | ||
97 | }; | ||
98 | |||
99 | /* Register map for S2MPS13 */ | ||
100 | static const struct s5m_rtc_reg_config s2mps13_rtc_regs = { | ||
101 | .regs_count = 7, | ||
102 | .time = S2MPS_RTC_SEC, | ||
103 | .ctrl = S2MPS_RTC_CTRL, | ||
104 | .alarm0 = S2MPS_ALARM0_SEC, | ||
105 | .alarm1 = S2MPS_ALARM1_SEC, | ||
106 | .udr_update = S2MPS_RTC_UDR_CON, | ||
107 | .autoclear_udr_mask = S2MPS_RTC_WUDR_MASK, | ||
108 | .read_time_udr_mask = S2MPS_RTC_RUDR_MASK, | ||
109 | .write_time_udr_mask = S2MPS_RTC_WUDR_MASK, | ||
110 | .write_alarm_udr_mask = S2MPS_RTC_WUDR_MASK | S2MPS13_RTC_AUDR_MASK, | ||
111 | }; | ||
112 | |||
113 | /* Register map for S2MPS11/14 */ | ||
114 | static const struct s5m_rtc_reg_config s2mps14_rtc_regs = { | ||
115 | .regs_count = 7, | ||
116 | .time = S2MPS_RTC_SEC, | ||
117 | .ctrl = S2MPS_RTC_CTRL, | ||
118 | .alarm0 = S2MPS_ALARM0_SEC, | ||
119 | .alarm1 = S2MPS_ALARM1_SEC, | ||
120 | .udr_update = S2MPS_RTC_UDR_CON, | ||
121 | .autoclear_udr_mask = S2MPS_RTC_WUDR_MASK, | ||
122 | .read_time_udr_mask = S2MPS_RTC_RUDR_MASK, | ||
123 | .write_time_udr_mask = S2MPS_RTC_WUDR_MASK, | ||
124 | .write_alarm_udr_mask = S2MPS_RTC_WUDR_MASK | S2MPS_RTC_RUDR_MASK, | ||
72 | }; | 125 | }; |
73 | 126 | ||
74 | /* | 127 | /* |
75 | * Register map for S2MPS14. | 128 | * Register map for S2MPS15 - in comparison to S2MPS14 the WUDR and AUDR bits |
76 | * It may be also suitable for S2MPS11 but this was not tested. | 129 | * are swapped. |
77 | */ | 130 | */ |
78 | static const struct s5m_rtc_reg_config s2mps_rtc_regs = { | 131 | static const struct s5m_rtc_reg_config s2mps15_rtc_regs = { |
79 | .regs_count = 7, | 132 | .regs_count = 7, |
80 | .time = S2MPS_RTC_SEC, | 133 | .time = S2MPS_RTC_SEC, |
81 | .ctrl = S2MPS_RTC_CTRL, | 134 | .ctrl = S2MPS_RTC_CTRL, |
82 | .alarm0 = S2MPS_ALARM0_SEC, | 135 | .alarm0 = S2MPS_ALARM0_SEC, |
83 | .alarm1 = S2MPS_ALARM1_SEC, | 136 | .alarm1 = S2MPS_ALARM1_SEC, |
84 | .rtc_udr_update = S2MPS_RTC_UDR_CON, | 137 | .udr_update = S2MPS_RTC_UDR_CON, |
85 | .rtc_udr_mask = S2MPS_RTC_WUDR_MASK, | 138 | .autoclear_udr_mask = S2MPS_RTC_WUDR_MASK, |
139 | .read_time_udr_mask = S2MPS_RTC_RUDR_MASK, | ||
140 | .write_time_udr_mask = S2MPS15_RTC_WUDR_MASK, | ||
141 | .write_alarm_udr_mask = S2MPS15_RTC_AUDR_MASK, | ||
86 | }; | 142 | }; |
87 | 143 | ||
88 | struct s5m_rtc_info { | 144 | struct s5m_rtc_info { |
@@ -166,9 +222,8 @@ static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info) | |||
166 | unsigned int data; | 222 | unsigned int data; |
167 | 223 | ||
168 | do { | 224 | do { |
169 | ret = regmap_read(info->regmap, info->regs->rtc_udr_update, | 225 | ret = regmap_read(info->regmap, info->regs->udr_update, &data); |
170 | &data); | 226 | } while (--retry && (data & info->regs->autoclear_udr_mask) && !ret); |
171 | } while (--retry && (data & info->regs->rtc_udr_mask) && !ret); | ||
172 | 227 | ||
173 | if (!retry) | 228 | if (!retry) |
174 | dev_err(info->dev, "waiting for UDR update, reached max number of retries\n"); | 229 | dev_err(info->dev, "waiting for UDR update, reached max number of retries\n"); |
@@ -188,6 +243,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info, | |||
188 | ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val); | 243 | ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val); |
189 | val &= S5M_ALARM0_STATUS; | 244 | val &= S5M_ALARM0_STATUS; |
190 | break; | 245 | break; |
246 | case S2MPS15X: | ||
191 | case S2MPS14X: | 247 | case S2MPS14X: |
192 | case S2MPS13X: | 248 | case S2MPS13X: |
193 | ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2, | 249 | ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2, |
@@ -213,17 +269,15 @@ static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info) | |||
213 | int ret; | 269 | int ret; |
214 | unsigned int data; | 270 | unsigned int data; |
215 | 271 | ||
216 | ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data); | 272 | ret = regmap_read(info->regmap, info->regs->udr_update, &data); |
217 | if (ret < 0) { | 273 | if (ret < 0) { |
218 | dev_err(info->dev, "failed to read update reg(%d)\n", ret); | 274 | dev_err(info->dev, "failed to read update reg(%d)\n", ret); |
219 | return ret; | 275 | return ret; |
220 | } | 276 | } |
221 | 277 | ||
222 | data |= info->regs->rtc_udr_mask; | 278 | data |= info->regs->write_time_udr_mask; |
223 | if (info->device_type == S5M8763X || info->device_type == S5M8767X) | ||
224 | data |= S5M_RTC_TIME_EN_MASK; | ||
225 | 279 | ||
226 | ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data); | 280 | ret = regmap_write(info->regmap, info->regs->udr_update, data); |
227 | if (ret < 0) { | 281 | if (ret < 0) { |
228 | dev_err(info->dev, "failed to write update reg(%d)\n", ret); | 282 | dev_err(info->dev, "failed to write update reg(%d)\n", ret); |
229 | return ret; | 283 | return ret; |
@@ -239,30 +293,29 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) | |||
239 | int ret; | 293 | int ret; |
240 | unsigned int data; | 294 | unsigned int data; |
241 | 295 | ||
242 | ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data); | 296 | ret = regmap_read(info->regmap, info->regs->udr_update, &data); |
243 | if (ret < 0) { | 297 | if (ret < 0) { |
244 | dev_err(info->dev, "%s: fail to read update reg(%d)\n", | 298 | dev_err(info->dev, "%s: fail to read update reg(%d)\n", |
245 | __func__, ret); | 299 | __func__, ret); |
246 | return ret; | 300 | return ret; |
247 | } | 301 | } |
248 | 302 | ||
249 | data |= info->regs->rtc_udr_mask; | 303 | data |= info->regs->write_alarm_udr_mask; |
250 | switch (info->device_type) { | 304 | switch (info->device_type) { |
251 | case S5M8763X: | 305 | case S5M8763X: |
252 | case S5M8767X: | 306 | case S5M8767X: |
253 | data &= ~S5M_RTC_TIME_EN_MASK; | 307 | data &= ~S5M_RTC_TIME_EN_MASK; |
254 | break; | 308 | break; |
309 | case S2MPS15X: | ||
255 | case S2MPS14X: | 310 | case S2MPS14X: |
256 | data |= S2MPS_RTC_RUDR_MASK; | ||
257 | break; | ||
258 | case S2MPS13X: | 311 | case S2MPS13X: |
259 | data |= S2MPS13_RTC_AUDR_MASK; | 312 | /* No exceptions needed */ |
260 | break; | 313 | break; |
261 | default: | 314 | default: |
262 | return -EINVAL; | 315 | return -EINVAL; |
263 | } | 316 | } |
264 | 317 | ||
265 | ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data); | 318 | ret = regmap_write(info->regmap, info->regs->udr_update, data); |
266 | if (ret < 0) { | 319 | if (ret < 0) { |
267 | dev_err(info->dev, "%s: fail to write update reg(%d)\n", | 320 | dev_err(info->dev, "%s: fail to write update reg(%d)\n", |
268 | __func__, ret); | 321 | __func__, ret); |
@@ -273,7 +326,7 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) | |||
273 | 326 | ||
274 | /* On S2MPS13 the AUDR is not auto-cleared */ | 327 | /* On S2MPS13 the AUDR is not auto-cleared */ |
275 | if (info->device_type == S2MPS13X) | 328 | if (info->device_type == S2MPS13X) |
276 | regmap_update_bits(info->regmap, info->regs->rtc_udr_update, | 329 | regmap_update_bits(info->regmap, info->regs->udr_update, |
277 | S2MPS13_RTC_AUDR_MASK, 0); | 330 | S2MPS13_RTC_AUDR_MASK, 0); |
278 | 331 | ||
279 | return ret; | 332 | return ret; |
@@ -317,10 +370,11 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
317 | u8 data[info->regs->regs_count]; | 370 | u8 data[info->regs->regs_count]; |
318 | int ret; | 371 | int ret; |
319 | 372 | ||
320 | if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) { | 373 | if (info->regs->read_time_udr_mask) { |
321 | ret = regmap_update_bits(info->regmap, | 374 | ret = regmap_update_bits(info->regmap, |
322 | info->regs->rtc_udr_update, | 375 | info->regs->udr_update, |
323 | S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK); | 376 | info->regs->read_time_udr_mask, |
377 | info->regs->read_time_udr_mask); | ||
324 | if (ret) { | 378 | if (ret) { |
325 | dev_err(dev, | 379 | dev_err(dev, |
326 | "Failed to prepare registers for time reading: %d\n", | 380 | "Failed to prepare registers for time reading: %d\n", |
@@ -339,6 +393,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
339 | break; | 393 | break; |
340 | 394 | ||
341 | case S5M8767X: | 395 | case S5M8767X: |
396 | case S2MPS15X: | ||
342 | case S2MPS14X: | 397 | case S2MPS14X: |
343 | case S2MPS13X: | 398 | case S2MPS13X: |
344 | s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); | 399 | s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); |
@@ -366,6 +421,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
366 | s5m8763_tm_to_data(tm, data); | 421 | s5m8763_tm_to_data(tm, data); |
367 | break; | 422 | break; |
368 | case S5M8767X: | 423 | case S5M8767X: |
424 | case S2MPS15X: | ||
369 | case S2MPS14X: | 425 | case S2MPS14X: |
370 | case S2MPS13X: | 426 | case S2MPS13X: |
371 | ret = s5m8767_tm_to_data(tm, data); | 427 | ret = s5m8767_tm_to_data(tm, data); |
@@ -414,6 +470,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
414 | break; | 470 | break; |
415 | 471 | ||
416 | case S5M8767X: | 472 | case S5M8767X: |
473 | case S2MPS15X: | ||
417 | case S2MPS14X: | 474 | case S2MPS14X: |
418 | case S2MPS13X: | 475 | case S2MPS13X: |
419 | s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); | 476 | s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); |
@@ -463,6 +520,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) | |||
463 | break; | 520 | break; |
464 | 521 | ||
465 | case S5M8767X: | 522 | case S5M8767X: |
523 | case S2MPS15X: | ||
466 | case S2MPS14X: | 524 | case S2MPS14X: |
467 | case S2MPS13X: | 525 | case S2MPS13X: |
468 | for (i = 0; i < info->regs->regs_count; i++) | 526 | for (i = 0; i < info->regs->regs_count; i++) |
@@ -508,6 +566,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) | |||
508 | break; | 566 | break; |
509 | 567 | ||
510 | case S5M8767X: | 568 | case S5M8767X: |
569 | case S2MPS15X: | ||
511 | case S2MPS14X: | 570 | case S2MPS14X: |
512 | case S2MPS13X: | 571 | case S2MPS13X: |
513 | data[RTC_SEC] |= ALARM_ENABLE_MASK; | 572 | data[RTC_SEC] |= ALARM_ENABLE_MASK; |
@@ -548,6 +607,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
548 | break; | 607 | break; |
549 | 608 | ||
550 | case S5M8767X: | 609 | case S5M8767X: |
610 | case S2MPS15X: | ||
551 | case S2MPS14X: | 611 | case S2MPS14X: |
552 | case S2MPS13X: | 612 | case S2MPS13X: |
553 | s5m8767_tm_to_data(&alrm->time, data); | 613 | s5m8767_tm_to_data(&alrm->time, data); |
@@ -631,6 +691,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) | |||
631 | ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2); | 691 | ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2); |
632 | break; | 692 | break; |
633 | 693 | ||
694 | case S2MPS15X: | ||
634 | case S2MPS14X: | 695 | case S2MPS14X: |
635 | case S2MPS13X: | 696 | case S2MPS13X: |
636 | data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | 697 | data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); |
@@ -679,10 +740,19 @@ static int s5m_rtc_probe(struct platform_device *pdev) | |||
679 | return -ENOMEM; | 740 | return -ENOMEM; |
680 | 741 | ||
681 | switch (platform_get_device_id(pdev)->driver_data) { | 742 | switch (platform_get_device_id(pdev)->driver_data) { |
743 | case S2MPS15X: | ||
744 | regmap_cfg = &s2mps14_rtc_regmap_config; | ||
745 | info->regs = &s2mps15_rtc_regs; | ||
746 | alarm_irq = S2MPS14_IRQ_RTCA0; | ||
747 | break; | ||
682 | case S2MPS14X: | 748 | case S2MPS14X: |
749 | regmap_cfg = &s2mps14_rtc_regmap_config; | ||
750 | info->regs = &s2mps14_rtc_regs; | ||
751 | alarm_irq = S2MPS14_IRQ_RTCA0; | ||
752 | break; | ||
683 | case S2MPS13X: | 753 | case S2MPS13X: |
684 | regmap_cfg = &s2mps14_rtc_regmap_config; | 754 | regmap_cfg = &s2mps14_rtc_regmap_config; |
685 | info->regs = &s2mps_rtc_regs; | 755 | info->regs = &s2mps13_rtc_regs; |
686 | alarm_irq = S2MPS14_IRQ_RTCA0; | 756 | alarm_irq = S2MPS14_IRQ_RTCA0; |
687 | break; | 757 | break; |
688 | case S5M8763X: | 758 | case S5M8763X: |
@@ -805,6 +875,7 @@ static const struct platform_device_id s5m_rtc_id[] = { | |||
805 | { "s5m-rtc", S5M8767X }, | 875 | { "s5m-rtc", S5M8767X }, |
806 | { "s2mps13-rtc", S2MPS13X }, | 876 | { "s2mps13-rtc", S2MPS13X }, |
807 | { "s2mps14-rtc", S2MPS14X }, | 877 | { "s2mps14-rtc", S2MPS14X }, |
878 | { "s2mps15-rtc", S2MPS15X }, | ||
808 | { }, | 879 | { }, |
809 | }; | 880 | }; |
810 | MODULE_DEVICE_TABLE(platform, s5m_rtc_id); | 881 | MODULE_DEVICE_TABLE(platform, s5m_rtc_id); |
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c index 52543ae37c98..abada609ddc7 100644 --- a/drivers/rtc/rtc-sunxi.c +++ b/drivers/rtc/rtc-sunxi.c | |||
@@ -133,7 +133,7 @@ struct sunxi_rtc_data_year { | |||
133 | unsigned char leap_shift; /* bit shift to get the leap year */ | 133 | unsigned char leap_shift; /* bit shift to get the leap year */ |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static struct sunxi_rtc_data_year data_year_param[] = { | 136 | static const struct sunxi_rtc_data_year data_year_param[] = { |
137 | [0] = { | 137 | [0] = { |
138 | .min = 2010, | 138 | .min = 2010, |
139 | .max = 2073, | 139 | .max = 2073, |
@@ -151,7 +151,7 @@ static struct sunxi_rtc_data_year data_year_param[] = { | |||
151 | struct sunxi_rtc_dev { | 151 | struct sunxi_rtc_dev { |
152 | struct rtc_device *rtc; | 152 | struct rtc_device *rtc; |
153 | struct device *dev; | 153 | struct device *dev; |
154 | struct sunxi_rtc_data_year *data_year; | 154 | const struct sunxi_rtc_data_year *data_year; |
155 | void __iomem *base; | 155 | void __iomem *base; |
156 | int irq; | 156 | int irq; |
157 | }; | 157 | }; |
@@ -175,7 +175,7 @@ static irqreturn_t sunxi_rtc_alarmirq(int irq, void *id) | |||
175 | return IRQ_NONE; | 175 | return IRQ_NONE; |
176 | } | 176 | } |
177 | 177 | ||
178 | static void sunxi_rtc_setaie(int to, struct sunxi_rtc_dev *chip) | 178 | static void sunxi_rtc_setaie(unsigned int to, struct sunxi_rtc_dev *chip) |
179 | { | 179 | { |
180 | u32 alrm_val = 0; | 180 | u32 alrm_val = 0; |
181 | u32 alrm_irq_val = 0; | 181 | u32 alrm_irq_val = 0; |
@@ -343,7 +343,7 @@ static int sunxi_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) | |||
343 | struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); | 343 | struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); |
344 | u32 date = 0; | 344 | u32 date = 0; |
345 | u32 time = 0; | 345 | u32 time = 0; |
346 | int year; | 346 | unsigned int year; |
347 | 347 | ||
348 | /* | 348 | /* |
349 | * the input rtc_tm->tm_year is the offset relative to 1900. We use | 349 | * the input rtc_tm->tm_year is the offset relative to 1900. We use |
@@ -353,8 +353,8 @@ static int sunxi_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) | |||
353 | 353 | ||
354 | year = rtc_tm->tm_year + 1900; | 354 | year = rtc_tm->tm_year + 1900; |
355 | if (year < chip->data_year->min || year > chip->data_year->max) { | 355 | if (year < chip->data_year->min || year > chip->data_year->max) { |
356 | dev_err(dev, "rtc only supports year in range %d - %d\n", | 356 | dev_err(dev, "rtc only supports year in range %u - %u\n", |
357 | chip->data_year->min, chip->data_year->max); | 357 | chip->data_year->min, chip->data_year->max); |
358 | return -EINVAL; | 358 | return -EINVAL; |
359 | } | 359 | } |
360 | 360 | ||
@@ -436,7 +436,6 @@ static int sunxi_rtc_probe(struct platform_device *pdev) | |||
436 | { | 436 | { |
437 | struct sunxi_rtc_dev *chip; | 437 | struct sunxi_rtc_dev *chip; |
438 | struct resource *res; | 438 | struct resource *res; |
439 | const struct of_device_id *of_id; | ||
440 | int ret; | 439 | int ret; |
441 | 440 | ||
442 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); | 441 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); |
@@ -463,12 +462,11 @@ static int sunxi_rtc_probe(struct platform_device *pdev) | |||
463 | return ret; | 462 | return ret; |
464 | } | 463 | } |
465 | 464 | ||
466 | of_id = of_match_device(sunxi_rtc_dt_ids, &pdev->dev); | 465 | chip->data_year = of_device_get_match_data(&pdev->dev); |
467 | if (!of_id) { | 466 | if (!chip->data_year) { |
468 | dev_err(&pdev->dev, "Unable to setup RTC data\n"); | 467 | dev_err(&pdev->dev, "Unable to setup RTC data\n"); |
469 | return -ENODEV; | 468 | return -ENODEV; |
470 | } | 469 | } |
471 | chip->data_year = (struct sunxi_rtc_data_year *) of_id->data; | ||
472 | 470 | ||
473 | /* clear the alarm count value */ | 471 | /* clear the alarm count value */ |
474 | writel(0, chip->base + SUNXI_ALRM_DHMS); | 472 | writel(0, chip->base + SUNXI_ALRM_DHMS); |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 7273855ed02e..463e286064ab 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -91,7 +91,12 @@ max_user_freq_store(struct device *dev, struct device_attribute *attr, | |||
91 | const char *buf, size_t n) | 91 | const char *buf, size_t n) |
92 | { | 92 | { |
93 | struct rtc_device *rtc = to_rtc_device(dev); | 93 | struct rtc_device *rtc = to_rtc_device(dev); |
94 | unsigned long val = simple_strtoul(buf, NULL, 0); | 94 | unsigned long val; |
95 | int err; | ||
96 | |||
97 | err = kstrtoul(buf, 0, &val); | ||
98 | if (err) | ||
99 | return err; | ||
95 | 100 | ||
96 | if (val >= 4096 || val == 0) | 101 | if (val >= 4096 || val == 0) |
97 | return -EINVAL; | 102 | return -EINVAL; |
@@ -175,7 +180,9 @@ wakealarm_store(struct device *dev, struct device_attribute *attr, | |||
175 | } else | 180 | } else |
176 | adjust = 1; | 181 | adjust = 1; |
177 | } | 182 | } |
178 | alarm = simple_strtoul(buf_ptr, NULL, 0); | 183 | retval = kstrtoul(buf_ptr, 0, &alarm); |
184 | if (retval) | ||
185 | return retval; | ||
179 | if (adjust) { | 186 | if (adjust) { |
180 | alarm += now; | 187 | alarm += now; |
181 | } | 188 | } |
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index f9f97098c254..7a0436329d6c 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
@@ -57,7 +57,7 @@ struct v3020 { | |||
57 | /* GPIO access */ | 57 | /* GPIO access */ |
58 | struct gpio *gpio; | 58 | struct gpio *gpio; |
59 | 59 | ||
60 | struct v3020_chip_ops *ops; | 60 | const struct v3020_chip_ops *ops; |
61 | 61 | ||
62 | struct rtc_device *rtc; | 62 | struct rtc_device *rtc; |
63 | }; | 63 | }; |
@@ -95,7 +95,7 @@ static unsigned char v3020_mmio_read_bit(struct v3020 *chip) | |||
95 | return !!(readl(chip->ioaddress) & (1 << chip->leftshift)); | 95 | return !!(readl(chip->ioaddress) & (1 << chip->leftshift)); |
96 | } | 96 | } |
97 | 97 | ||
98 | static struct v3020_chip_ops v3020_mmio_ops = { | 98 | static const struct v3020_chip_ops v3020_mmio_ops = { |
99 | .map_io = v3020_mmio_map, | 99 | .map_io = v3020_mmio_map, |
100 | .unmap_io = v3020_mmio_unmap, | 100 | .unmap_io = v3020_mmio_unmap, |
101 | .read_bit = v3020_mmio_read_bit, | 101 | .read_bit = v3020_mmio_read_bit, |
@@ -158,7 +158,7 @@ static unsigned char v3020_gpio_read_bit(struct v3020 *chip) | |||
158 | return bit; | 158 | return bit; |
159 | } | 159 | } |
160 | 160 | ||
161 | static struct v3020_chip_ops v3020_gpio_ops = { | 161 | static const struct v3020_chip_ops v3020_gpio_ops = { |
162 | .map_io = v3020_gpio_map, | 162 | .map_io = v3020_gpio_map, |
163 | .unmap_io = v3020_gpio_unmap, | 163 | .unmap_io = v3020_gpio_unmap, |
164 | .read_bit = v3020_gpio_read_bit, | 164 | .read_bit = v3020_gpio_read_bit, |