aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ds3232.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-ds3232.c')
-rw-r--r--drivers/rtc/rtc-ds3232.c81
1 files changed, 12 insertions, 69 deletions
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index f0ffd3f5d8f5..9857287215a9 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -20,7 +20,6 @@
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/rtc.h> 21#include <linux/rtc.h>
22#include <linux/bcd.h> 22#include <linux/bcd.h>
23#include <linux/workqueue.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <linux/regmap.h> 24#include <linux/regmap.h>
26 25
@@ -52,7 +51,6 @@ struct ds3232 {
52 struct regmap *regmap; 51 struct regmap *regmap;
53 int irq; 52 int irq;
54 struct rtc_device *rtc; 53 struct rtc_device *rtc;
55 struct work_struct work;
56 54
57 /* The mutex protects alarm operations, and prevents a race 55 /* The mutex protects alarm operations, and prevents a race
58 * between the enable_irq() in the workqueue and the free_irq() 56 * between the enable_irq() in the workqueue and the free_irq()
@@ -60,7 +58,6 @@ struct ds3232 {
60 */ 58 */
61 struct mutex mutex; 59 struct mutex mutex;
62 bool suspended; 60 bool suspended;
63 int exiting;
64}; 61};
65 62
66static int ds3232_check_rtc_status(struct device *dev) 63static int ds3232_check_rtc_status(struct device *dev)
@@ -314,23 +311,6 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
314{ 311{
315 struct device *dev = dev_id; 312 struct device *dev = dev_id;
316 struct ds3232 *ds3232 = dev_get_drvdata(dev); 313 struct ds3232 *ds3232 = dev_get_drvdata(dev);
317
318 disable_irq_nosync(irq);
319
320 /*
321 * If rtc as a wakeup source, can't schedule the work
322 * at system resume flow, because at this time the i2c bus
323 * has not been resumed.
324 */
325 if (!ds3232->suspended)
326 schedule_work(&ds3232->work);
327
328 return IRQ_HANDLED;
329}
330
331static void ds3232_work(struct work_struct *work)
332{
333 struct ds3232 *ds3232 = container_of(work, struct ds3232, work);
334 int ret; 314 int ret;
335 int stat, control; 315 int stat, control;
336 316
@@ -343,8 +323,8 @@ static void ds3232_work(struct work_struct *work)
343 if (stat & DS3232_REG_SR_A1F) { 323 if (stat & DS3232_REG_SR_A1F) {
344 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control); 324 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
345 if (ret) { 325 if (ret) {
346 pr_warn("Read Control Register error - Disable IRQ%d\n", 326 dev_warn(ds3232->dev,
347 ds3232->irq); 327 "Read Control Register error %d\n", ret);
348 } else { 328 } else {
349 /* disable alarm1 interrupt */ 329 /* disable alarm1 interrupt */
350 control &= ~(DS3232_REG_CR_A1IE); 330 control &= ~(DS3232_REG_CR_A1IE);
@@ -368,14 +348,13 @@ static void ds3232_work(struct work_struct *work)
368 } 348 }
369 349
370 rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF); 350 rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF);
371
372 if (!ds3232->exiting)
373 enable_irq(ds3232->irq);
374 } 351 }
375 } 352 }
376 353
377unlock: 354unlock:
378 mutex_unlock(&ds3232->mutex); 355 mutex_unlock(&ds3232->mutex);
356
357 return IRQ_HANDLED;
379} 358}
380 359
381static const struct rtc_class_ops ds3232_rtc_ops = { 360static const struct rtc_class_ops ds3232_rtc_ops = {
@@ -401,7 +380,6 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
401 ds3232->dev = dev; 380 ds3232->dev = dev;
402 dev_set_drvdata(dev, ds3232); 381 dev_set_drvdata(dev, ds3232);
403 382
404 INIT_WORK(&ds3232->work, ds3232_work);
405 mutex_init(&ds3232->mutex); 383 mutex_init(&ds3232->mutex);
406 384
407 ret = ds3232_check_rtc_status(dev); 385 ret = ds3232_check_rtc_status(dev);
@@ -409,8 +387,10 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
409 return ret; 387 return ret;
410 388
411 if (ds3232->irq > 0) { 389 if (ds3232->irq > 0) {
412 ret = devm_request_irq(dev, ds3232->irq, ds3232_irq, 390 ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
413 IRQF_SHARED, name, dev); 391 ds3232_irq,
392 IRQF_SHARED | IRQF_ONESHOT,
393 name, dev);
414 if (ret) { 394 if (ret) {
415 ds3232->irq = 0; 395 ds3232->irq = 0;
416 dev_err(dev, "unable to request IRQ\n"); 396 dev_err(dev, "unable to request IRQ\n");
@@ -423,33 +403,14 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
423 return PTR_ERR_OR_ZERO(ds3232->rtc); 403 return PTR_ERR_OR_ZERO(ds3232->rtc);
424} 404}
425 405
426static int ds3232_remove(struct device *dev)
427{
428 struct ds3232 *ds3232 = dev_get_drvdata(dev);
429
430 if (ds3232->irq > 0) {
431 mutex_lock(&ds3232->mutex);
432 ds3232->exiting = 1;
433 mutex_unlock(&ds3232->mutex);
434
435 devm_free_irq(dev, ds3232->irq, dev);
436 cancel_work_sync(&ds3232->work);
437 }
438
439 return 0;
440}
441
442#ifdef CONFIG_PM_SLEEP 406#ifdef CONFIG_PM_SLEEP
443static int ds3232_suspend(struct device *dev) 407static int ds3232_suspend(struct device *dev)
444{ 408{
445 struct ds3232 *ds3232 = dev_get_drvdata(dev); 409 struct ds3232 *ds3232 = dev_get_drvdata(dev);
446 410
447 if (device_can_wakeup(dev)) { 411 if (device_may_wakeup(dev)) {
448 ds3232->suspended = true; 412 if (enable_irq_wake(ds3232->irq))
449 if (irq_set_irq_wake(ds3232->irq, 1)) {
450 dev_warn_once(dev, "Cannot set wakeup source\n"); 413 dev_warn_once(dev, "Cannot set wakeup source\n");
451 ds3232->suspended = false;
452 }
453 } 414 }
454 415
455 return 0; 416 return 0;
@@ -459,14 +420,8 @@ static int ds3232_resume(struct device *dev)
459{ 420{
460 struct ds3232 *ds3232 = dev_get_drvdata(dev); 421 struct ds3232 *ds3232 = dev_get_drvdata(dev);
461 422
462 if (ds3232->suspended) { 423 if (device_may_wakeup(dev))
463 ds3232->suspended = false; 424 disable_irq_wake(ds3232->irq);
464
465 /* Clear the hardware alarm pend flag */
466 schedule_work(&ds3232->work);
467
468 irq_set_irq_wake(ds3232->irq, 0);
469 }
470 425
471 return 0; 426 return 0;
472} 427}
@@ -497,11 +452,6 @@ static int ds3232_i2c_probe(struct i2c_client *client,
497 return ds3232_probe(&client->dev, regmap, client->irq, client->name); 452 return ds3232_probe(&client->dev, regmap, client->irq, client->name);
498} 453}
499 454
500static int ds3232_i2c_remove(struct i2c_client *client)
501{
502 return ds3232_remove(&client->dev);
503}
504
505static const struct i2c_device_id ds3232_id[] = { 455static const struct i2c_device_id ds3232_id[] = {
506 { "ds3232", 0 }, 456 { "ds3232", 0 },
507 { } 457 { }
@@ -514,7 +464,6 @@ static struct i2c_driver ds3232_driver = {
514 .pm = &ds3232_pm_ops, 464 .pm = &ds3232_pm_ops,
515 }, 465 },
516 .probe = ds3232_i2c_probe, 466 .probe = ds3232_i2c_probe,
517 .remove = ds3232_i2c_remove,
518 .id_table = ds3232_id, 467 .id_table = ds3232_id,
519}; 468};
520 469
@@ -611,17 +560,11 @@ static int ds3234_probe(struct spi_device *spi)
611 return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234"); 560 return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234");
612} 561}
613 562
614static int ds3234_remove(struct spi_device *spi)
615{
616 return ds3232_remove(&spi->dev);
617}
618
619static struct spi_driver ds3234_driver = { 563static struct spi_driver ds3234_driver = {
620 .driver = { 564 .driver = {
621 .name = "ds3234", 565 .name = "ds3234",
622 }, 566 },
623 .probe = ds3234_probe, 567 .probe = ds3234_probe,
624 .remove = ds3234_remove,
625}; 568};
626 569
627static int ds3234_register_driver(void) 570static int ds3234_register_driver(void)