From 91b0abe36a7b2b3b02d7500925a5f8455334f0e5 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 3 Apr 2014 14:47:49 -0700 Subject: mm + fs: store shadow entries in page cache Reclaim will be leaving shadow entries in the page cache radix tree upon evicting the real page. As those pages are found from the LRU, an iput() can lead to the inode being freed concurrently. At this point, reclaim must no longer install shadow pages because the inode freeing code needs to ensure the page tree is really empty. Add an address_space flag, AS_EXITING, that the inode freeing code sets under the tree lock before doing the final truncate. Reclaim will check for this flag before installing shadow pages. Signed-off-by: Johannes Weiner Reviewed-by: Rik van Riel Reviewed-by: Minchan Kim Cc: Andrea Arcangeli Cc: Bob Liu Cc: Christoph Hellwig Cc: Dave Chinner Cc: Greg Thelen Cc: Hugh Dickins Cc: Jan Kara Cc: KOSAKI Motohiro Cc: Luigi Semenzato Cc: Mel Gorman Cc: Metin Doslu Cc: Michel Lespinasse Cc: Ozgun Erdogan Cc: Peter Zijlstra Cc: Roman Gushchin Cc: Ryan Mallon Cc: Tejun Heo Cc: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 26003d3c1be7..7c4fd97a7fa0 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1877,7 +1877,7 @@ void ll_delete_inode(struct inode *inode) cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_DISCARD, 1); - truncate_inode_pages(&inode->i_data, 0); + truncate_inode_pages_final(&inode->i_data); /* Workaround for LU-118 */ if (inode->i_data.nrpages) { -- cgit v1.2.3 From a55944ca82d287ca099ca90413af857af9086773 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 3 Apr 2014 14:48:54 -0700 Subject: backlight: update bd state & fb_blank properties when necessary We don't have to update the state and fb_blank properties of a backlight device every time a blanking or unblanking event comes because they may have already been what we want. Another thought is that one backlight device may be shared by multiple framebuffers. The backlight driver should take the backlight device as a resource shared by all the associated framebuffers. This patch adds some logic to record each framebuffer's backlight usage to determine the backlight device use count and whether the two properties should be updated or not. To be more specific, only one unblank operation on a certain blanked framebuffer may increase the backlight device's use count by one, while one blank operation on a certain unblanked framebuffer may decrease the use count by one, because the userspace is likely to unblank an unblanked framebuffer or blank a blanked framebuffer. Signed-off-by: Liu Ying Cc: Jingoo Han Cc: Jean-Christophe PLAGNIOL-VILLARD Cc: Tomi Valkeinen Cc: Jani Nikula Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/backlight.c | 23 ++++++++++++++++++----- include/linux/backlight.h | 6 ++++++ 2 files changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 5d05555fe841..efc9a2da918d 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -41,6 +41,8 @@ static int fb_notifier_callback(struct notifier_block *self, { struct backlight_device *bd; struct fb_event *evdata = data; + int node = evdata->info->node; + int fb_blank = 0; /* If we aren't interested in this event, skip it immediately ... */ if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK) @@ -51,11 +53,22 @@ static int fb_notifier_callback(struct notifier_block *self, if (bd->ops) if (!bd->ops->check_fb || bd->ops->check_fb(bd, evdata->info)) { - bd->props.fb_blank = *(int *)evdata->data; - if (bd->props.fb_blank == FB_BLANK_UNBLANK) - bd->props.state &= ~BL_CORE_FBBLANK; - else - bd->props.state |= BL_CORE_FBBLANK; + fb_blank = *(int *)evdata->data; + if (fb_blank == FB_BLANK_UNBLANK && + !bd->fb_bl_on[node]) { + bd->fb_bl_on[node] = true; + if (!bd->use_count++) { + bd->props.state &= ~BL_CORE_FBBLANK; + bd->props.fb_blank = FB_BLANK_UNBLANK; + } + } else if (fb_blank != FB_BLANK_UNBLANK && + bd->fb_bl_on[node]) { + bd->fb_bl_on[node] = false; + if (!(--bd->use_count)) { + bd->props.state |= BL_CORE_FBBLANK; + bd->props.fb_blank = fb_blank; + } + } backlight_update_status(bd); } mutex_unlock(&bd->ops_lock); diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 5f9cd963213d..72647429adf6 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -9,6 +9,7 @@ #define _LINUX_BACKLIGHT_H #include +#include #include #include @@ -104,6 +105,11 @@ struct backlight_device { struct list_head entry; struct device dev; + + /* Multiple framebuffers may share one backlight device */ + bool fb_bl_on[FB_MAX]; + + int use_count; }; static inline void backlight_update_status(struct backlight_device *bd) -- cgit v1.2.3 From 8c16f3303c3410d4af19c8bdc73b74c83c042e87 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 3 Apr 2014 14:48:55 -0700 Subject: backlight: update backlight status when necessary We don't have to update a backlight status every time a blanking or unblanking event comes because the backlight status may have already been what we want. Another thought is that one backlight device may be shared by multiple framebuffers. We don't hope blanking one of the framebuffers may turn the backlight off for all the other framebuffers, since they are likely being active to display something. This patch makes the backlight status be updated only when the relevant backlight device's use count changes from zero to one or from one to zero. Signed-off-by: Liu Ying Cc: Jingoo Han Cc: Jean-Christophe PLAGNIOL-VILLARD Cc: Tomi Valkeinen Cc: Jani Nikula Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/backlight.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index efc9a2da918d..27d3cf255e78 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -34,7 +34,7 @@ static const char *const backlight_types[] = { defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) /* This callback gets called when something important happens inside a * framebuffer driver. We're looking if that important event is blanking, - * and if it is, we're switching backlight power as well ... + * and if it is and necessary, we're switching backlight power as well ... */ static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) @@ -60,6 +60,7 @@ static int fb_notifier_callback(struct notifier_block *self, if (!bd->use_count++) { bd->props.state &= ~BL_CORE_FBBLANK; bd->props.fb_blank = FB_BLANK_UNBLANK; + backlight_update_status(bd); } } else if (fb_blank != FB_BLANK_UNBLANK && bd->fb_bl_on[node]) { @@ -67,9 +68,9 @@ static int fb_notifier_callback(struct notifier_block *self, if (!(--bd->use_count)) { bd->props.state |= BL_CORE_FBBLANK; bd->props.fb_blank = fb_blank; + backlight_update_status(bd); } } - backlight_update_status(bd); } mutex_unlock(&bd->ops_lock); return 0; -- cgit v1.2.3 From 78b35cf81e5d8b449f09aef0a65ac2d521dcce36 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:48:56 -0700 Subject: backlight: aat2870: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Jinyoung Park Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/aat2870_bl.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c index ee0c0a982e4e..ec5350f2c28a 100644 --- a/drivers/video/backlight/aat2870_bl.c +++ b/drivers/video/backlight/aat2870_bl.c @@ -149,8 +149,6 @@ static int aat2870_bl_probe(struct platform_device *pdev) sizeof(struct aat2870_bl_driver_data), GFP_KERNEL); if (!aat2870_bl) { - dev_err(&pdev->dev, - "Failed to allocate memory for aat2870 backlight\n"); ret = -ENOMEM; goto out; } -- cgit v1.2.3 From ba464d0c88af59ccd35929eff010747de0fb0dec Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:48:57 -0700 Subject: backlight: adp8860: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Michael Hennerich Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/adp8860_bl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 9d656717d0f7..be8d83deca7d 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -224,10 +224,8 @@ static int adp8860_led_probe(struct i2c_client *client) led = devm_kzalloc(&client->dev, sizeof(*led) * pdata->num_leds, GFP_KERNEL); - if (led == NULL) { - dev_err(&client->dev, "failed to alloc memory\n"); + if (led == NULL) return -ENOMEM; - } ret = adp8860_write(client, ADP8860_ISCFR, pdata->led_fade_law); ret = adp8860_write(client, ADP8860_ISCT1, -- cgit v1.2.3 From 0167a956984e4ef1963fb76aa8bcd9481491d2f4 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:48:58 -0700 Subject: backlight: adp8870: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Michael Hennerich Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/adp8870_bl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 63707205326b..251af4d38d86 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -246,10 +246,8 @@ static int adp8870_led_probe(struct i2c_client *client) led = devm_kzalloc(&client->dev, pdata->num_leds * sizeof(*led), GFP_KERNEL); - if (led == NULL) { - dev_err(&client->dev, "failed to alloc memory\n"); + if (led == NULL) return -ENOMEM; - } ret = adp8870_write(client, ADP8870_ISCLAW, pdata->led_fade_law); if (ret) -- cgit v1.2.3 From 3b20b894d4b3424824c8138e564d6f97bea0f114 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:48:59 -0700 Subject: backlight: corgi_lcd: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/corgi_lcd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index db8db5fa6583..51d18d637e2b 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -543,10 +543,8 @@ static int corgi_lcd_probe(struct spi_device *spi) } lcd = devm_kzalloc(&spi->dev, sizeof(struct corgi_lcd), GFP_KERNEL); - if (!lcd) { - dev_err(&spi->dev, "failed to allocate memory\n"); + if (!lcd) return -ENOMEM; - } lcd->spi_dev = spi; -- cgit v1.2.3 From aff70f9ab1c3c1ce47ccc1b65880195be1dab8d4 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:00 -0700 Subject: backlight: hx8357: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Maxime Ripard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/hx8357.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/hx8357.c b/drivers/video/backlight/hx8357.c index 985e854e244b..23f50b92a930 100644 --- a/drivers/video/backlight/hx8357.c +++ b/drivers/video/backlight/hx8357.c @@ -587,10 +587,8 @@ static int hx8357_probe(struct spi_device *spi) int i, ret; lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) { - dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n"); + if (!lcd) return -ENOMEM; - } ret = spi_setup(spi); if (ret < 0) { -- cgit v1.2.3 From 619e1b491b7065d5db6d547be12a8d073825e992 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:01 -0700 Subject: backlight: ili922x: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Stefano Babic Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/ili922x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/ili922x.c b/drivers/video/backlight/ili922x.c index 73464e4b4c74..ea67fe199e34 100644 --- a/drivers/video/backlight/ili922x.c +++ b/drivers/video/backlight/ili922x.c @@ -482,10 +482,8 @@ static int ili922x_probe(struct spi_device *spi) u16 reg = 0; ili = devm_kzalloc(&spi->dev, sizeof(*ili), GFP_KERNEL); - if (!ili) { - dev_err(&spi->dev, "cannot alloc priv data\n"); + if (!ili) return -ENOMEM; - } ili->spi = spi; spi_set_drvdata(spi, ili); -- cgit v1.2.3 From a82bdcfb3ba25843320cde0aa624532e90fa2c43 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:02 -0700 Subject: backlight: ili9320: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/ili9320.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c index e2b8b40a9bd9..2cf39e6d519d 100644 --- a/drivers/video/backlight/ili9320.c +++ b/drivers/video/backlight/ili9320.c @@ -219,10 +219,8 @@ int ili9320_probe_spi(struct spi_device *spi, /* allocate and initialse our state */ ili = devm_kzalloc(&spi->dev, sizeof(struct ili9320), GFP_KERNEL); - if (ili == NULL) { - dev_err(dev, "no memory for device\n"); + if (ili == NULL) return -ENOMEM; - } ili->access.spi.id = ILI9320_SPI_IDCODE | ILI9320_SPI_ID(1); -- cgit v1.2.3 From 1bd04820b921b4aac9a8793388b0c14607cd860a Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:02 -0700 Subject: backlight: l4f00242t03: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/l4f00242t03.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 63e763828e0e..5fa2649c9631 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -181,11 +181,8 @@ static int l4f00242t03_probe(struct spi_device *spi) priv = devm_kzalloc(&spi->dev, sizeof(struct l4f00242t03_priv), GFP_KERNEL); - - if (priv == NULL) { - dev_err(&spi->dev, "No memory for this device.\n"); + if (priv == NULL) return -ENOMEM; - } spi_set_drvdata(spi, priv); spi->bits_per_word = 9; -- cgit v1.2.3 From 44d516f99b96d6e55868fd4e87679f1cef6f1344 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:03 -0700 Subject: backlight: lm3533_bl: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Johan Hovold Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/lm3533_bl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c index 187d1c283c1d..cff1fbe89a1b 100644 --- a/drivers/video/backlight/lm3533_bl.c +++ b/drivers/video/backlight/lm3533_bl.c @@ -296,11 +296,8 @@ static int lm3533_bl_probe(struct platform_device *pdev) } bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL); - if (!bl) { - dev_err(&pdev->dev, - "failed to allocate memory for backlight\n"); + if (!bl) return -ENOMEM; - } bl->lm3533 = lm3533; bl->id = pdev->id; -- cgit v1.2.3 From e1094f9f74cc728c06160a2600e77a25bc5fac68 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:04 -0700 Subject: backlight: lms283gf05: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Marek Vasut Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/lms283gf05.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c index de8832504f68..14590c54aedf 100644 --- a/drivers/video/backlight/lms283gf05.c +++ b/drivers/video/backlight/lms283gf05.c @@ -168,10 +168,8 @@ static int lms283gf05_probe(struct spi_device *spi) st = devm_kzalloc(&spi->dev, sizeof(struct lms283gf05_state), GFP_KERNEL); - if (st == NULL) { - dev_err(&spi->dev, "No memory for device state\n"); + if (st == NULL) return -ENOMEM; - } ld = devm_lcd_device_register(&spi->dev, "lms283gf05", &spi->dev, st, &lms_ops); -- cgit v1.2.3 From c6915be435f93d725cd158d1a70251d3ff70737e Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:05 -0700 Subject: backlight: platform_lcd: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/platform_lcd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index d01884d4f1bf..c3d2e209fc8f 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -94,10 +94,8 @@ static int platform_lcd_probe(struct platform_device *pdev) plcd = devm_kzalloc(&pdev->dev, sizeof(struct platform_lcd), GFP_KERNEL); - if (!plcd) { - dev_err(dev, "no memory for state\n"); + if (!plcd) return -ENOMEM; - } plcd->us = dev; plcd->pdata = pdata; -- cgit v1.2.3 From 3d8e4b401cdf6fcfdd1a897f585c88afc2e386c7 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:06 -0700 Subject: backlight: tps65217_bl: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/tps65217_bl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c index cbba37e6836e..595dcf561020 100644 --- a/drivers/video/backlight/tps65217_bl.c +++ b/drivers/video/backlight/tps65217_bl.c @@ -200,7 +200,6 @@ tps65217_bl_parse_dt(struct platform_device *pdev) pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dev_err(&pdev->dev, "failed to allocate platform data\n"); err = ERR_PTR(-ENOMEM); goto err; } @@ -296,10 +295,8 @@ static int tps65217_bl_probe(struct platform_device *pdev) tps65217_bl = devm_kzalloc(&pdev->dev, sizeof(*tps65217_bl), GFP_KERNEL); - if (tps65217_bl == NULL) { - dev_err(&pdev->dev, "allocation of struct tps65217_bl failed\n"); + if (tps65217_bl == NULL) return -ENOMEM; - } tps65217_bl->tps = tps; tps65217_bl->dev = &pdev->dev; -- cgit v1.2.3 From 4071ea25cc08d41002746cca2d69ac700d67a2ac Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Thu, 3 Apr 2014 14:49:36 -0700 Subject: rtc: fix potential race condition RTC drivers must not return an error after device registration. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Alessandro Zummo Reported-by: Ales Novak Cc: Alexander Shiyan Cc: Atsushi Nemoto Cc: Jiri Kosina Cc: Srikanth Srinivasan Cc: Lee Jones Cc: Sascha Hauer Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1305.c | 10 ++++---- drivers/rtc/rtc-ds1307.c | 60 ++++++++++++++++++++++++++---------------------- drivers/rtc/rtc-ds1511.c | 18 ++++++++------- drivers/rtc/rtc-ds1553.c | 18 ++++++++------- drivers/rtc/rtc-ds1672.c | 11 ++++----- drivers/rtc/rtc-ds1742.c | 5 +++- drivers/rtc/rtc-ds3232.c | 2 -- drivers/rtc/rtc-test.c | 9 +++----- drivers/rtc/rtc-x1205.c | 2 +- 9 files changed, 70 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 2dd586a19b59..129add77065d 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -756,19 +756,17 @@ static int ds1305_probe(struct spi_device *spi) status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq, 0, dev_name(&ds1305->rtc->dev), ds1305); if (status < 0) { - dev_dbg(&spi->dev, "request_irq %d --> %d\n", + dev_err(&spi->dev, "request_irq %d --> %d\n", spi->irq, status); - return status; + } else { + device_set_wakeup_capable(&spi->dev, 1); } - - device_set_wakeup_capable(&spi->dev, 1); } /* export NVRAM */ status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); if (status < 0) { - dev_dbg(&spi->dev, "register nvram --> %d\n", status); - return status; + dev_err(&spi->dev, "register nvram --> %d\n", status); } return 0; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 4e75345a559a..9e2aad68f96d 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -930,52 +930,58 @@ read_rtc: ds1307->rtc = devm_rtc_device_register(&client->dev, client->name, &ds13xx_rtc_ops, THIS_MODULE); if (IS_ERR(ds1307->rtc)) { - err = PTR_ERR(ds1307->rtc); - dev_err(&client->dev, - "unable to register the class device\n"); - goto exit; + return PTR_ERR(ds1307->rtc); } if (want_irq) { err = request_irq(client->irq, ds1307_irq, IRQF_SHARED, ds1307->rtc->name, client); if (err) { - dev_err(&client->dev, - "unable to request IRQ!\n"); - goto exit; - } + client->irq = 0; + dev_err(&client->dev, "unable to request IRQ!\n"); + } else { - device_set_wakeup_capable(&client->dev, 1); - set_bit(HAS_ALARM, &ds1307->flags); - dev_dbg(&client->dev, "got IRQ %d\n", client->irq); + device_set_wakeup_capable(&client->dev, 1); + set_bit(HAS_ALARM, &ds1307->flags); + dev_dbg(&client->dev, "got IRQ %d\n", client->irq); + } } if (chip->nvram_size) { + ds1307->nvram = devm_kzalloc(&client->dev, sizeof(struct bin_attribute), GFP_KERNEL); if (!ds1307->nvram) { - err = -ENOMEM; - goto err_irq; + dev_err(&client->dev, "cannot allocate memory for nvram sysfs\n"); + } else { + + ds1307->nvram->attr.name = "nvram"; + ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; + + sysfs_bin_attr_init(ds1307->nvram); + + ds1307->nvram->read = ds1307_nvram_read; + ds1307->nvram->write = ds1307_nvram_write; + ds1307->nvram->size = chip->nvram_size; + ds1307->nvram_offset = chip->nvram_offset; + + err = sysfs_create_bin_file(&client->dev.kobj, + ds1307->nvram); + if (err) { + dev_err(&client->dev, + "unable to create sysfs file: %s\n", + ds1307->nvram->attr.name); + } else { + set_bit(HAS_NVRAM, &ds1307->flags); + dev_info(&client->dev, "%zu bytes nvram\n", + ds1307->nvram->size); + } } - ds1307->nvram->attr.name = "nvram"; - ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; - sysfs_bin_attr_init(ds1307->nvram); - ds1307->nvram->read = ds1307_nvram_read; - ds1307->nvram->write = ds1307_nvram_write; - ds1307->nvram->size = chip->nvram_size; - ds1307->nvram_offset = chip->nvram_offset; - err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram); - if (err) - goto err_irq; - set_bit(HAS_NVRAM, &ds1307->flags); - dev_info(&client->dev, "%zu bytes nvram\n", ds1307->nvram->size); } return 0; -err_irq: - free_irq(client->irq, client); exit: return err; } diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index bc7b4fcf603c..4ff20f9dc212 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -473,7 +473,6 @@ static struct bin_attribute ds1511_nvram_attr = { static int ds1511_rtc_probe(struct platform_device *pdev) { - struct rtc_device *rtc; struct resource *res; struct rtc_plat_data *pdata; int ret = 0; @@ -512,6 +511,12 @@ static int ds1511_rtc_probe(struct platform_device *pdev) spin_lock_init(&pdata->lock); platform_set_drvdata(pdev, pdata); + + pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &ds1511_rtc_ops, THIS_MODULE); + if (IS_ERR(pdata->rtc)) + return PTR_ERR(pdata->rtc); + /* * if the platform has an interrupt in mind for this device, * then by all means, set it @@ -526,15 +531,12 @@ static int ds1511_rtc_probe(struct platform_device *pdev) } } - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &ds1511_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - pdata->rtc = rtc; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); + if (ret) + dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", + ds1511_nvram_attr.attr.name); - return ret; + return 0; } static int ds1511_rtc_remove(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index fd31571941f5..9ac2fa07dffa 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -278,7 +278,6 @@ static struct bin_attribute ds1553_nvram_attr = { static int ds1553_rtc_probe(struct platform_device *pdev) { - struct rtc_device *rtc; struct resource *res; unsigned int cen, sec; struct rtc_plat_data *pdata; @@ -311,6 +310,12 @@ static int ds1553_rtc_probe(struct platform_device *pdev) spin_lock_init(&pdata->lock); pdata->last_jiffies = jiffies; platform_set_drvdata(pdev, pdata); + + pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &ds1553_rtc_ops, THIS_MODULE); + if (IS_ERR(pdata->rtc)) + return PTR_ERR(pdata->rtc); + if (pdata->irq > 0) { writeb(0, ioaddr + RTC_INTERRUPTS); if (devm_request_irq(&pdev->dev, pdata->irq, @@ -321,15 +326,12 @@ static int ds1553_rtc_probe(struct platform_device *pdev) } } - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &ds1553_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - pdata->rtc = rtc; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); + if (ret) + dev_err(&pdev->dev, "unable to create sysfs file: %s\n", + ds1553_nvram_attr.attr.name); - return ret; + return 0; } static int ds1553_rtc_remove(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 18e2d8471472..a4888dbca2e1 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -177,8 +177,9 @@ static int ds1672_probe(struct i2c_client *client, /* read control register */ err = ds1672_get_control(client, &control); - if (err) - goto exit_devreg; + if (err) { + dev_warn(&client->dev, "Unable to read the control register\n"); + } if (control & DS1672_REG_CONTROL_EOSC) dev_warn(&client->dev, "Oscillator not enabled. " @@ -187,12 +188,10 @@ static int ds1672_probe(struct i2c_client *client, /* Register sysfs hooks */ err = device_create_file(&client->dev, &dev_attr_control); if (err) - goto exit_devreg; + dev_err(&client->dev, "Unable to create sysfs entry: %s\n", + dev_attr_control.attr.name); return 0; - - exit_devreg: - return err; } static struct i2c_device_id ds1672_id[] = { diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 5a1f3b2a8f1e..942103dac30f 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -204,8 +204,11 @@ static int ds1742_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc); ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); + if (ret) + dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", + pdata->nvram_attr.attr.name); - return ret; + return 0; } static int ds1742_rtc_remove(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index b83bb5a527f8..15497c578af5 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -414,7 +414,6 @@ static int ds3232_probe(struct i2c_client *client, ds3232->rtc = devm_rtc_device_register(&client->dev, client->name, &ds3232_rtc_ops, THIS_MODULE); if (IS_ERR(ds3232->rtc)) { - dev_err(&client->dev, "unable to register the class device\n"); return PTR_ERR(ds3232->rtc); } @@ -423,7 +422,6 @@ static int ds3232_probe(struct i2c_client *client, "ds3232", client); if (ret) { dev_err(&client->dev, "unable to request IRQ\n"); - return ret; } } diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 7746e65b93f2..6599c20bc454 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -104,20 +104,17 @@ static int test_probe(struct platform_device *plat_dev) rtc = devm_rtc_device_register(&plat_dev->dev, "test", &test_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - return err; + return PTR_ERR(rtc); } err = device_create_file(&plat_dev->dev, &dev_attr_irq); if (err) - goto err; + dev_err(&plat_dev->dev, "Unable to create sysfs entry: %s\n", + dev_attr_irq.attr.name); platform_set_drvdata(plat_dev, rtc); return 0; - -err: - return err; } static int test_remove(struct platform_device *plat_dev) diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 365dc6505148..b1de58e0b3d0 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -660,7 +660,7 @@ static int x1205_probe(struct i2c_client *client, err = x1205_sysfs_register(&client->dev); if (err) - return err; + dev_err(&client->dev, "Unable to create sysfs entries\n"); return 0; } -- cgit v1.2.3 From 3378f73da2d7fb765240dbf348cad11648c5b775 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 3 Apr 2014 14:49:38 -0700 Subject: drivers/rtc/rtc-imxdi.c: check the return value from clk_prepare_enable() clk_prepare_enable() may fail, so let's check its return value and propagate it in the case of error. Signed-off-by: Fabio Estevam Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-imxdi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index abd7f9091f34..cd741c77e085 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -401,7 +401,9 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) imxdi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(imxdi->clk)) return PTR_ERR(imxdi->clk); - clk_prepare_enable(imxdi->clk); + rc = clk_prepare_enable(imxdi->clk); + if (rc) + return rc; /* * Initialize dryice hardware -- cgit v1.2.3 From 61dba62506491d83ee9bfd86aee7f7b6e9622d49 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:38 -0700 Subject: rtc: rtc-at32ap700x: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Hans-Christian Egtvedt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-at32ap700x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 3161ab5263ed..aee3387fb099 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c @@ -204,10 +204,8 @@ static int __init at32_rtc_probe(struct platform_device *pdev) rtc = devm_kzalloc(&pdev->dev, sizeof(struct rtc_at32ap700x), GFP_KERNEL); - if (!rtc) { - dev_dbg(&pdev->dev, "out of memory\n"); + if (!rtc) return -ENOMEM; - } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) { -- cgit v1.2.3 From a3080fa7ec028dca0ac24399e19292bcf4feaf6c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:39 -0700 Subject: rtc: rtc-davinci: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-davinci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 24677ef8c39a..1f3495e4e634 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -486,10 +486,8 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) int ret = 0; davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL); - if (!davinci_rtc) { - dev_dbg(dev, "could not allocate memory for private data\n"); + if (!davinci_rtc) return -ENOMEM; - } davinci_rtc->irq = platform_get_irq(pdev, 0); if (davinci_rtc->irq < 0) { -- cgit v1.2.3 From 7841fe5396a33eaa7fd180dbed6f551a92657435 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:40 -0700 Subject: rtc: rtc-ds1390: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1390.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index be9d8c0a7e3a..e67bfcb3a1aa 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -132,10 +132,9 @@ static int ds1390_probe(struct spi_device *spi) spi_setup(spi); chip = devm_kzalloc(&spi->dev, sizeof(*chip), GFP_KERNEL); - if (!chip) { - dev_err(&spi->dev, "unable to allocate device memory\n"); + if (!chip) return -ENOMEM; - } + spi_set_drvdata(spi, chip); res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); -- cgit v1.2.3 From 4410af6e7eef106d21b6698d507661b546b25cfa Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:41 -0700 Subject: rtc: rtc-moxart: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-moxart.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-moxart.c b/drivers/rtc/rtc-moxart.c index c29dee0946e6..c31846238871 100644 --- a/drivers/rtc/rtc-moxart.c +++ b/drivers/rtc/rtc-moxart.c @@ -247,10 +247,8 @@ static int moxart_rtc_probe(struct platform_device *pdev) int ret = 0; moxart_rtc = devm_kzalloc(&pdev->dev, sizeof(*moxart_rtc), GFP_KERNEL); - if (!moxart_rtc) { - dev_err(&pdev->dev, "devm_kzalloc failed\n"); + if (!moxart_rtc) return -ENOMEM; - } moxart_rtc->gpio_data = of_get_named_gpio(pdev->dev.of_node, "gpio-rtc-data", 0); -- cgit v1.2.3 From ee567199941245e1d3f7b8df0113d1077e78ce0b Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:42 -0700 Subject: rtc: rtc-nuc900: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-nuc900.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index 248653c74b80..a53da0958e95 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -229,10 +229,9 @@ static int __init nuc900_rtc_probe(struct platform_device *pdev) nuc900_rtc = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_rtc), GFP_KERNEL); - if (!nuc900_rtc) { - dev_err(&pdev->dev, "kzalloc nuc900_rtc failed\n"); + if (!nuc900_rtc) return -ENOMEM; - } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); nuc900_rtc->rtc_reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(nuc900_rtc->rtc_reg)) -- cgit v1.2.3 From 49ae425b8273d0856ffef41df51a1d1bdd06d0d0 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:43 -0700 Subject: rtc: rtc-pm8xxx: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pm8xxx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 03f8f75d5af2..bd76ffe92784 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -396,10 +396,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) rtc_write_enable = pdata->rtc_write_enable; rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL); - if (rtc_dd == NULL) { - dev_err(&pdev->dev, "Unable to allocate memory!\n"); + if (rtc_dd == NULL) return -ENOMEM; - } /* Initialise spinlock to protect RTC control register */ spin_lock_init(&rtc_dd->ctrl_reg_lock); -- cgit v1.2.3 From 147a9855364dcd5271338c4fe0707b2d670d103d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:44 -0700 Subject: rtc: rtc-rx8025: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-rx8025.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 8fa23eabcb68..e6298e02b400 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -551,7 +551,6 @@ static int rx8025_probe(struct i2c_client *client, rx8025 = devm_kzalloc(&client->dev, sizeof(*rx8025), GFP_KERNEL); if (!rx8025) { - dev_err(&adapter->dev, "failed to alloc memory\n"); err = -ENOMEM; goto errout; } -- cgit v1.2.3 From 98e2d21faaf96d879e2746cedd96f5c38c04f9b3 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:45 -0700 Subject: rtc: rtc-sirfsoc: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Barry Song Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-sirfsoc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index 3eb3642ae299..9e3cbce56ec1 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -264,12 +264,8 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev) rtcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL); - if (rtcdrv == NULL) { - dev_err(&pdev->dev, - "%s: can't alloc mem for drv struct\n", - pdev->name); + if (rtcdrv == NULL) return -ENOMEM; - } err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base); if (err) { -- cgit v1.2.3 From 5c336b0a7a7636d81e9960bea29574e561df4d74 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:46 -0700 Subject: rtc: rtc-lpc32xx: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-lpc32xx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index bfdbcb82d069..f130c08c98f8 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c @@ -211,10 +211,9 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev) } rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); - if (unlikely(!rtc)) { - dev_err(&pdev->dev, "Can't allocate memory\n"); + if (unlikely(!rtc)) return -ENOMEM; - } + rtc->irq = rtcirq; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.3 From 681acc9f53210f8a4c1b280b077f2cd73e63ac4c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:46 -0700 Subject: rtc: rtc-spear: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Viresh Kumar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-spear.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index c492cf0ab8cd..d2cdb9823a15 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -365,10 +365,8 @@ static int spear_rtc_probe(struct platform_device *pdev) } config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); - if (!config) { - dev_err(&pdev->dev, "out of memory\n"); + if (!config) return -ENOMEM; - } /* alarm irqs */ irq = platform_get_irq(pdev, 0); -- cgit v1.2.3 From daaf90f0b014106e5672381c7b576a149b346dd9 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:47 -0700 Subject: rtc: rtc-coh901331: use devm_ioremap_resource() Use devm_ioremap_resource() in order to make the code simpler, and remove redundant return value check of platform_get_resource() because the value is checked by devm_ioremap_resource(). Signed-off-by: Jingoo Han Acked-by: Linus Walleij Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-coh901331.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 73f157519dff..869cae273799 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -43,8 +43,6 @@ struct coh901331_port { struct rtc_device *rtc; struct clk *clk; - u32 phybase; - u32 physize; void __iomem *virtbase; int irq; #ifdef CONFIG_PM_SLEEP @@ -173,19 +171,9 @@ static int __init coh901331_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENOENT; - - rtap->phybase = res->start; - rtap->physize = resource_size(res); - - if (devm_request_mem_region(&pdev->dev, rtap->phybase, rtap->physize, - "rtc-coh901331") == NULL) - return -EBUSY; - - rtap->virtbase = devm_ioremap(&pdev->dev, rtap->phybase, rtap->physize); - if (!rtap->virtbase) - return -ENOMEM; + rtap->virtbase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rtap->virtbase)) + return PTR_ERR(rtap->virtbase); rtap->irq = platform_get_irq(pdev, 0); if (devm_request_irq(&pdev->dev, rtap->irq, coh901331_interrupt, 0, -- cgit v1.2.3 From 1e6789f6e2e2b1645527d08832bfb95982da17ff Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:48 -0700 Subject: rtc: rtc-davinci: use devm_ioremap_resource() Use devm_ioremap_resource() in order to make the code simpler, and remove redundant return value check of platform_get_resource() because the value is checked by devm_ioremap_resource(). Signed-off-by: Jingoo Han Cc: Kevin Hilman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-davinci.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 1f3495e4e634..c0a3b59f65a2 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -119,8 +119,6 @@ static DEFINE_SPINLOCK(davinci_rtc_lock); struct davinci_rtc { struct rtc_device *rtc; void __iomem *base; - resource_size_t pbase; - size_t base_size; int irq; }; @@ -482,7 +480,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct davinci_rtc *davinci_rtc; - struct resource *res, *mem; + struct resource *res; int ret = 0; davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL); @@ -496,28 +494,9 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "no mem resource\n"); - return -EINVAL; - } - - davinci_rtc->pbase = res->start; - davinci_rtc->base_size = resource_size(res); - - mem = devm_request_mem_region(dev, davinci_rtc->pbase, - davinci_rtc->base_size, pdev->name); - if (!mem) { - dev_err(dev, "RTC registers at %08x are not free\n", - davinci_rtc->pbase); - return -EBUSY; - } - - davinci_rtc->base = devm_ioremap(dev, davinci_rtc->pbase, - davinci_rtc->base_size); - if (!davinci_rtc->base) { - dev_err(dev, "unable to ioremap MEM resource\n"); - return -ENOMEM; - } + davinci_rtc->base = devm_ioremap_resource(dev, res); + if (IS_ERR(davinci_rtc->base)) + return PTR_ERR(davinci_rtc->base); platform_set_drvdata(pdev, davinci_rtc); -- cgit v1.2.3 From caa3af259d5439e28c6ed1fc0efbed994146e403 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:49 -0700 Subject: rtc: rtc-vt8500: use devm_ioremap_resource() Use devm_ioremap_resource() in order to make the code simpler, and move 'struct resource *res' from 'struct vt8500_rtc' to vt8500_rtc_probe() because the 'res' variable is used only in vt8500_rtc_probe(). Signed-off-by: Jingoo Han Cc: Tony Prisk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-vt8500.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index df2ef3eba7cd..051da968da6d 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -79,7 +79,6 @@ struct vt8500_rtc { void __iomem *regbase; - struct resource *res; int irq_alarm; struct rtc_device *rtc; spinlock_t lock; /* Protects this structure */ @@ -209,6 +208,7 @@ static const struct rtc_class_ops vt8500_rtc_ops = { static int vt8500_rtc_probe(struct platform_device *pdev) { struct vt8500_rtc *vt8500_rtc; + struct resource *res; int ret; vt8500_rtc = devm_kzalloc(&pdev->dev, @@ -219,34 +219,16 @@ static int vt8500_rtc_probe(struct platform_device *pdev) spin_lock_init(&vt8500_rtc->lock); platform_set_drvdata(pdev, vt8500_rtc); - vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!vt8500_rtc->res) { - dev_err(&pdev->dev, "No I/O memory resource defined\n"); - return -ENXIO; - } - vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0); if (vt8500_rtc->irq_alarm < 0) { dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); return vt8500_rtc->irq_alarm; } - vt8500_rtc->res = devm_request_mem_region(&pdev->dev, - vt8500_rtc->res->start, - resource_size(vt8500_rtc->res), - "vt8500-rtc"); - if (vt8500_rtc->res == NULL) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - return -EBUSY; - } - - vt8500_rtc->regbase = devm_ioremap(&pdev->dev, vt8500_rtc->res->start, - resource_size(vt8500_rtc->res)); - if (!vt8500_rtc->regbase) { - dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); - ret = -EBUSY; - goto err_return; - } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + vt8500_rtc->regbase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(vt8500_rtc->regbase)) + return PTR_ERR(vt8500_rtc->regbase); /* Enable RTC and set it to 24-hour mode */ writel(VT8500_RTC_CR_ENABLE, -- cgit v1.2.3 From 3b6aa907f316a51345987327083aa266870d06cc Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:49:50 -0700 Subject: rtc: rtc-jz4740: use devm_ioremap_resource() Use devm_ioremap_resource() in order to make the code simpler, and move 'struct resource *mem' from 'struct jz4740_rtc' to jz4740_rtc_probe() because the 'mem' variable is used only in jz4740_rtc_probe(). Also the redundant return value check of platform_get_resource() is removed, because the value is checked by devm_ioremap_resource(). Signed-off-by: Jingoo Han Cc: Lars-Peter Clausen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-jz4740.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 1b126d2513de..08f5160fb6d4 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -38,7 +38,6 @@ #define JZ_RTC_CTRL_ENABLE BIT(0) struct jz4740_rtc { - struct resource *mem; void __iomem *base; struct rtc_device *rtc; @@ -216,6 +215,7 @@ static int jz4740_rtc_probe(struct platform_device *pdev) int ret; struct jz4740_rtc *rtc; uint32_t scratchpad; + struct resource *mem; rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) @@ -227,25 +227,10 @@ static int jz4740_rtc_probe(struct platform_device *pdev) return -ENOENT; } - rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!rtc->mem) { - dev_err(&pdev->dev, "Failed to get platform mmio memory\n"); - return -ENOENT; - } - - rtc->mem = devm_request_mem_region(&pdev->dev, rtc->mem->start, - resource_size(rtc->mem), pdev->name); - if (!rtc->mem) { - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - return -EBUSY; - } - - rtc->base = devm_ioremap_nocache(&pdev->dev, rtc->mem->start, - resource_size(rtc->mem)); - if (!rtc->base) { - dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); - return -EBUSY; - } + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rtc->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(rtc->base)) + return PTR_ERR(rtc->base); spin_lock_init(&rtc->lock); -- cgit v1.2.3 From 7b8dc3eb678304420c09135fe0576bea65b7b08f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 3 Apr 2014 14:49:51 -0700 Subject: drivers/rtc/rtc-isl12057.c: remove duplicate include linux/rtc.h was included twice. Signed-off-by: Sachin Kamat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-isl12057.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c index 7854a656628f..7e5ead936a04 100644 --- a/drivers/rtc/rtc-isl12057.c +++ b/drivers/rtc/rtc-isl12057.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From c2c0eed7f20cbfb20b346f1854afaf485bc6c207 Mon Sep 17 00:00:00 2001 From: Anthony Olech Date: Thu, 3 Apr 2014 14:49:52 -0700 Subject: drivers/rtc/rtc-da9052.c: remove redundant private structure field Remove redundant irq field in private rtc structure. Signed-off-by: Anthony Olech Acked-by: David Dajun Chen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-da9052.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 4385ca4503da..a1cbf64242a5 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -26,7 +26,6 @@ struct da9052_rtc { struct rtc_device *rtc; struct da9052 *da9052; - int irq; }; static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable) @@ -240,8 +239,7 @@ static int da9052_rtc_probe(struct platform_device *pdev) rtc->da9052 = dev_get_drvdata(pdev->dev.parent); platform_set_drvdata(pdev, rtc); - rtc->irq = DA9052_IRQ_ALARM; - ret = da9052_request_irq(rtc->da9052, rtc->irq, "ALM", + ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM", da9052_rtc_irq, rtc); if (ret != 0) { rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); -- cgit v1.2.3 From 3916b09eed268705f738957aba6fd380470e994a Mon Sep 17 00:00:00 2001 From: Xianglong Du Date: Thu, 3 Apr 2014 14:49:53 -0700 Subject: drivers/rtc/rtc-sirfsoc.c: fix kernel panic of backing from hibernation RTC settings will be lost if power supply is cut off after hibernation finished, but the current "restore" function does not restore RTC related settings, this causes rtc_read_time failure and kernel panic: rtc rtc0: **** DPM device timeout **** Stack trace: unwind_backtrace+0x0/0xf4 show_stack+0x10/0x14 dpm_wd_handler+0x24/0x28 call_timer_fn.isra.33+0x24/0x88 run_timer_softirq+0x178/0x1f0 __do_softirq+0x120/0x200 do_softirq+0x54/0x5c irq_exit+0x9c/0xd0 handle_IRQ+0x44/0x90 __irq_svc+0x40/0x70 _raw_spin_unlock_irqrestore+0x10/0x48 sirfsoc_rtc_iobrg_readl+0x34/0x3c sirfsoc_rtc_read_time+0x24/0x48 __rtc_read_time.isra.3+0x48/0x5c rtc_read_time+0x30/0x44 rtc_resume.part.9+0x20/0x104 rtc_resume+0x5c/0x64 dpm_run_callback.isra.4+0x2c/0x74 device_resume+0x9c/0x144 dpm_resume+0x100/0x224 hibernation_snapshot+0x170/0x398 hibernate+0x13c/0x1d8 state_store+0xb4/0xb8 kobj_attr_store+0x14/0x20 sysfs_write_file+0x160/0x190 vfs_write+0xb4/0x194 SyS_write+0x3c/0x78 this patch uses SIMPLE_DEV_PM_OPS() to make restore() execute the existing resume() function which will restore the set of RTC. Signed-off-by: Xianglong Du Signed-off-by: Barry Song Cc: Grant Likely Cc: Rob Herring Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-sirfsoc.c | 62 +++++++---------------------------------------- 1 file changed, 9 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index 9e3cbce56ec1..76e38007ba90 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -331,39 +331,29 @@ static int sirfsoc_rtc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static int sirfsoc_rtc_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev); + struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev); rtcdrv->overflow_rtc = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); rtcdrv->saved_counter = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc; - if (device_may_wakeup(&pdev->dev) && !enable_irq_wake(rtcdrv->irq)) + if (device_may_wakeup(dev) && !enable_irq_wake(rtcdrv->irq)) rtcdrv->irq_wake = 1; return 0; } -static int sirfsoc_rtc_freeze(struct device *dev) -{ - sirfsoc_rtc_suspend(dev); - - return 0; -} - -static int sirfsoc_rtc_thaw(struct device *dev) +static int sirfsoc_rtc_resume(struct device *dev) { u32 tmp; - struct sirfsoc_rtc_drv *rtcdrv; - rtcdrv = dev_get_drvdata(dev); + struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev); /* - * if resume from snapshot and the rtc power is losed, + * if resume from snapshot and the rtc power is lost, * restroe the rtc settings */ if (SIRFSOC_RTC_CLK != sirfsoc_rtc_iobrg_readl( @@ -403,57 +393,23 @@ static int sirfsoc_rtc_thaw(struct device *dev) sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc, rtcdrv->rtc_base + RTC_SW_VALUE); - return 0; -} - -static int sirfsoc_rtc_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev); - sirfsoc_rtc_thaw(dev); - if (device_may_wakeup(&pdev->dev) && rtcdrv->irq_wake) { + if (device_may_wakeup(dev) && rtcdrv->irq_wake) { disable_irq_wake(rtcdrv->irq); rtcdrv->irq_wake = 0; } return 0; } - -static int sirfsoc_rtc_restore(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev); - - if (device_may_wakeup(&pdev->dev) && rtcdrv->irq_wake) { - disable_irq_wake(rtcdrv->irq); - rtcdrv->irq_wake = 0; - } - return 0; -} - -#else -#define sirfsoc_rtc_suspend NULL -#define sirfsoc_rtc_resume NULL -#define sirfsoc_rtc_freeze NULL -#define sirfsoc_rtc_thaw NULL -#define sirfsoc_rtc_restore NULL #endif -static const struct dev_pm_ops sirfsoc_rtc_pm_ops = { - .suspend = sirfsoc_rtc_suspend, - .resume = sirfsoc_rtc_resume, - .freeze = sirfsoc_rtc_freeze, - .thaw = sirfsoc_rtc_thaw, - .restore = sirfsoc_rtc_restore, -}; +static SIMPLE_DEV_PM_OPS(sirfsoc_rtc_pm_ops, + sirfsoc_rtc_suspend, sirfsoc_rtc_resume); static struct platform_driver sirfsoc_rtc_driver = { .driver = { .name = "sirfsoc-rtc", .owner = THIS_MODULE, -#ifdef CONFIG_PM .pm = &sirfsoc_rtc_pm_ops, -#endif .of_match_table = sirfsoc_rtc_of_match, }, .probe = sirfsoc_rtc_probe, -- cgit v1.2.3 From 5ea735144dd4d2716557ff62dbcc940d62d62208 Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Thu, 3 Apr 2014 14:49:54 -0700 Subject: drivers/rtc/rtc-ds1307.c: fix sysfs wakealarm attribute creation In order to allow the creation of the sysfs attribute wakealarm, this patch moves the device_set_wakeup_capable() call above the RTC device registration. Signed-off-by: Simon Guinot Cc: Jason Cooper Cc: Andrew Lunn Cc: Gregory Clement Cc: Sebastian Hesselbarth Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 9e2aad68f96d..f739be96cbc0 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -927,6 +927,7 @@ read_rtc: bin2bcd(tmp)); } + device_set_wakeup_capable(&client->dev, want_irq); ds1307->rtc = devm_rtc_device_register(&client->dev, client->name, &ds13xx_rtc_ops, THIS_MODULE); if (IS_ERR(ds1307->rtc)) { @@ -941,7 +942,6 @@ read_rtc: dev_err(&client->dev, "unable to request IRQ!\n"); } else { - device_set_wakeup_capable(&client->dev, 1); set_bit(HAS_ALARM, &ds1307->flags); dev_dbg(&client->dev, "got IRQ %d\n", client->irq); } -- cgit v1.2.3 From 1d1945d261a2af4e1ddaf609308c30b83143c2da Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Thu, 3 Apr 2014 14:49:55 -0700 Subject: drivers/rtc/rtc-ds1307.c: add alarm support for mcp7941x chips Add alarm support for the Microchip RTC devices MCP794xx. Note that two programmable alarms are provided by the chip but only one is used by the driver. Signed-off-by: Simon Guinot Cc: Jason Cooper Cc: Andrew Lunn Cc: Gregory Clement Cc: Sebastian Hesselbarth Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f739be96cbc0..f03d5ba96db1 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -154,6 +154,7 @@ static const struct chip_desc chips[last_ds_type] = { .alarm = 1, }, [mcp7941x] = { + .alarm = 1, /* this is battery backed SRAM */ .nvram_offset = 0x20, .nvram_size = 0x40, @@ -606,6 +607,178 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { /*----------------------------------------------------------------------*/ +/* + * Alarm support for mcp7941x devices. + */ + +#define MCP7941X_REG_CONTROL 0x07 +# define MCP7941X_BIT_ALM0_EN 0x10 +# define MCP7941X_BIT_ALM1_EN 0x20 +#define MCP7941X_REG_ALARM0_BASE 0x0a +#define MCP7941X_REG_ALARM0_CTRL 0x0d +#define MCP7941X_REG_ALARM1_BASE 0x11 +#define MCP7941X_REG_ALARM1_CTRL 0x14 +# define MCP7941X_BIT_ALMX_IF (1 << 3) +# define MCP7941X_BIT_ALMX_C0 (1 << 4) +# define MCP7941X_BIT_ALMX_C1 (1 << 5) +# define MCP7941X_BIT_ALMX_C2 (1 << 6) +# define MCP7941X_BIT_ALMX_POL (1 << 7) +# define MCP7941X_MSK_ALMX_MATCH (MCP7941X_BIT_ALMX_C0 | \ + MCP7941X_BIT_ALMX_C1 | \ + MCP7941X_BIT_ALMX_C2) + +static void mcp7941x_work(struct work_struct *work) +{ + struct ds1307 *ds1307 = container_of(work, struct ds1307, work); + struct i2c_client *client = ds1307->client; + int reg, ret; + + mutex_lock(&ds1307->rtc->ops_lock); + + /* Check and clear alarm 0 interrupt flag. */ + reg = i2c_smbus_read_byte_data(client, MCP7941X_REG_ALARM0_CTRL); + if (reg < 0) + goto out; + if (!(reg & MCP7941X_BIT_ALMX_IF)) + goto out; + reg &= ~MCP7941X_BIT_ALMX_IF; + ret = i2c_smbus_write_byte_data(client, MCP7941X_REG_ALARM0_CTRL, reg); + if (ret < 0) + goto out; + + /* Disable alarm 0. */ + reg = i2c_smbus_read_byte_data(client, MCP7941X_REG_CONTROL); + if (reg < 0) + goto out; + reg &= ~MCP7941X_BIT_ALM0_EN; + ret = i2c_smbus_write_byte_data(client, MCP7941X_REG_CONTROL, reg); + if (ret < 0) + goto out; + + rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF); + +out: + if (test_bit(HAS_ALARM, &ds1307->flags)) + enable_irq(client->irq); + mutex_unlock(&ds1307->rtc->ops_lock); +} + +static int mcp7941x_read_alarm(struct device *dev, struct rtc_wkalrm *t) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ds1307 *ds1307 = i2c_get_clientdata(client); + u8 *regs = ds1307->regs; + int ret; + + if (!test_bit(HAS_ALARM, &ds1307->flags)) + return -EINVAL; + + /* Read control and alarm 0 registers. */ + ret = ds1307->read_block_data(client, MCP7941X_REG_CONTROL, 10, regs); + if (ret < 0) + return ret; + + t->enabled = !!(regs[0] & MCP7941X_BIT_ALM0_EN); + + /* Report alarm 0 time assuming 24-hour and day-of-month modes. */ + t->time.tm_sec = bcd2bin(ds1307->regs[3] & 0x7f); + t->time.tm_min = bcd2bin(ds1307->regs[4] & 0x7f); + t->time.tm_hour = bcd2bin(ds1307->regs[5] & 0x3f); + t->time.tm_wday = bcd2bin(ds1307->regs[6] & 0x7) - 1; + t->time.tm_mday = bcd2bin(ds1307->regs[7] & 0x3f); + t->time.tm_mon = bcd2bin(ds1307->regs[8] & 0x1f) - 1; + t->time.tm_year = -1; + t->time.tm_yday = -1; + t->time.tm_isdst = -1; + + dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d " + "enabled=%d polarity=%d irq=%d match=%d\n", __func__, + t->time.tm_sec, t->time.tm_min, t->time.tm_hour, + t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled, + !!(ds1307->regs[6] & MCP7941X_BIT_ALMX_POL), + !!(ds1307->regs[6] & MCP7941X_BIT_ALMX_IF), + (ds1307->regs[6] & MCP7941X_MSK_ALMX_MATCH) >> 4); + + return 0; +} + +static int mcp7941x_set_alarm(struct device *dev, struct rtc_wkalrm *t) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ds1307 *ds1307 = i2c_get_clientdata(client); + unsigned char *regs = ds1307->regs; + int ret; + + if (!test_bit(HAS_ALARM, &ds1307->flags)) + return -EINVAL; + + dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d " + "enabled=%d pending=%d\n", __func__, + t->time.tm_sec, t->time.tm_min, t->time.tm_hour, + t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, + t->enabled, t->pending); + + /* Read control and alarm 0 registers. */ + ret = ds1307->read_block_data(client, MCP7941X_REG_CONTROL, 10, regs); + if (ret < 0) + return ret; + + /* Set alarm 0, using 24-hour and day-of-month modes. */ + regs[3] = bin2bcd(t->time.tm_sec); + regs[4] = bin2bcd(t->time.tm_min); + regs[5] = bin2bcd(t->time.tm_hour); + regs[6] = bin2bcd(t->time.tm_wday) + 1; + regs[7] = bin2bcd(t->time.tm_mday); + regs[8] = bin2bcd(t->time.tm_mon) + 1; + + /* Clear the alarm 0 interrupt flag. */ + regs[6] &= ~MCP7941X_BIT_ALMX_IF; + /* Set alarm match: second, minute, hour, day, date, month. */ + regs[6] |= MCP7941X_MSK_ALMX_MATCH; + + if (t->enabled) + regs[0] |= MCP7941X_BIT_ALM0_EN; + else + regs[0] &= ~MCP7941X_BIT_ALM0_EN; + + ret = ds1307->write_block_data(client, MCP7941X_REG_CONTROL, 10, regs); + if (ret < 0) + return ret; + + return 0; +} + +static int mcp7941x_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ds1307 *ds1307 = i2c_get_clientdata(client); + int reg; + + if (!test_bit(HAS_ALARM, &ds1307->flags)) + return -EINVAL; + + reg = i2c_smbus_read_byte_data(client, MCP7941X_REG_CONTROL); + if (reg < 0) + return reg; + + if (enabled) + reg |= MCP7941X_BIT_ALM0_EN; + else + reg &= ~MCP7941X_BIT_ALM0_EN; + + return i2c_smbus_write_byte_data(client, MCP7941X_REG_CONTROL, reg); +} + +static const struct rtc_class_ops mcp7941x_rtc_ops = { + .read_time = ds1307_get_time, + .set_time = ds1307_set_time, + .read_alarm = mcp7941x_read_alarm, + .set_alarm = mcp7941x_set_alarm, + .alarm_irq_enable = mcp7941x_alarm_irq_enable, +}; + +/*----------------------------------------------------------------------*/ + static ssize_t ds1307_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, @@ -678,6 +851,7 @@ static int ds1307_probe(struct i2c_client *client, [ds_1339] = DS1339_BIT_BBSQI, [ds_3231] = DS3231_BIT_BBSQW, }; + const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) @@ -816,6 +990,13 @@ static int ds1307_probe(struct i2c_client *client, case ds_1388: ds1307->offset = 1; /* Seconds starts at 1 */ break; + case mcp7941x: + rtc_ops = &mcp7941x_rtc_ops; + if (ds1307->client->irq > 0 && chip->alarm) { + INIT_WORK(&ds1307->work, mcp7941x_work); + want_irq = true; + } + break; default: break; } @@ -929,7 +1110,7 @@ read_rtc: device_set_wakeup_capable(&client->dev, want_irq); ds1307->rtc = devm_rtc_device_register(&client->dev, client->name, - &ds13xx_rtc_ops, THIS_MODULE); + rtc_ops, THIS_MODULE); if (IS_ERR(ds1307->rtc)) { return PTR_ERR(ds1307->rtc); } -- cgit v1.2.3 From 77bf2ea8de78ce7dd842409a847b888e720f62d8 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:49:56 -0700 Subject: rtc: mc13xxx: remove __exit_p() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we no longer allow building without hotplug, the mc13xxx_rtc_remove() function is always present and we should not use __exit_p() to refer to it. Signed-off-by: Alexander Shiyan Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mc13xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 77ea9896b5ba..480d51f71064 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -375,7 +375,7 @@ err_reset_irq_request: return ret; } -static int __exit mc13xxx_rtc_remove(struct platform_device *pdev) +static int mc13xxx_rtc_remove(struct platform_device *pdev) { struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); @@ -404,7 +404,7 @@ MODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable); static struct platform_driver mc13xxx_rtc_driver = { .id_table = mc13xxx_rtc_idtable, - .remove = __exit_p(mc13xxx_rtc_remove), + .remove = mc13xxx_rtc_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, -- cgit v1.2.3 From 589e501439f9866b4bc415743b0ae0bb9a461c69 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:49:57 -0700 Subject: rtc: mc13xxx: request IRQs after RTC registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Interrupts can appear after request_irq and interrupt handlers can use the RTC device, but currently we register RTC after IRQs. This patch changes this order and simplify error path a bit. Signed-off-by: Alexander Shiyan Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mc13xxx.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 480d51f71064..6b5d7d43af89 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -325,6 +325,11 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); + priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &mc13xxx_rtc_ops, THIS_MODULE); + if (IS_ERR(priv->rtc)) + return PTR_ERR(priv->rtc); + mc13xxx_lock(mc13xxx); ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, @@ -342,35 +347,20 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_1HZ, mc13xxx_rtc_update_handler, DRIVER_NAME, priv); if (ret) - goto err_update_irq_request; + goto err_reset_irq_status; ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA, mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv); - if (ret) - goto err_alarm_irq_request; - - mc13xxx_unlock(mc13xxx); - - priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &mc13xxx_rtc_ops, THIS_MODULE); - if (IS_ERR(priv->rtc)) { - ret = PTR_ERR(priv->rtc); - - mc13xxx_lock(mc13xxx); - - mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); -err_alarm_irq_request: + if (!ret) + goto err_reset_irq_request; - mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv); -err_update_irq_request: + mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv); err_reset_irq_status: + mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); - mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); err_reset_irq_request: - - mc13xxx_unlock(mc13xxx); - } + mc13xxx_unlock(mc13xxx); return ret; } -- cgit v1.2.3 From 2fb004a9b00e34908e59a1c1c5770910690a7588 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:49:58 -0700 Subject: rtc: mc13xxx: simplify alarm_irq_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes excess layer for alarm_irq_enable() function. Signed-off-by: Alexander Shiyan Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mc13xxx.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 6b5d7d43af89..1fa2748ab40e 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -42,15 +42,15 @@ static int mc13xxx_rtc_irq_enable_unlocked(struct device *dev, return func(priv->mc13xxx, irq); } -static int mc13xxx_rtc_irq_enable(struct device *dev, - unsigned int enabled, int irq) +static int mc13xxx_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); int ret; mc13xxx_lock(priv->mc13xxx); - ret = mc13xxx_rtc_irq_enable_unlocked(dev, enabled, irq); + ret = mc13xxx_rtc_irq_enable_unlocked(dev, enabled, MC13XXX_IRQ_TODA); mc13xxx_unlock(priv->mc13xxx); @@ -282,12 +282,6 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev) return IRQ_HANDLED; } -static int mc13xxx_rtc_alarm_irq_enable(struct device *dev, - unsigned int enabled) -{ - return mc13xxx_rtc_irq_enable(dev, enabled, MC13XXX_IRQ_TODA); -} - static const struct rtc_class_ops mc13xxx_rtc_ops = { .read_time = mc13xxx_rtc_read_time, .set_mmss = mc13xxx_rtc_set_mmss, -- cgit v1.2.3 From fb1bd9a22da3d0f2436ffa95fdc0382b89659288 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:49:59 -0700 Subject: rtc: mc13xxx: fix 1Hz interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1Hz interrupt is never unmasked, so no interrupts appears. This patch fix this issue. Signed-off-by: Alexander Shiyan Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mc13xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 1fa2748ab40e..0d60dd5273d1 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -338,7 +338,7 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) priv->valid = !rtcrst_pending; - ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_1HZ, + ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ, mc13xxx_rtc_update_handler, DRIVER_NAME, priv); if (ret) goto err_reset_irq_status; -- cgit v1.2.3 From 12de362108d5ec24cce1bbe520570dc8fdccca9c Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:50:00 -0700 Subject: rtc: mc13xxx: change RTC validation scheme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Datasheet says: "When the VSRTC voltage drops to the range of 0.9 - 0.8V, the RTCPORB reset signal is generated and the contents of the RTC will be reset. . To inform the processor that the contents of the RTC are no longer valid due to the reset, a timer reset interrupt function is implemented with the RTCRSTI bit." This patch makes the RTC valid by default until RTCRST interrupt occurs. Signed-off-by: Alexander Shiyan Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mc13xxx.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 0d60dd5273d1..7b39852eb542 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -64,12 +64,10 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) unsigned long s1970; int ret; - mc13xxx_lock(priv->mc13xxx); + if (!priv->valid) + return -ENODATA; - if (!priv->valid) { - ret = -ENODATA; - goto out; - } + mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); if (unlikely(ret)) @@ -154,11 +152,14 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) goto out; } - ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); - if (unlikely(ret)) - goto out; + if (!priv->valid) { + ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); + if (unlikely(ret)) + goto out; + + ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); + } - ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); out: priv->valid = !ret; @@ -295,7 +296,7 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) struct mc13xxx_rtc *priv = dev; struct mc13xxx *mc13xxx = priv->mc13xxx; - dev_dbg(&priv->rtc->dev, "RTCRST\n"); + dev_warn(&priv->rtc->dev, "Contents of the RTC are no longer valid\n"); priv->valid = 0; mc13xxx_irq_mask(mc13xxx, irq); @@ -308,7 +309,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) int ret; struct mc13xxx_rtc *priv; struct mc13xxx *mc13xxx; - int rtcrst_pending; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -316,6 +316,7 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) mc13xxx = dev_get_drvdata(pdev->dev.parent); priv->mc13xxx = mc13xxx; + priv->valid = 1; platform_set_drvdata(pdev, priv); @@ -326,18 +327,13 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) mc13xxx_lock(mc13xxx); + mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_RTCRST); + ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, mc13xxx_rtc_reset_handler, DRIVER_NAME, priv); if (ret) goto err_reset_irq_request; - ret = mc13xxx_irq_status(mc13xxx, MC13XXX_IRQ_RTCRST, - NULL, &rtcrst_pending); - if (ret) - goto err_reset_irq_status; - - priv->valid = !rtcrst_pending; - ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ, mc13xxx_rtc_update_handler, DRIVER_NAME, priv); if (ret) -- cgit v1.2.3 From 6a2b342228b98432a585c83d59ed6aa0620be7c4 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:50:01 -0700 Subject: rtc: mc13xxx: make rtc_read_time() more readable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unnecessary locks when reading the time and make the read operation until the values of day matched between reading the seconds, it will make the mc13xxx_rtc_read_time() procedure more readable. Additionally, patch introduced a "seconds in a day" definition. Signed-off-by: Alexander Shiyan Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mc13xxx.c | 59 ++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 7b39852eb542..9b1a77eb91a9 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -23,6 +23,8 @@ #define MC13XXX_RTCDAY 22 #define MC13XXX_RTCDAYA 23 +#define SEC_PER_DAY (24 * 60 * 60) + struct mc13xxx_rtc { struct rtc_device *rtc; struct mc13xxx *mc13xxx; @@ -61,42 +63,27 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days1, days2; - unsigned long s1970; - int ret; if (!priv->valid) return -ENODATA; - mc13xxx_lock(priv->mc13xxx); + do { + int ret; - ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); - if (unlikely(ret)) - goto out; - - ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); - if (unlikely(ret)) - goto out; - - ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); -out: - mc13xxx_unlock(priv->mc13xxx); - - if (ret) - return ret; - - if (days2 == days1 + 1) { - if (seconds >= 86400 / 2) - days2 = days1; - else - days1 = days2; - } + ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); + if (ret) + return ret; - if (days1 != days2) - return -EIO; + ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); + if (ret) + return ret; - s1970 = days1 * 86400 + seconds; + ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); + if (ret) + return ret; + } while (days1 != days2); - rtc_time_to_tm(s1970, tm); + rtc_time_to_tm(days1 * SEC_PER_DAY + seconds, tm); return rtc_valid_tm(tm); } @@ -108,8 +95,8 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) unsigned int alarmseconds; int ret; - seconds = secs % 86400; - days = secs / 86400; + seconds = secs % SEC_PER_DAY; + days = secs / SEC_PER_DAY; mc13xxx_lock(priv->mc13xxx); @@ -121,7 +108,7 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) if (unlikely(ret)) goto out; - if (alarmseconds < 86400) { + if (alarmseconds < SEC_PER_DAY) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); if (unlikely(ret)) @@ -145,7 +132,7 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) goto out; /* restore alarm */ - if (alarmseconds < 86400) { + if (alarmseconds < SEC_PER_DAY) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, alarmseconds); if (unlikely(ret)) @@ -181,7 +168,7 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds); if (unlikely(ret)) goto out; - if (seconds >= 86400) { + if (seconds >= SEC_PER_DAY) { ret = -ENODATA; goto out; } @@ -202,7 +189,7 @@ out: alarm->enabled = enabled; alarm->pending = pending; - s1970 = days * 86400 + seconds; + s1970 = days * SEC_PER_DAY + seconds; rtc_time_to_tm(s1970, &alarm->time); dev_dbg(dev, "%s: %lu\n", __func__, s1970); @@ -240,8 +227,8 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) if (unlikely(ret)) goto out; - seconds = s1970 % 86400; - days = s1970 / 86400; + seconds = s1970 % SEC_PER_DAY; + days = s1970 / SEC_PER_DAY; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); if (unlikely(ret)) -- cgit v1.2.3 From f49bd06e1d423e045f36a85fb3935fab706b1bf6 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Apr 2014 14:50:02 -0700 Subject: rtc: sunxi: change compatibles The Allwinner A10 compatibles were following a slightly different compatible patterns than the rest of the SoCs for historical reasons. Change the compatibles to match the other pattern in the RTC driver for consistency. Signed-off-by: Maxime Ripard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/devicetree/bindings/rtc/sunxi-rtc.txt | 4 ++-- drivers/rtc/rtc-sunxi.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt b/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt index 7cb9dbf34878..6983aad376c3 100644 --- a/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt @@ -3,7 +3,7 @@ RTC controller for the Allwinner A10/A20 Required properties: -- compatible : Should be "allwinner,sun4i-rtc" or "allwinner,sun7i-a20-rtc" +- compatible : Should be "allwinner,sun4i-a10-rtc" or "allwinner,sun7i-a20-rtc" - reg: physical base address of the controller and length of memory mapped region. - interrupts: IRQ line for the RTC. @@ -11,7 +11,7 @@ Required properties: Example: rtc: rtc@01c20d00 { - compatible = "allwinner,sun4i-rtc"; + compatible = "allwinner,sun4i-a10-rtc"; reg = <0x01c20d00 0x20>; interrupts = <24>; }; diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c index 68a35284e5ad..b6f21f73d508 100644 --- a/drivers/rtc/rtc-sunxi.c +++ b/drivers/rtc/rtc-sunxi.c @@ -428,7 +428,7 @@ static const struct rtc_class_ops sunxi_rtc_ops = { }; static const struct of_device_id sunxi_rtc_dt_ids[] = { - { .compatible = "allwinner,sun4i-rtc", .data = &data_year_param[0] }, + { .compatible = "allwinner,sun4i-a10-rtc", .data = &data_year_param[0] }, { .compatible = "allwinner,sun7i-a20-rtc", .data = &data_year_param[1] }, { /* sentinel */ }, }; -- cgit v1.2.3 From a8a15eb19d885bec172c396178c148264987922f Mon Sep 17 00:00:00 2001 From: Bharat Bhushan Date: Thu, 3 Apr 2014 14:50:04 -0700 Subject: drivers/rtc/rtc-ds3232.c: make it possible to share an irq It's possible to have RTC irq shared with other device (e.g. t4240qds board shares ds3232irq with phy one). Handle this in driver. Signed-off-by: Bharat Bhushan Cc: Scott Wood Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds3232.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 15497c578af5..813c6aa70d3d 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -418,8 +418,8 @@ static int ds3232_probe(struct i2c_client *client, } if (client->irq >= 0) { - ret = devm_request_irq(&client->dev, client->irq, ds3232_irq, 0, - "ds3232", client); + ret = devm_request_irq(&client->dev, client->irq, ds3232_irq, + IRQF_SHARED, "ds3232", client); if (ret) { dev_err(&client->dev, "unable to request IRQ\n"); } -- cgit v1.2.3 From b5ada4600dfd4f07f570a6dda7b5b020d96f8591 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 3 Apr 2014 14:50:05 -0700 Subject: drivers/rtc/rtc-cmos.c: fix compilation warning when !CONFIG_PM_SLEEP CONFIG_PM will be set also if only CONFIG_PM_RUNTIME is set which causes the compiler to emit following warning: drivers/rtc/rtc-cmos.c:845:12: warning: =E2=80=98cmos_resume=E2=80=99 defined but not used [-Wunused-function] Fix this by using CONFIG_PM_SLEEP instead of CONFIG_PM and removing it from the driver pm ops as this has been taken care by SIMPLE_DEV_PM_OPS() already. Signed-off-by: Mika Westerberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-cmos.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index cae212f30d65..0963c9309c74 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -837,7 +837,7 @@ static void __exit cmos_do_remove(struct device *dev) cmos->dev = NULL; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int cmos_suspend(struct device *dev) { @@ -935,8 +935,6 @@ static int cmos_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); - #else static inline int cmos_poweroff(struct device *dev) @@ -946,6 +944,8 @@ static inline int cmos_poweroff(struct device *dev) #endif +static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); + /*----------------------------------------------------------------*/ /* On non-x86 systems, a "CMOS" RTC lives most naturally on platform_bus. @@ -1088,11 +1088,9 @@ static struct pnp_driver cmos_pnp_driver = { /* flag ensures resume() gets called, and stops syslog spam */ .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, -#ifdef CONFIG_PM_SLEEP .driver = { .pm = &cmos_pm_ops, }, -#endif }; #endif /* CONFIG_PNP */ -- cgit v1.2.3 From d55255cb11ca2220d09c2a08adee7ca3e14e0ba1 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:50:06 -0700 Subject: drivers/rtc/rtc-as3722.c: use SIMPLE_DEV_PM_OPS macro Use SIMPLE_DEV_PM_OPS macro in order to make the code simpler. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-as3722.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-as3722.c b/drivers/rtc/rtc-as3722.c index 4af016985890..9f38eda69154 100644 --- a/drivers/rtc/rtc-as3722.c +++ b/drivers/rtc/rtc-as3722.c @@ -242,9 +242,8 @@ static int as3722_rtc_resume(struct device *dev) } #endif -static const struct dev_pm_ops as3722_rtc_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(as3722_rtc_suspend, as3722_rtc_resume) -}; +static SIMPLE_DEV_PM_OPS(as3722_rtc_pm_ops, as3722_rtc_suspend, + as3722_rtc_resume); static struct platform_driver as3722_rtc_driver = { .probe = as3722_rtc_probe, -- cgit v1.2.3 From 3f93822d36fc8413658a67f5fb853bbe1b2a1f4d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 3 Apr 2014 14:50:07 -0700 Subject: drivers/rtc/rtc-palmas.c: use SIMPLE_DEV_PM_OPS macro Use SIMPLE_DEV_PM_OPS macro in order to make the code simpler. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-palmas.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c index fffb7d3449d7..c360d62fb3f6 100644 --- a/drivers/rtc/rtc-palmas.c +++ b/drivers/rtc/rtc-palmas.c @@ -348,9 +348,8 @@ static int palmas_rtc_resume(struct device *dev) } #endif -static const struct dev_pm_ops palmas_rtc_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(palmas_rtc_suspend, palmas_rtc_resume) -}; +static SIMPLE_DEV_PM_OPS(palmas_rtc_pm_ops, palmas_rtc_suspend, + palmas_rtc_resume); #ifdef CONFIG_OF static struct of_device_id of_palmas_rtc_match[] = { -- cgit v1.2.3 From c93a3ae2d213ff75a279fe6e28d8f41ca7f01483 Mon Sep 17 00:00:00 2001 From: Wang Dongsheng Date: Thu, 3 Apr 2014 14:50:08 -0700 Subject: drivers/rtc/rtc-ds3232.c: enable ds3232 to work as wakeup source Add suspend/resume and device_init_wakeup to enable ds3232 as wakeup source, /sys/class/rtc/rtcX/wakealarm for set wakeup alarm. Signed-off-by: Wang Dongsheng Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds3232.c | 94 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 813c6aa70d3d..adaf06c41479 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -57,6 +57,7 @@ struct ds3232 { * in the remove function. */ struct mutex mutex; + bool suspended; int exiting; }; @@ -345,7 +346,15 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id) struct ds3232 *ds3232 = i2c_get_clientdata(client); disable_irq_nosync(irq); - schedule_work(&ds3232->work); + + /* + * If rtc as a wakeup source, can't schedule the work + * at system resume flow, because at this time the i2c bus + * has not been resumed. + */ + if (!ds3232->suspended) + schedule_work(&ds3232->work); + return IRQ_HANDLED; } @@ -363,22 +372,26 @@ static void ds3232_work(struct work_struct *work) if (stat & DS3232_REG_SR_A1F) { control = i2c_smbus_read_byte_data(client, DS3232_REG_CR); - if (control < 0) - goto out; - /* disable alarm1 interrupt */ - control &= ~(DS3232_REG_CR_A1IE); - i2c_smbus_write_byte_data(client, DS3232_REG_CR, control); - - /* clear the alarm pend flag */ - stat &= ~DS3232_REG_SR_A1F; - i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat); - - rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF); + if (control < 0) { + pr_warn("Read DS3232 Control Register error." + "Disable IRQ%d.\n", client->irq); + } else { + /* disable alarm1 interrupt */ + control &= ~(DS3232_REG_CR_A1IE); + i2c_smbus_write_byte_data(client, DS3232_REG_CR, + control); + + /* clear the alarm pend flag */ + stat &= ~DS3232_REG_SR_A1F; + i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat); + + rtc_update_irq(ds3232->rtc, 1, RTC_AF | RTC_IRQF); + + if (!ds3232->exiting) + enable_irq(client->irq); + } } -out: - if (!ds3232->exiting) - enable_irq(client->irq); unlock: mutex_unlock(&ds3232->mutex); } @@ -411,21 +424,17 @@ static int ds3232_probe(struct i2c_client *client, if (ret) return ret; - ds3232->rtc = devm_rtc_device_register(&client->dev, client->name, - &ds3232_rtc_ops, THIS_MODULE); - if (IS_ERR(ds3232->rtc)) { - return PTR_ERR(ds3232->rtc); - } - - if (client->irq >= 0) { + if (client->irq > 0) { ret = devm_request_irq(&client->dev, client->irq, ds3232_irq, IRQF_SHARED, "ds3232", client); if (ret) { dev_err(&client->dev, "unable to request IRQ\n"); } + device_init_wakeup(&client->dev, 1); } - - return 0; + ds3232->rtc = devm_rtc_device_register(&client->dev, client->name, + &ds3232_rtc_ops, THIS_MODULE); + return PTR_ERR_OR_ZERO(ds3232->rtc); } static int ds3232_remove(struct i2c_client *client) @@ -444,6 +453,42 @@ static int ds3232_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM_SLEEP +static int ds3232_suspend(struct device *dev) +{ + struct ds3232 *ds3232 = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + + if (device_can_wakeup(dev)) { + ds3232->suspended = true; + irq_set_irq_wake(client->irq, 1); + } + + return 0; +} + +static int ds3232_resume(struct device *dev) +{ + struct ds3232 *ds3232 = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + + if (ds3232->suspended) { + ds3232->suspended = false; + + /* Clear the hardware alarm pend flag */ + schedule_work(&ds3232->work); + + irq_set_irq_wake(client->irq, 0); + } + + return 0; +} +#endif + +static const struct dev_pm_ops ds3232_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume) +}; + static const struct i2c_device_id ds3232_id[] = { { "ds3232", 0 }, { } @@ -454,6 +499,7 @@ static struct i2c_driver ds3232_driver = { .driver = { .name = "rtc-ds3232", .owner = THIS_MODULE, + .pm = &ds3232_pm_ops, }, .probe = ds3232_probe, .remove = ds3232_remove, -- cgit v1.2.3 From 131c9cc832162bfe45be1065fa88d1ec2c165a3d Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Thu, 3 Apr 2014 14:50:09 -0700 Subject: rtc: verify a critical argument to rtc_update_irq() before using it This small addition to the core simplifies code in the drivers and makes them more robust when handling shared IRQs. Signed-off-by: Alessandro Zummo Cc: Alexander Shiyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/interface.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 544be722937c..c2eff6082363 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -584,6 +584,9 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) void rtc_update_irq(struct rtc_device *rtc, unsigned long num, unsigned long events) { + if (unlikely(IS_ERR_OR_NULL(rtc))) + return; + pm_stay_awake(rtc->dev.parent); schedule_work(&rtc->irqwork); } -- cgit v1.2.3 From 5bed811d668ca042b5ee711e27a3c4496179145c Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 3 Apr 2014 14:50:10 -0700 Subject: rtc: pm8xxx: fixup checkpatch/style issues This patchset is based on Stephen Boyd's PM8921 modernization/cleanups (http://lkml.kernel.org/g/1393441166-32692-1-git-send-email-sboyd@codeaurora.org), and allows for this RTC driver to be usable again. This patch (of 6): Before performing additional cleanups to this driver, do the easy cleanups first. Signed-off-by: Josh Cartwright Reviewed-by: Stephen Boyd Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pm8xxx.c | 97 ++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index bd76ffe92784..af60ee46075d 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -53,7 +53,7 @@ struct pm8xxx_rtc { int rtc_read_base; int rtc_write_base; int alarm_rw_base; - u8 ctrl_reg; + u8 ctrl_reg; struct device *rtc_dev; spinlock_t ctrl_reg_lock; }; @@ -63,7 +63,7 @@ struct pm8xxx_rtc { * hardware limitation. */ static int pm8xxx_read_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val, - int base, int count) + int base, int count) { int i, rc; struct device *parent = rtc_dd->rtc_dev->parent; @@ -80,7 +80,7 @@ static int pm8xxx_read_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val, } static int pm8xxx_write_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val, - int base, int count) + int base, int count) { int i, rc; struct device *parent = rtc_dd->rtc_dev->parent; @@ -126,15 +126,15 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) alarm_enabled = 1; ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, - 1); + 1); if (rc < 0) { - dev_err(dev, "Write to RTC control register " - "failed\n"); + dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } rtc_dd->ctrl_reg = ctrl_reg; - } else + } else { spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); + } /* Write 0 to Byte[0] */ reg = 0; @@ -146,7 +146,7 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) /* Write Byte[1], Byte[2], Byte[3] */ rc = pm8xxx_write_wrapper(rtc_dd, value + 1, - rtc_dd->rtc_write_base + 1, 3); + rtc_dd->rtc_write_base + 1, 3); if (rc < 0) { dev_err(dev, "Write to RTC write data register failed\n"); goto rtc_rw_fail; @@ -162,10 +162,9 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) if (alarm_enabled) { ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE; rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, - 1); + 1); if (rc < 0) { - dev_err(dev, "Write to RTC control register " - "failed\n"); + dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } rtc_dd->ctrl_reg = ctrl_reg; @@ -186,7 +185,7 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); rc = pm8xxx_read_wrapper(rtc_dd, value, rtc_dd->rtc_read_base, - NUM_8_BIT_RTC_REGS); + NUM_8_BIT_RTC_REGS); if (rc < 0) { dev_err(dev, "RTC read data register failed\n"); return rc; @@ -204,7 +203,8 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) if (unlikely(reg < value[0])) { rc = pm8xxx_read_wrapper(rtc_dd, value, - rtc_dd->rtc_read_base, NUM_8_BIT_RTC_REGS); + rtc_dd->rtc_read_base, + NUM_8_BIT_RTC_REGS); if (rc < 0) { dev_err(dev, "RTC read data register failed\n"); return rc; @@ -222,8 +222,8 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) } dev_dbg(dev, "secs = %lu, h:m:s == %d:%d:%d, d/m/y = %d/%d/%d\n", - secs, tm->tm_hour, tm->tm_min, tm->tm_sec, - tm->tm_mday, tm->tm_mon, tm->tm_year); + secs, tm->tm_hour, tm->tm_min, tm->tm_sec, + tm->tm_mday, tm->tm_mon, tm->tm_year); return 0; } @@ -245,15 +245,18 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); rc = pm8xxx_write_wrapper(rtc_dd, value, rtc_dd->alarm_rw_base, - NUM_8_BIT_RTC_REGS); + NUM_8_BIT_RTC_REGS); if (rc < 0) { dev_err(dev, "Write to RTC ALARM register failed\n"); goto rtc_rw_fail; } ctrl_reg = rtc_dd->ctrl_reg; - ctrl_reg = alarm->enabled ? (ctrl_reg | PM8xxx_RTC_ALARM_ENABLE) : - (ctrl_reg & ~PM8xxx_RTC_ALARM_ENABLE); + + if (alarm->enabled) + ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE; + else + ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); if (rc < 0) { @@ -264,9 +267,9 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) rtc_dd->ctrl_reg = ctrl_reg; dev_dbg(dev, "Alarm Set for h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n", - alarm->time.tm_hour, alarm->time.tm_min, - alarm->time.tm_sec, alarm->time.tm_mday, - alarm->time.tm_mon, alarm->time.tm_year); + alarm->time.tm_hour, alarm->time.tm_min, + alarm->time.tm_sec, alarm->time.tm_mday, + alarm->time.tm_mon, alarm->time.tm_year); rtc_rw_fail: spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); return rc; @@ -280,7 +283,7 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); rc = pm8xxx_read_wrapper(rtc_dd, value, rtc_dd->alarm_rw_base, - NUM_8_BIT_RTC_REGS); + NUM_8_BIT_RTC_REGS); if (rc < 0) { dev_err(dev, "RTC alarm time read failed\n"); return rc; @@ -297,9 +300,9 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) } dev_dbg(dev, "Alarm set for - h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n", - alarm->time.tm_hour, alarm->time.tm_min, - alarm->time.tm_sec, alarm->time.tm_mday, - alarm->time.tm_mon, alarm->time.tm_year); + alarm->time.tm_hour, alarm->time.tm_min, + alarm->time.tm_sec, alarm->time.tm_mday, + alarm->time.tm_mon, alarm->time.tm_year); return 0; } @@ -312,9 +315,13 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) u8 ctrl_reg; spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); + ctrl_reg = rtc_dd->ctrl_reg; - ctrl_reg = (enable) ? (ctrl_reg | PM8xxx_RTC_ALARM_ENABLE) : - (ctrl_reg & ~PM8xxx_RTC_ALARM_ENABLE); + + if (enable) + ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE; + else + ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); if (rc < 0) { @@ -354,8 +361,8 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); if (rc < 0) { spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); - dev_err(rtc_dd->rtc_dev, "Write to RTC control register " - "failed\n"); + dev_err(rtc_dd->rtc_dev, + "Write to RTC control register failed\n"); goto rtc_alarm_handled; } @@ -364,19 +371,19 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) /* Clear RTC alarm register */ rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base + - PM8XXX_ALARM_CTRL_OFFSET, 1); + PM8XXX_ALARM_CTRL_OFFSET, 1); if (rc < 0) { - dev_err(rtc_dd->rtc_dev, "RTC Alarm control register read " - "failed\n"); + dev_err(rtc_dd->rtc_dev, + "RTC Alarm control register read failed\n"); goto rtc_alarm_handled; } ctrl_reg &= ~PM8xxx_RTC_ALARM_CLEAR; rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base + - PM8XXX_ALARM_CTRL_OFFSET, 1); + PM8XXX_ALARM_CTRL_OFFSET, 1); if (rc < 0) - dev_err(rtc_dd->rtc_dev, "Write to RTC Alarm control register" - " failed\n"); + dev_err(rtc_dd->rtc_dev, + "Write to RTC Alarm control register failed\n"); rtc_alarm_handled: return IRQ_HANDLED; @@ -409,7 +416,7 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) } rtc_resource = platform_get_resource_byname(pdev, IORESOURCE_IO, - "pmic_rtc_base"); + "pmic_rtc_base"); if (!(rtc_resource && rtc_resource->start)) { dev_err(&pdev->dev, "RTC IO resource absent!\n"); return -ENXIO; @@ -436,31 +443,31 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); if (rc < 0) { - dev_err(&pdev->dev, "Write to RTC control register " - "failed\n"); + dev_err(&pdev->dev, + "Write to RTC control register failed\n"); return rc; } } rtc_dd->ctrl_reg = ctrl_reg; - if (rtc_write_enable == true) + if (rtc_write_enable) pm8xxx_rtc_ops.set_time = pm8xxx_rtc_set_time; platform_set_drvdata(pdev, rtc_dd); /* Register the RTC device */ rtc_dd->rtc = devm_rtc_device_register(&pdev->dev, "pm8xxx_rtc", - &pm8xxx_rtc_ops, THIS_MODULE); + &pm8xxx_rtc_ops, THIS_MODULE); if (IS_ERR(rtc_dd->rtc)) { dev_err(&pdev->dev, "%s: RTC registration failed (%ld)\n", - __func__, PTR_ERR(rtc_dd->rtc)); + __func__, PTR_ERR(rtc_dd->rtc)); return PTR_ERR(rtc_dd->rtc); } /* Request the alarm IRQ */ rc = request_any_context_irq(rtc_dd->rtc_alarm_irq, - pm8xxx_alarm_trigger, IRQF_TRIGGER_RISING, - "pm8xxx_rtc_alarm", rtc_dd); + pm8xxx_alarm_trigger, IRQF_TRIGGER_RISING, + "pm8xxx_rtc_alarm", rtc_dd); if (rc < 0) { dev_err(&pdev->dev, "Request IRQ failed (%d)\n", rc); return rc; @@ -505,7 +512,9 @@ static int pm8xxx_rtc_suspend(struct device *dev) } #endif -static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume); +static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, + pm8xxx_rtc_suspend, + pm8xxx_rtc_resume); static struct platform_driver pm8xxx_rtc_driver = { .probe = pm8xxx_rtc_probe, -- cgit v1.2.3 From 5d7dc4cf14da184fb7aca8f298e9667746e9f980 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 3 Apr 2014 14:50:11 -0700 Subject: rtc: pm8xxx: use regmap API for register accesses Now that the parent mfd driver has been made to work again, and has been reworked to create a regmap instance intended for its children to use, rework the pm8xxx driver to use the regmap API for its register accesses. Signed-off-by: Josh Cartwright Reviewed-by: Stephen Boyd Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pm8xxx.c | 145 +++++++++++++++++++---------------------------- 1 file changed, 57 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index af60ee46075d..cdc9dc211eb0 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -13,11 +13,12 @@ #include #include #include +#include #include +#include #include #include -#include #include @@ -37,6 +38,7 @@ /** * struct pm8xxx_rtc - rtc driver internal structure * @rtc: rtc device for this driver. + * @regmap: regmap used to access RTC registers * @rtc_alarm_irq: rtc alarm irq number. * @rtc_base: address of rtc control register. * @rtc_read_base: base address of read registers. @@ -48,6 +50,7 @@ */ struct pm8xxx_rtc { struct rtc_device *rtc; + struct regmap *regmap; int rtc_alarm_irq; int rtc_base; int rtc_read_base; @@ -58,44 +61,6 @@ struct pm8xxx_rtc { spinlock_t ctrl_reg_lock; }; -/* - * The RTC registers need to be read/written one byte at a time. This is a - * hardware limitation. - */ -static int pm8xxx_read_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val, - int base, int count) -{ - int i, rc; - struct device *parent = rtc_dd->rtc_dev->parent; - - for (i = 0; i < count; i++) { - rc = pm8xxx_readb(parent, base + i, &rtc_val[i]); - if (rc < 0) { - dev_err(rtc_dd->rtc_dev, "PMIC read failed\n"); - return rc; - } - } - - return 0; -} - -static int pm8xxx_write_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val, - int base, int count) -{ - int i, rc; - struct device *parent = rtc_dd->rtc_dev->parent; - - for (i = 0; i < count; i++) { - rc = pm8xxx_writeb(parent, base + i, rtc_val[i]); - if (rc < 0) { - dev_err(rtc_dd->rtc_dev, "PMIC write failed\n"); - return rc; - } - } - - return 0; -} - /* * Steps to write the RTC registers. * 1. Disable alarm if enabled. @@ -107,7 +72,7 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) { int rc, i; unsigned long secs, irq_flags; - u8 value[NUM_8_BIT_RTC_REGS], reg = 0, alarm_enabled = 0, ctrl_reg; + u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, ctrl_reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); rtc_tm_to_time(tm, &secs); @@ -125,9 +90,8 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) if (ctrl_reg & PM8xxx_RTC_ALARM_ENABLE) { alarm_enabled = 1; ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; - rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, - 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } @@ -137,33 +101,31 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) } /* Write 0 to Byte[0] */ - reg = 0; - rc = pm8xxx_write_wrapper(rtc_dd, ®, rtc_dd->rtc_write_base, 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_write_base, 0); + if (rc) { dev_err(dev, "Write to RTC write data register failed\n"); goto rtc_rw_fail; } /* Write Byte[1], Byte[2], Byte[3] */ - rc = pm8xxx_write_wrapper(rtc_dd, value + 1, - rtc_dd->rtc_write_base + 1, 3); - if (rc < 0) { + rc = regmap_bulk_write(rtc_dd->regmap, rtc_dd->rtc_write_base + 1, + &value[1], sizeof(value) - 1); + if (rc) { dev_err(dev, "Write to RTC write data register failed\n"); goto rtc_rw_fail; } /* Write Byte[0] */ - rc = pm8xxx_write_wrapper(rtc_dd, value, rtc_dd->rtc_write_base, 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_write_base, value[0]); + if (rc) { dev_err(dev, "Write to RTC write data register failed\n"); goto rtc_rw_fail; } if (alarm_enabled) { ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE; - rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, - 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } @@ -180,13 +142,14 @@ rtc_rw_fail: static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) { int rc; - u8 value[NUM_8_BIT_RTC_REGS], reg; + u8 value[NUM_8_BIT_RTC_REGS]; unsigned long secs; + unsigned int reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); - rc = pm8xxx_read_wrapper(rtc_dd, value, rtc_dd->rtc_read_base, - NUM_8_BIT_RTC_REGS); - if (rc < 0) { + rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->rtc_read_base, + value, sizeof(value)); + if (rc) { dev_err(dev, "RTC read data register failed\n"); return rc; } @@ -195,17 +158,16 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) * Read the LSB again and check if there has been a carry over. * If there is, redo the read operation. */ - rc = pm8xxx_read_wrapper(rtc_dd, ®, rtc_dd->rtc_read_base, 1); + rc = regmap_read(rtc_dd->regmap, rtc_dd->rtc_read_base, ®); if (rc < 0) { dev_err(dev, "RTC read data register failed\n"); return rc; } if (unlikely(reg < value[0])) { - rc = pm8xxx_read_wrapper(rtc_dd, value, - rtc_dd->rtc_read_base, - NUM_8_BIT_RTC_REGS); - if (rc < 0) { + rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->rtc_read_base, + value, sizeof(value)); + if (rc) { dev_err(dev, "RTC read data register failed\n"); return rc; } @@ -244,9 +206,9 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); - rc = pm8xxx_write_wrapper(rtc_dd, value, rtc_dd->alarm_rw_base, - NUM_8_BIT_RTC_REGS); - if (rc < 0) { + rc = regmap_bulk_write(rtc_dd->regmap, rtc_dd->alarm_rw_base, value, + sizeof(value)); + if (rc) { dev_err(dev, "Write to RTC ALARM register failed\n"); goto rtc_rw_fail; } @@ -258,8 +220,8 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) else ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; - rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } @@ -282,9 +244,9 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) unsigned long secs; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); - rc = pm8xxx_read_wrapper(rtc_dd, value, rtc_dd->alarm_rw_base, - NUM_8_BIT_RTC_REGS); - if (rc < 0) { + rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->alarm_rw_base, value, + sizeof(value)); + if (rc) { dev_err(dev, "RTC alarm time read failed\n"); return rc; } @@ -323,8 +285,8 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) else ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; - rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } @@ -346,7 +308,7 @@ static struct rtc_class_ops pm8xxx_rtc_ops = { static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) { struct pm8xxx_rtc *rtc_dd = dev_id; - u8 ctrl_reg; + unsigned int ctrl_reg; int rc; unsigned long irq_flags; @@ -358,8 +320,8 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) ctrl_reg = rtc_dd->ctrl_reg; ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; - rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + if (rc) { spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); dev_err(rtc_dd->rtc_dev, "Write to RTC control register failed\n"); @@ -370,18 +332,20 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); /* Clear RTC alarm register */ - rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base + - PM8XXX_ALARM_CTRL_OFFSET, 1); - if (rc < 0) { + rc = regmap_read(rtc_dd->regmap, + rtc_dd->rtc_base + PM8XXX_ALARM_CTRL_OFFSET, + &ctrl_reg); + if (rc) { dev_err(rtc_dd->rtc_dev, "RTC Alarm control register read failed\n"); goto rtc_alarm_handled; } ctrl_reg &= ~PM8xxx_RTC_ALARM_CLEAR; - rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base + - PM8XXX_ALARM_CTRL_OFFSET, 1); - if (rc < 0) + rc = regmap_write(rtc_dd->regmap, + rtc_dd->rtc_base + PM8XXX_ALARM_CTRL_OFFSET, + ctrl_reg); + if (rc) dev_err(rtc_dd->rtc_dev, "Write to RTC Alarm control register failed\n"); @@ -392,7 +356,7 @@ rtc_alarm_handled: static int pm8xxx_rtc_probe(struct platform_device *pdev) { int rc; - u8 ctrl_reg; + unsigned int ctrl_reg; bool rtc_write_enable = false; struct pm8xxx_rtc *rtc_dd; struct resource *rtc_resource; @@ -409,6 +373,12 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) /* Initialise spinlock to protect RTC control register */ spin_lock_init(&rtc_dd->ctrl_reg_lock); + rtc_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!rtc_dd->regmap) { + dev_err(&pdev->dev, "Parent regmap unavailable.\n"); + return -ENXIO; + } + rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0); if (rtc_dd->rtc_alarm_irq < 0) { dev_err(&pdev->dev, "Alarm IRQ resource absent!\n"); @@ -432,17 +402,16 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) rtc_dd->rtc_dev = &pdev->dev; /* Check if the RTC is on, else turn it on */ - rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1); - if (rc < 0) { + rc = regmap_read(rtc_dd->regmap, rtc_dd->rtc_base, &ctrl_reg); + if (rc) { dev_err(&pdev->dev, "RTC control register read failed!\n"); return rc; } if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) { ctrl_reg |= PM8xxx_RTC_ENABLE; - rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, - 1); - if (rc < 0) { + rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + if (rc) { dev_err(&pdev->dev, "Write to RTC control register failed\n"); return rc; -- cgit v1.2.3 From bffcbc0887a7496c19639d55ff0e7483ee17aa42 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 3 Apr 2014 14:50:12 -0700 Subject: rtc: pm8xxx: use devm_request_any_context_irq Make use of the devm_* variant of request_any_context_irq to allow for elimination of remove(). Signed-off-by: Josh Cartwright Reviewed-by: Stephen Boyd Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pm8xxx.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index cdc9dc211eb0..91ac2e346aea 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -434,9 +434,10 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) } /* Request the alarm IRQ */ - rc = request_any_context_irq(rtc_dd->rtc_alarm_irq, - pm8xxx_alarm_trigger, IRQF_TRIGGER_RISING, - "pm8xxx_rtc_alarm", rtc_dd); + rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->rtc_alarm_irq, + pm8xxx_alarm_trigger, + IRQF_TRIGGER_RISING, + "pm8xxx_rtc_alarm", rtc_dd); if (rc < 0) { dev_err(&pdev->dev, "Request IRQ failed (%d)\n", rc); return rc; @@ -449,16 +450,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) return 0; } -static int pm8xxx_rtc_remove(struct platform_device *pdev) -{ - struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev); - - device_init_wakeup(&pdev->dev, 0); - free_irq(rtc_dd->rtc_alarm_irq, rtc_dd); - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int pm8xxx_rtc_resume(struct device *dev) { @@ -487,7 +478,6 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, static struct platform_driver pm8xxx_rtc_driver = { .probe = pm8xxx_rtc_probe, - .remove = pm8xxx_rtc_remove, .driver = { .name = PM8XXX_RTC_DEV_NAME, .owner = THIS_MODULE, -- cgit v1.2.3 From 5a418558cdae4fd0699b7b6a960f03a8bb38a338 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 3 Apr 2014 14:50:13 -0700 Subject: rtc: pm8xxx: add support for devicetree Add support for describing the PM8921/PM8058 RTC in device tree. Additionally: - drop support for describing the RTC using platform data, as there are no current in tree users who do so. - make allow_set_time a device-specific flag, instead of mucking with the rtc_ops Signed-off-by: Josh Cartwright Reviewed-by: Stephen Boyd Acked-by: Lee Jones Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pm8xxx.c | 52 +++++++++++++++++++++++------------------- include/linux/mfd/pm8xxx/rtc.h | 25 -------------------- 2 files changed, 29 insertions(+), 48 deletions(-) delete mode 100644 include/linux/mfd/pm8xxx/rtc.h (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 91ac2e346aea..6e3cd345379d 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -9,7 +9,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - +#include #include #include #include @@ -19,9 +19,6 @@ #include #include -#include - - /* RTC Register offsets from RTC CTRL REG */ #define PM8XXX_ALARM_CTRL_OFFSET 0x01 #define PM8XXX_RTC_WRITE_OFFSET 0x02 @@ -39,6 +36,7 @@ * struct pm8xxx_rtc - rtc driver internal structure * @rtc: rtc device for this driver. * @regmap: regmap used to access RTC registers + * @allow_set_time: indicates whether writing to the RTC is allowed * @rtc_alarm_irq: rtc alarm irq number. * @rtc_base: address of rtc control register. * @rtc_read_base: base address of read registers. @@ -51,6 +49,7 @@ struct pm8xxx_rtc { struct rtc_device *rtc; struct regmap *regmap; + bool allow_set_time; int rtc_alarm_irq; int rtc_base; int rtc_read_base; @@ -75,6 +74,9 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, ctrl_reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); + if (!rtc_dd->allow_set_time) + return -EACCES; + rtc_tm_to_time(tm, &secs); for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) { @@ -298,8 +300,9 @@ rtc_rw_fail: return rc; } -static struct rtc_class_ops pm8xxx_rtc_ops = { +static const struct rtc_class_ops pm8xxx_rtc_ops = { .read_time = pm8xxx_rtc_read_time, + .set_time = pm8xxx_rtc_set_time, .set_alarm = pm8xxx_rtc_set_alarm, .read_alarm = pm8xxx_rtc_read_alarm, .alarm_irq_enable = pm8xxx_rtc_alarm_irq_enable, @@ -353,18 +356,26 @@ rtc_alarm_handled: return IRQ_HANDLED; } +/* + * Hardcoded RTC bases until IORESOURCE_REG mapping is figured out + */ +static const struct of_device_id pm8xxx_id_table[] = { + { .compatible = "qcom,pm8921-rtc", .data = (void *) 0x11D }, + { .compatible = "qcom,pm8058-rtc", .data = (void *) 0x1E8 }, + { }, +}; +MODULE_DEVICE_TABLE(of, pm8xxx_id_table); + static int pm8xxx_rtc_probe(struct platform_device *pdev) { int rc; unsigned int ctrl_reg; - bool rtc_write_enable = false; struct pm8xxx_rtc *rtc_dd; - struct resource *rtc_resource; - const struct pm8xxx_rtc_platform_data *pdata = - dev_get_platdata(&pdev->dev); + const struct of_device_id *match; - if (pdata != NULL) - rtc_write_enable = pdata->rtc_write_enable; + match = of_match_node(pm8xxx_id_table, pdev->dev.of_node); + if (!match) + return -ENXIO; rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL); if (rtc_dd == NULL) @@ -385,14 +396,10 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) return -ENXIO; } - rtc_resource = platform_get_resource_byname(pdev, IORESOURCE_IO, - "pmic_rtc_base"); - if (!(rtc_resource && rtc_resource->start)) { - dev_err(&pdev->dev, "RTC IO resource absent!\n"); - return -ENXIO; - } + rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node, + "allow-set-time"); - rtc_dd->rtc_base = rtc_resource->start; + rtc_dd->rtc_base = (long) match->data; /* Setup RTC register addresses */ rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET; @@ -419,8 +426,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) } rtc_dd->ctrl_reg = ctrl_reg; - if (rtc_write_enable) - pm8xxx_rtc_ops.set_time = pm8xxx_rtc_set_time; platform_set_drvdata(pdev, rtc_dd); @@ -479,9 +484,10 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, static struct platform_driver pm8xxx_rtc_driver = { .probe = pm8xxx_rtc_probe, .driver = { - .name = PM8XXX_RTC_DEV_NAME, - .owner = THIS_MODULE, - .pm = &pm8xxx_rtc_pm_ops, + .name = "rtc-pm8xxx", + .owner = THIS_MODULE, + .pm = &pm8xxx_rtc_pm_ops, + .of_match_table = pm8xxx_id_table, }, }; diff --git a/include/linux/mfd/pm8xxx/rtc.h b/include/linux/mfd/pm8xxx/rtc.h deleted file mode 100644 index 14f1983eaecc..000000000000 --- a/include/linux/mfd/pm8xxx/rtc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __RTC_PM8XXX_H__ -#define __RTC_PM8XXX_H__ - -#define PM8XXX_RTC_DEV_NAME "rtc-pm8xxx" -/** - * struct pm8xxx_rtc_pdata - RTC driver platform data - * @rtc_write_enable: variable stating RTC write capability - */ -struct pm8xxx_rtc_platform_data { - bool rtc_write_enable; -}; - -#endif /* __RTC_PM8XXX_H__ */ -- cgit v1.2.3 From fda9909ddaab13fb7b35b94f204623c1f9571fc7 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Thu, 3 Apr 2014 14:50:14 -0700 Subject: rtc: pm8xxx: move device_init_wakeup() before rtc_register Setup wakeup capability before rtc_register to ensure the rtc class core properly sets up our 'wakealarm' sysfs attribute. Signed-off-by: Josh Cartwright Reviewed-by: Stephen Boyd Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pm8xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 6e3cd345379d..197699f358c7 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -429,6 +429,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc_dd); + device_init_wakeup(&pdev->dev, 1); + /* Register the RTC device */ rtc_dd->rtc = devm_rtc_device_register(&pdev->dev, "pm8xxx_rtc", &pm8xxx_rtc_ops, THIS_MODULE); @@ -448,8 +450,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) return rc; } - device_init_wakeup(&pdev->dev, 1); - dev_dbg(&pdev->dev, "Probe success !!\n"); return 0; -- cgit v1.2.3 From 5ab9a52a3af613b74a7cda033c1623c7913c50d9 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:50:15 -0700 Subject: drivers/rtc/rtc-mc13xxx.c: fix potential race condition RTC drivers must not return an error after device registration. This patch makes RTC registration as the last action. Signed-off-by: Alexander Shiyan Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mc13xxx.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 9b1a77eb91a9..0765606a2d14 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -247,8 +247,6 @@ static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev) struct mc13xxx_rtc *priv = dev; struct mc13xxx *mc13xxx = priv->mc13xxx; - dev_dbg(&priv->rtc->dev, "Alarm\n"); - rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); mc13xxx_irq_ack(mc13xxx, irq); @@ -261,8 +259,6 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev) struct mc13xxx_rtc *priv = dev; struct mc13xxx *mc13xxx = priv->mc13xxx; - dev_dbg(&priv->rtc->dev, "1HZ\n"); - rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF); mc13xxx_irq_ack(mc13xxx, irq); @@ -283,7 +279,6 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) struct mc13xxx_rtc *priv = dev; struct mc13xxx *mc13xxx = priv->mc13xxx; - dev_warn(&priv->rtc->dev, "Contents of the RTC are no longer valid\n"); priv->valid = 0; mc13xxx_irq_mask(mc13xxx, irq); @@ -307,11 +302,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); - priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &mc13xxx_rtc_ops, THIS_MODULE); - if (IS_ERR(priv->rtc)) - return PTR_ERR(priv->rtc); - mc13xxx_lock(mc13xxx); mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_RTCRST); @@ -319,24 +309,30 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, mc13xxx_rtc_reset_handler, DRIVER_NAME, priv); if (ret) - goto err_reset_irq_request; + goto err_irq_request; ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ, mc13xxx_rtc_update_handler, DRIVER_NAME, priv); if (ret) - goto err_reset_irq_status; + goto err_irq_request; ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA, mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv); - if (!ret) - goto err_reset_irq_request; + if (ret) + goto err_irq_request; - mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv); + mc13xxx_unlock(mc13xxx); + + priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &mc13xxx_rtc_ops, THIS_MODULE); -err_reset_irq_status: + return 0; + +err_irq_request: + mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); + mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv); mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); -err_reset_irq_request: mc13xxx_unlock(mc13xxx); return ret; -- cgit v1.2.3 From 617b26a0e1cf8f183328763b6f1a33a422b60614 Mon Sep 17 00:00:00 2001 From: Raghavendra Ganiga Date: Thu, 3 Apr 2014 14:50:16 -0700 Subject: rtc: add support for maxim dallas rtc ds1347 Add support for maxim dallas rtc ds1347 Signed-off-by: Raghavendra Chandra Ganiga Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 12 ++++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-ds1347.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/rtc/rtc-ds1347.c (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index db933decc39c..2e565f8e5165 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -573,6 +573,18 @@ config RTC_DRV_DS1305 This driver can also be built as a module. If so, the module will be called rtc-ds1305. +config RTC_DRV_DS1347 + tristate "Dallas/Maxim DS1347" + help + If you say yes here you get support for the + Dallas/Maxim DS1347 chips. + + This driver only supports the RTC feature, and not other chip + features such as alarms. + + This driver can also be built as a module. If so, the module + will be called rtc-ds1347. + config RTC_DRV_DS1390 tristate "Dallas/Maxim DS1390/93/94" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index b427bf7dd20d..40a09915c8f6 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o +obj-$(CONFIG_RTC_DRV_DS1347) += rtc-ds1347.o obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o obj-$(CONFIG_RTC_DRV_DS1390) += rtc-ds1390.o obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c new file mode 100644 index 000000000000..c82b4c050326 --- /dev/null +++ b/drivers/rtc/rtc-ds1347.c @@ -0,0 +1,166 @@ +/* rtc-ds1347.c + * + * Driver for Dallas Semiconductor DS1347 Low Current, SPI Compatible + * Real Time Clock + * + * Author : Raghavendra Chandra Ganiga + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Registers in ds1347 rtc */ + +#define DS1347_SECONDS_REG 0x01 +#define DS1347_MINUTES_REG 0x03 +#define DS1347_HOURS_REG 0x05 +#define DS1347_DATE_REG 0x07 +#define DS1347_MONTH_REG 0x09 +#define DS1347_DAY_REG 0x0B +#define DS1347_YEAR_REG 0x0D +#define DS1347_CONTROL_REG 0x0F +#define DS1347_STATUS_REG 0x17 +#define DS1347_CLOCK_BURST 0x3F + +static int ds1347_read_reg(struct device *dev, unsigned char address, + unsigned char *data) +{ + struct spi_device *spi = to_spi_device(dev); + + *data = address | 0x80; + + return spi_write_then_read(spi, data, 1, data, 1); +} + +static int ds1347_write_reg(struct device *dev, unsigned char address, + unsigned char data) +{ + struct spi_device *spi = to_spi_device(dev); + unsigned char buf[2]; + + buf[0] = address & 0x7F; + buf[1] = data; + + return spi_write_then_read(spi, buf, 2, NULL, 0); +} + +static int ds1347_read_time(struct device *dev, struct rtc_time *dt) +{ + struct spi_device *spi = to_spi_device(dev); + int err; + unsigned char buf[8]; + + buf[0] = DS1347_CLOCK_BURST | 0x80; + + err = spi_write_then_read(spi, buf, 1, buf, 8); + if (err) + return err; + + dt->tm_sec = bcd2bin(buf[0]); + dt->tm_min = bcd2bin(buf[1]); + dt->tm_hour = bcd2bin(buf[2] & 0x3F); + dt->tm_mday = bcd2bin(buf[3]); + dt->tm_mon = bcd2bin(buf[4]) - 1; + dt->tm_wday = bcd2bin(buf[5]) - 1; + dt->tm_year = bcd2bin(buf[6]) + 100; + + return rtc_valid_tm(dt); +} + +static int ds1347_set_time(struct device *dev, struct rtc_time *dt) +{ + struct spi_device *spi = to_spi_device(dev); + unsigned char buf[9]; + + buf[0] = DS1347_CLOCK_BURST & 0x7F; + buf[1] = bin2bcd(dt->tm_sec); + buf[2] = bin2bcd(dt->tm_min); + buf[3] = (bin2bcd(dt->tm_hour) & 0x3F); + buf[4] = bin2bcd(dt->tm_mday); + buf[5] = bin2bcd(dt->tm_mon + 1); + buf[6] = bin2bcd(dt->tm_wday + 1); + + /* year in linux is from 1900 i.e in range of 100 + in rtc it is from 00 to 99 */ + dt->tm_year = dt->tm_year % 100; + + buf[7] = bin2bcd(dt->tm_year); + buf[8] = bin2bcd(0x00); + + /* write the rtc settings */ + return spi_write_then_read(spi, buf, 9, NULL, 0); +} + +static const struct rtc_class_ops ds1347_rtc_ops = { + .read_time = ds1347_read_time, + .set_time = ds1347_set_time, +}; + +static int ds1347_probe(struct spi_device *spi) +{ + struct rtc_device *rtc; + unsigned char data; + int res; + + /* spi setup with ds1347 in mode 3 and bits per word as 8 */ + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + + /* RTC Settings */ + res = ds1347_read_reg(&spi->dev, DS1347_SECONDS_REG, &data); + if (res) + return res; + + /* Disable the write protect of rtc */ + ds1347_read_reg(&spi->dev, DS1347_CONTROL_REG, &data); + data = data & ~(1<<7); + ds1347_write_reg(&spi->dev, DS1347_CONTROL_REG, data); + + /* Enable the oscillator , disable the oscillator stop flag, + and glitch filter to reduce current consumption */ + ds1347_read_reg(&spi->dev, DS1347_STATUS_REG, &data); + data = data & 0x1B; + ds1347_write_reg(&spi->dev, DS1347_STATUS_REG, data); + + /* display the settings */ + ds1347_read_reg(&spi->dev, DS1347_CONTROL_REG, &data); + dev_info(&spi->dev, "DS1347 RTC CTRL Reg = 0x%02x\n", data); + + ds1347_read_reg(&spi->dev, DS1347_STATUS_REG, &data); + dev_info(&spi->dev, "DS1347 RTC Status Reg = 0x%02x\n", data); + + rtc = devm_rtc_device_register(&spi->dev, "ds1347", + &ds1347_rtc_ops, THIS_MODULE); + + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + spi_set_drvdata(spi, rtc); + + return 0; +} + +static struct spi_driver ds1347_driver = { + .driver = { + .name = "ds1347", + .owner = THIS_MODULE, + }, + .probe = ds1347_probe, +}; + +module_spi_driver(ds1347_driver); + +MODULE_DESCRIPTION("DS1347 SPI RTC DRIVER"); +MODULE_AUTHOR("Raghavendra C Ganiga "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 67ab2440b40610b3b91068844640df6d3de3464f Mon Sep 17 00:00:00 2001 From: Gregory Hermant Date: Thu, 3 Apr 2014 14:50:17 -0700 Subject: drivers/rtc/rtc-rv3029c2.c: fix potential race condition RTC drivers must not return an error after device registration. Signed-off-by: Gregory Hermant Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-rv3029c2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 1a779a67ff66..e9ac5a43be1a 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -395,6 +395,12 @@ static int rv3029c2_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL)) return -ENODEV; + rc = rv3029c2_i2c_get_sr(client, buf); + if (rc < 0) { + dev_err(&client->dev, "reading status failed\n"); + return rc; + } + rtc = devm_rtc_device_register(&client->dev, client->name, &rv3029c2_rtc_ops, THIS_MODULE); @@ -403,12 +409,6 @@ static int rv3029c2_probe(struct i2c_client *client, i2c_set_clientdata(client, rtc); - rc = rv3029c2_i2c_get_sr(client, buf); - if (rc < 0) { - dev_err(&client->dev, "reading status failed\n"); - return rc; - } - return 0; } -- cgit v1.2.3 From dc9d8887408ac3dfd907b826c5dfdfe953c21a0f Mon Sep 17 00:00:00 2001 From: Adam Thomson Date: Thu, 3 Apr 2014 14:50:18 -0700 Subject: drivers/rtc/rtc-da9055.c: remove use of regmap_irq_get_virq() Using platform_get_irq_byname() to retrieve the IRQ number returns the VIRQ number rather than the local IRQ number for the device. Passing that value then into regmap_irq_get_virq() causes a failure because the function is expecting the local IRQ number (e.g. 0, 1, 2, 3, etc). This patch removes use of regmap_irq_get_virq() to prevent this failure from happening Signed-off-by: Adam Thomson Cc: Alessandro Zummo Cc: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-da9055.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c index 48cb2ac3bd3e..a825491331c8 100644 --- a/drivers/rtc/rtc-da9055.c +++ b/drivers/rtc/rtc-da9055.c @@ -302,7 +302,9 @@ static int da9055_rtc_probe(struct platform_device *pdev) } alm_irq = platform_get_irq_byname(pdev, "ALM"); - alm_irq = regmap_irq_get_virq(rtc->da9055->irq_data, alm_irq); + if (alm_irq < 0) + return alm_irq; + ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL, da9055_rtc_alm_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, -- cgit v1.2.3 From ebe753357ecd10a6dc521dc89f2bfea6c0ee0ca2 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Thu, 3 Apr 2014 14:50:19 -0700 Subject: drivers/rtc/rtc-s3c.c: remove NO_IRQ macro NO_IRQ may be defined as '(unsigned int) -1' in some architectures (arm, sh ...), and either may not be defined in some architectures (arm64) which can enable RTC_DRV_S3C. Also since platform_get_irq returns err-code in case of any error, we do not need to intialize s3c_rtc_alarmno and s3c_rtc_tickno. Signed-off-by: Pankaj Dubey Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index c4cde9c08f1f..4958a363b2c7 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -48,8 +48,8 @@ struct s3c_rtc_drv_data { static struct clk *rtc_clk; static void __iomem *s3c_rtc_base; -static int s3c_rtc_alarmno = NO_IRQ; -static int s3c_rtc_tickno = NO_IRQ; +static int s3c_rtc_alarmno; +static int s3c_rtc_tickno; static enum s3c_cpu_type s3c_rtc_cpu_type; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); -- cgit v1.2.3 From 0d71915d27a6bfd896513c5aa3bae4a09ca81c2c Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 14:50:20 -0700 Subject: rtc: treewide: remove excess rtc_device validation The patch "rtc: verify a critical argument to rtc_update_irq() before using it" introduces validation for rtc_device in the RTC core, so there are no need to check this argument for rtc_update_irq() from the drivers. This patch removes such check for the existing rtc_update_irq() users. Signed-off-by: Alexander Shiyan Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1511.c | 3 +-- drivers/rtc/rtc-ds1553.c | 3 +-- drivers/rtc/rtc-stk17ta8.c | 3 +-- drivers/rtc/rtc-tx4939.c | 4 ++-- 4 files changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 4ff20f9dc212..b13d1399b81a 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -371,8 +371,7 @@ ds1511_interrupt(int irq, void *dev_id) events |= RTC_UF; else events |= RTC_AF; - if (likely(pdata->rtc)) - rtc_update_irq(pdata->rtc, 1, events); + rtc_update_irq(pdata->rtc, 1, events); } spin_unlock(&pdata->lock); return events ? IRQ_HANDLED : IRQ_NONE; diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 9ac2fa07dffa..ab56893aac73 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -206,8 +206,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id) events |= RTC_UF; else events |= RTC_AF; - if (likely(pdata->rtc)) - rtc_update_irq(pdata->rtc, 1, events); + rtc_update_irq(pdata->rtc, 1, events); } spin_unlock(&pdata->lock); return events ? IRQ_HANDLED : IRQ_NONE; diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index a176ba614683..35ed49ea1f81 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -214,8 +214,7 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id) events |= RTC_UF; else events |= RTC_AF; - if (likely(pdata->rtc)) - rtc_update_irq(pdata->rtc, 1, events); + rtc_update_irq(pdata->rtc, 1, events); } spin_unlock(&pdata->lock); return events ? IRQ_HANDLED : IRQ_NONE; diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 4f87234e0dee..2e678c681b13 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -176,8 +176,8 @@ static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id) tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP); } spin_unlock(&pdata->lock); - if (likely(pdata->rtc)) - rtc_update_irq(pdata->rtc, 1, events); + rtc_update_irq(pdata->rtc, 1, events); + return IRQ_HANDLED; } -- cgit v1.2.3