Skip to content

Commit 43e112b

Browse files
Boris BREZILLONNicolas Ferre
Boris BREZILLON
authored and
Nicolas Ferre
committed
rtc: at91sam9: make use of syscon/regmap to access GPBR registers
The GPBR registers are not part of the RTT block and thus should not be defined in the reg property of the rtt node. Use syscon to provide a proper DT representation and reference the GPBR syscon device in a new "atmel,rtt-rtc-time-reg" property which store both the syscon device phandle and the register offset within the GPBR block. When using non DT boards, we won't be able to retrieve the syscon regmap, hence we need to create our own regmap using the memory region defined in the 2nd memory resource assigned to the RTT platform device. Signed-off-by: Boris BREZILLON <[email protected]> Acked-by: Alexandre Belloni <[email protected]> Acked-by: Johan Hovold <[email protected]> Acked-by: Arnd Bergmann <[email protected]> Signed-off-by: Nicolas Ferre <[email protected]>
1 parent 07d4d72 commit 43e112b

File tree

2 files changed

+56
-9
lines changed

2 files changed

+56
-9
lines changed

drivers/rtc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,7 @@ config RTC_DRV_AT91RM9200
11111111
config RTC_DRV_AT91SAM9
11121112
tristate "AT91SAM9x/AT91CAP9 RTT as RTC"
11131113
depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40)
1114+
select MFD_SYSCON
11141115
help
11151116
RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT
11161117
(Real Time Timer). These timers are powered by the backup power

drivers/rtc/rtc-at91sam9.c

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <linux/slab.h>
2222
#include <linux/platform_data/atmel.h>
2323
#include <linux/io.h>
24+
#include <linux/mfd/syscon.h>
25+
#include <linux/regmap.h>
2426

2527
/*
2628
* This driver uses two configurable hardware resources that live in the
@@ -72,7 +74,8 @@ struct sam9_rtc {
7274
void __iomem *rtt;
7375
struct rtc_device *rtcdev;
7476
u32 imr;
75-
void __iomem *gpbr;
77+
struct regmap *gpbr;
78+
unsigned int gpbr_offset;
7679
int irq;
7780
};
7881

@@ -81,10 +84,19 @@ struct sam9_rtc {
8184
#define rtt_writel(rtc, field, val) \
8285
writel((val), (rtc)->rtt + AT91_RTT_ ## field)
8386

84-
#define gpbr_readl(rtc) \
85-
readl((rtc)->gpbr)
86-
#define gpbr_writel(rtc, val) \
87-
writel((val), (rtc)->gpbr)
87+
static inline unsigned int gpbr_readl(struct sam9_rtc *rtc)
88+
{
89+
unsigned int val;
90+
91+
regmap_read(rtc->gpbr, rtc->gpbr_offset, &val);
92+
93+
return val;
94+
}
95+
96+
static inline void gpbr_writel(struct sam9_rtc *rtc, unsigned int val)
97+
{
98+
regmap_write(rtc->gpbr, rtc->gpbr_offset, val);
99+
}
88100

89101
/*
90102
* Read current time and date in RTC
@@ -301,6 +313,12 @@ static const struct rtc_class_ops at91_rtc_ops = {
301313
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
302314
};
303315

316+
static struct regmap_config gpbr_regmap_config = {
317+
.reg_bits = 32,
318+
.val_bits = 32,
319+
.reg_stride = 4,
320+
};
321+
304322
/*
305323
* Initialize and install RTC driver
306324
*/
@@ -334,10 +352,38 @@ static int at91_rtc_probe(struct platform_device *pdev)
334352
if (IS_ERR(rtc->rtt))
335353
return PTR_ERR(rtc->rtt);
336354

337-
r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
338-
rtc->gpbr = devm_ioremap_resource(&pdev->dev, r);
339-
if (IS_ERR(rtc->gpbr))
340-
return PTR_ERR(rtc->rtt);
355+
if (!pdev->dev.of_node) {
356+
/*
357+
* TODO: Remove this code chunk when removing non DT board
358+
* support. Remember to remove the gpbr_regmap_config
359+
* variable too.
360+
*/
361+
void __iomem *gpbr;
362+
363+
r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
364+
gpbr = devm_ioremap_resource(&pdev->dev, r);
365+
if (IS_ERR(gpbr))
366+
return PTR_ERR(gpbr);
367+
368+
rtc->gpbr = regmap_init_mmio(NULL, gpbr,
369+
&gpbr_regmap_config);
370+
} else {
371+
struct of_phandle_args args;
372+
373+
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
374+
"atmel,rtt-rtc-time-reg", 1, 0,
375+
&args);
376+
if (ret)
377+
return ret;
378+
379+
rtc->gpbr = syscon_node_to_regmap(args.np);
380+
rtc->gpbr_offset = args.args[0];
381+
}
382+
383+
if (IS_ERR(rtc->gpbr)) {
384+
dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n");
385+
return -ENOMEM;
386+
}
341387

342388
mr = rtt_readl(rtc, MR);
343389

0 commit comments

Comments
 (0)