diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 7 | ||||
-rw-r--r-- | arch/arm/common/rtctime.c | 108 | ||||
-rw-r--r-- | arch/arm/lib/copy_template.S | 2 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/core.c | 68 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/time.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-integrator/core.c | 46 | ||||
-rw-r--r-- | arch/arm/mach-integrator/time.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-netstar.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-voiceblue.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/generic.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/generic.c | 6 |
11 files changed, 158 insertions, 122 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 427c72140110..ba46d779ede7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -8,6 +8,7 @@ mainmenu "Linux Kernel Configuration" config ARM bool default y + select RTC_LIB help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -53,6 +54,10 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config GENERIC_HWEIGHT + bool + default y + config GENERIC_CALIBRATE_DELAY bool default y @@ -844,6 +849,8 @@ source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" +source "drivers/rtc/Kconfig" + endmenu source "fs/Kconfig" diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c index e851d86c212c..35c9a64ac14c 100644 --- a/arch/arm/common/rtctime.c +++ b/arch/arm/common/rtctime.c @@ -20,6 +20,7 @@ #include <linux/capability.h> #include <linux/device.h> #include <linux/mutex.h> +#include <linux/rtc.h> #include <asm/rtc.h> #include <asm/semaphore.h> @@ -42,89 +43,6 @@ static struct rtc_ops *rtc_ops; #define rtc_epoch 1900UL -static const unsigned char days_in_month[] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) -#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) - -static int month_days(unsigned int month, unsigned int year) -{ - return days_in_month[month] + (LEAP_YEAR(year) && month == 1); -} - -/* - * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. - */ -void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) -{ - int days, month, year; - - days = time / 86400; - time -= days * 86400; - - tm->tm_wday = (days + 4) % 7; - - year = 1970 + days / 365; - days -= (year - 1970) * 365 - + LEAPS_THRU_END_OF(year - 1) - - LEAPS_THRU_END_OF(1970 - 1); - if (days < 0) { - year -= 1; - days += 365 + LEAP_YEAR(year); - } - tm->tm_year = year - 1900; - tm->tm_yday = days + 1; - - for (month = 0; month < 11; month++) { - int newdays; - - newdays = days - month_days(month, year); - if (newdays < 0) - break; - days = newdays; - } - tm->tm_mon = month; - tm->tm_mday = days + 1; - - tm->tm_hour = time / 3600; - time -= tm->tm_hour * 3600; - tm->tm_min = time / 60; - tm->tm_sec = time - tm->tm_min * 60; -} -EXPORT_SYMBOL(rtc_time_to_tm); - -/* - * Does the rtc_time represent a valid date/time? - */ -int rtc_valid_tm(struct rtc_time *tm) -{ - if (tm->tm_year < 70 || - tm->tm_mon >= 12 || - tm->tm_mday < 1 || - tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) || - tm->tm_hour >= 24 || - tm->tm_min >= 60 || - tm->tm_sec >= 60) - return -EINVAL; - - return 0; -} -EXPORT_SYMBOL(rtc_valid_tm); - -/* - * Convert Gregorian date to seconds since 01-01-1970 00:00:00. - */ -int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) -{ - *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return 0; -} -EXPORT_SYMBOL(rtc_tm_to_time); - /* * Calculate the next alarm time given the requested alarm time mask * and the current time. @@ -151,13 +69,13 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc } } -static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) +static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) { memset(tm, 0, sizeof(struct rtc_time)); return ops->read_time(tm); } -static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) +static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) { int ret; @@ -168,7 +86,7 @@ static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) return ret; } -static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) +static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) { int ret = -EINVAL; if (ops->read_alarm) { @@ -178,7 +96,7 @@ static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) return ret; } -static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) +static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) { int ret = -EINVAL; if (ops->set_alarm) @@ -266,7 +184,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, switch (cmd) { case RTC_ALM_READ: - ret = rtc_read_alarm(ops, &alrm); + ret = rtc_arm_read_alarm(ops, &alrm); if (ret) break; ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); @@ -288,11 +206,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, alrm.time.tm_wday = -1; alrm.time.tm_yday = -1; alrm.time.tm_isdst = -1; - ret = rtc_set_alarm(ops, &alrm); + ret = rtc_arm_set_alarm(ops, &alrm); break; case RTC_RD_TIME: - ret = rtc_read_time(ops, &tm); + ret = rtc_arm_read_time(ops, &tm); if (ret) break; ret = copy_to_user(uarg, &tm, sizeof(tm)); @@ -310,7 +228,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ret = -EFAULT; break; } - ret = rtc_set_time(ops, &tm); + ret = rtc_arm_set_time(ops, &tm); break; case RTC_EPOCH_SET: @@ -341,11 +259,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ret = -EFAULT; break; } - ret = rtc_set_alarm(ops, &alrm); + ret = rtc_arm_set_alarm(ops, &alrm); break; case RTC_WKALM_RD: - ret = rtc_read_alarm(ops, &alrm); + ret = rtc_arm_read_alarm(ops, &alrm); if (ret) break; ret = copy_to_user(uarg, &alrm, sizeof(alrm)); @@ -435,7 +353,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo struct rtc_time tm; char *p = page; - if (rtc_read_time(ops, &tm) == 0) { + if (rtc_arm_read_time(ops, &tm) == 0) { p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n" "rtc_date\t: %04d-%02d-%02d\n" @@ -445,7 +363,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo rtc_epoch); } - if (rtc_read_alarm(ops, &alrm) == 0) { + if (rtc_arm_read_alarm(ops, &alrm) == 0) { p += sprintf(p, "alrm_time\t: "); if ((unsigned int)alrm.time.tm_hour <= 24) p += sprintf(p, "%02d:", alrm.time.tm_hour); diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S index 838e435e4922..cab355c0c1f7 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib/copy_template.S @@ -236,7 +236,7 @@ /* - * Abort preanble and completion macros. + * Abort preamble and completion macros. * If a fixup handler is required then those macros must surround it. * It is assumed that the fixup code will handle the private part of * the exit macro. diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 865427bfad7e..2d892e4daa07 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -30,7 +30,9 @@ #include <linux/time.h> #include <linux/timex.h> #include <linux/delay.h> +#include <linux/termios.h> #include <linux/amba/bus.h> +#include <linux/amba/serial.h> #include <asm/types.h> #include <asm/setup.h> @@ -360,6 +362,68 @@ void __init ep93xx_init_irq(void) /************************************************************************* * EP93xx peripheral handling *************************************************************************/ +#define EP93XX_UART_MCR_OFFSET (0x0100) + +static void ep93xx_uart_set_mctrl(struct amba_device *dev, + void __iomem *base, unsigned int mctrl) +{ + unsigned int mcr; + + mcr = 0; + if (!(mctrl & TIOCM_RTS)) + mcr |= 2; + if (!(mctrl & TIOCM_DTR)) + mcr |= 1; + + __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET); +} + +static struct amba_pl010_data ep93xx_uart_data = { + .set_mctrl = ep93xx_uart_set_mctrl, +}; + +static struct amba_device uart1_device = { + .dev = { + .bus_id = "apb:uart1", + .platform_data = &ep93xx_uart_data, + }, + .res = { + .start = EP93XX_UART1_PHYS_BASE, + .end = EP93XX_UART1_PHYS_BASE + 0x0fff, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_EP93XX_UART1, NO_IRQ }, + .periphid = 0x00041010, +}; + +static struct amba_device uart2_device = { + .dev = { + .bus_id = "apb:uart2", + .platform_data = &ep93xx_uart_data, + }, + .res = { + .start = EP93XX_UART2_PHYS_BASE, + .end = EP93XX_UART2_PHYS_BASE + 0x0fff, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_EP93XX_UART2, NO_IRQ }, + .periphid = 0x00041010, +}; + +static struct amba_device uart3_device = { + .dev = { + .bus_id = "apb:uart3", + .platform_data = &ep93xx_uart_data, + }, + .res = { + .start = EP93XX_UART3_PHYS_BASE, + .end = EP93XX_UART3_PHYS_BASE + 0x0fff, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_EP93XX_UART3, NO_IRQ }, + .periphid = 0x00041010, +}; + void __init ep93xx_init_devices(void) { unsigned int v; @@ -371,4 +435,8 @@ void __init ep93xx_init_devices(void) v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG); + + amba_device_register(&uart1_device, &iomem_resource); + amba_device_register(&uart2_device, &iomem_resource); + amba_device_register(&uart3_device, &iomem_resource); } diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c index 2c64a0b0502e..5d02e95dede3 100644 --- a/arch/arm/mach-footbridge/time.c +++ b/arch/arm/mach-footbridge/time.c @@ -34,27 +34,12 @@ static int rtc_base; static unsigned long __init get_isa_cmos_time(void) { unsigned int year, mon, day, hour, min, sec; - int i; // check to see if the RTC makes sense..... if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) return mktime(1970, 1, 1, 0, 0, 0); - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - - do { /* Isn't this overkill ? UIP above should guarantee consistency */ + do { sec = CMOS_READ(RTC_SECONDS); min = CMOS_READ(RTC_MINUTES); hour = CMOS_READ(RTC_HOURS); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 20071a2767cc..576a5e979c00 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -15,7 +15,9 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/smp.h> +#include <linux/termios.h> #include <linux/amba/bus.h> +#include <linux/amba/serial.h> #include <asm/hardware.h> #include <asm/irq.h> @@ -28,6 +30,8 @@ #include "common.h" +static struct amba_pl010_data integrator_uart_data; + static struct amba_device rtc_device = { .dev = { .bus_id = "mb:15", @@ -44,6 +48,7 @@ static struct amba_device rtc_device = { static struct amba_device uart0_device = { .dev = { .bus_id = "mb:16", + .platform_data = &integrator_uart_data, }, .res = { .start = INTEGRATOR_UART0_BASE, @@ -57,6 +62,7 @@ static struct amba_device uart0_device = { static struct amba_device uart1_device = { .dev = { .bus_id = "mb:17", + .platform_data = &integrator_uart_data, }, .res = { .start = INTEGRATOR_UART1_BASE, @@ -115,6 +121,46 @@ static int __init integrator_init(void) arch_initcall(integrator_init); +/* + * On the Integrator platform, the port RTS and DTR are provided by + * bits in the following SC_CTRLS register bits: + * RTS DTR + * UART0 7 6 + * UART1 5 4 + */ +#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) +#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) + +static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl) +{ + unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask; + + if (dev == &uart0_device) { + rts_mask = 1 << 4; + dtr_mask = 1 << 5; + } else { + rts_mask = 1 << 6; + dtr_mask = 1 << 7; + } + + if (mctrl & TIOCM_RTS) + ctrlc |= rts_mask; + else + ctrls |= rts_mask; + + if (mctrl & TIOCM_DTR) + ctrlc |= dtr_mask; + else + ctrls |= dtr_mask; + + __raw_writel(ctrls, SC_CTRLS); + __raw_writel(ctrlc, SC_CTRLC); +} + +static struct amba_pl010_data integrator_uart_data = { + .set_mctrl = integrator_uart_set_mctrl, +}; + #define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET static DEFINE_SPINLOCK(cm_lock); diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c index 3c22c16b38bf..bc07f52a6fd7 100644 --- a/arch/arm/mach-integrator/time.c +++ b/arch/arm/mach-integrator/time.c @@ -40,13 +40,13 @@ static int integrator_set_rtc(void) return 1; } -static int rtc_read_alarm(struct rtc_wkalrm *alrm) +static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm) { rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); return 0; } -static inline int rtc_set_alarm(struct rtc_wkalrm *alrm) +static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm) { unsigned long time; int ret; @@ -62,7 +62,7 @@ static inline int rtc_set_alarm(struct rtc_wkalrm *alrm) return ret; } -static int rtc_read_time(struct rtc_time *tm) +static int integrator_rtc_read_time(struct rtc_time *tm) { rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); return 0; @@ -76,7 +76,7 @@ static int rtc_read_time(struct rtc_time *tm) * edge of the 1Hz clock, we must write the time one second * in advance. */ -static inline int rtc_set_time(struct rtc_time *tm) +static inline int integrator_rtc_set_time(struct rtc_time *tm) { unsigned long time; int ret; @@ -90,10 +90,10 @@ static inline int rtc_set_time(struct rtc_time *tm) static struct rtc_ops rtc_ops = { .owner = THIS_MODULE, - .read_time = rtc_read_time, - .set_time = rtc_set_time, - .read_alarm = rtc_read_alarm, - .set_alarm = rtc_set_alarm, + .read_time = integrator_rtc_read_time, + .set_time = integrator_rtc_set_time, + .read_alarm = integrator_rtc_read_alarm, + .set_alarm = integrator_rtc_set_alarm, }; static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id, diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index 60d5f8a3339c..7520e602d7a2 100644 --- a/arch/arm/mach-omap1/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c @@ -141,7 +141,7 @@ static int __init netstar_late_init(void) /* TODO: Setup front panel switch here */ /* Setup panic notifier */ - notifier_chain_register(&panic_notifier_list, &panic_block); + atomic_notifier_chain_register(&panic_notifier_list, &panic_block); return 0; } diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index bfd5fdd1a875..52e4a9d69642 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -235,7 +235,7 @@ static struct notifier_block panic_block = { static int __init voiceblue_setup(void) { /* Setup panic notifier */ - notifier_chain_register(&panic_notifier_list, &panic_block); + atomic_notifier_chain_register(&panic_notifier_list, &panic_block); return 0; } diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 9b48a90aefce..5efa84749f37 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -319,6 +319,11 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) pxaficp_device.dev.platform_data = info; } +static struct platform_device pxartc_device = { + .name = "sa1100-rtc", + .id = -1, +}; + static struct platform_device *devices[] __initdata = { &pxamci_device, &udc_device, @@ -329,6 +334,7 @@ static struct platform_device *devices[] __initdata = { &pxaficp_device, &i2c_device, &i2s_device, + &pxartc_device, }; static int __init pxa_init(void) diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 2abdc419e984..9ea71551fc04 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -324,6 +324,11 @@ void sa11x0_set_irda_data(struct irda_platform_data *irda) sa11x0ir_device.dev.platform_data = irda; } +static struct platform_device sa11x0rtc_device = { + .name = "sa1100-rtc", + .id = -1, +}; + static struct platform_device *sa11x0_devices[] __initdata = { &sa11x0udc_device, &sa11x0uart1_device, @@ -333,6 +338,7 @@ static struct platform_device *sa11x0_devices[] __initdata = { &sa11x0pcmcia_device, &sa11x0fb_device, &sa11x0mtd_device, + &sa11x0rtc_device, }; static int __init sa1100_init(void) |