Skip to content

Commit 0c6e718

Browse files
Nadav Haklaialexandrebelloni
authored andcommitted
rtc: armada38x: Align RTC set time procedure with the official errata
According to the Armada38x functional errata FE-3124064, writing to the RTC TIME register may fail. As a workaround, after writing to RTC TIME register, issue a dummy write of 0x0 twice to the RTC Status register. This is the updated implementation of the Errata that eliminates the need of the long 100ms delay during the RTC set time procedure. [[email protected]]: removed the mutex and use the spinlock again Signed-off-by: Nadav Haklai <[email protected]> Reviewed-by: Neta Zur Hershkovits <[email protected]> Signed-off-by: Gregory CLEMENT <[email protected]> Signed-off-by: Alexandre Belloni <[email protected]>
1 parent efbbb4f commit 0c6e718

File tree

1 file changed

+12
-20
lines changed

1 file changed

+12
-20
lines changed

drivers/rtc/rtc-armada38x.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,6 @@ struct armada38x_rtc {
4040
void __iomem *regs;
4141
void __iomem *regs_soc;
4242
spinlock_t lock;
43-
/*
44-
* While setting the time, the RTC TIME register should not be
45-
* accessed. Setting the RTC time involves sleeping during
46-
* 100ms, so a mutex instead of a spinlock is used to protect
47-
* it
48-
*/
49-
struct mutex mutex_time;
5043
int irq;
5144
};
5245

@@ -64,9 +57,9 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
6457
static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
6558
{
6659
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
67-
unsigned long time, time_check;
60+
unsigned long time, time_check, flags;
6861

69-
mutex_lock(&rtc->mutex_time);
62+
spin_lock_irqsave(&rtc->lock, flags);
7063
time = readl(rtc->regs + RTC_TIME);
7164
/*
7265
* 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)
7770
if ((time_check - time) > 1)
7871
time_check = readl(rtc->regs + RTC_TIME);
7972

80-
mutex_unlock(&rtc->mutex_time);
73+
spin_unlock_irqrestore(&rtc->lock, flags);
8174

8275
rtc_time_to_tm(time_check, tm);
8376

@@ -88,23 +81,23 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
8881
{
8982
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
9083
int ret = 0;
91-
unsigned long time;
84+
unsigned long time, flags;
9285

9386
ret = rtc_tm_to_time(tm, &time);
9487

9588
if (ret)
9689
goto out;
9790
/*
98-
* Setting the RTC time not always succeeds. According to the
99-
* errata we need to first write on the status register and
100-
* then wait for 100ms before writing to the time register to be
101-
* sure that the data will be taken into account.
91+
* According to errata FE-3124064, Write to RTC TIME register
92+
* may fail. As a workaround, after writing to RTC TIME
93+
* register, issue a dummy write of 0x0 twice to RTC Status
94+
* register.
10295
*/
103-
mutex_lock(&rtc->mutex_time);
104-
rtc_delayed_write(0, rtc, RTC_STATUS);
105-
msleep(100);
96+
spin_lock_irqsave(&rtc->lock, flags);
10697
rtc_delayed_write(time, rtc, RTC_TIME);
107-
mutex_unlock(&rtc->mutex_time);
98+
rtc_delayed_write(0, rtc, RTC_STATUS);
99+
rtc_delayed_write(0, rtc, RTC_STATUS);
100+
spin_unlock_irqrestore(&rtc->lock, flags);
108101

109102
out:
110103
return ret;
@@ -229,7 +222,6 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
229222
return -ENOMEM;
230223

231224
spin_lock_init(&rtc->lock);
232-
mutex_init(&rtc->mutex_time);
233225

234226
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
235227
rtc->regs = devm_ioremap_resource(&pdev->dev, res);

0 commit comments

Comments
 (0)