diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-25 01:49:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-25 01:49:08 -0400 |
commit | 8407ef4685895759f111190d091394ef974f52fb (patch) | |
tree | 7f654f935e405bf7eceab590cb1b718d395ee3f9 | |
parent | b4ae78edf77f1751a2a0ae08a8398b35a763d6f6 (diff) | |
parent | ee087744247c421c83abea7f01217bfd39b8f5a9 (diff) |
Merge tag 'rtc-4.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull more RTC updates from Alexandre Belloni:
"A second pull request for v4.6 with a few fixesi before -rc1. The new
features for abx80x actually make the RTC behave correctly.
Drivers:
- abx80x: handle both XT and RC oscillators, XT failure bit and
autocalibration
- m41t80: avoid out of range year values
- rv8803: workaround an i2c HW issue"
* tag 'rtc-4.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux:
rtc: abx80x: handle the oscillator failure bit
rtc: abx80x: handle autocalibration
rtc: rv8803: workaround i2c HW issue
rtc: mcp795: add devicetree support
rtc: asm9260: remove incorrect __init/__exit annotations
rtc: m41t80: avoid out of range year values
rtc: s3c: Don't print an error on probe deferral
rtc: rv3029: stop mentioning rv3029c2
-rw-r--r-- | Documentation/devicetree/bindings/rtc/maxim,mcp795.txt | 11 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-abx80x.c | 252 | ||||
-rw-r--r-- | drivers/rtc/rtc-asm9260.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-m41t80.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-mcp795.c | 10 | ||||
-rw-r--r-- | drivers/rtc/rtc-rv8803.c | 28 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 19 |
8 files changed, 316 insertions, 16 deletions
diff --git a/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt b/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt new file mode 100644 index 000000000000..a59fdd8c236d --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt | |||
@@ -0,0 +1,11 @@ | |||
1 | * Maxim MCP795 SPI Serial Real-Time Clock | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should contain "maxim,mcp795". | ||
5 | - reg: SPI address for chip | ||
6 | |||
7 | Example: | ||
8 | mcp795: rtc@0 { | ||
9 | compatible = "maxim,mcp795"; | ||
10 | reg = <0>; | ||
11 | }; | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 544bd3493852..3e84315c6f12 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -589,7 +589,7 @@ config RTC_DRV_RV3029_HWMON | |||
589 | default y | 589 | default y |
590 | help | 590 | help |
591 | Say Y here if you want to expose temperature sensor data on | 591 | Say Y here if you want to expose temperature sensor data on |
592 | rtc-rv3029c2. | 592 | rtc-rv3029. |
593 | 593 | ||
594 | config RTC_DRV_RV8803 | 594 | config RTC_DRV_RV8803 |
595 | tristate "Micro Crystal RV8803" | 595 | tristate "Micro Crystal RV8803" |
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index d41bbcd653f6..ba0d61934d35 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c | |||
@@ -49,7 +49,20 @@ | |||
49 | 49 | ||
50 | #define ABX8XX_REG_CD_TIMER_CTL 0x18 | 50 | #define ABX8XX_REG_CD_TIMER_CTL 0x18 |
51 | 51 | ||
52 | #define ABX8XX_REG_OSC 0x1c | ||
53 | #define ABX8XX_OSC_FOS BIT(3) | ||
54 | #define ABX8XX_OSC_BOS BIT(4) | ||
55 | #define ABX8XX_OSC_ACAL_512 BIT(5) | ||
56 | #define ABX8XX_OSC_ACAL_1024 BIT(6) | ||
57 | |||
58 | #define ABX8XX_OSC_OSEL BIT(7) | ||
59 | |||
60 | #define ABX8XX_REG_OSS 0x1d | ||
61 | #define ABX8XX_OSS_OF BIT(1) | ||
62 | #define ABX8XX_OSS_OMODE BIT(4) | ||
63 | |||
52 | #define ABX8XX_REG_CFG_KEY 0x1f | 64 | #define ABX8XX_REG_CFG_KEY 0x1f |
65 | #define ABX8XX_CFG_KEY_OSC 0xa1 | ||
53 | #define ABX8XX_CFG_KEY_MISC 0x9d | 66 | #define ABX8XX_CFG_KEY_MISC 0x9d |
54 | 67 | ||
55 | #define ABX8XX_REG_ID0 0x28 | 68 | #define ABX8XX_REG_ID0 0x28 |
@@ -81,6 +94,20 @@ static struct abx80x_cap abx80x_caps[] = { | |||
81 | [ABX80X] = {.pn = 0} | 94 | [ABX80X] = {.pn = 0} |
82 | }; | 95 | }; |
83 | 96 | ||
97 | static int abx80x_is_rc_mode(struct i2c_client *client) | ||
98 | { | ||
99 | int flags = 0; | ||
100 | |||
101 | flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS); | ||
102 | if (flags < 0) { | ||
103 | dev_err(&client->dev, | ||
104 | "Failed to read autocalibration attribute\n"); | ||
105 | return flags; | ||
106 | } | ||
107 | |||
108 | return (flags & ABX8XX_OSS_OMODE) ? 1 : 0; | ||
109 | } | ||
110 | |||
84 | static int abx80x_enable_trickle_charger(struct i2c_client *client, | 111 | static int abx80x_enable_trickle_charger(struct i2c_client *client, |
85 | u8 trickle_cfg) | 112 | u8 trickle_cfg) |
86 | { | 113 | { |
@@ -112,7 +139,23 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
112 | { | 139 | { |
113 | struct i2c_client *client = to_i2c_client(dev); | 140 | struct i2c_client *client = to_i2c_client(dev); |
114 | unsigned char buf[8]; | 141 | unsigned char buf[8]; |
115 | int err; | 142 | int err, flags, rc_mode = 0; |
143 | |||
144 | /* Read the Oscillator Failure only in XT mode */ | ||
145 | rc_mode = abx80x_is_rc_mode(client); | ||
146 | if (rc_mode < 0) | ||
147 | return rc_mode; | ||
148 | |||
149 | if (!rc_mode) { | ||
150 | flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS); | ||
151 | if (flags < 0) | ||
152 | return flags; | ||
153 | |||
154 | if (flags & ABX8XX_OSS_OF) { | ||
155 | dev_err(dev, "Oscillator failure, data is invalid.\n"); | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | } | ||
116 | 159 | ||
117 | err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH, | 160 | err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH, |
118 | sizeof(buf), buf); | 161 | sizeof(buf), buf); |
@@ -140,7 +183,7 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
140 | { | 183 | { |
141 | struct i2c_client *client = to_i2c_client(dev); | 184 | struct i2c_client *client = to_i2c_client(dev); |
142 | unsigned char buf[8]; | 185 | unsigned char buf[8]; |
143 | int err; | 186 | int err, flags; |
144 | 187 | ||
145 | if (tm->tm_year < 100) | 188 | if (tm->tm_year < 100) |
146 | return -EINVAL; | 189 | return -EINVAL; |
@@ -161,6 +204,18 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
161 | return -EIO; | 204 | return -EIO; |
162 | } | 205 | } |
163 | 206 | ||
207 | /* Clear the OF bit of Oscillator Status Register */ | ||
208 | flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS); | ||
209 | if (flags < 0) | ||
210 | return flags; | ||
211 | |||
212 | err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSS, | ||
213 | flags & ~ABX8XX_OSS_OF); | ||
214 | if (err < 0) { | ||
215 | dev_err(&client->dev, "Unable to write oscillator status register\n"); | ||
216 | return err; | ||
217 | } | ||
218 | |||
164 | return 0; | 219 | return 0; |
165 | } | 220 | } |
166 | 221 | ||
@@ -248,6 +303,174 @@ static int abx80x_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
248 | return 0; | 303 | return 0; |
249 | } | 304 | } |
250 | 305 | ||
306 | static int abx80x_rtc_set_autocalibration(struct device *dev, | ||
307 | int autocalibration) | ||
308 | { | ||
309 | struct i2c_client *client = to_i2c_client(dev); | ||
310 | int retval, flags = 0; | ||
311 | |||
312 | if ((autocalibration != 0) && (autocalibration != 1024) && | ||
313 | (autocalibration != 512)) { | ||
314 | dev_err(dev, "autocalibration value outside permitted range\n"); | ||
315 | return -EINVAL; | ||
316 | } | ||
317 | |||
318 | flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC); | ||
319 | if (flags < 0) | ||
320 | return flags; | ||
321 | |||
322 | if (autocalibration == 0) { | ||
323 | flags &= ~(ABX8XX_OSC_ACAL_512 | ABX8XX_OSC_ACAL_1024); | ||
324 | } else if (autocalibration == 1024) { | ||
325 | /* 1024 autocalibration is 0x10 */ | ||
326 | flags |= ABX8XX_OSC_ACAL_1024; | ||
327 | flags &= ~(ABX8XX_OSC_ACAL_512); | ||
328 | } else { | ||
329 | /* 512 autocalibration is 0x11 */ | ||
330 | flags |= (ABX8XX_OSC_ACAL_1024 | ABX8XX_OSC_ACAL_512); | ||
331 | } | ||
332 | |||
333 | /* Unlock write access to Oscillator Control Register */ | ||
334 | retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, | ||
335 | ABX8XX_CFG_KEY_OSC); | ||
336 | if (retval < 0) { | ||
337 | dev_err(dev, "Failed to write CONFIG_KEY register\n"); | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags); | ||
342 | |||
343 | return retval; | ||
344 | } | ||
345 | |||
346 | static int abx80x_rtc_get_autocalibration(struct device *dev) | ||
347 | { | ||
348 | struct i2c_client *client = to_i2c_client(dev); | ||
349 | int flags = 0, autocalibration; | ||
350 | |||
351 | flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC); | ||
352 | if (flags < 0) | ||
353 | return flags; | ||
354 | |||
355 | if (flags & ABX8XX_OSC_ACAL_512) | ||
356 | autocalibration = 512; | ||
357 | else if (flags & ABX8XX_OSC_ACAL_1024) | ||
358 | autocalibration = 1024; | ||
359 | else | ||
360 | autocalibration = 0; | ||
361 | |||
362 | return autocalibration; | ||
363 | } | ||
364 | |||
365 | static ssize_t autocalibration_store(struct device *dev, | ||
366 | struct device_attribute *attr, | ||
367 | const char *buf, size_t count) | ||
368 | { | ||
369 | int retval; | ||
370 | unsigned long autocalibration = 0; | ||
371 | |||
372 | retval = kstrtoul(buf, 10, &autocalibration); | ||
373 | if (retval < 0) { | ||
374 | dev_err(dev, "Failed to store RTC autocalibration attribute\n"); | ||
375 | return -EINVAL; | ||
376 | } | ||
377 | |||
378 | retval = abx80x_rtc_set_autocalibration(dev, autocalibration); | ||
379 | |||
380 | return retval ? retval : count; | ||
381 | } | ||
382 | |||
383 | static ssize_t autocalibration_show(struct device *dev, | ||
384 | struct device_attribute *attr, char *buf) | ||
385 | { | ||
386 | int autocalibration = 0; | ||
387 | |||
388 | autocalibration = abx80x_rtc_get_autocalibration(dev); | ||
389 | if (autocalibration < 0) { | ||
390 | dev_err(dev, "Failed to read RTC autocalibration\n"); | ||
391 | sprintf(buf, "0\n"); | ||
392 | return autocalibration; | ||
393 | } | ||
394 | |||
395 | return sprintf(buf, "%d\n", autocalibration); | ||
396 | } | ||
397 | |||
398 | static DEVICE_ATTR_RW(autocalibration); | ||
399 | |||
400 | static ssize_t oscillator_store(struct device *dev, | ||
401 | struct device_attribute *attr, | ||
402 | const char *buf, size_t count) | ||
403 | { | ||
404 | struct i2c_client *client = to_i2c_client(dev); | ||
405 | int retval, flags, rc_mode = 0; | ||
406 | |||
407 | if (strncmp(buf, "rc", 2) == 0) { | ||
408 | rc_mode = 1; | ||
409 | } else if (strncmp(buf, "xtal", 4) == 0) { | ||
410 | rc_mode = 0; | ||
411 | } else { | ||
412 | dev_err(dev, "Oscillator selection value outside permitted ones\n"); | ||
413 | return -EINVAL; | ||
414 | } | ||
415 | |||
416 | flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC); | ||
417 | if (flags < 0) | ||
418 | return flags; | ||
419 | |||
420 | if (rc_mode == 0) | ||
421 | flags &= ~(ABX8XX_OSC_OSEL); | ||
422 | else | ||
423 | flags |= (ABX8XX_OSC_OSEL); | ||
424 | |||
425 | /* Unlock write access on Oscillator Control register */ | ||
426 | retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, | ||
427 | ABX8XX_CFG_KEY_OSC); | ||
428 | if (retval < 0) { | ||
429 | dev_err(dev, "Failed to write CONFIG_KEY register\n"); | ||
430 | return retval; | ||
431 | } | ||
432 | |||
433 | retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags); | ||
434 | if (retval < 0) { | ||
435 | dev_err(dev, "Failed to write Oscillator Control register\n"); | ||
436 | return retval; | ||
437 | } | ||
438 | |||
439 | return retval ? retval : count; | ||
440 | } | ||
441 | |||
442 | static ssize_t oscillator_show(struct device *dev, | ||
443 | struct device_attribute *attr, char *buf) | ||
444 | { | ||
445 | int rc_mode = 0; | ||
446 | struct i2c_client *client = to_i2c_client(dev); | ||
447 | |||
448 | rc_mode = abx80x_is_rc_mode(client); | ||
449 | |||
450 | if (rc_mode < 0) { | ||
451 | dev_err(dev, "Failed to read RTC oscillator selection\n"); | ||
452 | sprintf(buf, "\n"); | ||
453 | return rc_mode; | ||
454 | } | ||
455 | |||
456 | if (rc_mode) | ||
457 | return sprintf(buf, "rc\n"); | ||
458 | else | ||
459 | return sprintf(buf, "xtal\n"); | ||
460 | } | ||
461 | |||
462 | static DEVICE_ATTR_RW(oscillator); | ||
463 | |||
464 | static struct attribute *rtc_calib_attrs[] = { | ||
465 | &dev_attr_autocalibration.attr, | ||
466 | &dev_attr_oscillator.attr, | ||
467 | NULL, | ||
468 | }; | ||
469 | |||
470 | static const struct attribute_group rtc_calib_attr_group = { | ||
471 | .attrs = rtc_calib_attrs, | ||
472 | }; | ||
473 | |||
251 | static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled) | 474 | static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled) |
252 | { | 475 | { |
253 | struct i2c_client *client = to_i2c_client(dev); | 476 | struct i2c_client *client = to_i2c_client(dev); |
@@ -303,6 +526,13 @@ static int abx80x_dt_trickle_cfg(struct device_node *np) | |||
303 | return (trickle_cfg | i); | 526 | return (trickle_cfg | i); |
304 | } | 527 | } |
305 | 528 | ||
529 | static void rtc_calib_remove_sysfs_group(void *_dev) | ||
530 | { | ||
531 | struct device *dev = _dev; | ||
532 | |||
533 | sysfs_remove_group(&dev->kobj, &rtc_calib_attr_group); | ||
534 | } | ||
535 | |||
306 | static int abx80x_probe(struct i2c_client *client, | 536 | static int abx80x_probe(struct i2c_client *client, |
307 | const struct i2c_device_id *id) | 537 | const struct i2c_device_id *id) |
308 | { | 538 | { |
@@ -405,6 +635,24 @@ static int abx80x_probe(struct i2c_client *client, | |||
405 | } | 635 | } |
406 | } | 636 | } |
407 | 637 | ||
638 | /* Export sysfs entries */ | ||
639 | err = sysfs_create_group(&(&client->dev)->kobj, &rtc_calib_attr_group); | ||
640 | if (err) { | ||
641 | dev_err(&client->dev, "Failed to create sysfs group: %d\n", | ||
642 | err); | ||
643 | return err; | ||
644 | } | ||
645 | |||
646 | err = devm_add_action(&client->dev, rtc_calib_remove_sysfs_group, | ||
647 | &client->dev); | ||
648 | if (err) { | ||
649 | rtc_calib_remove_sysfs_group(&client->dev); | ||
650 | dev_err(&client->dev, | ||
651 | "Failed to add sysfs cleanup action: %d\n", | ||
652 | err); | ||
653 | return err; | ||
654 | } | ||
655 | |||
408 | return 0; | 656 | return 0; |
409 | } | 657 | } |
410 | 658 | ||
diff --git a/drivers/rtc/rtc-asm9260.c b/drivers/rtc/rtc-asm9260.c index 14e08c4c1a01..355fdb97a006 100644 --- a/drivers/rtc/rtc-asm9260.c +++ b/drivers/rtc/rtc-asm9260.c | |||
@@ -255,7 +255,7 @@ static const struct rtc_class_ops asm9260_rtc_ops = { | |||
255 | .alarm_irq_enable = asm9260_alarm_irq_enable, | 255 | .alarm_irq_enable = asm9260_alarm_irq_enable, |
256 | }; | 256 | }; |
257 | 257 | ||
258 | static int __init asm9260_rtc_probe(struct platform_device *pdev) | 258 | static int asm9260_rtc_probe(struct platform_device *pdev) |
259 | { | 259 | { |
260 | struct asm9260_rtc_priv *priv; | 260 | struct asm9260_rtc_priv *priv; |
261 | struct device *dev = &pdev->dev; | 261 | struct device *dev = &pdev->dev; |
@@ -323,7 +323,7 @@ err_return: | |||
323 | return ret; | 323 | return ret; |
324 | } | 324 | } |
325 | 325 | ||
326 | static int __exit asm9260_rtc_remove(struct platform_device *pdev) | 326 | static int asm9260_rtc_remove(struct platform_device *pdev) |
327 | { | 327 | { |
328 | struct asm9260_rtc_priv *priv = platform_get_drvdata(pdev); | 328 | struct asm9260_rtc_priv *priv = platform_get_drvdata(pdev); |
329 | 329 | ||
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index a82937e2f824..d107a8e72a7d 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -176,7 +176,13 @@ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
176 | bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f); | 176 | bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f); |
177 | buf[M41T80_REG_MON] = | 177 | buf[M41T80_REG_MON] = |
178 | bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f); | 178 | bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f); |
179 | |||
179 | /* assume 20YY not 19YY */ | 180 | /* assume 20YY not 19YY */ |
181 | if (tm->tm_year < 100 || tm->tm_year > 199) { | ||
182 | dev_err(&client->dev, "Year must be between 2000 and 2099. It's %d.\n", | ||
183 | tm->tm_year + 1900); | ||
184 | return -EINVAL; | ||
185 | } | ||
180 | buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100); | 186 | buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100); |
181 | 187 | ||
182 | if (i2c_transfer(client->adapter, msgs, 1) != 1) { | 188 | if (i2c_transfer(client->adapter, msgs, 1) != 1) { |
diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c index 1c91ce8a6d75..025bb33b9cd2 100644 --- a/drivers/rtc/rtc-mcp795.c +++ b/drivers/rtc/rtc-mcp795.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/printk.h> | 20 | #include <linux/printk.h> |
21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
22 | #include <linux/rtc.h> | 22 | #include <linux/rtc.h> |
23 | #include <linux/of.h> | ||
23 | 24 | ||
24 | /* MCP795 Instructions, see datasheet table 3-1 */ | 25 | /* MCP795 Instructions, see datasheet table 3-1 */ |
25 | #define MCP795_EEREAD 0x03 | 26 | #define MCP795_EEREAD 0x03 |
@@ -183,9 +184,18 @@ static int mcp795_probe(struct spi_device *spi) | |||
183 | return 0; | 184 | return 0; |
184 | } | 185 | } |
185 | 186 | ||
187 | #ifdef CONFIG_OF | ||
188 | static const struct of_device_id mcp795_of_match[] = { | ||
189 | { .compatible = "maxim,mcp795" }, | ||
190 | { } | ||
191 | }; | ||
192 | MODULE_DEVICE_TABLE(of, mcp795_of_match); | ||
193 | #endif | ||
194 | |||
186 | static struct spi_driver mcp795_driver = { | 195 | static struct spi_driver mcp795_driver = { |
187 | .driver = { | 196 | .driver = { |
188 | .name = "rtc-mcp795", | 197 | .name = "rtc-mcp795", |
198 | .of_match_table = of_match_ptr(mcp795_of_match), | ||
189 | }, | 199 | }, |
190 | .probe = mcp795_probe, | 200 | .probe = mcp795_probe, |
191 | }; | 201 | }; |
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index 8d9f35ceb808..f623038e586e 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c | |||
@@ -61,11 +61,14 @@ 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 | int flags; | 64 | int flags, try = 0; |
65 | 65 | ||
66 | mutex_lock(&rv8803->flags_lock); | 66 | mutex_lock(&rv8803->flags_lock); |
67 | 67 | ||
68 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 68 | do { |
69 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | ||
70 | try++; | ||
71 | } while ((flags == -ENXIO) && (try < 3)); | ||
69 | if (flags <= 0) { | 72 | if (flags <= 0) { |
70 | mutex_unlock(&rv8803->flags_lock); | 73 | mutex_unlock(&rv8803->flags_lock); |
71 | return IRQ_NONE; | 74 | return IRQ_NONE; |
@@ -424,7 +427,7 @@ static int rv8803_probe(struct i2c_client *client, | |||
424 | { | 427 | { |
425 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 428 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
426 | struct rv8803_data *rv8803; | 429 | struct rv8803_data *rv8803; |
427 | int err, flags; | 430 | int err, flags, try = 0; |
428 | 431 | ||
429 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 432 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
430 | I2C_FUNC_SMBUS_I2C_BLOCK)) { | 433 | I2C_FUNC_SMBUS_I2C_BLOCK)) { |
@@ -441,7 +444,16 @@ static int rv8803_probe(struct i2c_client *client, | |||
441 | rv8803->client = client; | 444 | rv8803->client = client; |
442 | i2c_set_clientdata(client, rv8803); | 445 | i2c_set_clientdata(client, rv8803); |
443 | 446 | ||
444 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 447 | /* |
448 | * There is a 60µs window where the RTC may not reply on the i2c bus in | ||
449 | * that case, the transfer is not ACKed. In that case, ensure there are | ||
450 | * multiple attempts. | ||
451 | */ | ||
452 | do { | ||
453 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | ||
454 | try++; | ||
455 | } while ((flags == -ENXIO) && (try < 3)); | ||
456 | |||
445 | if (flags < 0) | 457 | if (flags < 0) |
446 | return flags; | 458 | return flags; |
447 | 459 | ||
@@ -476,8 +488,12 @@ static int rv8803_probe(struct i2c_client *client, | |||
476 | return PTR_ERR(rv8803->rtc); | 488 | return PTR_ERR(rv8803->rtc); |
477 | } | 489 | } |
478 | 490 | ||
479 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT, | 491 | try = 0; |
480 | RV8803_EXT_WADA); | 492 | do { |
493 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT, | ||
494 | RV8803_EXT_WADA); | ||
495 | try++; | ||
496 | } while ((err == -ENXIO) && (try < 3)); | ||
481 | if (err) | 497 | if (err) |
482 | return err; | 498 | return err; |
483 | 499 | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index ffb860d18701..d01ad7e8078e 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -501,18 +501,27 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
501 | 501 | ||
502 | info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); | 502 | info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); |
503 | if (IS_ERR(info->rtc_clk)) { | 503 | if (IS_ERR(info->rtc_clk)) { |
504 | dev_err(&pdev->dev, "failed to find rtc clock\n"); | 504 | ret = PTR_ERR(info->rtc_clk); |
505 | return PTR_ERR(info->rtc_clk); | 505 | if (ret != -EPROBE_DEFER) |
506 | dev_err(&pdev->dev, "failed to find rtc clock\n"); | ||
507 | else | ||
508 | dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n"); | ||
509 | return ret; | ||
506 | } | 510 | } |
507 | clk_prepare_enable(info->rtc_clk); | 511 | clk_prepare_enable(info->rtc_clk); |
508 | 512 | ||
509 | if (info->data->needs_src_clk) { | 513 | if (info->data->needs_src_clk) { |
510 | info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); | 514 | info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); |
511 | if (IS_ERR(info->rtc_src_clk)) { | 515 | if (IS_ERR(info->rtc_src_clk)) { |
512 | dev_err(&pdev->dev, | 516 | ret = PTR_ERR(info->rtc_src_clk); |
513 | "failed to find rtc source clock\n"); | 517 | if (ret != -EPROBE_DEFER) |
518 | dev_err(&pdev->dev, | ||
519 | "failed to find rtc source clock\n"); | ||
520 | else | ||
521 | dev_dbg(&pdev->dev, | ||
522 | "probe deferred due to missing rtc src clk\n"); | ||
514 | clk_disable_unprepare(info->rtc_clk); | 523 | clk_disable_unprepare(info->rtc_clk); |
515 | return PTR_ERR(info->rtc_src_clk); | 524 | return ret; |
516 | } | 525 | } |
517 | clk_prepare_enable(info->rtc_src_clk); | 526 | clk_prepare_enable(info->rtc_src_clk); |
518 | } | 527 | } |