summaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-armada38x.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-08 15:46:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-08 15:46:31 -0700
commitc19176154b464c861e49355eff636aa6896735b5 (patch)
tree5dd931abe6aa3b73d10119a77950f2a0f3323a74 /drivers/rtc/rtc-armada38x.c
parent12f03ee606914317e7e6a0815e53a48205c31dae (diff)
parent5f1b2f77646fc0ef2f36fc554f5722a1381d0892 (diff)
Merge tag 'rtc-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni: "Core: - use is_visible() to control sysfs attributes - switch wakealarm attribute to DEVICE_ATTR_RW - make rtc_does_wakealarm() return boolean - properly manage lifetime of dev and cdev in rtc device - remove unnecessary device_get() in rtc_device_unregister - fix double free in rtc_register_device() error path New drivers: - NXP LPC24xx - Xilinx Zynq MP - Dialog DA9062 Subsystem wide cleanups: - fix drivers that consider 0 as a valid IRQ in client->irq - Drop (un)likely before IS_ERR(_OR_NULL) - drop the remaining owner assignment for i2c_driver and platform_driver - module autoload fixes Drivers: - 88pm80x: add device tree support - abx80x: fix RTC write bit - ab8500: Add a sentinel to ab85xx_rtc_ids[] - armada38x: Align RTC set time procedure with the official errata - as3722: correct month value - at91sam9: cleanups - at91rm9200: get and use slow clock and cleanups - bq32k: remove redundant check - cmos: century support, proper fix for the spurious wakeup - ds1307: cleanups and wakeup irq support - ds1374: Remove unused variable - ds1685: Use module_platform_driver - ds3232: fix WARNING trace in resume function - gemini: fix ptr_ret.cocci warnings - mt6397: implement suspend/resume - omap: support internal and external clock enabling - opal: Enable alarms only when opal supports tpo - pcf2127: use OFS flag to detect unreliable date and warn the user - pl031: fix typo for author email - rx8025: huge cleanup and fixes - sa1100/pxa: share common code - s5m: fix to update ctrl register - s3c: fix clocks and wakeup, cleanup - sirfsoc: use regmap - nvram_read()/nvram_write() functions for cmos, ds1305, ds1307, ds1343, ds1511, ds1553, ds1742, m48t59, rp5c01, stk17ta8, tx4939 - use rtc_valid_tm() error code when reading date/time instead of 0 for isl12022, pcf2123, pcf2127" * tag 'rtc-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (90 commits) rtc: abx80x: fix RTC write bit rtc: ab8500: Add a sentinel to ab85xx_rtc_ids[] rtc: ds1374: Remove unused variable rtc: Fix module autoload for OF platform drivers rtc: Fix module autoload for rtc-{ab8500,max8997,s5m} drivers rtc: omap: Add external clock enabling support rtc: omap: Add internal clock enabling support ARM: dts: AM437x: Add the internal and external clock nodes for rtc rtc: s5m: fix to update ctrl register rtc: add xilinx zynqmp rtc driver devicetree: bindings: rtc: add bindings for xilinx zynqmp rtc rtc: as3722: correct month value ARM: config: Switch PXA27x platforms to use PXA RTC driver ARM: mmp: remove unused RTC register definitions ARM: sa1100: remove unused RTC register definitions rtc: sa1100/pxa: convert to run-time register mapping ARM: pxa: add memory resource to SA1100 RTC device rtc: pxa: convert to use shared sa1100 functions rtc: sa1100: prepare to share sa1100_rtc_ops rtc: ds3232: fix WARNING trace in resume function ...
Diffstat (limited to 'drivers/rtc/rtc-armada38x.c')
-rw-r--r--drivers/rtc/rtc-armada38x.c33
1 files changed, 13 insertions, 20 deletions
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 2b08cac62f07..9a3f2a6f512e 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -40,13 +40,6 @@ struct armada38x_rtc {
void __iomem *regs;
void __iomem *regs_soc;
spinlock_t lock;
- /*
- * While setting the time, the RTC TIME register should not be
- * accessed. Setting the RTC time involves sleeping during
- * 100ms, so a mutex instead of a spinlock is used to protect
- * it
- */
- struct mutex mutex_time;
int irq;
};
@@ -64,9 +57,9 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
- unsigned long time, time_check;
+ unsigned long time, time_check, flags;
- mutex_lock(&rtc->mutex_time);
+ spin_lock_irqsave(&rtc->lock, flags);
time = readl(rtc->regs + RTC_TIME);
/*
* WA for failing time set attempts. As stated in HW ERRATA if
@@ -77,7 +70,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
if ((time_check - time) > 1)
time_check = readl(rtc->regs + RTC_TIME);
- mutex_unlock(&rtc->mutex_time);
+ spin_unlock_irqrestore(&rtc->lock, flags);
rtc_time_to_tm(time_check, tm);
@@ -88,23 +81,23 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
int ret = 0;
- unsigned long time;
+ unsigned long time, flags;
ret = rtc_tm_to_time(tm, &time);
if (ret)
goto out;
/*
- * Setting the RTC time not always succeeds. According to the
- * errata we need to first write on the status register and
- * then wait for 100ms before writing to the time register to be
- * sure that the data will be taken into account.
+ * According to errata FE-3124064, Write to RTC TIME register
+ * may fail. As a workaround, after writing to RTC TIME
+ * register, issue a dummy write of 0x0 twice to RTC Status
+ * register.
*/
- mutex_lock(&rtc->mutex_time);
- rtc_delayed_write(0, rtc, RTC_STATUS);
- msleep(100);
+ spin_lock_irqsave(&rtc->lock, flags);
rtc_delayed_write(time, rtc, RTC_TIME);
- mutex_unlock(&rtc->mutex_time);
+ rtc_delayed_write(0, rtc, RTC_STATUS);
+ rtc_delayed_write(0, rtc, RTC_STATUS);
+ spin_unlock_irqrestore(&rtc->lock, flags);
out:
return ret;
@@ -229,7 +222,6 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&rtc->lock);
- mutex_init(&rtc->mutex_time);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
rtc->regs = devm_ioremap_resource(&pdev->dev, res);
@@ -303,6 +295,7 @@ static const struct of_device_id armada38x_rtc_of_match_table[] = {
{ .compatible = "marvell,armada-380-rtc", },
{}
};
+MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
#endif
static struct platform_driver armada38x_rtc_driver = {