First batch of drivers for 3.19:
It is only about a not so recent driver for old platforms: RTT as RTC driver: - RTT as RTC driver enhancements and machine specific include files removal - RTT as RTC driver conversion to device tree -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJUZg/EAAoJEAf03oE53VmQ/KAIAJi5Ky2ekaZ4FGWbDrnQBHV+ X0M/wvCdHw4D7VENo1W3U3ulf5r0XimeY6nnbmx3Ki0fTE2O3VyfLNzkjQtMf6iX TfoJM9y4fWsY5AXnynYO1Gj/2CH6Xab79Kb5sxL8b9VvlUMxlsKoQOmUYHC775OX YiBfp3dZYODkMyIIQmSkoZGj+kkgWbjMrp9CPueqVltha/EbfBP96Kib2G/aJVkb F9QyOq8B/mpUk2P29L1hc9X0/tjwaLZsO97zzhYVj7VwZS9sbYztQgmUNdtEds4/ 7EhMwSXxb9L5LkuoyuHFpRLMGzLrN9XBftE58s92hXwnM2KZE4eNo/JF0SGDOKo= =POJG -----END PGP SIGNATURE----- Merge tag 'at91-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91 into next/drivers Pull "First batch of drivers for 3.19" from Nicolas Ferre: It is only about a not so recent driver for old platforms: RTT as RTC driver: - RTT as RTC driver enhancements and machine specific include files removal - RTT as RTC driver conversion to device tree * tag 'at91-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91: rtc: at91sam9: add DT bindings documentation rtc: at91sam9: use clk API instead of relying on AT91_SLOW_CLOCK ARM: at91: add clk_lookup entry for RTT devices rtc: at91sam9: rework the Kconfig description rtc: at91sam9: make use of syscon/regmap to access GPBR registers rtc: at91sam9: add DT support rtc: at91sam9: replace devm_ioremap by devm_ioremap_resource rtc: at91sam9: use standard readl/writel functions instead of raw versions rtc: at91sam9: remove references to mach specific headers Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
c3e6dc65f2
|
@ -0,0 +1,23 @@
|
|||
Atmel AT91SAM9260 Real Time Timer
|
||||
|
||||
Required properties:
|
||||
- compatible: should be: "atmel,at91sam9260-rtt"
|
||||
- reg: should encode the memory region of the RTT controller
|
||||
- interrupts: rtt alarm/event interrupt
|
||||
- clocks: should contain the 32 KHz slow clk that will drive the RTT block.
|
||||
- atmel,rtt-rtc-time-reg: should encode the GPBR register used to store
|
||||
the time base when the RTT is used as an RTC.
|
||||
The first cell should point to the GPBR node and the second one
|
||||
encode the offset within the GPBR block (or in other words, the
|
||||
GPBR register used to store the time base).
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
rtt@fffffd20 {
|
||||
compatible = "atmel,at91sam9260-rtt";
|
||||
reg = <0xfffffd20 0x10>;
|
||||
interrupts = <1 4 7>;
|
||||
clocks = <&clk32k>;
|
||||
atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
|
||||
};
|
|
@ -217,6 +217,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "rtc-at91sam9.0", &clk32k),
|
||||
/* more usart lookup table for DT entries */
|
||||
CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
|
||||
CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
|
||||
|
@ -237,6 +238,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk),
|
||||
CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", &spi0_clk),
|
||||
CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", &spi1_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffd20.rtc", &clk32k),
|
||||
/* fake hclk clock */
|
||||
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
|
||||
CLKDEV_CON_ID("pioA", &pioA_clk),
|
||||
|
|
|
@ -192,6 +192,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_ID("pioA", &pioA_clk),
|
||||
CLKDEV_CON_ID("pioB", &pioB_clk),
|
||||
CLKDEV_CON_ID("pioC", &pioC_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "rtc-at91sam9.0", &clk32k),
|
||||
/* more lookup table for DT entries */
|
||||
CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
|
||||
CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
|
||||
|
@ -209,6 +210,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffd20.rtc", &clk32k),
|
||||
};
|
||||
|
||||
static struct clk_lookup usart_clocks_lookups[] = {
|
||||
|
|
|
@ -201,6 +201,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "rtc-at91sam9.0", &clk32k),
|
||||
CLKDEV_CON_DEV_ID(NULL, "rtc-at91sam9.1", &clk32k),
|
||||
/* fake hclk clock */
|
||||
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
|
||||
CLKDEV_CON_ID("pioA", &pioA_clk),
|
||||
|
@ -227,6 +229,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCDE_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCDE_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffb8000.pwm", &pwm_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffd20.rtc", &clk32k),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffd50.rtc", &clk32k),
|
||||
};
|
||||
|
||||
static struct clk_lookup usart_clocks_lookups[] = {
|
||||
|
|
|
@ -254,6 +254,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "atmel_aes", &aestdessha_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "rtc-at91sam9.0", &clk32k),
|
||||
/* more usart lookup table for DT entries */
|
||||
CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck),
|
||||
CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk),
|
||||
|
@ -280,6 +281,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioDE_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioDE_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffd20.rtc", &clk32k),
|
||||
|
||||
CLKDEV_CON_ID("pioA", &pioA_clk),
|
||||
CLKDEV_CON_ID("pioB", &pioB_clk),
|
||||
|
|
|
@ -205,6 +205,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_ID("pioB", &pioB_clk),
|
||||
CLKDEV_CON_ID("pioC", &pioC_clk),
|
||||
CLKDEV_CON_ID("pioD", &pioD_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "rtc-at91sam9.0", &clk32k),
|
||||
/* more lookup table for DT entries */
|
||||
CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
|
||||
CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
|
||||
|
@ -223,6 +224,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
|
|||
CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk),
|
||||
CLKDEV_CON_DEV_ID(NULL, "fffffd20.rtc", &clk32k),
|
||||
CLKDEV_CON_ID("adc_clk", &tsc_clk),
|
||||
};
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ static u32 at91_pllb_usb_init;
|
|||
* 48 MHz (unless no USB function clocks are needed). The main clock and
|
||||
* both PLLs are turned off to run in "slow clock mode" (system suspend).
|
||||
*/
|
||||
static struct clk clk32k = {
|
||||
struct clk clk32k = {
|
||||
.name = "clk32k",
|
||||
.rate_hz = AT91_SLOW_CLOCK,
|
||||
.users = 1, /* always on */
|
||||
|
|
|
@ -34,6 +34,7 @@ struct clk {
|
|||
extern int __init clk_register(struct clk *clk);
|
||||
extern struct clk mck;
|
||||
extern struct clk utmi_clk;
|
||||
extern struct clk clk32k;
|
||||
|
||||
#define CLKDEV_CON_ID(_id, _clk) \
|
||||
{ \
|
||||
|
|
|
@ -1109,16 +1109,18 @@ config RTC_DRV_AT91RM9200
|
|||
this is powered by the backup power supply.
|
||||
|
||||
config RTC_DRV_AT91SAM9
|
||||
tristate "AT91SAM9x/AT91CAP9 RTT as RTC"
|
||||
tristate "AT91SAM9 RTT as RTC"
|
||||
depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40)
|
||||
select MFD_SYSCON
|
||||
help
|
||||
RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT
|
||||
(Real Time Timer). These timers are powered by the backup power
|
||||
supply (such as a small coin cell battery), but do not need to
|
||||
be used as RTCs.
|
||||
|
||||
(On AT91SAM9rl and AT91SAM9G45 chips you probably want to use the
|
||||
dedicated RTC module and leave the RTT available for other uses.)
|
||||
Some AT91SAM9 SoCs provide an RTT (Real Time Timer) block which
|
||||
can be used as an RTC thanks to the backup power supply (e.g. a
|
||||
small coin cell battery) which keeps this block and the GPBR
|
||||
(General Purpose Backup Registers) block powered when the device
|
||||
is shutdown.
|
||||
Some AT91SAM9 SoCs provide a real RTC block, on those ones you'd
|
||||
probably want to use the real RTC block instead of the "RTT as an
|
||||
RTC" driver.
|
||||
|
||||
config RTC_DRV_AT91SAM9_RTT
|
||||
int
|
||||
|
@ -1127,6 +1129,9 @@ config RTC_DRV_AT91SAM9_RTT
|
|||
prompt "RTT module Number" if ARCH_AT91SAM9263
|
||||
depends on RTC_DRV_AT91SAM9
|
||||
help
|
||||
This option is only relevant for legacy board support and
|
||||
won't be used when booting a DT board.
|
||||
|
||||
More than one RTT module is available. You can choose which
|
||||
one will be used as an RTC. The default of zero is normally
|
||||
OK to use, though some systems use that for non-RTC purposes.
|
||||
|
@ -1139,6 +1144,9 @@ config RTC_DRV_AT91SAM9_GPBR
|
|||
prompt "Backup Register Number"
|
||||
depends on RTC_DRV_AT91SAM9
|
||||
help
|
||||
This option is only relevant for legacy board support and
|
||||
won't be used when booting a DT board.
|
||||
|
||||
The RTC driver needs to use one of the General Purpose Backup
|
||||
Registers (GPBRs) as well as the RTT. You can choose which one
|
||||
will be used. The default of zero is normally OK to use, but
|
||||
|
|
|
@ -21,10 +21,9 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/platform_data/atmel.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <mach/at91_rtt.h>
|
||||
#include <mach/cpu.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
/*
|
||||
* This driver uses two configurable hardware resources that live in the
|
||||
|
@ -47,6 +46,22 @@
|
|||
* registers available, likewise usable for more than "RTC" support.
|
||||
*/
|
||||
|
||||
#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
|
||||
#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */
|
||||
#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
|
||||
#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
|
||||
#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */
|
||||
|
||||
#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */
|
||||
#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */
|
||||
|
||||
#define AT91_RTT_VR 0x08 /* Real-time Value Register */
|
||||
#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */
|
||||
|
||||
#define AT91_RTT_SR 0x0c /* Real-time Status Register */
|
||||
#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */
|
||||
#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */
|
||||
|
||||
/*
|
||||
* We store ALARM_DISABLED in ALMV to record that no alarm is set.
|
||||
* It's also the reset value for that field.
|
||||
|
@ -58,19 +73,30 @@ struct sam9_rtc {
|
|||
void __iomem *rtt;
|
||||
struct rtc_device *rtcdev;
|
||||
u32 imr;
|
||||
void __iomem *gpbr;
|
||||
struct regmap *gpbr;
|
||||
unsigned int gpbr_offset;
|
||||
int irq;
|
||||
struct clk *sclk;
|
||||
};
|
||||
|
||||
#define rtt_readl(rtc, field) \
|
||||
__raw_readl((rtc)->rtt + AT91_RTT_ ## field)
|
||||
readl((rtc)->rtt + AT91_RTT_ ## field)
|
||||
#define rtt_writel(rtc, field, val) \
|
||||
__raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field)
|
||||
writel((val), (rtc)->rtt + AT91_RTT_ ## field)
|
||||
|
||||
#define gpbr_readl(rtc) \
|
||||
__raw_readl((rtc)->gpbr)
|
||||
#define gpbr_writel(rtc, val) \
|
||||
__raw_writel((val), (rtc)->gpbr)
|
||||
static inline unsigned int gpbr_readl(struct sam9_rtc *rtc)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
regmap_read(rtc->gpbr, rtc->gpbr_offset, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void gpbr_writel(struct sam9_rtc *rtc, unsigned int val)
|
||||
{
|
||||
regmap_write(rtc->gpbr, rtc->gpbr_offset, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read current time and date in RTC
|
||||
|
@ -287,22 +313,22 @@ static const struct rtc_class_ops at91_rtc_ops = {
|
|||
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static struct regmap_config gpbr_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize and install RTC driver
|
||||
*/
|
||||
static int at91_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *r, *r_gpbr;
|
||||
struct resource *r;
|
||||
struct sam9_rtc *rtc;
|
||||
int ret, irq;
|
||||
u32 mr;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
r_gpbr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!r || !r_gpbr) {
|
||||
dev_err(&pdev->dev, "need 2 ressources\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
unsigned int sclk_rate;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
|
@ -321,24 +347,66 @@ static int at91_rtc_probe(struct platform_device *pdev)
|
|||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
platform_set_drvdata(pdev, rtc);
|
||||
rtc->rtt = devm_ioremap(&pdev->dev, r->start, resource_size(r));
|
||||
if (!rtc->rtt) {
|
||||
dev_err(&pdev->dev, "failed to map registers, aborting.\n");
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rtc->rtt = devm_ioremap_resource(&pdev->dev, r);
|
||||
if (IS_ERR(rtc->rtt))
|
||||
return PTR_ERR(rtc->rtt);
|
||||
|
||||
if (!pdev->dev.of_node) {
|
||||
/*
|
||||
* TODO: Remove this code chunk when removing non DT board
|
||||
* support. Remember to remove the gpbr_regmap_config
|
||||
* variable too.
|
||||
*/
|
||||
void __iomem *gpbr;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
gpbr = devm_ioremap_resource(&pdev->dev, r);
|
||||
if (IS_ERR(gpbr))
|
||||
return PTR_ERR(gpbr);
|
||||
|
||||
rtc->gpbr = regmap_init_mmio(NULL, gpbr,
|
||||
&gpbr_regmap_config);
|
||||
} else {
|
||||
struct of_phandle_args args;
|
||||
|
||||
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
|
||||
"atmel,rtt-rtc-time-reg", 1, 0,
|
||||
&args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rtc->gpbr = syscon_node_to_regmap(args.np);
|
||||
rtc->gpbr_offset = args.args[0];
|
||||
}
|
||||
|
||||
if (IS_ERR(rtc->gpbr)) {
|
||||
dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rtc->gpbr = devm_ioremap(&pdev->dev, r_gpbr->start,
|
||||
resource_size(r_gpbr));
|
||||
if (!rtc->gpbr) {
|
||||
dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n");
|
||||
return -ENOMEM;
|
||||
rtc->sclk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(rtc->sclk))
|
||||
return PTR_ERR(rtc->sclk);
|
||||
|
||||
sclk_rate = clk_get_rate(rtc->sclk);
|
||||
if (!sclk_rate || sclk_rate > AT91_RTT_RTPRES) {
|
||||
dev_err(&pdev->dev, "Invalid slow clock rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(rtc->sclk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Could not enable slow clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
mr = rtt_readl(rtc, MR);
|
||||
|
||||
/* unless RTT is counting at 1 Hz, re-initialize it */
|
||||
if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) {
|
||||
mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES);
|
||||
if ((mr & AT91_RTT_RTPRES) != sclk_rate) {
|
||||
mr = AT91_RTT_RTTRST | (sclk_rate & AT91_RTT_RTPRES);
|
||||
gpbr_writel(rtc, 0);
|
||||
}
|
||||
|
||||
|
@ -383,6 +451,9 @@ static int at91_rtc_remove(struct platform_device *pdev)
|
|||
/* disable all interrupts */
|
||||
rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN));
|
||||
|
||||
if (!IS_ERR(rtc->sclk))
|
||||
clk_disable_unprepare(rtc->sclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -440,6 +511,14 @@ static int at91_rtc_resume(struct device *dev)
|
|||
|
||||
static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id at91_rtc_dt_ids[] = {
|
||||
{ .compatible = "atmel,at91sam9260-rtt" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver at91_rtc_driver = {
|
||||
.probe = at91_rtc_probe,
|
||||
.remove = at91_rtc_remove,
|
||||
|
@ -448,6 +527,7 @@ static struct platform_driver at91_rtc_driver = {
|
|||
.name = "rtc-at91sam9",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &at91_rtc_pm_ops,
|
||||
.of_match_table = of_match_ptr(at91_rtc_dt_ids),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue