ARM: at91: make rm9200 rtc drivers soc independent

switch the rtc drivers to resource and pass it via platform_device
Signed-off-by: NJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
上级 be6d4321
...@@ -665,10 +665,24 @@ static void __init at91_add_device_tc(void) { } ...@@ -665,10 +665,24 @@ static void __init at91_add_device_tc(void) { }
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
static struct resource rtc_resources[] = {
[0] = {
.start = AT91RM9200_BASE_RTC,
.end = AT91RM9200_BASE_RTC + SZ_256 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91_ID_SYS,
.end = AT91_ID_SYS,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device at91rm9200_rtc_device = { static struct platform_device at91rm9200_rtc_device = {
.name = "at91_rtc", .name = "at91_rtc",
.id = -1, .id = -1,
.num_resources = 0, .resource = rtc_resources,
.num_resources = ARRAY_SIZE(rtc_resources),
}; };
static void __init at91_add_device_rtc(void) static void __init at91_add_device_rtc(void)
......
...@@ -1009,10 +1009,24 @@ static void __init at91_add_device_tc(void) { } ...@@ -1009,10 +1009,24 @@ static void __init at91_add_device_tc(void) { }
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
static struct resource rtc_resources[] = {
[0] = {
.start = AT91SAM9G45_BASE_RTC,
.end = AT91SAM9G45_BASE_RTC + SZ_256 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91_ID_SYS,
.end = AT91_ID_SYS,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device at91sam9g45_rtc_device = { static struct platform_device at91sam9g45_rtc_device = {
.name = "at91_rtc", .name = "at91_rtc",
.id = -1, .id = -1,
.num_resources = 0, .resource = rtc_resources,
.num_resources = ARRAY_SIZE(rtc_resources),
}; };
static void __init at91_add_device_rtc(void) static void __init at91_add_device_rtc(void)
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#ifndef AT91_RTC_H #ifndef AT91_RTC_H
#define AT91_RTC_H #define AT91_RTC_H
#define AT91_RTC_CR (AT91_RTC + 0x00) /* Control Register */ #define AT91_RTC_CR 0x00 /* Control Register */
#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */ #define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */
#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ #define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */
#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ #define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */
...@@ -29,44 +29,44 @@ ...@@ -29,44 +29,44 @@
#define AT91_RTC_CALEVSEL_MONTH (1 << 16) #define AT91_RTC_CALEVSEL_MONTH (1 << 16)
#define AT91_RTC_CALEVSEL_YEAR (2 << 16) #define AT91_RTC_CALEVSEL_YEAR (2 << 16)
#define AT91_RTC_MR (AT91_RTC + 0x04) /* Mode Register */ #define AT91_RTC_MR 0x04 /* Mode Register */
#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ #define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */
#define AT91_RTC_TIMR (AT91_RTC + 0x08) /* Time Register */ #define AT91_RTC_TIMR 0x08 /* Time Register */
#define AT91_RTC_SEC (0x7f << 0) /* Current Second */ #define AT91_RTC_SEC (0x7f << 0) /* Current Second */
#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ #define AT91_RTC_MIN (0x7f << 8) /* Current Minute */
#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ #define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */
#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ #define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */
#define AT91_RTC_CALR (AT91_RTC + 0x0c) /* Calendar Register */ #define AT91_RTC_CALR 0x0c /* Calendar Register */
#define AT91_RTC_CENT (0x7f << 0) /* Current Century */ #define AT91_RTC_CENT (0x7f << 0) /* Current Century */
#define AT91_RTC_YEAR (0xff << 8) /* Current Year */ #define AT91_RTC_YEAR (0xff << 8) /* Current Year */
#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */ #define AT91_RTC_MONTH (0x1f << 16) /* Current Month */
#define AT91_RTC_DAY (7 << 21) /* Current Day */ #define AT91_RTC_DAY (7 << 21) /* Current Day */
#define AT91_RTC_DATE (0x3f << 24) /* Current Date */ #define AT91_RTC_DATE (0x3f << 24) /* Current Date */
#define AT91_RTC_TIMALR (AT91_RTC + 0x10) /* Time Alarm Register */ #define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */ #define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */
#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */ #define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */
#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */ #define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */
#define AT91_RTC_CALALR (AT91_RTC + 0x14) /* Calendar Alarm Register */ #define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */ #define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */
#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */ #define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */
#define AT91_RTC_SR (AT91_RTC + 0x18) /* Status Register */ #define AT91_RTC_SR 0x18 /* Status Register */
#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */ #define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */
#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */ #define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */
#define AT91_RTC_SECEV (1 << 2) /* Second Event */ #define AT91_RTC_SECEV (1 << 2) /* Second Event */
#define AT91_RTC_TIMEV (1 << 3) /* Time Event */ #define AT91_RTC_TIMEV (1 << 3) /* Time Event */
#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */ #define AT91_RTC_CALEV (1 << 4) /* Calendar Event */
#define AT91_RTC_SCCR (AT91_RTC + 0x1c) /* Status Clear Command Register */ #define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
#define AT91_RTC_IER (AT91_RTC + 0x20) /* Interrupt Enable Register */ #define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
#define AT91_RTC_IDR (AT91_RTC + 0x24) /* Interrupt Disable Register */ #define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
#define AT91_RTC_IMR (AT91_RTC + 0x28) /* Interrupt Mask Register */ #define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
#define AT91_RTC_VER (AT91_RTC + 0x2c) /* Valid Entry Register */ #define AT91_RTC_VER 0x2c /* Valid Entry Register */
#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ #define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */
#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */ #define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */
#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */ #define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */
......
...@@ -81,7 +81,6 @@ ...@@ -81,7 +81,6 @@
*/ */
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */
#define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */
#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */
#define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ #define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */
#define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */ #define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */
...@@ -89,6 +88,7 @@ ...@@ -89,6 +88,7 @@
#define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */ #define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */
#define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */ #define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */
#define AT91RM9200_BASE_PIOD 0xfffffa00 /* PIO Controller D */ #define AT91RM9200_BASE_PIOD 0xfffffa00 /* PIO Controller D */
#define AT91RM9200_BASE_RTC 0xfffffe00 /* Real-Time Clock */
#define AT91_USART0 AT91RM9200_BASE_US0 #define AT91_USART0 AT91RM9200_BASE_US0
#define AT91_USART1 AT91RM9200_BASE_US1 #define AT91_USART1 AT91RM9200_BASE_US1
......
...@@ -92,7 +92,6 @@ ...@@ -92,7 +92,6 @@
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS)
#define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_ECC 0xffffe200
#define AT91SAM9G45_BASE_DMA 0xffffec00 #define AT91SAM9G45_BASE_DMA 0xffffec00
...@@ -107,6 +106,7 @@ ...@@ -107,6 +106,7 @@
#define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_RTT 0xfffffd20
#define AT91SAM9G45_BASE_PIT 0xfffffd30 #define AT91SAM9G45_BASE_PIT 0xfffffd30
#define AT91SAM9G45_BASE_WDT 0xfffffd40 #define AT91SAM9G45_BASE_WDT 0xfffffd40
#define AT91SAM9G45_BASE_RTC 0xfffffdb0
#define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART0 AT91SAM9G45_BASE_US0
#define AT91_USART1 AT91SAM9G45_BASE_US1 #define AT91_USART1 AT91SAM9G45_BASE_US1
......
...@@ -75,7 +75,6 @@ ...@@ -75,7 +75,6 @@
#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS)
#define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_DMA 0xffffe600
#define AT91SAM9RL_BASE_ECC 0xffffe800 #define AT91SAM9RL_BASE_ECC 0xffffe800
...@@ -89,6 +88,7 @@ ...@@ -89,6 +88,7 @@
#define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_RTT 0xfffffd20
#define AT91SAM9RL_BASE_PIT 0xfffffd30 #define AT91SAM9RL_BASE_PIT 0xfffffd30
#define AT91SAM9RL_BASE_WDT 0xfffffd40 #define AT91SAM9RL_BASE_WDT 0xfffffd40
#define AT91SAM9RL_BASE_RTC 0xfffffe00
#define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART0 AT91SAM9RL_BASE_US0
#define AT91_USART1 AT91SAM9RL_BASE_US1 #define AT91_USART1 AT91SAM9RL_BASE_US1
......
...@@ -32,11 +32,17 @@ ...@@ -32,11 +32,17 @@
#include <mach/at91_rtc.h> #include <mach/at91_rtc.h>
#define at91_rtc_read(field) \
__raw_readl(at91_rtc_regs + field)
#define at91_rtc_write(field, val) \
__raw_writel((val), at91_rtc_regs + field)
#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */
static DECLARE_COMPLETION(at91_rtc_updated); static DECLARE_COMPLETION(at91_rtc_updated);
static unsigned int at91_alarm_year = AT91_RTC_EPOCH; static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
static void __iomem *at91_rtc_regs;
static int irq;
/* /*
* Decode time/date into rtc_time structure * Decode time/date into rtc_time structure
...@@ -48,10 +54,10 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, ...@@ -48,10 +54,10 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
/* must read twice in case it changes */ /* must read twice in case it changes */
do { do {
time = at91_sys_read(timereg); time = at91_rtc_read(timereg);
date = at91_sys_read(calreg); date = at91_rtc_read(calreg);
} while ((time != at91_sys_read(timereg)) || } while ((time != at91_rtc_read(timereg)) ||
(date != at91_sys_read(calreg))); (date != at91_rtc_read(calreg)));
tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0); tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0);
tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8); tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8);
...@@ -98,19 +104,19 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) ...@@ -98,19 +104,19 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
tm->tm_hour, tm->tm_min, tm->tm_sec); tm->tm_hour, tm->tm_min, tm->tm_sec);
/* Stop Time/Calendar from counting */ /* Stop Time/Calendar from counting */
cr = at91_sys_read(AT91_RTC_CR); cr = at91_rtc_read(AT91_RTC_CR);
at91_sys_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);
at91_sys_write(AT91_RTC_IER, AT91_RTC_ACKUPD); at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD);
wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD);
at91_sys_write(AT91_RTC_TIMR, at91_rtc_write(AT91_RTC_TIMR,
bin2bcd(tm->tm_sec) << 0 bin2bcd(tm->tm_sec) << 0
| bin2bcd(tm->tm_min) << 8 | bin2bcd(tm->tm_min) << 8
| bin2bcd(tm->tm_hour) << 16); | bin2bcd(tm->tm_hour) << 16);
at91_sys_write(AT91_RTC_CALR, at91_rtc_write(AT91_RTC_CALR,
bin2bcd((tm->tm_year + 1900) / 100) /* century */ bin2bcd((tm->tm_year + 1900) / 100) /* century */
| bin2bcd(tm->tm_year % 100) << 8 /* year */ | bin2bcd(tm->tm_year % 100) << 8 /* year */
| bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */
...@@ -118,8 +124,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) ...@@ -118,8 +124,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
| bin2bcd(tm->tm_mday) << 24); | bin2bcd(tm->tm_mday) << 24);
/* Restart Time/Calendar */ /* Restart Time/Calendar */
cr = at91_sys_read(AT91_RTC_CR); cr = at91_rtc_read(AT91_RTC_CR);
at91_sys_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM));
return 0; return 0;
} }
...@@ -135,7 +141,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -135,7 +141,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
tm->tm_year = at91_alarm_year - 1900; tm->tm_year = at91_alarm_year - 1900;
alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM) alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM)
? 1 : 0; ? 1 : 0;
pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
...@@ -160,20 +166,20 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -160,20 +166,20 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
tm.tm_min = alrm->time.tm_min; tm.tm_min = alrm->time.tm_min;
tm.tm_sec = alrm->time.tm_sec; tm.tm_sec = alrm->time.tm_sec;
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
at91_sys_write(AT91_RTC_TIMALR, at91_rtc_write(AT91_RTC_TIMALR,
bin2bcd(tm.tm_sec) << 0 bin2bcd(tm.tm_sec) << 0
| bin2bcd(tm.tm_min) << 8 | bin2bcd(tm.tm_min) << 8
| bin2bcd(tm.tm_hour) << 16 | bin2bcd(tm.tm_hour) << 16
| AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
at91_sys_write(AT91_RTC_CALALR, at91_rtc_write(AT91_RTC_CALALR,
bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
| bin2bcd(tm.tm_mday) << 24 | bin2bcd(tm.tm_mday) << 24
| AT91_RTC_DATEEN | AT91_RTC_MTHEN); | AT91_RTC_DATEEN | AT91_RTC_MTHEN);
if (alrm->enabled) { if (alrm->enabled) {
at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
} }
pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
...@@ -188,10 +194,10 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -188,10 +194,10 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
pr_debug("%s(): cmd=%08x\n", __func__, enabled); pr_debug("%s(): cmd=%08x\n", __func__, enabled);
if (enabled) { if (enabled) {
at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
} else } else
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
return 0; return 0;
} }
...@@ -200,7 +206,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -200,7 +206,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
*/ */
static int at91_rtc_proc(struct device *dev, struct seq_file *seq) static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
{ {
unsigned long imr = at91_sys_read(AT91_RTC_IMR); unsigned long imr = at91_rtc_read(AT91_RTC_IMR);
seq_printf(seq, "update_IRQ\t: %s\n", seq_printf(seq, "update_IRQ\t: %s\n",
(imr & AT91_RTC_ACKUPD) ? "yes" : "no"); (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
...@@ -220,7 +226,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) ...@@ -220,7 +226,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
unsigned int rtsr; unsigned int rtsr;
unsigned long events = 0; unsigned long events = 0;
rtsr = at91_sys_read(AT91_RTC_SR) & at91_sys_read(AT91_RTC_IMR); rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR);
if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr) { /* this interrupt is shared! Is it ours? */
if (rtsr & AT91_RTC_ALARM) if (rtsr & AT91_RTC_ALARM)
events |= (RTC_AF | RTC_IRQF); events |= (RTC_AF | RTC_IRQF);
...@@ -229,7 +235,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) ...@@ -229,7 +235,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
if (rtsr & AT91_RTC_ACKUPD) if (rtsr & AT91_RTC_ACKUPD)
complete(&at91_rtc_updated); complete(&at91_rtc_updated);
at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */
rtc_update_irq(rtc, 1, events); rtc_update_irq(rtc, 1, events);
...@@ -256,22 +262,41 @@ static const struct rtc_class_ops at91_rtc_ops = { ...@@ -256,22 +262,41 @@ static const struct rtc_class_ops at91_rtc_ops = {
static int __init at91_rtc_probe(struct platform_device *pdev) static int __init at91_rtc_probe(struct platform_device *pdev)
{ {
struct rtc_device *rtc; struct rtc_device *rtc;
int ret; struct resource *regs;
int ret = 0;
at91_sys_write(AT91_RTC_CR, 0); regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
at91_sys_write(AT91_RTC_MR, 0); /* 24 hour mode */ if (!regs) {
dev_err(&pdev->dev, "no mmio resource defined\n");
return -ENXIO;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq resource defined\n");
return -ENXIO;
}
at91_rtc_regs = ioremap(regs->start, resource_size(regs));
if (!at91_rtc_regs) {
dev_err(&pdev->dev, "failed to map registers, aborting.\n");
return -ENOMEM;
}
at91_rtc_write(AT91_RTC_CR, 0);
at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */
/* Disable all interrupts */ /* Disable all interrupts */
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_SECEV | AT91_RTC_TIMEV |
AT91_RTC_CALEV); AT91_RTC_CALEV);
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, ret = request_irq(irq, at91_rtc_interrupt,
IRQF_SHARED, IRQF_SHARED,
"at91_rtc", pdev); "at91_rtc", pdev);
if (ret) { if (ret) {
printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n",
AT91_ID_SYS); irq);
return ret; return ret;
} }
...@@ -284,7 +309,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) ...@@ -284,7 +309,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
rtc = rtc_device_register(pdev->name, &pdev->dev, rtc = rtc_device_register(pdev->name, &pdev->dev,
&at91_rtc_ops, THIS_MODULE); &at91_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(rtc)) {
free_irq(AT91_ID_SYS, pdev); free_irq(irq, pdev);
return PTR_ERR(rtc); return PTR_ERR(rtc);
} }
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
...@@ -301,10 +326,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) ...@@ -301,10 +326,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
struct rtc_device *rtc = platform_get_drvdata(pdev); struct rtc_device *rtc = platform_get_drvdata(pdev);
/* Disable all interrupts */ /* Disable all interrupts */
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_SECEV | AT91_RTC_TIMEV |
AT91_RTC_CALEV); AT91_RTC_CALEV);
free_irq(AT91_ID_SYS, pdev); free_irq(irq, pdev);
rtc_device_unregister(rtc); rtc_device_unregister(rtc);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
...@@ -323,13 +348,13 @@ static int at91_rtc_suspend(struct device *dev) ...@@ -323,13 +348,13 @@ static int at91_rtc_suspend(struct device *dev)
/* this IRQ is shared with DBGU and other hardware which isn't /* this IRQ is shared with DBGU and other hardware which isn't
* necessarily doing PM like we are... * necessarily doing PM like we are...
*/ */
at91_rtc_imr = at91_sys_read(AT91_RTC_IMR) at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR)
& (AT91_RTC_ALARM|AT91_RTC_SECEV); & (AT91_RTC_ALARM|AT91_RTC_SECEV);
if (at91_rtc_imr) { if (at91_rtc_imr) {
if (device_may_wakeup(dev)) if (device_may_wakeup(dev))
enable_irq_wake(AT91_ID_SYS); enable_irq_wake(irq);
else else
at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr);
} }
return 0; return 0;
} }
...@@ -338,9 +363,9 @@ static int at91_rtc_resume(struct device *dev) ...@@ -338,9 +363,9 @@ static int at91_rtc_resume(struct device *dev)
{ {
if (at91_rtc_imr) { if (at91_rtc_imr) {
if (device_may_wakeup(dev)) if (device_may_wakeup(dev))
disable_irq_wake(AT91_ID_SYS); disable_irq_wake(irq);
else else
at91_sys_write(AT91_RTC_IER, at91_rtc_imr); at91_rtc_write(AT91_RTC_IER, at91_rtc_imr);
} }
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册