From b0c57b5941c4a42698d845ada6a76feeba2d1be9 Mon Sep 17 00:00:00 2001 From: Robert Kmiec Date: Thu, 16 Apr 2015 12:45:01 -0700 Subject: drivers/rtc/rtc-pcf8563.c: simplify return from function This commit does not change any logic here. It just makes the code easier to read. This is how it looked like: If err != 0 return err; else return 0; Signed-off-by: Robert Kmiec Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pcf8563.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 96fb32e7d6f8..0ba7e59929be 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -246,7 +246,6 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) { struct pcf8563 *pcf8563 = i2c_get_clientdata(client); - int err; unsigned char buf[9]; dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " @@ -272,12 +271,8 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; - err = pcf8563_write_block_data(client, PCF8563_REG_SC, + return pcf8563_write_block_data(client, PCF8563_REG_SC, 9 - PCF8563_REG_SC, buf + PCF8563_REG_SC); - if (err) - return err; - - return 0; } #ifdef CONFIG_RTC_INTF_DEV -- cgit v1.2.3 From 7f48b21bdfede2c06e966258317a3bb4be3e4f25 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 16 Apr 2015 12:45:04 -0700 Subject: rtc: stmp3xxx: use optional crystal in low power states MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rtc's status register allows to determine if a 32k crystal is connected to keep the rtc running in low power states provided the corresponding fuse bits were blown correctly during production. (In case they were not, the right frequency can be stated in the device tree.) If there is no such crystal available force the 24 MHz XTAL clock to keep running to retain the right date and time. Otherwise use the crystal to save some power. It would be nice to only switch to the crystal when the XTAL clock is about to be disabled and keep the crystal off when unneeded because XTAL is always on while the chip is powered on. But as sudden power loss isn't detectable this is not save. Signed-off-by: Uwe Kleine-König Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .../devicetree/bindings/rtc/stmp3xxx-rtc.txt | 5 ++ drivers/rtc/rtc-stmp3xxx.c | 66 ++++++++++++++++++++-- 2 files changed, 65 insertions(+), 6 deletions(-) (limited to 'drivers/rtc') diff --git a/Documentation/devicetree/bindings/rtc/stmp3xxx-rtc.txt b/Documentation/devicetree/bindings/rtc/stmp3xxx-rtc.txt index b800070fe6e9..fa6a94226669 100644 --- a/Documentation/devicetree/bindings/rtc/stmp3xxx-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/stmp3xxx-rtc.txt @@ -7,6 +7,11 @@ Required properties: region. - interrupts: rtc alarm interrupt +Optional properties: +- stmp,crystal-freq: override crystal frequency as determined from fuse bits. + Only <32000> and <32768> are possible for the hardware. Use <0> for + "no crystal". + Example: rtc@80056000 { diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 2939cdcb2688..eb09eddf39b8 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -42,6 +42,8 @@ #define STMP3XXX_RTC_STAT 0x10 #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 +#define STMP3XXX_RTC_STAT_XTAL32000_PRESENT 0x10000000 +#define STMP3XXX_RTC_STAT_XTAL32768_PRESENT 0x08000000 #define STMP3XXX_RTC_SECONDS 0x30 @@ -52,9 +54,13 @@ #define STMP3XXX_RTC_PERSISTENT0 0x60 #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 -#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 -#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 -#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 +#define STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE (1 << 0) +#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN (1 << 1) +#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN (1 << 2) +#define STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP (1 << 4) +#define STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP (1 << 5) +#define STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ (1 << 6) +#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE (1 << 7) #define STMP3XXX_RTC_PERSISTENT1 0x70 /* missing bitmask in headers */ @@ -248,6 +254,9 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) { struct stmp3xxx_rtc_data *rtc_data; struct resource *r; + u32 rtc_stat; + u32 pers0_set, pers0_clr; + u32 crystalfreq = 0; int err; rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL); @@ -268,8 +277,8 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) rtc_data->irq_alarm = platform_get_irq(pdev, 0); - if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & - STMP3XXX_RTC_STAT_RTC_PRESENT)) { + rtc_stat = readl(rtc_data->io + STMP3XXX_RTC_STAT); + if (!(rtc_stat & STMP3XXX_RTC_STAT_RTC_PRESENT)) { dev_err(&pdev->dev, "no device onboard\n"); return -ENODEV; } @@ -282,9 +291,54 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) return err; } + /* + * Obviously the rtc needs a clock input to be able to run. + * This clock can be provided by an external 32k crystal. If that one is + * missing XTAL must not be disabled in suspend which consumes a + * lot of power. Normally the presence and exact frequency (supported + * are 32000 Hz and 32768 Hz) is detectable from fuses, but as reality + * proves these fuses are not blown correctly on all machines, so the + * frequency can be overridden in the device tree. + */ + if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32000_PRESENT) + crystalfreq = 32000; + else if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32768_PRESENT) + crystalfreq = 32768; + + of_property_read_u32(pdev->dev.of_node, "stmp,crystal-freq", + &crystalfreq); + + switch (crystalfreq) { + case 32000: + /* keep 32kHz crystal running in low-power mode */ + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ | + STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP; + break; + case 32768: + /* keep 32.768kHz crystal running in low-power mode */ + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ; + break; + default: + dev_warn(&pdev->dev, + "invalid crystal-freq specified in device-tree. Assuming no crystal\n"); + /* fall-through */ + case 0: + /* keep XTAL on in low-power mode */ + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP; + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; + } + + writel(pers0_set, rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); + writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | - STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, + STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE | pers0_clr, rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | -- cgit v1.2.3 From e706974dc3e2f44891e736f4a96eb88b60356178 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 16 Apr 2015 12:45:07 -0700 Subject: drivers/rtc/rtc-em3027.c: add device tree support Set the of_match_table for this driver so that devices can be described in the device tree. This device is used in the Trimslice and is already defined in the Trimslice device tree. Signed-off-by: Peter Robinson Cc: Mike Rapoport Cc: Alessandro Zummo Cc: Grant Likely Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-em3027.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index fccf36699245..4f4930a2004c 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -15,6 +15,7 @@ #include #include #include +#include /* Registers */ #define EM3027_REG_ON_OFF_CTRL 0x00 @@ -135,10 +136,20 @@ static struct i2c_device_id em3027_id[] = { { "em3027", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, em3027_id); + +#ifdef CONFIG_OF +static const struct of_device_id em3027_of_match[] = { + { .compatible = "emmicro,em3027", }, + {} +}; +MODULE_DEVICE_TABLE(of, em3027_of_match); +#endif static struct i2c_driver em3027_driver = { .driver = { .name = "rtc-em3027", + .of_match_table = of_match_ptr(em3027_of_match), }, .probe = &em3027_probe, .id_table = em3027_id, -- cgit v1.2.3 From 86e66604fca053e5ecb2427538aa233637119409 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 16 Apr 2015 12:45:09 -0700 Subject: drivers/rtc/rtc-x1205.c: use sign_extend32() for sign extension Despite its name, sign_extend32() is safe to use for 8 bit types too. (See https://lkml.org/lkml/2015/1/18/289). Signed-off-by: Martin Kepplinger Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-x1205.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index b1de58e0b3d0..5638b7ba8b06 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -22,6 +22,7 @@ #include #include #include +#include #define DRV_VERSION "1.0.8" @@ -366,8 +367,7 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) * perform sign extension. The formula is * Catr = (atr * 0.25pF) + 11.00pF. */ - if (atr & 0x20) - atr |= 0xC0; + atr = sign_extend32(atr, 5); dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __func__, atr, atr); -- cgit v1.2.3 From aed98b9a1be6fcf1685dfd37f0a3e78e92a21f7d Mon Sep 17 00:00:00 2001 From: Floris Bos Date: Thu, 16 Apr 2015 12:45:12 -0700 Subject: rtc: hctosys: do not treat lack of RTC device as error When using device trees on the ARM platform, it is not certain at compile time whether or not the system will have a RTC. If one enables CONFIG_HCTOSYS just in case the system booted has a RTC, and it turns out not to be, this will result in a big fat "unable to open rtc device" error being printed to console, even when "quiet" is set in the kernel cmdline. Fix this by outputting the message with loglevel info instead. Signed-off-by: Floris Bos Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/hctosys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index 6c719f23520a..fb4251de7ce1 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c @@ -32,7 +32,7 @@ static int __init rtc_hctosys(void) struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (rtc == NULL) { - pr_err("%s: unable to open rtc device (%s)\n", + pr_info("%s: unable to open rtc device (%s)\n", __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); goto err_open; } -- cgit v1.2.3 From 24e1455493dae5ce4b15f83d6ad549befd15f980 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Thu, 16 Apr 2015 12:45:15 -0700 Subject: drivers/rtc/rtc-s3c.c: delete duplicate clock control The current functions in s3c-rtc driver execute clk_enable/disable() to control clocks and some functions execute s3c_rtc_alarm_clk_enable() unnecessarily. So this patch deletes the duplicate clock control and spilts s3c_rtc_alarm_clk_enable() out as s3c_rtc_enable_clk()/s3c_rtc_disable_clk() to improve readability. Signed-off-by: Chanwoo Choi Cc: Alessandro Zummo Cc: Kukjin Kim Cc: Inki Dae Cc: Kyungmin Park Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 163 ++++++++++++-------------------------------------- 1 file changed, 39 insertions(+), 124 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index f4cf6851fae9..fb0c569765c6 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -39,7 +39,6 @@ struct s3c_rtc { void __iomem *base; struct clk *rtc_clk; struct clk *rtc_src_clk; - bool enabled; struct s3c_rtc_data *data; @@ -67,26 +66,25 @@ struct s3c_rtc_data { void (*disable) (struct s3c_rtc *info); }; -static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable) +static void s3c_rtc_enable_clk(struct s3c_rtc *info) { unsigned long irq_flags; spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); - if (enable) { - if (!info->enabled) { - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - info->enabled = true; - } - } else { - if (info->enabled) { - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - info->enabled = false; - } - } + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); +} + +static void s3c_rtc_disable_clk(struct s3c_rtc *info) +{ + unsigned long irq_flags; + + spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); } @@ -119,20 +117,16 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); + tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; if (enabled) tmp |= S3C2410_RTCALM_ALMEN; writeb(tmp, info->base + S3C2410_RTCALM); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - s3c_rtc_alarm_clk_enable(info, enabled); + s3c_rtc_disable_clk(info); return 0; } @@ -143,18 +137,12 @@ static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) if (!is_power_of_2(freq)) return -EINVAL; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); spin_lock_irq(&info->pie_lock); if (info->data->set_freq) info->data->set_freq(info, freq); spin_unlock_irq(&info->pie_lock); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); return 0; } @@ -165,9 +153,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) struct s3c_rtc *info = dev_get_drvdata(dev); unsigned int have_retried = 0; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); retry_get_time: rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN); @@ -194,6 +180,8 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); + s3c_rtc_disable_clk(info); + rtc_tm->tm_year += 100; dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n", @@ -202,10 +190,6 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_mon -= 1; - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return rtc_valid_tm(rtc_tm); } @@ -225,9 +209,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) return -EINVAL; } - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC); writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN); @@ -236,9 +218,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON); writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_disable_clk(info); return 0; } @@ -249,9 +229,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *alm_tm = &alrm->time; unsigned int alm_en; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC); alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN); @@ -262,6 +240,8 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) alm_en = readb(info->base + S3C2410_RTCALM); + s3c_rtc_disable_clk(info); + alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", @@ -269,9 +249,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); - /* decode the alarm enable field */ - if (alm_en & S3C2410_RTCALM_SECEN) alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); else @@ -304,10 +282,6 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) else alm_tm->tm_year = -1; - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return 0; } @@ -317,15 +291,13 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *tm = &alrm->time; unsigned int alrm_en; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", alrm->enabled, 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); + s3c_rtc_enable_clk(info); + alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; writeb(0x00, info->base + S3C2410_RTCALM); @@ -348,11 +320,9 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) writeb(alrm_en, info->base + S3C2410_RTCALM); - s3c_rtc_setaie(dev, alrm->enabled); + s3c_rtc_disable_clk(info); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_setaie(dev, alrm->enabled); return 0; } @@ -361,16 +331,12 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); if (info->data->enable_tick) info->data->enable_tick(info, seq); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_disable_clk(info); return 0; } @@ -388,10 +354,6 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info) { unsigned int con, tmp; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - con = readw(info->base + S3C2410_RTCCON); /* re-enable the device, and check it is ok */ if ((con & S3C2410_RTCCON_RTCEN) == 0) { @@ -417,20 +379,12 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info) writew(tmp & ~S3C2410_RTCCON_CLKRST, info->base + S3C2410_RTCCON); } - - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); } static void s3c24xx_rtc_disable(struct s3c_rtc *info) { unsigned int con; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - con = readw(info->base + S3C2410_RTCCON); con &= ~S3C2410_RTCCON_RTCEN; writew(con, info->base + S3C2410_RTCCON); @@ -438,28 +392,16 @@ static void s3c24xx_rtc_disable(struct s3c_rtc *info) con = readb(info->base + S3C2410_TICNT); con &= ~S3C2410_TICNT_ENABLE; writeb(con, info->base + S3C2410_TICNT); - - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); } static void s3c6410_rtc_disable(struct s3c_rtc *info) { unsigned int con; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - con = readw(info->base + S3C2410_RTCCON); con &= ~S3C64XX_RTCCON_TICEN; con &= ~S3C2410_RTCCON_RTCEN; writew(con, info->base + S3C2410_RTCCON); - - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); } static int s3c_rtc_remove(struct platform_device *pdev) @@ -598,15 +540,16 @@ static int s3c_rtc_probe(struct platform_device *pdev) s3c_rtc_setfreq(info, 1); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_disable_clk(info); return 0; err_nortc: if (info->data->disable) info->data->disable(info); + + if (info->data->needs_src_clk) + clk_disable_unprepare(info->rtc_src_clk); clk_disable_unprepare(info->rtc_clk); return ret; @@ -618,9 +561,7 @@ static int s3c_rtc_suspend(struct device *dev) { struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); /* save TICNT for anyone using periodic interrupts */ if (info->data->save_tick_cnt) @@ -636,10 +577,6 @@ static int s3c_rtc_suspend(struct device *dev) dev_err(dev, "enable_irq_wake failed\n"); } - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return 0; } @@ -647,25 +584,19 @@ static int s3c_rtc_resume(struct device *dev) { struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - if (info->data->enable) info->data->enable(info); if (info->data->restore_tick_cnt) info->data->restore_tick_cnt(info); + s3c_rtc_disable_clk(info); + if (device_may_wakeup(dev) && info->wake_en) { disable_irq_wake(info->irq_alarm); info->wake_en = false; } - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return 0; } #endif @@ -673,29 +604,13 @@ static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) { - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - - s3c_rtc_alarm_clk_enable(info, false); } static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) { - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); writeb(mask, info->base + S3C2410_INTP); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - - s3c_rtc_alarm_clk_enable(info, false); } static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq) -- cgit v1.2.3 From ac2a2726661a8f8f74af0d499cb16b3adf90d764 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 16 Apr 2015 12:45:18 -0700 Subject: drivers/rtc/rtc-ab-b5ze-s3.c: constify struct regmap_config The regmap_config struct may be const because it is not modified by the driver and regmap_init() accepts pointer to const. Signed-off-by: Krzysztof Kozlowski Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ab-b5ze-s3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index cfc2ef98d393..b5cbc1bf5a3e 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -881,7 +881,7 @@ static const struct rtc_class_ops rtc_ops = { .alarm_irq_enable = abb5zes3_rtc_alarm_irq_enable, }; -static struct regmap_config abb5zes3_rtc_regmap_config = { +static const struct regmap_config abb5zes3_rtc_regmap_config = { .reg_bits = 8, .val_bits = 8, }; -- cgit v1.2.3 From 269812de8b1c28cd477a3f9cc9793047f0de530e Mon Sep 17 00:00:00 2001 From: Joshua Kinard Date: Thu, 16 Apr 2015 12:45:21 -0700 Subject: drivers/rtc/rtc-ds1685.c: remove .owner assignment from platform_driver The rtc driver core now sets the platform_driver 'owner' property, so remove the assignment from the DS1685 driver. Fixes: aaaf5fbf56f1: "rtc: add driver for DS1685 family of real time clocks" Signed-off-by: Joshua Kinard Reported-by: kbuild test robot Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1685.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 803869c7d7c2..7a7c8de7c92c 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -2139,7 +2139,6 @@ ds1685_rtc_remove(struct platform_device *pdev) static struct platform_driver ds1685_rtc_driver = { .driver = { .name = "rtc-ds1685", - .owner = THIS_MODULE, }, .probe = ds1685_rtc_probe, .remove = ds1685_rtc_remove, -- cgit v1.2.3 From 52ef84d566dc145b4d469f06667c5fa3118fdd44 Mon Sep 17 00:00:00 2001 From: Joshua Kinard Date: Thu, 16 Apr 2015 12:45:23 -0700 Subject: drivers/rtc/rtc-ds1685.c: fix sparse warnings Fix two minor sparse warnings: CHECK drivers/rtc/rtc-ds1685.c drivers/rtc/rtc-ds1685.c:2178:1: warning: function 'ds1685_rtc_poweroff' with external linkage has definition drivers/rtc/rtc-ds1685.c:802:23: warning: Using plain integer as NULL pointer Fixes: aaaf5fbf56f1 ("rtc: add driver for DS1685 family of real time clocks") Signed-off-by: Joshua Kinard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1685.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 7a7c8de7c92c..70202098a8ce 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -799,7 +799,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq) struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = platform_get_drvdata(pdev); u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8]; - char *model = '\0'; + char *model; #ifdef CONFIG_RTC_DS1685_PROC_REGS char bits[NUM_REGS][(NUM_BITS * NUM_SPACES) + NUM_BITS + 1]; #endif @@ -2174,7 +2174,7 @@ module_exit(ds1685_rtc_exit); * ds1685_rtc_poweroff - uses the RTC chip to power the system off. * @pdev: pointer to platform_device structure. */ -extern void __noreturn +void __noreturn ds1685_rtc_poweroff(struct platform_device *pdev) { u8 ctrla, ctrl4a, ctrl4b; -- cgit v1.2.3 From 03cc1625e1f2e9fc6910af4174c942d56292f556 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Thu, 16 Apr 2015 12:45:26 -0700 Subject: drivers/rtc/rtc-da9052.c: add extra reads with timeouts to avoid returning partially updated values The RTC is in a different clock domain so a quick read after write can retrieve a mangled value of the old/new values Signed-off-by: Adam Ward Tested-by: Adam Ward Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-da9052.c | 87 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 21 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 613c43b7e9ae..ead02fad2de5 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,8 @@ #define rtc_err(rtc, fmt, ...) \ dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__) +#define DA9052_GET_TIME_RETRIES 5 + struct da9052_rtc { struct rtc_device *rtc; struct da9052 *da9052; @@ -58,22 +61,43 @@ static irqreturn_t da9052_rtc_irq(int irq, void *data) static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) { int ret; - uint8_t v[5]; + uint8_t v[2][5]; + int idx = 1; + int timeout = DA9052_GET_TIME_RETRIES; - ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, v); - if (ret != 0) { + ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, &v[0][0]); + if (ret) { rtc_err(rtc, "Failed to group read ALM: %d\n", ret); return ret; } - rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100; - rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1; - rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY; - rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR; - rtc_tm->tm_min = v[0] & DA9052_RTC_MIN; + do { + ret = da9052_group_read(rtc->da9052, + DA9052_ALARM_MI_REG, 5, &v[idx][0]); + if (ret) { + rtc_err(rtc, "Failed to group read ALM: %d\n", ret); + return ret; + } - ret = rtc_valid_tm(rtc_tm); - return ret; + if (memcmp(&v[0][0], &v[1][0], 5) == 0) { + rtc_tm->tm_year = (v[0][4] & DA9052_RTC_YEAR) + 100; + rtc_tm->tm_mon = (v[0][3] & DA9052_RTC_MONTH) - 1; + rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; + rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; + rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; + + ret = rtc_valid_tm(rtc_tm); + return ret; + } + + idx = (1-idx); + msleep(20); + + } while (timeout--); + + rtc_err(rtc, "Timed out reading alarm time\n"); + + return -EIO; } static int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) @@ -135,24 +159,45 @@ static int da9052_rtc_get_alarm_status(struct da9052_rtc *rtc) static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) { struct da9052_rtc *rtc = dev_get_drvdata(dev); - uint8_t v[6]; int ret; + uint8_t v[2][6]; + int idx = 1; + int timeout = DA9052_GET_TIME_RETRIES; - ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v); - if (ret < 0) { + ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, &v[0][0]); + if (ret) { rtc_err(rtc, "Failed to read RTC time : %d\n", ret); return ret; } - rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100; - rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1; - rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY; - rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR; - rtc_tm->tm_min = v[1] & DA9052_RTC_MIN; - rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC; + do { + ret = da9052_group_read(rtc->da9052, + DA9052_COUNT_S_REG, 6, &v[idx][0]); + if (ret) { + rtc_err(rtc, "Failed to read RTC time : %d\n", ret); + return ret; + } - ret = rtc_valid_tm(rtc_tm); - return ret; + if (memcmp(&v[0][0], &v[1][0], 6) == 0) { + rtc_tm->tm_year = (v[0][5] & DA9052_RTC_YEAR) + 100; + rtc_tm->tm_mon = (v[0][4] & DA9052_RTC_MONTH) - 1; + rtc_tm->tm_mday = v[0][3] & DA9052_RTC_DAY; + rtc_tm->tm_hour = v[0][2] & DA9052_RTC_HOUR; + rtc_tm->tm_min = v[0][1] & DA9052_RTC_MIN; + rtc_tm->tm_sec = v[0][0] & DA9052_RTC_SEC; + + ret = rtc_valid_tm(rtc_tm); + return ret; + } + + idx = (1-idx); + msleep(20); + + } while (timeout--); + + rtc_err(rtc, "Timed out reading time\n"); + + return -EIO; } static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm) -- cgit v1.2.3 From ae824c484c85d77e3f272515aafb410bbade13fa Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Thu, 16 Apr 2015 12:45:29 -0700 Subject: drivers/rtc/rtc-da9052.c: add constraints to set valid year Signed-off-by: Adam Ward Tested-by: Adam Ward Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-da9052.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index ead02fad2de5..acc3e5a1f61a 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -206,6 +206,10 @@ static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm) uint8_t v[6]; int ret; + /* DA9052 only has 6 bits for year - to represent 2000-2063 */ + if ((tm->tm_year < 100) || (tm->tm_year > 163)) + return -EINVAL; + rtc = dev_get_drvdata(dev); v[0] = tm->tm_sec; @@ -243,6 +247,10 @@ static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *tm = &alrm->time; struct da9052_rtc *rtc = dev_get_drvdata(dev); + /* DA9052 only has 6 bits for year - to represent 2000-2063 */ + if ((tm->tm_year < 100) || (tm->tm_year > 163)) + return -EINVAL; + ret = da9052_rtc_enable_alarm(rtc, 0); if (ret < 0) return ret; -- cgit v1.2.3 From d174a024007dd543fd066cffd8eb727806a62da6 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Thu, 16 Apr 2015 12:45:32 -0700 Subject: drivers/rtc/rtc-da9052.c: register ability of alarm to wake device from suspend Signed-off-by: Adam Ward Tested-by: Adam Ward Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-da9052.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index acc3e5a1f61a..1ba4371cbc2d 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -309,6 +309,8 @@ static int da9052_rtc_probe(struct platform_device *pdev) return ret; } + device_init_wakeup(&pdev->dev, true); + rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &da9052_rtc_ops, THIS_MODULE); return PTR_ERR_OR_ZERO(rtc->rtc); -- cgit v1.2.3 From b3288a43b4dacd2b4d2b24726d7b469d8ade5120 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 16 Apr 2015 12:45:34 -0700 Subject: drivers/rtc/rtc-hym8563.c: return clock rate even when clock is disabled When the clock is disabled, do not return a rate of 0 but instead return the rate the clock will be running at after it gets enabled. This prevents problems when the core clock code is trying to determine a suitable rate, while the clock is still off. Signed-off-by: Heiko Stuebner Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-hym8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index b936bb4096b5..d4a65619ef14 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -309,7 +309,7 @@ static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw, struct i2c_client *client = hym8563->client; int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT); - if (ret < 0 || ret & HYM8563_CLKOUT_DISABLE) + if (ret < 0) return 0; ret &= HYM8563_CLKOUT_MASK; -- cgit v1.2.3 From ba17220878bf74b95ea24de568939e7b9e1b02db Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 16 Apr 2015 12:45:40 -0700 Subject: rtc: driver for Conexant Digicolor CX92755 on-chip RTC Add driver for the RTC hardware block on the Conexant CX92755 SoC, from the Digicolor series of SoCs. Tested on the Equinox evaluation board for the CX92755 chip. [akpm@linux-foundation.org: build command arrays at compile-time] Signed-off-by: Baruch Siach Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-digicolor.c | 227 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 drivers/rtc/rtc-digicolor.c (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b5b5c3d485d6..faeee2d2550b 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1111,6 +1111,16 @@ config RTC_DRV_DAVINCI This driver can also be built as a module. If so, the module will be called rtc-davinci. +config RTC_DRV_DIGICOLOR + tristate "Conexant Digicolor RTC" + depends on ARCH_DIGICOLOR + help + If you say yes here you get support for the RTC on Conexant + Digicolor platforms. This currently includes the CX92755 SoC. + + This driver can also be built as a module. If so, the module + will be called rtc-digicolor. + config RTC_DRV_IMXDI tristate "Freescale IMX DryIce Real Time Clock" depends on ARCH_MXC diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 69c87062b098..c31731c29762 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o +obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o diff --git a/drivers/rtc/rtc-digicolor.c b/drivers/rtc/rtc-digicolor.c new file mode 100644 index 000000000000..8d05596a6765 --- /dev/null +++ b/drivers/rtc/rtc-digicolor.c @@ -0,0 +1,227 @@ +/* + * Real Time Clock driver for Conexant Digicolor + * + * Copyright (C) 2015 Paradox Innovation Ltd. + * + * Author: Baruch Siach + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DC_RTC_CONTROL 0x0 +#define DC_RTC_TIME 0x8 +#define DC_RTC_REFERENCE 0xc +#define DC_RTC_ALARM 0x10 +#define DC_RTC_INTFLAG_CLEAR 0x14 +#define DC_RTC_INTENABLE 0x16 + +#define DC_RTC_CMD_MASK 0xf +#define DC_RTC_GO_BUSY BIT(7) + +#define CMD_NOP 0 +#define CMD_RESET 1 +#define CMD_WRITE 3 +#define CMD_READ 4 + +#define CMD_DELAY_US (10*1000) +#define CMD_TIMEOUT_US (500*CMD_DELAY_US) + +struct dc_rtc { + struct rtc_device *rtc_dev; + void __iomem *regs; +}; + +static int dc_rtc_cmds(struct dc_rtc *rtc, const u8 *cmds, int len) +{ + u8 val; + int i, ret; + + for (i = 0; i < len; i++) { + writeb_relaxed((cmds[i] & DC_RTC_CMD_MASK) | DC_RTC_GO_BUSY, + rtc->regs + DC_RTC_CONTROL); + ret = readb_relaxed_poll_timeout( + rtc->regs + DC_RTC_CONTROL, val, + !(val & DC_RTC_GO_BUSY), CMD_DELAY_US, CMD_TIMEOUT_US); + if (ret < 0) + return ret; + } + + return 0; +} + +static int dc_rtc_read(struct dc_rtc *rtc, unsigned long *val) +{ + static const u8 read_cmds[] = {CMD_READ, CMD_NOP}; + u32 reference, time1, time2; + int ret; + + ret = dc_rtc_cmds(rtc, read_cmds, ARRAY_SIZE(read_cmds)); + if (ret < 0) + return ret; + + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); + time1 = readl_relaxed(rtc->regs + DC_RTC_TIME); + /* Read twice to ensure consistency */ + while (1) { + time2 = readl_relaxed(rtc->regs + DC_RTC_TIME); + if (time1 == time2) + break; + time1 = time2; + } + + *val = reference + time1; + return 0; +} + +static int dc_rtc_write(struct dc_rtc *rtc, u32 val) +{ + static const u8 write_cmds[] = {CMD_WRITE, CMD_NOP, CMD_RESET, CMD_NOP}; + + writel_relaxed(val, rtc->regs + DC_RTC_REFERENCE); + return dc_rtc_cmds(rtc, write_cmds, ARRAY_SIZE(write_cmds)); +} + +static int dc_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + unsigned long now; + int ret; + + ret = dc_rtc_read(rtc, &now); + if (ret < 0) + return ret; + rtc_time64_to_tm(now, tm); + + return 0; +} + +static int dc_rtc_set_mmss(struct device *dev, unsigned long secs) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + + return dc_rtc_write(rtc, secs); +} + +static int dc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + u32 alarm_reg, reference; + unsigned long now; + int ret; + + alarm_reg = readl_relaxed(rtc->regs + DC_RTC_ALARM); + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); + rtc_time64_to_tm(reference + alarm_reg, &alarm->time); + + ret = dc_rtc_read(rtc, &now); + if (ret < 0) + return ret; + + alarm->pending = alarm_reg + reference > now; + alarm->enabled = readl_relaxed(rtc->regs + DC_RTC_INTENABLE); + + return 0; +} + +static int dc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + time64_t alarm_time; + u32 reference; + + alarm_time = rtc_tm_to_time64(&alarm->time); + + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); + writel_relaxed(alarm_time - reference, rtc->regs + DC_RTC_ALARM); + + writeb_relaxed(!!alarm->enabled, rtc->regs + DC_RTC_INTENABLE); + + return 0; +} + +static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + + writeb_relaxed(!!enabled, rtc->regs + DC_RTC_INTENABLE); + + return 0; +} + +static struct rtc_class_ops dc_rtc_ops = { + .read_time = dc_rtc_read_time, + .set_mmss = dc_rtc_set_mmss, + .read_alarm = dc_rtc_read_alarm, + .set_alarm = dc_rtc_set_alarm, + .alarm_irq_enable = dc_rtc_alarm_irq_enable, +}; + +static irqreturn_t dc_rtc_irq(int irq, void *dev_id) +{ + struct dc_rtc *rtc = dev_id; + + writeb_relaxed(1, rtc->regs + DC_RTC_INTFLAG_CLEAR); + rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); + + return IRQ_HANDLED; +} + +static int __init dc_rtc_probe(struct platform_device *pdev) +{ + struct resource *res; + struct dc_rtc *rtc; + int irq, ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rtc->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rtc->regs)) + return PTR_ERR(rtc->regs); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + ret = devm_request_irq(&pdev->dev, irq, dc_rtc_irq, 0, pdev->name, rtc); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, rtc); + rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, + &dc_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + + return 0; +} + +static const struct of_device_id dc_dt_ids[] = { + { .compatible = "cnxt,cx92755-rtc" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, dc_dt_ids); + +static struct platform_driver dc_rtc_driver = { + .driver = { + .name = "digicolor_rtc", + .of_match_table = of_match_ptr(dc_dt_ids), + }, +}; +module_platform_driver_probe(dc_rtc_driver, dc_rtc_probe); + +MODULE_AUTHOR("Baruch Siach "); +MODULE_DESCRIPTION("Conexant Digicolor Realtime Clock Driver (RTC)"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 5281f94ae7f54d2d1a48dbc10223fd12d2aea716 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 16 Apr 2015 12:45:45 -0700 Subject: drivers/rtc/rtc-s5m.c: add support for S2MPS13 RTC The S2MPS13 RTC is almost the same as S2MPS14. The differences when updating alarm are: 1. Set WUDR+AUDR field instead of WUDR+RUDR. 2. Clear the AUDR field later (it is not auto-cleared). Signed-off-by: Krzysztof Kozlowski Cc: Alexandre Belloni Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s5m.c | 20 +++++++++++++++++++- include/linux/mfd/samsung/rtc.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 4008b84246ca..f0cb0ecb3d8d 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -187,6 +187,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info, val &= S5M_ALARM0_STATUS; break; case S2MPS14X: + case S2MPS13X: ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2, &val); val &= S2MPS_ALARM0_STATUS; @@ -252,6 +253,9 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) case S2MPS14X: data |= S2MPS_RTC_RUDR_MASK; break; + case S2MPS13X: + data |= S2MPS13_RTC_AUDR_MASK; + break; default: return -EINVAL; } @@ -265,6 +269,11 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) ret = s5m8767_wait_for_udr_update(info); + /* On S2MPS13 the AUDR is not auto-cleared */ + if (info->device_type == S2MPS13X) + regmap_update_bits(info->regmap, info->regs->rtc_udr_update, + S2MPS13_RTC_AUDR_MASK, 0); + return ret; } @@ -306,7 +315,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) u8 data[info->regs->regs_count]; int ret; - if (info->device_type == S2MPS14X) { + if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) { ret = regmap_update_bits(info->regmap, info->regs->rtc_udr_update, S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK); @@ -329,6 +338,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) case S5M8767X: case S2MPS14X: + case S2MPS13X: s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); break; @@ -355,6 +365,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) break; case S5M8767X: case S2MPS14X: + case S2MPS13X: ret = s5m8767_tm_to_data(tm, data); break; default: @@ -402,6 +413,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) case S5M8767X: case S2MPS14X: + case S2MPS13X: s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); alrm->enabled = 0; for (i = 0; i < info->regs->regs_count; i++) { @@ -450,6 +462,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) case S5M8767X: case S2MPS14X: + case S2MPS13X: for (i = 0; i < info->regs->regs_count; i++) data[i] &= ~ALARM_ENABLE_MASK; @@ -494,6 +507,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) case S5M8767X: case S2MPS14X: + case S2MPS13X: data[RTC_SEC] |= ALARM_ENABLE_MASK; data[RTC_MIN] |= ALARM_ENABLE_MASK; data[RTC_HOUR] |= ALARM_ENABLE_MASK; @@ -533,6 +547,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) case S5M8767X: case S2MPS14X: + case S2MPS13X: s5m8767_tm_to_data(&alrm->time, data); break; @@ -615,6 +630,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) break; case S2MPS14X: + case S2MPS13X: data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); ret = regmap_write(info->regmap, info->regs->ctrl, data[0]); break; @@ -652,6 +668,7 @@ static int s5m_rtc_probe(struct platform_device *pdev) switch (pdata->device_type) { case S2MPS14X: + case S2MPS13X: regmap_cfg = &s2mps14_rtc_regmap_config; info->regs = &s2mps_rtc_regs; alarm_irq = S2MPS14_IRQ_RTCA0; @@ -772,6 +789,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); static const struct platform_device_id s5m_rtc_id[] = { { "s5m-rtc", S5M8767X }, + { "s2mps13-rtc", S2MPS13X }, { "s2mps14-rtc", S2MPS14X }, { }, }; diff --git a/include/linux/mfd/samsung/rtc.h b/include/linux/mfd/samsung/rtc.h index b6401e7661c7..29c30ac36020 100644 --- a/include/linux/mfd/samsung/rtc.h +++ b/include/linux/mfd/samsung/rtc.h @@ -105,6 +105,8 @@ enum s2mps_rtc_reg { #define S5M_RTC_UDR_MASK (1 << S5M_RTC_UDR_SHIFT) #define S2MPS_RTC_WUDR_SHIFT 4 #define S2MPS_RTC_WUDR_MASK (1 << S2MPS_RTC_WUDR_SHIFT) +#define S2MPS13_RTC_AUDR_SHIFT 1 +#define S2MPS13_RTC_AUDR_MASK (1 << S2MPS13_RTC_AUDR_SHIFT) #define S2MPS_RTC_RUDR_SHIFT 0 #define S2MPS_RTC_RUDR_MASK (1 << S2MPS_RTC_RUDR_SHIFT) #define RTC_TCON_SHIFT 1 -- cgit v1.2.3 From 182683e955af4dd2324427129f3b90558d644066 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 16 Apr 2015 12:45:48 -0700 Subject: drivers/rtc/class.c: initialize rtc name early In some error cases RTC name is used before it is initialized: rtc-rs5c372 0-0032: clock needs to be set rtc-rs5c372 0-0032: rs5c372b found, 24hr, driver version 0.6 rtc (null): read_time: fail to read rtc-rs5c372 0-0032: rtc core: registered rtc-rs5c372 as rtc0 Fix by initializing the name early. Signed-off-by: Aaro Koskinen Acked-by: Alexandre Belloni Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/class.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index c29ba7e14304..ea2a315df6b7 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -221,15 +221,15 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, rtc->pie_timer.function = rtc_pie_update_irq; rtc->pie_enabled = 0; + strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); + dev_set_name(&rtc->dev, "rtc%d", id); + /* Check to see if there is an ALARM already set in hw */ err = __rtc_read_alarm(rtc, &alrm); if (!err && !rtc_valid_tm(&alrm.time)) rtc_initialize_alarm(rtc, &alrm); - strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); - dev_set_name(&rtc->dev, "rtc%d", id); - rtc_dev_prepare(rtc); err = device_register(&rtc->dev); -- cgit v1.2.3 From d0bddb512d9c8e1adefc7416ef6c71cba05d62c8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 16 Apr 2015 12:45:51 -0700 Subject: drivers/rtc/interface.c: __rtc_read_time: reduce log level __rtc_read_time logs should be debug logs instead of error logs. For example, when the RTC clock is not set, it's not really useful to print a kernel error log every time someone tries to read the clock: ~ # hwclock -r [ 604.508263] rtc rtc0: read_time: fail to read hwclock: RTC_RD_TIME: Invalid argument If there's a real error, it's likely that lower level or higher level code will tell it anyway. Make these logs debug logs, and also print the error code for the read failure. Signed-off-by: Aaro Koskinen Acked-by: Alexandre Belloni Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/interface.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index d43ee409a5f2..166fc60d8b55 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -31,13 +31,14 @@ static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) memset(tm, 0, sizeof(struct rtc_time)); err = rtc->ops->read_time(rtc->dev.parent, tm); if (err < 0) { - dev_err(&rtc->dev, "read_time: fail to read\n"); + dev_dbg(&rtc->dev, "read_time: fail to read: %d\n", + err); return err; } err = rtc_valid_tm(tm); if (err < 0) - dev_err(&rtc->dev, "read_time: rtc_time isn't valid\n"); + dev_dbg(&rtc->dev, "read_time: rtc_time isn't valid\n"); } return err; } -- cgit v1.2.3 From 521fca18e828cddc94535a1ea5ac33460f1de679 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 16 Apr 2015 12:45:54 -0700 Subject: rtc: hctosys: use function name in the error log Use function name in the error log instead of __FILE__. Signed-off-by: Aaro Koskinen Cc: Alexandre Belloni Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/hctosys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index fb4251de7ce1..91fb5f3c1051 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c @@ -33,7 +33,7 @@ static int __init rtc_hctosys(void) if (rtc == NULL) { pr_info("%s: unable to open rtc device (%s)\n", - __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); + __func__, CONFIG_RTC_HCTOSYS_DEVICE); goto err_open; } -- cgit v1.2.3 From 202fe4c27f427c48ca5660277d743ee8b43fc200 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 16 Apr 2015 12:45:57 -0700 Subject: drivers/rtc/rtc-s3c.c: fix failed first read of RTC time Initialize the device time (if it is wrong) before registering RTC device to fix following error message during rtc-s3c probe: [ 2.215414] rtc (null): read_time: fail to read [ 2.216322] s3c-rtc 10070000.rtc: rtc core: registered s3c as rtc1 Signed-off-by: Krzysztof Kozlowski Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Marek Szyprowski Reviewed-by: Chanwoo Choi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index fb0c569765c6..a313b9b5a27e 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -496,6 +496,22 @@ static int s3c_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); + /* Check RTC Time */ + s3c_rtc_gettime(&pdev->dev, &rtc_tm); + + if (rtc_valid_tm(&rtc_tm)) { + rtc_tm.tm_year = 100; + rtc_tm.tm_mon = 0; + rtc_tm.tm_mday = 1; + rtc_tm.tm_hour = 0; + rtc_tm.tm_min = 0; + rtc_tm.tm_sec = 0; + + s3c_rtc_settime(&pdev->dev, &rtc_tm); + + dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); + } + /* register RTC and exit */ info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, THIS_MODULE); @@ -519,22 +535,6 @@ static int s3c_rtc_probe(struct platform_device *pdev) goto err_nortc; } - /* Check RTC Time */ - s3c_rtc_gettime(&pdev->dev, &rtc_tm); - - if (rtc_valid_tm(&rtc_tm)) { - rtc_tm.tm_year = 100; - rtc_tm.tm_mon = 0; - rtc_tm.tm_mday = 1; - rtc_tm.tm_hour = 0; - rtc_tm.tm_min = 0; - rtc_tm.tm_sec = 0; - - s3c_rtc_settime(&pdev->dev, &rtc_tm); - - dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); - } - if (info->data->select_tick_clk) info->data->select_tick_clk(info); -- cgit v1.2.3 From 9c28bd07c20776cc04aecf04ba5be53fa5fa6dd2 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Thu, 16 Apr 2015 12:46:00 -0700 Subject: drivers/rtc/rtc-omap.c: unlock and lock rtc registers before and after register writes RTC module contains a kicker mechanism to prevent any spurious writes from changing the register values. This mechanism requires two MMR writes to the KICK0 and KICK1 registers with exact data values before the kicker lock mechanism is released. Currently the driver release the lock in the probe and leaves it enabled until the rtc driver removal. This eliminates the idea of preventing spurious writes when RTC driver is loaded. So implement rtc lock and unlock functions before and after register writes. This is as advised by Paul to implement lock and unlock functions in the driver and not to unlock and leave it in probe. The same discussion can be seen here: http://www.mail-archive.com/linux-omap%40vger.kernel.org/msg111588.html Signed-off-by: Lokesh Vutla Acked-by: Alexandre Belloni Cc: Alessandro Zummo Cc: Paul Walmsley Cc: Tero Kristo Cc: Sekhar Nori Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-omap.c | 63 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 11 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 8e5851aa4369..a5ff00931360 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -118,12 +118,15 @@ #define KICK0_VALUE 0x83e70b13 #define KICK1_VALUE 0x95a4f1e0 +struct omap_rtc; + struct omap_rtc_device_type { bool has_32kclk_en; - bool has_kicker; bool has_irqwakeen; bool has_pmic_mode; bool has_power_up_reset; + void (*lock)(struct omap_rtc *rtc); + void (*unlock)(struct omap_rtc *rtc); }; struct omap_rtc { @@ -156,6 +159,26 @@ static inline void rtc_writel(struct omap_rtc *rtc, unsigned int reg, u32 val) writel(val, rtc->base + reg); } +static void am3352_rtc_unlock(struct omap_rtc *rtc) +{ + rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); + rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); +} + +static void am3352_rtc_lock(struct omap_rtc *rtc) +{ + rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); + rtc_writel(rtc, OMAP_RTC_KICK1_REG, 0); +} + +static void default_rtc_unlock(struct omap_rtc *rtc) +{ +} + +static void default_rtc_lock(struct omap_rtc *rtc) +{ +} + /* * We rely on the rtc framework to handle locking (rtc->ops_lock), * so the only other requirement is that register accesses which @@ -186,7 +209,9 @@ static irqreturn_t rtc_irq(int irq, void *dev_id) /* alarm irq? */ if (irq_data & OMAP_RTC_STATUS_ALARM) { + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); + rtc->type->lock(rtc); events |= RTC_IRQF | RTC_AF; } @@ -218,9 +243,11 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; } rtc_wait_not_busy(rtc); + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); if (rtc->type->has_irqwakeen) rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); + rtc->type->lock(rtc); local_irq_enable(); return 0; @@ -293,12 +320,14 @@ static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) local_irq_disable(); rtc_wait_not_busy(rtc); + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_YEARS_REG, tm->tm_year); rtc_write(rtc, OMAP_RTC_MONTHS_REG, tm->tm_mon); rtc_write(rtc, OMAP_RTC_DAYS_REG, tm->tm_mday); rtc_write(rtc, OMAP_RTC_HOURS_REG, tm->tm_hour); rtc_write(rtc, OMAP_RTC_MINUTES_REG, tm->tm_min); rtc_write(rtc, OMAP_RTC_SECONDS_REG, tm->tm_sec); + rtc->type->lock(rtc); local_irq_enable(); @@ -341,6 +370,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) local_irq_disable(); rtc_wait_not_busy(rtc); + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_ALARM_YEARS_REG, alm->time.tm_year); rtc_write(rtc, OMAP_RTC_ALARM_MONTHS_REG, alm->time.tm_mon); rtc_write(rtc, OMAP_RTC_ALARM_DAYS_REG, alm->time.tm_mday); @@ -362,6 +392,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); if (rtc->type->has_irqwakeen) rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); + rtc->type->lock(rtc); local_irq_enable(); @@ -391,6 +422,7 @@ static void omap_rtc_power_off(void) unsigned long now; u32 val; + rtc->type->unlock(rtc); /* enable pmic_power_en control */ val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN); @@ -423,6 +455,7 @@ static void omap_rtc_power_off(void) val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, val | OMAP_RTC_INTERRUPTS_IT_ALARM2); + rtc->type->lock(rtc); /* * Wait for alarm to trigger (within two seconds) and external PMIC to @@ -442,17 +475,21 @@ static struct rtc_class_ops omap_rtc_ops = { static const struct omap_rtc_device_type omap_rtc_default_type = { .has_power_up_reset = true, + .lock = default_rtc_lock, + .unlock = default_rtc_unlock, }; static const struct omap_rtc_device_type omap_rtc_am3352_type = { .has_32kclk_en = true, - .has_kicker = true, .has_irqwakeen = true, .has_pmic_mode = true, + .lock = am3352_rtc_lock, + .unlock = am3352_rtc_unlock, }; static const struct omap_rtc_device_type omap_rtc_da830_type = { - .has_kicker = true, + .lock = am3352_rtc_lock, + .unlock = am3352_rtc_unlock, }; static const struct platform_device_id omap_rtc_id_table[] = { @@ -527,10 +564,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - if (rtc->type->has_kicker) { - rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); - rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); - } + rtc->type->unlock(rtc); /* * disable interrupts @@ -593,6 +627,8 @@ static int __init omap_rtc_probe(struct platform_device *pdev) if (reg != new_ctrl) rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); + rtc->type->lock(rtc); + device_init_wakeup(&pdev->dev, true); rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, @@ -626,8 +662,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) err: device_init_wakeup(&pdev->dev, false); - if (rtc->type->has_kicker) - rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); + rtc->type->lock(rtc); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -646,11 +681,11 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); + rtc->type->unlock(rtc); /* leave rtc running, but disable irqs */ rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); - if (rtc->type->has_kicker) - rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); + rtc->type->lock(rtc); /* Disable the clock/module */ pm_runtime_put_sync(&pdev->dev); @@ -666,6 +701,7 @@ static int omap_rtc_suspend(struct device *dev) rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); + rtc->type->unlock(rtc); /* * FIXME: the RTC alarm is not currently acting as a wakeup event * source on some platforms, and in fact this enable() call is just @@ -675,6 +711,7 @@ static int omap_rtc_suspend(struct device *dev) enable_irq_wake(rtc->irq_alarm); else rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); + rtc->type->lock(rtc); /* Disable the clock/module */ pm_runtime_put_sync(dev); @@ -689,10 +726,12 @@ static int omap_rtc_resume(struct device *dev) /* Enable the clock/module so that we can access the registers */ pm_runtime_get_sync(dev); + rtc->type->unlock(rtc); if (device_may_wakeup(dev)) disable_irq_wake(rtc->irq_alarm); else rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg); + rtc->type->lock(rtc); return 0; } @@ -709,9 +748,11 @@ static void omap_rtc_shutdown(struct platform_device *pdev) * Keep the ALARM interrupt enabled to allow the system to power up on * alarm events. */ + rtc->type->unlock(rtc); mask = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); mask &= OMAP_RTC_INTERRUPTS_IT_ALARM; rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, mask); + rtc->type->lock(rtc); } static struct platform_driver omap_rtc_driver = { -- cgit v1.2.3 From 8608976e2bc9c1df090e1b346c65ec1405e9d03d Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Thu, 16 Apr 2015 12:46:03 -0700 Subject: drivers/rtc/Kconfig: update Kconfig for OMAP RTC RTC is present in AM43xx and DRA7xx also. Updating the Kconfig to depend on ARCH_OMAP or ARCH_DAVINCI Signed-off-by: Lokesh Vutla Acked-by: Alexandre Belloni Cc: Alessandro Zummo Cc: Paul Walmsley Cc: Tero Kristo Cc: Sekhar Nori Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index faeee2d2550b..6149ae01e11f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1131,11 +1131,11 @@ config RTC_DRV_IMXDI will be called "rtc-imxdi". config RTC_DRV_OMAP - tristate "TI OMAP1" - depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX + tristate "TI OMAP Real Time Clock" + depends on ARCH_OMAP || ARCH_DAVINCI help Say "yes" here to support the on chip real time clock - present on TI OMAP1, AM33xx and DA8xx/OMAP-L13x. + present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx. This driver can also be built as a module, if so, module will be called rtc-omap. -- cgit v1.2.3 From 5d9094b6c7fc87d1909143540c1e2fddde9129b3 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Thu, 16 Apr 2015 12:46:05 -0700 Subject: drivers/rtc/rtc-omap.c: use module_platform_driver module_platform_driver_probe() prevents driver from requesting probe deferral. So using module_platform_drive() to support probe deferral. Signed-off-by: Lokesh Vutla Acked-by: Alexandre Belloni Cc: Alessandro Zummo Cc: Paul Walmsley Cc: Tero Kristo Cc: Sekhar Nori Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-omap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index a5ff00931360..8b6355ffaff9 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -521,7 +521,7 @@ static const struct of_device_id omap_rtc_of_match[] = { }; MODULE_DEVICE_TABLE(of, omap_rtc_of_match); -static int __init omap_rtc_probe(struct platform_device *pdev) +static int omap_rtc_probe(struct platform_device *pdev) { struct omap_rtc *rtc; struct resource *res; @@ -756,6 +756,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev) } static struct platform_driver omap_rtc_driver = { + .probe = omap_rtc_probe, .remove = __exit_p(omap_rtc_remove), .shutdown = omap_rtc_shutdown, .driver = { @@ -766,7 +767,7 @@ static struct platform_driver omap_rtc_driver = { .id_table = omap_rtc_id_table, }; -module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe); +module_platform_driver(omap_rtc_driver); MODULE_ALIAS("platform:omap_rtc"); MODULE_AUTHOR("George G. Davis (and others)"); -- cgit v1.2.3 From 492da68c8c3babc573208e057a9011d9489f2b5a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 16 Apr 2015 12:46:08 -0700 Subject: drivers/rtc/rtc-s3c.c: remove one superfluous rtc_valid_tm() check s3c_rtc_gettime() already returns the result of rtc_valid_tm() on the obtained time so get rid of another call to rtc_valid_tm(). Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Cc: Alexandre Belloni Cc: Alessandro Zummo Cc: Marek Szyprowski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a313b9b5a27e..76cbad7a99d3 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -497,9 +497,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); /* Check RTC Time */ - s3c_rtc_gettime(&pdev->dev, &rtc_tm); - - if (rtc_valid_tm(&rtc_tm)) { + if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) { rtc_tm.tm_year = 100; rtc_tm.tm_mon = 0; rtc_tm.tm_mday = 1; -- cgit v1.2.3 From f539a8acf1070557aef9c5df682751ba2af1005f Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Thu, 16 Apr 2015 12:46:11 -0700 Subject: drivers/rtc/rtc-hym8563.c: fix swapped enable/disable of clockout control bit The hym8563 datasheet describes the clock output control-bit as "when set to logic 0, the square wave output is enable, when set to logic 1, the CLKOUT output is inhibited". But in reality the setting is exactly opposite. Before now, the clock output was not really used, but on the rk3288 soc this generated clock is used to supply the temperature sensor block and the swapped bit value prevented it from working. With the corrected value, the tsadc now reports correct values. Signed-off-by: Heiko Stuebner Acked-by: Alexandre Belloni Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-hym8563.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index d4a65619ef14..0f710e98538f 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -66,7 +66,7 @@ #define HYM8563_ALM_BIT_DISABLE BIT(7) #define HYM8563_CLKOUT 0x0d -#define HYM8563_CLKOUT_DISABLE BIT(7) +#define HYM8563_CLKOUT_ENABLE BIT(7) #define HYM8563_CLKOUT_32768 0 #define HYM8563_CLKOUT_1024 1 #define HYM8563_CLKOUT_32 2 @@ -360,9 +360,9 @@ static int hym8563_clkout_control(struct clk_hw *hw, bool enable) return ret; if (enable) - ret &= ~HYM8563_CLKOUT_DISABLE; + ret |= HYM8563_CLKOUT_ENABLE; else - ret |= HYM8563_CLKOUT_DISABLE; + ret &= ~HYM8563_CLKOUT_ENABLE; return i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, ret); } @@ -386,7 +386,7 @@ static int hym8563_clkout_is_prepared(struct clk_hw *hw) if (ret < 0) return ret; - return !(ret & HYM8563_CLKOUT_DISABLE); + return !!(ret & HYM8563_CLKOUT_ENABLE); } static const struct clk_ops hym8563_clkout_ops = { @@ -407,7 +407,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563) int ret; ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, - HYM8563_CLKOUT_DISABLE); + 0); if (ret < 0) return ERR_PTR(ret); -- cgit v1.2.3 From a737e835e5769ef22897179ed7f82b1fc50bfa58 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:46:14 -0700 Subject: rtc: use more standard kernel logging styles Neaten the logging a bit by adding #define pr_fmt Miscellanea: o Remove __FILE__/__func__ uses o Coalesce formats adding missing spaces o Align arguments o (rtc-cmos) Integrated 2 consecutive messages Signed-off-by: Joe Perches Acked-by: Alexandre Belloni Cc: Alessandro Zummo Cc: Joshua Kinard Cc: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Tested-by: Krzysztof Kozlowski Cc: Aaro Koskinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/hctosys.c | 6 ++++-- drivers/rtc/rtc-cmos.c | 6 ++++-- drivers/rtc/rtc-ds1374.c | 8 +++++--- drivers/rtc/rtc-ds1685.c | 4 +++- drivers/rtc/rtc-ds3232.c | 6 ++++-- drivers/rtc/rtc-efi-platform.c | 3 +++ drivers/rtc/rtc-m41t80.c | 6 ++++-- drivers/rtc/rtc-max77686.c | 6 ++++-- drivers/rtc/rtc-max8997.c | 8 +++++--- drivers/rtc/rtc-msm6242.c | 4 +++- drivers/rtc/rtc-opal.c | 3 ++- drivers/rtc/rtc-s5m.c | 4 +++- drivers/rtc/rtc-twl.c | 9 +++++---- 13 files changed, 49 insertions(+), 24 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index 91fb5f3c1051..e1cfa06810ef 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c @@ -9,6 +9,8 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary @@ -32,8 +34,8 @@ static int __init rtc_hctosys(void) struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (rtc == NULL) { - pr_info("%s: unable to open rtc device (%s)\n", - __func__, CONFIG_RTC_HCTOSYS_DEVICE); + pr_info("unable to open rtc device (%s)\n", + CONFIG_RTC_HCTOSYS_DEVICE); goto err_open; } diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 87647f459198..a82556a0757a 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -28,6 +28,9 @@ * interrupts disabled, holding the global rtc_lock, to exclude those * other drivers and utilities on correctly configured systems. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -385,8 +388,7 @@ static bool alarm_disable_quirk; static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) { alarm_disable_quirk = true; - pr_info("rtc-cmos: BIOS has alarm-disable quirk. "); - pr_info("RTC alarms disabled\n"); + pr_info("BIOS has alarm-disable quirk - RTC alarms disabled\n"); return 0; } diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 8605fde394b2..167783fa7ac1 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -18,6 +18,8 @@ * "Sending and receiving", using SMBus level communication is preferred. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -406,7 +408,7 @@ static int ds1374_wdt_settimeout(unsigned int timeout) /* Set new watchdog time */ ret = ds1374_write_rtc(save_client, timeout, DS1374_REG_WDALM0, 3); if (ret) { - pr_info("rtc-ds1374 - couldn't set new watchdog time\n"); + pr_info("couldn't set new watchdog time\n"); goto out; } @@ -539,12 +541,12 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd, return -EFAULT; if (options & WDIOS_DISABLECARD) { - pr_info("rtc-ds1374: disable watchdog\n"); + pr_info("disable watchdog\n"); ds1374_wdt_disable(); } if (options & WDIOS_ENABLECARD) { - pr_info("rtc-ds1374: enable watchdog\n"); + pr_info("enable watchdog\n"); ds1374_wdt_settimeout(wdt_margin); ds1374_wdt_ping(); } diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 70202098a8ce..818a3635a8c8 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -16,6 +16,8 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -2182,7 +2184,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev) /* Check for valid RTC data, else, spin forever. */ if (unlikely(!pdev)) { - pr_emerg("rtc-ds1685: platform device data not available, spinning forever ...\n"); + pr_emerg("platform device data not available, spinning forever ...\n"); unreachable(); } else { /* Get the rtc data. */ diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index adaf06c41479..7e48e532214f 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -15,6 +15,8 @@ * "Sending and receiving", using SMBus level communication is preferred. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -373,8 +375,8 @@ 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) { - pr_warn("Read DS3232 Control Register error." - "Disable IRQ%d.\n", client->irq); + pr_warn("Read Control Register error - Disable IRQ%d\n", + client->irq); } else { /* disable alarm1 interrupt */ control &= ~(DS3232_REG_CR_A1IE); diff --git a/drivers/rtc/rtc-efi-platform.c b/drivers/rtc/rtc-efi-platform.c index b40fbe332af4..1a7f1d1bc174 100644 --- a/drivers/rtc/rtc-efi-platform.c +++ b/drivers/rtc/rtc-efi-platform.c @@ -8,6 +8,9 @@ * Copyright (C) 1999-2000 VA Linux Systems * Copyright (C) 1999-2000 Walt Drummond */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 7ff7427c2e6a..a82937e2f824 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -13,6 +13,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -513,12 +515,12 @@ static int wdt_ioctl(struct file *file, unsigned int cmd, return -EFAULT; if (rv & WDIOS_DISABLECARD) { - pr_info("rtc-m41t80: disable watchdog\n"); + pr_info("disable watchdog\n"); wdt_disable(); } if (rv & WDIOS_ENABLECARD) { - pr_info("rtc-m41t80: enable watchdog\n"); + pr_info("enable watchdog\n"); wdt_ping(); } diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 9d71328e59b9..7632a87784c3 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -12,6 +12,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -103,8 +105,8 @@ static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data) data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; if (tm->tm_year < 100) { - pr_warn("%s: MAX77686 RTC cannot handle the year %d." - "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); + pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n", + 1900 + tm->tm_year); return -EINVAL; } return 0; diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c index 67fbe559d535..9e02bcda0c09 100644 --- a/drivers/rtc/rtc-max8997.c +++ b/drivers/rtc/rtc-max8997.c @@ -12,6 +12,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -107,8 +109,8 @@ static int max8997_rtc_tm_to_data(struct rtc_time *tm, u8 *data) data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; if (tm->tm_year < 100) { - pr_warn("%s: MAX8997 RTC cannot handle the year %d." - "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); + pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n", + 1900 + tm->tm_year); return -EINVAL; } return 0; @@ -424,7 +426,7 @@ static void max8997_rtc_enable_smpl(struct max8997_rtc_info *info, bool enable) val = 0; max8997_read_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, &val); - pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val); + pr_info("WTSR_SMPL(0x%02x)\n", val); } static int max8997_rtc_init_reg(struct max8997_rtc_info *info) diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c index 9bf877bdf836..c1c5c4e3b3b4 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c @@ -7,6 +7,8 @@ * Copyright (C) 1993 Hamish Macdonald */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -111,7 +113,7 @@ static void msm6242_lock(struct msm6242_priv *priv) } if (!cnt) - pr_warn("msm6242: timed out waiting for RTC (0x%x)\n", + pr_warn("timed out waiting for RTC (0x%x)\n", msm6242_read(priv, MSM6242_CD)); } diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index 95f652165fe9..7061dcae2b09 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -16,8 +16,9 @@ * along with this program. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRVNAME "rtc-opal" -#define pr_fmt(fmt) DRVNAME ": " fmt #include #include diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index f0cb0ecb3d8d..64baad379174 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -15,6 +15,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -146,7 +148,7 @@ static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data) data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; if (tm->tm_year < 100) { - pr_err("s5m8767 RTC cannot handle the year %d.\n", + pr_err("RTC cannot handle the year %d\n", 1900 + tm->tm_year); return -EINVAL; } else { diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 5baea3f54926..2dc787dc06c1 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -18,6 +18,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -145,8 +147,7 @@ static int twl_rtc_read_u8(u8 *data, u8 reg) ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg])); if (ret < 0) - pr_err("twl_rtc: Could not read TWL" - "register %X - error %d\n", reg, ret); + pr_err("Could not read TWL register %X - error %d\n", reg, ret); return ret; } @@ -159,8 +160,8 @@ static int twl_rtc_write_u8(u8 data, u8 reg) ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg])); if (ret < 0) - pr_err("twl_rtc: Could not write TWL" - "register %X - error %d\n", reg, ret); + pr_err("Could not write TWL register %X - error %d\n", + reg, ret); return ret; } -- cgit v1.2.3 From 94f919225890a1adb3d44bf5b31ff4cb21d8ee7e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 16 Apr 2015 12:49:27 -0700 Subject: drivers/rtc/rtc-s5m.c: allow usage on device type different than main MFD type The RTC driver supports two flavors of S5M devices: S5M8767-like and S2MPS14-like. On S2MPS13 and S2MPS14 devices the RTC module is the same so we want to re-use the existing support of S2MPS14. However device type was passed from parent MFD driver in platform data structure. This way for the S2MPS13 device the main MFD driver passed device type of 'S2MPS13X'. Instead decouple detecting of device type between main MFD and RTC driver. This allows adding support for other S2MPS14 variations (like S2MPS11 and S2MPS13) easily by adding to mfd/sec-core.c: static const struct mfd_cell s2mps13_devs[] = { { .name = "s2mps14-rtc", } }; Signed-off-by: Krzysztof Kozlowski Cc: Alessandro Zummo Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Chanwoo Choi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s5m.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 64baad379174..8c70d785ba73 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -92,7 +92,7 @@ struct s5m_rtc_info { struct regmap *regmap; struct rtc_device *rtc_dev; int irq; - int device_type; + enum sec_device_type device_type; int rtc_24hr_mode; const struct s5m_rtc_reg_config *regs; }; @@ -668,7 +668,7 @@ static int s5m_rtc_probe(struct platform_device *pdev) if (!info) return -ENOMEM; - switch (pdata->device_type) { + switch (platform_get_device_id(pdev)->driver_data) { case S2MPS14X: case S2MPS13X: regmap_cfg = &s2mps14_rtc_regmap_config; @@ -686,7 +686,9 @@ static int s5m_rtc_probe(struct platform_device *pdev) alarm_irq = S5M8767_IRQ_RTCA1; break; default: - dev_err(&pdev->dev, "Device type is not supported by RTC driver\n"); + dev_err(&pdev->dev, + "Device type %lu is not supported by RTC driver\n", + platform_get_device_id(pdev)->driver_data); return -ENODEV; } @@ -706,7 +708,7 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; info->s5m87xx = s5m87xx; - info->device_type = s5m87xx->device_type; + info->device_type = platform_get_device_id(pdev)->driver_data; if (s5m87xx->irq_data) { info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq); -- cgit v1.2.3 From 6da7bb1e9cef9ab956e4223125090e4465f51fb2 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 16 Apr 2015 12:49:32 -0700 Subject: drivers/rtc/rtc-at91rm9200.c: make IO endian agnostic Change the __raw IO calls to readl/write_relaxed which makes the driver endian agnostic to run properly on big endian systems. Signed-off-by: Ben Dooks Cc: Alessandro Zummo Cc: Andrew Victor Acked-by: Nicolas Ferre Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-at91rm9200.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index b283a1a573b3..35efd3f75b18 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -37,9 +37,9 @@ #include "rtc-at91rm9200.h" #define at91_rtc_read(field) \ - __raw_readl(at91_rtc_regs + field) + readl_relaxed(at91_rtc_regs + field) #define at91_rtc_write(field, val) \ - __raw_writel((val), at91_rtc_regs + field) + writel_relaxed((val), at91_rtc_regs + field) #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ -- cgit v1.2.3