Commit 8a6d2688 authored by Linus Torvalds's avatar Linus Torvalds

Merge arm integrator time.h removal

parents d8b3edf1 8c246a13
......@@ -83,6 +83,8 @@ config ARCH_CLPS711X
config ARCH_CO285
bool "Co-EBSA285"
select FOOTBRIDGE
select FOOTBRIDGE_ADDIN
config ARCH_EBSA110
bool "EBSA-110"
......@@ -101,6 +103,7 @@ config ARCH_CAMELOT
config ARCH_FOOTBRIDGE
bool "FootBridge"
select FOOTBRIDGE
config ARCH_INTEGRATOR
bool "Integrator"
......@@ -213,28 +216,6 @@ config TIMER_ACORN
depends on ARCH_ACORN || ARCH_CLPS7500
default y
#####################################################################
# Footbridge support
config FOOTBRIDGE
bool
depends on ARCH_CO285 || ARCH_FOOTBRIDGE
default y
config FOOTBRIDGE_HOST
bool
depends on ARCH_CATS || ARCH_EBSA285_HOST || ARCH_NETWINDER || ARCH_PERSONAL_SERVER
default y
config FOOTBRIDGE_ADDIN
bool
depends on ARCH_CO285 || ARCH_EBSA285_ADDIN
default y
config ARCH_EBSA285
bool
depends on ARCH_EBSA285_HOST || ARCH_EBSA285_ADDIN
default y
#####################################################################
# SA1111 support
config SA1111
......
......@@ -109,6 +109,11 @@ ifeq ($(incdir-y),)
incdir-y := $(machine-y)
endif
INCDIR := arch-$(incdir-y)
ifneq ($(machine-y),)
MACHINE := arch/arm/mach-$(machine-y)/
else
MACHINE :=
endif
export TEXTADDR GZFLAGS
......@@ -120,9 +125,7 @@ endif
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
ifneq ($(machine-y),)
core-y += arch/arm/mach-$(machine-y)/
endif
core-y += $(MACHINE)
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
......@@ -162,10 +165,10 @@ maketools: include/asm-arm/constants.h include/linux/version.h FORCE
bzImage: zImage
zImage Image bootpImage uImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
zinstall install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
CLEAN_FILES += include/asm-arm/constants.h* include/asm-arm/mach-types.h \
include/asm-arm/arch include/asm-arm/.arch
......@@ -175,8 +178,8 @@ archclean:
$(Q)$(MAKE) $(clean)=$(boot)
# My testing targets (bypasses dependencies)
bp:; $(Q)$(MAKE) $(build)=$(boot) $(boot)/bootpImage
i zi:; $(Q)$(MAKE) $(build)=$(boot) $@
bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
include/asm-arm/.arch
......
......@@ -10,69 +10,14 @@
MKIMAGE := $(srctree)/scripts/mkuboot.sh
ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(TEXTADDR)
# PARAMS_PHYS must be with 4MB of ZRELADDR
# PARAMS_PHYS must be within 4MB of ZRELADDR
# INITRD_PHYS must be in RAM
zreladdr-$(CONFIG_ARCH_RPC) := 0x10008000
params_phys-$(CONFIG_ARCH_RPC) := 0x10000100
initrd_phys-$(CONFIG_ARCH_RPC) := 0x18000000
zreladdr-$(CONFIG_ARCH_CLPS7500) := 0x10008000
zreladdr-$(CONFIG_ARCH_CLPS7500) := 0x10008000
zreladdr-$(CONFIG_ARCH_EBSA110) := 0x00008000
params_phys-$(CONFIG_ARCH_EBSA110) := 0x00000400
initrd_phys-$(CONFIG_ARCH_EBSA110) := 0x00800000
ztextaddr-$(CONFIG_ARCH_SHARK) := 0x08508000
zreladdr-$(CONFIG_ARCH_SHARK) := 0x08008000
zreladdr-$(CONFIG_FOOTBRIDGE) := 0x00008000
params_phys-$(CONFIG_FOOTBRIDGE) := 0x00000100
initrd_phys-$(CONFIG_FOOTBRIDGE) := 0x00800000
zreladdr-$(CONFIG_ARCH_INTEGRATOR) := 0x00008000
params_phys-$(CONFIG_ARCH_INTEGRATOR) := 0x00000100
initrd_phys-$(CONFIG_ARCH_INTEGRATOR) := 0x00800000
zreladdr-$(CONFIG_ARCH_CAMELOT) := 0x00008000
zreladdr-$(CONFIG_ARCH_NEXUSPCI) := 0x40008000
zreladdr-$(CONFIG_ARCH_L7200) := 0xf0008000
# The standard locations for stuff on CLPS711x type processors
zreladdr-$(CONFIG_ARCH_CLPS711X) := 0xc0028000
params_phys-$(CONFIG_ARCH_CLPS711X) := 0xc0000100
# Should probably have some agreement on these...
initrd_phys-$(CONFIG_ARCH_P720T) := 0xc0400000
initrd_phys-$(CONFIG_ARCH_CDB89712) := 0x00700000
zreladdr-$(CONFIG_ARCH_SA1100) := 0xc0008000
ifeq ($(CONFIG_ARCH_SA1100),y)
zreladdr-$(CONFIG_SA1111) := 0xc0208000
endif
params_phys-$(CONFIG_ARCH_SA1100) := 0xc0000100
initrd_phys-$(CONFIG_ARCH_SA1100) := 0xc0800000
zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000
zreladdr-$(CONFIG_ARCH_MX1ADS) := 0x08008000
zreladdr-$(CONFIG_ARCH_IOP3XX) := 0xa0008000
params_phys-$(CONFIG_ARCH_IOP3XX) := 0xa0000100
initrd_phys-$(CONFIG_ARCH_IOP3XX) := 0xa0800000
ifeq ($(CONFIG_ARCH_IOP331),y)
zreladdr-$(CONFIG_ARCH_IOP3XX) := 0x00008000
params_phys-$(CONFIG_ARCH_IOP3XX) := 0x00000100
initrd_phys-$(CONFIG_ARCH_IOP3XX) := 0x00800000
endif
zreladdr-$(CONFIG_ARCH_IXP4XX) := 0x00008000
params-phys-$(CONFIG_ARCH_IXP4XX) := 0x00000100
zreladdr-$(CONFIG_ARCH_IXP2000) := 0x00008000
params-phys-$(CONFIG_ARCH_IXP2000) := 0x00000100
zreladdr-$(CONFIG_ARCH_OMAP) := 0x10008000
params_phys-$(CONFIG_ARCH_OMAP) := 0x10000100
initrd_phys-$(CONFIG_ARCH_OMAP) := 0x10800000
zreladdr-$(CONFIG_ARCH_LH7A40X) := 0xc0008000
params_phys-$(CONFIG_ARCH_LH7A40X) := 0xc0000100
initrd_phys-$(CONFIG_ARCH_LH7A40X) := 0xc4000000
zreladdr-$(CONFIG_ARCH_S3C2410) := 0x30008000
params_phys-$(CONFIG_ARCH_S3C2410) := 0x30000100
zreladdr-$(CONFIG_ARCH_VERSATILE_PB) := 0x00008000
params_phys-$(CONFIG_ARCH_VERSATILE_PB) := 0x00000100
initrd_phys-$(CONFIG_ARCH_VERSATILE_PB) := 0x00800000
zreladdr-$(CONFIG_ARCH_H720X) := 0x40008000
ZRELADDR := $(zreladdr-y)
PARAMS_PHYS := $(params_phys-y)
INITRD_PHYS := $(initrd_phys-y)
......
......@@ -2,6 +2,7 @@
# Makefile for the linux kernel.
#
obj-y += rtctime.o
obj-$(CONFIG_ARM_AMBA) += amba.o
obj-$(CONFIG_ICST525) += icst525.o
obj-$(CONFIG_SA1111) += sa1111.o
......
/*
* linux/arch/arm/common/rtctime.c
*
* Copyright (C) 2003 Deep Blue Solutions Ltd.
* Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre.
* Based on rtc.c by Paul Gortmaker
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/rtc.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/miscdevice.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <asm/rtc.h>
#include <asm/semaphore.h>
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
static struct fasync_struct *rtc_async_queue;
/*
* rtc_lock protects rtc_irq_data
*/
static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
static unsigned long rtc_irq_data;
/*
* rtc_sem protects rtc_inuse and rtc_ops
*/
static DECLARE_MUTEX(rtc_sem);
static unsigned long rtc_inuse;
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);
/*
* Convert Gregorian date to seconds since 01-01-1970 00:00:00.
*/
int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
{
unsigned int yrs = tm->tm_year + 1900;
*time = 0;
if (yrs < 1970 ||
tm->tm_mon >= 12 ||
tm->tm_mday < 1 ||
tm->tm_mday > month_days(tm->tm_mon, yrs) ||
tm->tm_hour >= 24 ||
tm->tm_min >= 60 ||
tm->tm_sec >= 60)
return -EINVAL;
*time = mktime(yrs, 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.
*
* FIXME: for now, we just copy the alarm time because we're lazy (and
* is therefore buggy - setting a 10am alarm at 8pm will not result in
* the alarm triggering.)
*/
void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
{
next->tm_year = now->tm_year;
next->tm_mon = now->tm_mon;
next->tm_mday = now->tm_mday;
next->tm_hour = alrm->tm_hour;
next->tm_min = alrm->tm_min;
next->tm_sec = alrm->tm_sec;
}
static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
{
memset(tm, 0, sizeof(struct rtc_time));
ops->read_time(tm);
}
static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
{
return ops->set_time(tm);
}
static inline void rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
{
memset(alrm, 0, sizeof(struct rtc_wkalrm));
ops->read_alarm(alrm);
}
static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
{
return ops->set_alarm(alrm);
}
void rtc_update(unsigned long num, unsigned long events)
{
spin_lock(&rtc_lock);
rtc_irq_data = (rtc_irq_data + (num << 8)) | events;
spin_unlock(&rtc_lock);
wake_up_interruptible(&rtc_wait);
kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
}
EXPORT_SYMBOL(rtc_update);
static ssize_t
rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long data;
ssize_t ret;
if (count < sizeof(unsigned long))
return -EINVAL;
add_wait_queue(&rtc_wait, &wait);
do {
__set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irq(&rtc_lock);
data = rtc_irq_data;
rtc_irq_data = 0;
spin_unlock_irq(&rtc_lock);
if (data != 0) {
ret = 0;
break;
}
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
break;
}
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
schedule();
} while (1);
set_current_state(TASK_RUNNING);
remove_wait_queue(&rtc_wait, &wait);
if (ret == 0) {
ret = put_user(data, (unsigned long *)buf);
if (ret == 0)
ret = sizeof(unsigned long);
}
return ret;
}
static unsigned int rtc_poll(struct file *file, poll_table *wait)
{
unsigned long data;
poll_wait(file, &rtc_wait, wait);
spin_lock_irq(&rtc_lock);
data = rtc_irq_data;
spin_unlock_irq(&rtc_lock);
return data != 0 ? POLLIN | POLLRDNORM : 0;
}
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct rtc_ops *ops = file->private_data;
struct rtc_time tm;
struct rtc_wkalrm alrm;
int ret;
switch (cmd) {
case RTC_ALM_READ:
rtc_read_alarm(ops, &alrm);
ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm));
if (ret)
ret = -EFAULT;
break;
case RTC_ALM_SET:
ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm));
alrm.enabled = 0;
alrm.pending = 0;
alrm.time.tm_mday = -1;
alrm.time.tm_mon = -1;
alrm.time.tm_year = -1;
alrm.time.tm_wday = -1;
alrm.time.tm_yday = -1;
alrm.time.tm_isdst = -1;
if (ret == 0)
ret = rtc_set_alarm(ops, &alrm);
else
ret = -EFAULT;
break;
case RTC_RD_TIME:
rtc_read_time(ops, &tm);
ret = copy_to_user((void *)arg, &tm, sizeof(tm));
if (ret)
ret = -EFAULT;
break;
case RTC_SET_TIME:
if (!capable(CAP_SYS_TIME)) {
ret = -EACCES;
break;
}
ret = copy_from_user(&tm, (void *)arg, sizeof(tm));
if (ret == 0)
ret = rtc_set_time(ops, &tm);
else
ret = -EFAULT;
break;
#ifndef rtc_epoch
case RTC_EPOCH_SET:
/*
* There were no RTC clocks before 1900.
*/
if (arg < 1900) {
ret = -EINVAL;
break;
}
if (!capable(CAP_SYS_TIME)) {
ret = -EACCES;
break;
}
rtc_epoch = arg;
ret = 0;
break;
#endif
case RTC_EPOCH_READ:
ret = put_user(rtc_epoch, (unsigned long *)arg);
break;
case RTC_WKALM_SET:
ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm));
if (ret == 0)
ret = rtc_set_alarm(ops, &alrm);
else
ret = -EFAULT;
break;
case RTC_WKALM_RD:
rtc_read_alarm(ops, &alrm);
ret = copy_to_user((void *)arg, &alrm, sizeof(alrm));
if (ret)
ret = -EFAULT;
break;
default:
ret = ops->ioctl(cmd, arg);
}
return ret;
}
static int rtc_open(struct inode *inode, struct file *file)
{
int ret;
down(&rtc_sem);
if (rtc_inuse) {
ret = -EBUSY;
} else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {
ret = -ENODEV;
} else {
file->private_data = rtc_ops;
ret = rtc_ops->open ? rtc_ops->open() : 0;
if (ret == 0) {
spin_lock_irq(&rtc_lock);
rtc_irq_data = 0;
spin_unlock_irq(&rtc_lock);
rtc_inuse = 1;
}
}
up(&rtc_sem);
return ret;
}
static int rtc_release(struct inode *inode, struct file *file)
{
struct rtc_ops *ops = file->private_data;
if (ops->release)
ops->release();
spin_lock_irq(&rtc_lock);
rtc_irq_data = 0;
spin_unlock_irq(&rtc_lock);
module_put(rtc_ops->owner);
rtc_inuse = 0;
return 0;
}
static int rtc_fasync(int fd, struct file *file, int on)
{
return fasync_helper(fd, file, on, &rtc_async_queue);
}
static struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = rtc_read,
.poll = rtc_poll,
.ioctl = rtc_ioctl,
.open = rtc_open,
.release = rtc_release,
.fasync = rtc_fasync,
};
static struct miscdevice rtc_miscdev = {
.minor = RTC_MINOR,
.name = "rtc",
.fops = &rtc_fops,
};
static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
{
struct rtc_ops *ops = data;
struct rtc_wkalrm alrm;
struct rtc_time tm;
char *p = page;
int len;
rtc_read_time(ops, &tm);
p += sprintf(p,
"rtc_time\t: %02d:%02d:%02d\n"
"rtc_date\t: %04d-%02d-%02d\n"
"rtc_epoch\t: %04lu\n",
tm.tm_hour, tm.tm_min, tm.tm_sec,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
rtc_epoch);
rtc_read_alarm(ops, &alrm);
p += sprintf(p, "alrm_time\t: ");
if ((unsigned int)alrm.time.tm_hour <= 24)
p += sprintf(p, "%02d:", alrm.time.tm_hour);
else
p += sprintf(p, "**:");
if ((unsigned int)alrm.time.tm_min <= 59)
p += sprintf(p, "%02d:", alrm.time.tm_min);
else
p += sprintf(p, "**:");
if ((unsigned int)alrm.time.tm_sec <= 59)
p += sprintf(p, "%02d\n", alrm.time.tm_sec);
else
p += sprintf(p, "**\n");
p += sprintf(p, "alrm_date\t: ");
if ((unsigned int)alrm.time.tm_year <= 200)
p += sprintf(p, "%04d-", alrm.time.tm_year + 1900);
else
p += sprintf(p, "****-");
if ((unsigned int)alrm.time.tm_mon <= 11)
p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);
else
p += sprintf(p, "**-");
if ((unsigned int)alrm.time.tm_mday <= 31)
p += sprintf(p, "%02d\n", alrm.time.tm_mday);
else
p += sprintf(p, "**\n");
p += sprintf(p, "alrm_wakeup\t: %s\n", alrm.enabled ? "yes" : "no");
p += sprintf(p, "alrm_pending\t: %s\n", alrm.pending ? "yes" : "no");
if (ops->proc)
p += ops->proc(p);
len = (p - page) - off;
if (len < 0)
len = 0;
*eof = len <= count;
*start = page + off;
return len;
}
int register_rtc(struct rtc_ops *ops)
{
int ret = -EBUSY;
down(&rtc_sem);
if (rtc_ops == NULL) {
rtc_ops = ops;
ret = misc_register(&rtc_miscdev);
if (ret == 0)
create_proc_read_entry("driver/rtc", 0, 0,
rtc_read_proc, ops);
}
up(&rtc_sem);
return ret;
}
EXPORT_SYMBOL(register_rtc);
void unregister_rtc(struct rtc_ops *rtc)
{
down(&rtc_sem);
if (rtc == rtc_ops) {
remove_proc_entry("driver/rtc", NULL);
misc_deregister(&rtc_miscdev);
rtc_ops = NULL;
}
up(&rtc_sem);
}
EXPORT_SYMBOL(unregister_rtc);
......@@ -15,6 +15,7 @@
*/
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/hardware.h>
#include <asm/io.h>
......@@ -22,7 +23,7 @@
#include <asm/mach/time.h>
static unsigned long ioctime_gettimeoffset(void)
unsigned long ioc_timer_gettimeoffset(void)
{
unsigned int count1, count2, status;
long offset;
......@@ -62,6 +63,33 @@ void __init ioctime_init(void)
ioc_writeb(LATCH & 255, IOC_T0LTCHL);
ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
ioc_writeb(0, IOC_T0GO);
}
static irqreturn_t
ioc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
timer_tick(regs);
gettimeoffset = ioctime_gettimeoffset;
return IRQ_HANDLED;
}
static struct irqaction ioc_timer_irq = {
.name = "timer",
.flags = SA_INTERRUPT,
.handler = ioc_timer_interrupt
};
/*
* Set up timer interrupt.
*/
static void __init ioc_timer_init(void)
{
ioctime_init();
setup_irq(IRQ_TIMER, &ioc_timer_irq);
}
struct sys_timer ioc_timer = {
.init = ioc_timer_init,
.offset = ioc_timer_gettimeoffset,
};
......@@ -60,7 +60,8 @@ EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
EXPORT_SYMBOL(__backtrace);
/* platform dependent support */
EXPORT_SYMBOL(udelay);
EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__const_udelay);
/* networking */
EXPORT_SYMBOL(csum_partial);
......
......@@ -726,7 +726,7 @@ void __init setup_arch(char **cmdline_p)
* Set up various architecture-specific pointers
*/
init_arch_irq = mdesc->init_irq;
init_arch_time = mdesc->init_time;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
#ifdef CONFIG_VT
......
......@@ -126,25 +126,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
return ret;
}
/*
* Do a signal return; undo the signal stack.
*/
struct sigframe
{
struct sigcontext sc;
unsigned long extramask[_NSIG_WORDS-1];
unsigned long retcode;
};
struct rt_sigframe
{
struct siginfo __user *pinfo;
void __user *puc;
struct siginfo info;
struct ucontext uc;
unsigned long retcode;
};
#ifdef CONFIG_IWMMXT
/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
......@@ -152,8 +133,15 @@ struct rt_sigframe
#define IWMMXT_MAGIC0 0x12ef842a
#define IWMMXT_MAGIC1 0x1c07ca71
static int page_present(struct mm_struct *mm, unsigned long addr, int wr)
struct iwmmxt_sigframe {
unsigned long magic0;
unsigned long magic1;
unsigned long storage[0x98/4];
};
static int page_present(struct mm_struct *mm, void __user *uptr, int wr)
{
unsigned long addr = (unsigned long)uptr;
pgd_t *pgd = pgd_offset(mm, addr);
if (pgd_present(*pgd)) {
pmd_t *pmd = pmd_offset(pgd, addr);
......@@ -165,49 +153,66 @@ static int page_present(struct mm_struct *mm, unsigned long addr, int wr)
return 0;
}
static int
preserve_iwmmxt_context(void *iwmmxt_save_area)
static int copy_locked(void __user *uptr, void *kptr, size_t size, int write,
void (*copyfn)(void *, void __user *))
{
unsigned char v, __user *userptr = uptr;
int err = 0;
do {
struct mm_struct *mm;
if (write) {
__put_user_error(0, userptr, err);
__put_user_error(0, userptr + size - 1, err);
} else {
__get_user_error(v, userptr, err);
__get_user_error(v, userptr + size - 1, err);
}
if (err)
break;
mm = current->mm;
spin_lock(&mm->page_table_lock);
if (page_present(mm, userptr, write) &&
page_present(mm, userptr + size - 1, write)) {
copyfn(kptr, uptr);
} else
err = 1;
spin_unlock(&mm->page_table_lock);
} while (err);
return err;
}
static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
{
int err = 0;
/* the iWMMXt context must be 64 bit aligned */
long *iwmmxt_storage = (long *)(((long)iwmmxt_save_area + 4) & ~7);
WARN_ON((unsigned long)frame & 7);
__put_user_error(IWMMXT_MAGIC0, &frame->magic0, err);
__put_user_error(IWMMXT_MAGIC1, &frame->magic1, err);
again:
__put_user_error(IWMMXT_MAGIC0, iwmmxt_storage+0, err);
__put_user_error(IWMMXT_MAGIC1, iwmmxt_storage+1, err);
/*
* iwmmxt_task_copy() doesn't check user permissions.
* Let's do a dummy write on the upper boundary to ensure
* access to user mem is OK all way up.
*/
__put_user_error(0, iwmmxt_storage+IWMMXT_STORAGE_SIZE/4-1, err);
if (!err) {
/* Let's make sure the user mapping won't disappear under us */
struct mm_struct *mm = current->mm;
unsigned long addr = (unsigned long)iwmmxt_storage;
spin_lock(&mm->page_table_lock);
if ( !page_present(mm, addr, 1) ||
!page_present(mm, addr+IWMMXT_STORAGE_SIZE-1, 1) ) {
/* our user area has gone before grabbing the lock */
spin_unlock(&mm->page_table_lock);
goto again;
}
iwmmxt_task_copy(current_thread_info(), iwmmxt_storage+2);
spin_unlock(&mm->page_table_lock);
return 0;
}
err |= copy_locked(&frame->storage, current_thread_info(),
sizeof(frame->storage), 1, iwmmxt_task_copy);
return err;
}
static int
restore_iwmmxt_context(void *iwmmxt_save_area)
static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
{
unsigned long magic0, magic1;
int err = 0;
long *iwmmxt_storage, magic0, magic1, dummy;
/* the iWMMXt context is 64 bit aligned */
iwmmxt_storage = (long *)(((long)iwmmxt_save_area + 4) & ~7);
WARN_ON((unsigned long)frame & 7);
/*
* Validate iWMMXt context signature.
......@@ -215,32 +220,51 @@ restore_iwmmxt_context(void *iwmmxt_save_area)
* Let's do a dummy write on the upper boundary to ensure
* access to user mem is OK all way up.
*/
again:
__get_user_error(magic0, iwmmxt_storage+0, err);
__get_user_error(magic1, iwmmxt_storage+1, err);
if (!err && magic0 == IWMMXT_MAGIC0 && magic1 == IWMMXT_MAGIC1 &&
!__get_user(dummy, iwmmxt_storage+IWMMXT_STORAGE_SIZE/4-1)) {
/* Let's make sure the user mapping won't disappear under us */
struct mm_struct *mm = current->mm;
unsigned long addr = (unsigned long)iwmmxt_storage;
spin_lock(&mm->page_table_lock);
if ( !page_present(mm, addr, 0) ||
!page_present(mm, addr+IWMMXT_STORAGE_SIZE-1, 0) ) {
/* our user area has gone before grabbing the lock */
spin_unlock(&mm->page_table_lock);
goto again;
}
iwmmxt_task_restore(current_thread_info(), iwmmxt_storage+2);
spin_unlock(&mm->page_table_lock);
return 0;
}
return -1;
__get_user_error(magic0, &frame->magic0, err);
__get_user_error(magic1, &frame->magic1, err);
if (!err && magic0 == IWMMXT_MAGIC0 && magic1 == IWMMXT_MAGIC1)
err = copy_locked(&frame->storage, current_thread_info(),
sizeof(frame->storage), 0, iwmmxt_task_restore);
return err;
}
#endif
/*
* Auxiliary signal frame. This saves stuff like FP state.
* The layout of this structure is not part of the user ABI.
*/
struct aux_sigframe {
#ifdef CONFIG_IWMMXT
struct iwmmxt_sigframe iwmmxt;
#endif
#ifdef CONFIG_VFP
union vfp_state vfp;
#endif
};
/*
* Do a signal return; undo the signal stack. These are aligned to 64-bit.
*/
struct sigframe {
struct sigcontext sc;
unsigned long extramask[_NSIG_WORDS-1];
unsigned long retcode;
struct aux_sigframe aux __attribute__((aligned(8)));
};
struct rt_sigframe {
struct siginfo __user *pinfo;
void __user *puc;
struct siginfo info;
struct ucontext uc;
unsigned long retcode;
struct aux_sigframe aux __attribute__((aligned(8)));
};
static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
struct aux_sigframe __user *aux)
{
int err = 0;
......@@ -264,6 +288,15 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
err |= !valid_user_regs(regs);
#ifdef CONFIG_IWMMXT
if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
err |= restore_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
// if (err == 0)
// err |= vfp_restore_state(&aux->vfp);
#endif
return err;
}
......@@ -299,13 +332,8 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
if (restore_sigcontext(regs, &frame->sc))
goto badframe;
#ifdef CONFIG_IWMMXT
if (test_thread_flag(TIF_USING_IWMMXT) && restore_iwmmxt_context(frame+1))
if (restore_sigcontext(regs, &frame->sc, &frame->aux))
goto badframe;
#endif
/* Send SIGTRAP if we're single-stepping */
if (current->ptrace & PT_SINGLESTEP) {
......@@ -349,17 +377,12 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux))
goto badframe;
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
goto badframe;
#ifdef CONFIG_IWMMXT
if (test_thread_flag(TIF_USING_IWMMXT) && restore_iwmmxt_context(frame+1))
goto badframe;
#endif
/* Send SIGTRAP if we're single-stepping */
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
......@@ -374,7 +397,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
}
static int
setup_sigcontext(struct sigcontext __user *sc, /*struct _fpstate *fpstate,*/
setup_sigcontext(struct sigcontext __user *sc, struct aux_sigframe __user *aux,
struct pt_regs *regs, unsigned long mask)
{
int err = 0;
......@@ -402,6 +425,15 @@ setup_sigcontext(struct sigcontext __user *sc, /*struct _fpstate *fpstate,*/
__put_user_error(current->thread.address, &sc->fault_address, err);
__put_user_error(mask, &sc->oldmask, err);
#ifdef CONFIG_IWMMXT
if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
err |= preserve_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
// if (err == 0)
// err |= vfp_save_state(&aux->vfp);
#endif
return err;
}
......@@ -411,11 +443,6 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
unsigned long sp = regs->ARM_sp;
void __user *frame;
#ifdef CONFIG_IWMMXT
if (test_thread_flag(TIF_USING_IWMMXT))
framesize = (framesize + 4 + IWMMXT_STORAGE_SIZE) & ~7;
#endif
/*
* This is the X/Open sanctioned signal stack switching.
*/
......@@ -505,18 +532,13 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
if (!frame)
return 1;
err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]);
if (_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask));
}
#ifdef CONFIG_IWMMXT
if (test_thread_flag(TIF_USING_IWMMXT))
err |= preserve_iwmmxt_context(frame+1);
#endif
if (err == 0)
err = setup_return(regs, ka, &frame->retcode, frame, usig);
......@@ -547,15 +569,10 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
stack.ss_size = current->sas_ss_size;
err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack));
err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux,
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
#ifdef CONFIG_IWMMXT
if (test_thread_flag(TIF_USING_IWMMXT))
err |= preserve_iwmmxt_context(frame+1);
#endif
if (err == 0)
err = setup_return(regs, ka, &frame->retcode, frame, usig);
......
......@@ -40,6 +40,11 @@ u64 jiffies_64 = INITIAL_JIFFIES;
EXPORT_SYMBOL(jiffies_64);
/*
* Our system timer.
*/
struct sys_timer *system_timer;
extern unsigned long wall_jiffies;
/* this needs a better home */
......@@ -77,12 +82,6 @@ static unsigned long dummy_gettimeoffset(void)
return 0;
}
/*
* hook for getting the time offset. Note that it is
* always called with interrupts disabled.
*/
unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset;
/*
* Scheduler clock - returns current time in nanosec units.
* This is the default implementation. Sub-architecture
......@@ -247,7 +246,7 @@ void do_gettimeofday(struct timeval *tv)
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = gettimeoffset();
usec = system_timer->offset();
lost = jiffies - wall_jiffies;
if (lost)
......@@ -284,7 +283,7 @@ int do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* done, and then undo it!
*/
nsec -= gettimeoffset() * NSEC_PER_USEC;
nsec -= system_timer->offset() * NSEC_PER_USEC;
nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
......@@ -337,6 +336,9 @@ void restore_time_delta(struct timespec *delta, struct timespec *rtc)
}
EXPORT_SYMBOL(restore_time_delta);
/*
* Kernel system timer support.
*/
void timer_tick(struct pt_regs *regs)
{
profile_tick(CPU_PROFILING, regs);
......@@ -348,10 +350,53 @@ void timer_tick(struct pt_regs *regs)
#endif
}
void (*init_arch_time)(void);
#ifdef CONFIG_PM
static int timer_suspend(struct sys_device *dev, u32 state)
{
struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
if (timer->suspend != NULL)
timer->suspend();
return 0;
}
static int timer_resume(struct sys_device *dev)
{
struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
if (timer->resume != NULL)
timer->resume();
return 0;
}
#else
#define timer_suspend NULL
#define timer_resume NULL
#endif
static struct sysdev_class timer_sysclass = {
set_kset_name("timer"),
.suspend = timer_suspend,
.resume = timer_resume,
};
static int __init timer_init_sysfs(void)
{
int ret = sysdev_class_register(&timer_sysclass);
if (ret == 0) {
system_timer->dev.cls = &timer_sysclass;
ret = sysdev_register(&system_timer->dev);
}
return ret;
}
device_initcall(timer_init_sysfs);
void __init time_init(void)
{
init_arch_time();
if (system_timer->offset == NULL)
system_timer->offset = dummy_gettimeoffset;
system_timer->init();
}
......@@ -16,15 +16,16 @@ LC0: .word loops_per_jiffy
/*
* 0 <= r0 <= 2000
*/
ENTRY(udelay)
ENTRY(__udelay)
mov r2, #0x6800
orr r2, r2, #0x00db
mul r1, r0, r2
mul r0, r2, r0
ENTRY(__const_udelay) @ 0 <= r0 <= 0x01ffffff
ldr r2, LC0
ldr r2, [r2]
mov r1, r1, lsr #11
mov r2, r2, lsr #11
mul r0, r1, r2
ldr r2, [r2] @ max = 0x0fffffff
mov r0, r0, lsr #11 @ max = 0x00003fff
mov r2, r2, lsr #11 @ max = 0x0003ffff
mul r0, r2, r0 @ max = 2^32-1
movs r0, r0, lsr #6
RETINSTR(moveq,pc,lr)
......
# The standard locations for stuff on CLPS711x type processors
zreladdr-y := 0xc0028000
params_phys-y := 0xc0000100
# Should probably have some agreement on these...
initrd_phys-$(CONFIG_ARCH_P720T) := 0xc0400000
initrd_phys-$(CONFIG_ARCH_CDB89712) := 0x00700000
......@@ -35,9 +35,7 @@
#include <asm/mach/map.h>
#include <asm/arch/autcpu12.h>
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
extern void clps711x_init_time(void);
#include "common.h"
/*
* The on-chip registers are given a size of 1MB so that a section can
......@@ -66,6 +64,6 @@ MACHINE_START(AUTCPU12, "autronix autcpu12")
BOOT_PARAMS(0xc0020000)
MAPIO(autcpu12_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
.timer = &clps711x_timer,
MACHINE_END
......@@ -32,9 +32,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
extern void clps711x_init_time(void);
#include "common.h"
/*
* Map the CS89712 Ethernet port. That should be moved to the
......@@ -56,13 +54,5 @@ MACHINE_START(CDB89712, "Cirrus-CDB89712")
BOOT_PARAMS(0xc0000100)
MAPIO(cdb89712_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
.timer = &clps711x_timer,
MACHINE_END
static int cdb89712_hw_init(void)
{
return 0;
}
__initcall(cdb89712_hw_init);
......@@ -34,8 +34,7 @@
#include <asm/mach/map.h>
extern void clps711x_init_irq(void);
extern void clps711x_init_time(void);
#include "common.h"
static struct map_desc ceiva_io_desc[] __initdata = {
/* virtual, physical, length, type */
......@@ -59,5 +58,5 @@ MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
BOOT_PARAMS(0xc0000100)
MAPIO(ceiva_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
.timer = &clps711x_timer,
MACHINE_END
......@@ -23,9 +23,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
extern void clps711x_init_time(void);
#include "common.h"
static void __init
fixup_clep7312(struct machine_desc *desc, struct tag *tags,
......@@ -45,6 +43,6 @@ MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
FIXUP(fixup_clep7312)
MAPIO(clps711x_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
.timer = &clps711x_timer,
MACHINE_END
/*
* linux/arch/arm/mach-clps711x/common.h
*
* Common bits.
*/
struct sys_timer;
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
extern struct sys_timer clps711x_timer;
......@@ -25,9 +25,9 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
extern void clps711x_init_irq(void);
#include "common.h"
extern void edb7211_map_io(void);
extern void clps711x_init_time(void);
static void __init
fixup_edb7211(struct machine_desc *desc, struct tag *tags,
......@@ -57,5 +57,5 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
FIXUP(fixup_edb7211)
MAPIO(edb7211_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
.timer = &clps711x_timer,
MACHINE_END
......@@ -31,9 +31,7 @@
#include <asm/mach/arch.h>
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
extern void clps711x_init_time(void);
#include "common.h"
struct meminfo memmap = {
.nr_banks = 1,
......@@ -83,5 +81,5 @@ MACHINE_START(FORTUNET, "ARM-FortuNet")
FIXUP(fortunet_fixup)
MAPIO(clps711x_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
.timer = &clps711x_timer,
MACHINE_END
......@@ -34,9 +34,7 @@
#include <asm/mach/map.h>
#include <asm/arch/syspld.h>
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
extern void clps711x_init_time(void);
#include "common.h"
/*
* Map the P720T system PLD. It occupies two address spaces:
......@@ -87,7 +85,7 @@ MACHINE_START(P720T, "ARM-Prospector720T")
FIXUP(fixup_p720t)
MAPIO(p720t_map_io)
INITIRQ(clps711x_init_irq)
INITTIME(clps711x_init_time)
.timer = &clps711x_timer,
MACHINE_END
static int p720t_hw_init(void)
......
......@@ -59,7 +59,7 @@ static struct irqaction clps711x_timer_irq = {
.handler = p720t_timer_interrupt
};
void __init clps711x_init_time(void)
static void __init clps711x_timer_init(void)
{
struct timespec tv;
unsigned int syscon;
......@@ -71,9 +71,13 @@ void __init clps711x_init_time(void)
clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
gettimeoffset = clps711x_gettimeoffset;
tv.tv_nsec = 0;
tv.tv_sec = clps_readl(RTCDR);
do_settimeofday(&tv);
}
struct sys_timer clps711x_timer = {
.init = clps711x_timer_init,
.offset = clps711x_gettimeoffset,
};
......@@ -267,6 +267,7 @@ static void __init clps7500_map_io(void)
}
extern void ioctime_init(void);
extern unsigned long ioc_timer_gettimeoffset(void);
static irqreturn_t
clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
......@@ -295,18 +296,23 @@ static struct irqaction clps7500_timer_irq = {
/*
* Set up timer interrupt.
*/
void __init clps7500_init_time(void)
static void __init clps7500_timer_init(void)
{
ioctime_init();
setup_irq(IRQ_TIMER, &clps7500_timer_irq);
}
static struct clps7500_timer = {
.init = clps7500_timer_init,
.offset = ioc_timer_gettimeoffset,
};
MACHINE_START(CLPS7500, "CL-PS7500")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
MAPIO(clps7500_map_io)
INITIRQ(clps7500_init_irq)
INITTIME(clps7500_init_time)
.timer = &clps7500_timer,
MACHINE_END
zreladdr-y := 0x00008000
params_phys-y := 0x00000400
initrd_phys-y := 0x00800000
......@@ -175,7 +175,7 @@ static struct irqaction ebsa110_timer_irq = {
/*
* Set up timer interrupt.
*/
static void __init ebsa110_init_time(void)
static void __init ebsa110_timer_init(void)
{
/*
* Timer 1, mode 2, LSB/MSB
......@@ -184,11 +184,14 @@ static void __init ebsa110_init_time(void)
__raw_writeb(COUNT & 0xff, PIT_T1);
__raw_writeb(COUNT >> 8, PIT_T1);
gettimeoffset = ebsa110_gettimeoffset;
setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq);
}
static struct sys_timer ebsa110_timer = {
.init = ebsa110_timer_init,
.offset = ebsa110_gettimeoffset,
};
MACHINE_START(EBSA110, "EBSA110")
MAINTAINER("Russell King")
BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
......@@ -198,5 +201,5 @@ MACHINE_START(EBSA110, "EBSA110")
SOFT_REBOOT
MAPIO(ebsa110_map_io)
INITIRQ(ebsa110_init_irq)
INITTIME(ebsa110_init_time)
.timer = &ebsa110_timer,
MACHINE_END
......@@ -29,13 +29,13 @@
extern void epxa10db_map_io(void);
extern void epxa10db_init_irq(void);
extern void epxa10db_init_time(void);
extern struct sys_timer epxa10db_timer;
MACHINE_START(CAMELOT, "Altera Epxa10db")
MAINTAINER("Altera Corporation")
BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
MAPIO(epxa10db_map_io)
INITIRQ(epxa10db_init_irq)
INITTIME(epxa10db_init_time)
.timer = &epxa10db_timer,
MACHINE_END
......@@ -61,7 +61,7 @@ static struct irqaction epxa10db_timer_irq = {
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init epxa10db_init_time(void)
static void __init epxa10db_timer_init(void)
{
/* Start the timer */
*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
......@@ -71,3 +71,6 @@ void __init epxa10db_init_time(void)
setup_irq(IRQ_TIMER0, &epxa10db_timer_irq);
}
struct sys_timer epxa10db_timer = {
.init = epxa10db_timer_init,
};
......@@ -4,6 +4,7 @@ menu "Footbridge Implementations"
config ARCH_CATS
bool "CATS"
select FOOTBRIDGE_HOST
help
Say Y here if you intend to run this kernel on the CATS.
......@@ -11,6 +12,7 @@ config ARCH_CATS
config ARCH_PERSONAL_SERVER
bool "Compaq Personal Server"
select FOOTBRIDGE_HOST
---help---
Say Y here if you intend to run this kernel on the Compaq
Personal Server.
......@@ -28,6 +30,8 @@ config ARCH_PERSONAL_SERVER
config ARCH_EBSA285_ADDIN
bool "EBSA285 (addin mode)"
select ARCH_EBSA285
select FOOTBRIDGE_ADDIN
help
Say Y here if you intend to run this kernel on the EBSA285 card
in addin mode.
......@@ -36,6 +40,8 @@ config ARCH_EBSA285_ADDIN
config ARCH_EBSA285_HOST
bool "EBSA285 (host mode)"
select ARCH_EBSA285
select FOOTBRIDGE_HOST
help
Say Y here if you intend to run this kernel on the EBSA285 card
in host ("central function") mode.
......@@ -44,6 +50,7 @@ config ARCH_EBSA285_HOST
config ARCH_NETWINDER
bool "NetWinder"
select FOOTBRIDGE_HOST
help
Say Y here if you intend to run this kernel on the Rebel.COM
NetWinder. Information about this machine can be found at:
......@@ -54,4 +61,20 @@ config ARCH_NETWINDER
endmenu
# Footbridge support
config FOOTBRIDGE
bool
# Footbridge in host mode
config FOOTBRIDGE_HOST
bool
# Footbridge in addin mode
config FOOTBRIDGE_ADDIN
bool
# EBSA285 board in either host or addin mode
config ARCH_EBSA285
bool
endif
......@@ -4,13 +4,13 @@
# Object file lists.
obj-y := arch.o dc21285.o dma.o irq.o isa-irq.o mm.o time.o
obj-y := common.o dc21285.o dma.o isa-irq.o time.o
obj-m :=
obj-n :=
obj- :=
pci-$(CONFIG_ARCH_CATS) += cats-pci.o
pci-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o
pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o
pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
......@@ -18,8 +18,11 @@ leds-$(CONFIG_ARCH_CO285) += ebsa285-leds.o
leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o
leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o
obj-$(CONFIG_ARCH_CATS) += cats-hw.o
obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o
obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o
obj-$(CONFIG_ARCH_CO285) += co285.o dc21285-timer.o
obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o
obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o
obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o
obj-$(CONFIG_PCI) +=$(pci-y)
obj-$(CONFIG_LEDS) +=$(leds-y)
zreladdr-y := 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
/*
* linux/arch/arm/mach-footbridge/arch.c
*
* Architecture specific fixups. This is where any
* parameters in the params struct are fixed up, or
* any additional architecture specific information
* is pulled from the params struct.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <asm/hardware/dec21285.h>
#include <asm/elf.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
extern void footbridge_map_io(void);
extern void footbridge_init_irq(void);
extern void footbridge_init_time(void);
unsigned int mem_fclk_21285 = 50000000;
EXPORT_SYMBOL(mem_fclk_21285);
static int __init parse_tag_memclk(const struct tag *tag)
{
mem_fclk_21285 = tag->u.memclk.fmemclk;
return 0;
}
__tagtable(ATAG_MEMCLK, parse_tag_memclk);
#ifdef CONFIG_ARCH_EBSA285
MACHINE_START(EBSA285, "EBSA285")
MAINTAINER("Russell King")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
VIDEO(0x000a0000, 0x000bffff)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_NETWINDER
/*
* Older NeTTroms either do not provide a parameters
* page, or they don't supply correct information in
* the parameter page.
*/
static void __init
fixup_netwinder(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
#ifdef CONFIG_ISAPNP
extern int isapnp_disable;
/*
* We must not use the kernels ISAPnP code
* on the NetWinder - it will reset the settings
* for the WaveArtist chip and render it inoperable.
*/
isapnp_disable = 1;
#endif
}
MACHINE_START(NETWINDER, "Rebel-NetWinder")
MAINTAINER("Russell King/Rebel.com")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
VIDEO(0x000a0000, 0x000bffff)
DISABLE_PARPORT(0)
DISABLE_PARPORT(2)
FIXUP(fixup_netwinder)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_CATS
/*
* CATS uses soft-reboot by default, since
* hard reboots fail on early boards.
*/
static void __init
fixup_cats(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
ORIG_VIDEO_LINES = 25;
ORIG_VIDEO_POINTS = 16;
ORIG_Y = 24;
}
MACHINE_START(CATS, "Chalice-CATS")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
SOFT_REBOOT
FIXUP(fixup_cats)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_CO285
static void __init
fixup_coebsa285(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
extern unsigned long boot_memory_end;
extern char boot_command_line[];
mi->nr_banks = 1;
mi->bank[0].start = PHYS_OFFSET;
mi->bank[0].size = boot_memory_end;
mi->bank[0].node = 0;
*cmdline = boot_command_line;
}
MACHINE_START(CO285, "co-EBSA285")
MAINTAINER("Mark van Doesburg")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
FIXUP(fixup_coebsa285)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_PERSONAL_SERVER
MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
MAINTAINER("Jamey Hicks / George France")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
INITTIME(footbridge_init_time)
MACHINE_END
#endif
......@@ -9,8 +9,14 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/hardware/dec21285.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/mach/arch.h>
#include "common.h"
#define CFG_PORT 0x370
#define INDEX_PORT (CFG_PORT)
......@@ -62,3 +68,27 @@ static int __init cats_hw_init(void)
}
__initcall(cats_hw_init);
/*
* CATS uses soft-reboot by default, since
* hard reboots fail on early boards.
*/
static void __init
fixup_cats(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
ORIG_VIDEO_LINES = 25;
ORIG_VIDEO_POINTS = 16;
ORIG_Y = 24;
}
MACHINE_START(CATS, "Chalice-CATS")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
SOFT_REBOOT
FIXUP(fixup_cats)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
.timer = &isa_timer,
MACHINE_END
/*
* linux/arch/arm/mach-footbridge/co285.c
*
* CO285 machine fixup
*/
#include <linux/init.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "common.h"
static void __init
fixup_coebsa285(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
extern unsigned long boot_memory_end;
extern char boot_command_line[];
mi->nr_banks = 1;
mi->bank[0].start = PHYS_OFFSET;
mi->bank[0].size = boot_memory_end;
mi->bank[0].node = 0;
*cmdline = boot_command_line;
}
MACHINE_START(CO285, "co-EBSA285")
MAINTAINER("Mark van Doesburg")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
FIXUP(fixup_coebsa285)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
.timer = &footbridge_timer,
MACHINE_END
/*
* linux/arch/arm/mach-footbridge/mm.c
* linux/arch/arm/mach-footbridge/common.c
*
* Copyright (C) 1998-2000 Russell King, Dave Gilbert.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Extra MM routines for the EBSA285 architecture
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/list.h>
#include <linux/init.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include "common.h"
extern void __init isa_init_irq(unsigned int irq);
unsigned int mem_fclk_21285 = 50000000;
EXPORT_SYMBOL(mem_fclk_21285);
static int __init parse_tag_memclk(const struct tag *tag)
{
mem_fclk_21285 = tag->u.memclk.fmemclk;
return 0;
}
__tagtable(ATAG_MEMCLK, parse_tag_memclk);
/*
* Footbridge IRQ translation table
* Converts from our IRQ numbers into FootBridge masks
*/
static const int fb_irq_mask[] = {
IRQ_MASK_UART_RX, /* 0 */
IRQ_MASK_UART_TX, /* 1 */
IRQ_MASK_TIMER1, /* 2 */
IRQ_MASK_TIMER2, /* 3 */
IRQ_MASK_TIMER3, /* 4 */
IRQ_MASK_IN0, /* 5 */
IRQ_MASK_IN1, /* 6 */
IRQ_MASK_IN2, /* 7 */
IRQ_MASK_IN3, /* 8 */
IRQ_MASK_DOORBELLHOST, /* 9 */
IRQ_MASK_DMA1, /* 10 */
IRQ_MASK_DMA2, /* 11 */
IRQ_MASK_PCI, /* 12 */
IRQ_MASK_SDRAMPARITY, /* 13 */
IRQ_MASK_I2OINPOST, /* 14 */
IRQ_MASK_PCI_ABORT, /* 15 */
IRQ_MASK_PCI_SERR, /* 16 */
IRQ_MASK_DISCARD_TIMER, /* 17 */
IRQ_MASK_PCI_DPERR, /* 18 */
IRQ_MASK_PCI_PERR, /* 19 */
};
static void fb_mask_irq(unsigned int irq)
{
*CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(irq)];
}
static void fb_unmask_irq(unsigned int irq)
{
*CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)];
}
static struct irqchip fb_chip = {
.ack = fb_mask_irq,
.mask = fb_mask_irq,
.unmask = fb_unmask_irq,
};
static void __init __fb_init_irq(void)
{
unsigned int irq;
/*
* setup DC21285 IRQs
*/
*CSR_IRQ_DISABLE = -1;
*CSR_FIQ_DISABLE = -1;
for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
set_irq_chip(irq, &fb_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
void __init footbridge_init_irq(void)
{
__fb_init_irq();
if (!footbridge_cfn_mode())
return;
if (machine_is_ebsa285())
/* The following is dependent on which slot
* you plug the Southbridge card into. We
* currently assume that you plug it into
* the right-hand most slot.
*/
isa_init_irq(IRQ_PCI);
if (machine_is_cats())
isa_init_irq(IRQ_IN2);
if (machine_is_netwinder())
isa_init_irq(IRQ_IN3);
}
/*
* Common mapping for all systems. Note that the outbound write flush is
* commented out since there is a "No Fix" problem with it. Not mapping
......
extern struct sys_timer footbridge_timer;
extern struct sys_timer isa_timer;
extern void isa_rtc_init(void);
extern void footbridge_map_io(void);
extern void footbridge_init_irq(void);
/*
* linux/arch/arm/mach-footbridge/dc21285-timer.c
*
* Copyright (C) 1998 Russell King.
* Copyright (C) 1998 Phil Blundell
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach/time.h>
#include "common.h"
/*
* Footbridge timer 1 support.
*/
static unsigned long timer1_latch;
static unsigned long timer1_gettimeoffset (void)
{
unsigned long value = timer1_latch - *CSR_TIMER1_VALUE;
return ((tick_nsec / 1000) * value) / timer1_latch;
}
static irqreturn_t
timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
*CSR_TIMER1_CLR = 0;
timer_tick(regs);
return IRQ_HANDLED;
}
static struct irqaction footbridge_timer_irq = {
.name = "Timer1 timer tick",
.handler = timer1_interrupt,
.flags = SA_INTERRUPT,
};
/*
* Set up timer interrupt.
*/
static void __init footbridge_timer_init(void)
{
isa_rtc_init();
timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
*CSR_TIMER1_CLR = 0;
*CSR_TIMER1_LOAD = timer1_latch;
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
setup_irq(IRQ_TIMER1, &footbridge_timer_irq);
}
struct sys_timer footbridge_timer = {
.init = footbridge_timer_init,
.offset = timer1_gettimeoffset,
};
/*
* linux/arch/arm/mach-footbridge/ebsa285.c
*
* EBSA285 machine fixup
*/
#include <linux/init.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "common.h"
MACHINE_START(EBSA285, "EBSA285")
MAINTAINER("Russell King")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
VIDEO(0x000a0000, 0x000bffff)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
.timer = &footbridge_timer,
MACHINE_END
/*
* linux/arch/arm/mach-footbridge/irq.c
*
* Copyright (C) 1996-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Changelog:
* 22-Aug-1998 RMK Restructured IRQ routines
* 03-Sep-1998 PJB Merged CATS support
* 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
* 26-Jan-1999 PJB Don't use IACK on CATS
* 16-Mar-1999 RMK Added autodetect of ISA PICs
*/
#include <linux/ioport.h>
#include <linux/list.h>
#include <linux/init.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/hardware/dec21285.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/mach-types.h>
extern void __init isa_init_irq(unsigned int irq);
/*
* Footbridge IRQ translation table
* Converts from our IRQ numbers into FootBridge masks
*/
static const int fb_irq_mask[] = {
IRQ_MASK_UART_RX, /* 0 */
IRQ_MASK_UART_TX, /* 1 */
IRQ_MASK_TIMER1, /* 2 */
IRQ_MASK_TIMER2, /* 3 */
IRQ_MASK_TIMER3, /* 4 */
IRQ_MASK_IN0, /* 5 */
IRQ_MASK_IN1, /* 6 */
IRQ_MASK_IN2, /* 7 */
IRQ_MASK_IN3, /* 8 */
IRQ_MASK_DOORBELLHOST, /* 9 */
IRQ_MASK_DMA1, /* 10 */
IRQ_MASK_DMA2, /* 11 */
IRQ_MASK_PCI, /* 12 */
IRQ_MASK_SDRAMPARITY, /* 13 */
IRQ_MASK_I2OINPOST, /* 14 */
IRQ_MASK_PCI_ABORT, /* 15 */
IRQ_MASK_PCI_SERR, /* 16 */
IRQ_MASK_DISCARD_TIMER, /* 17 */
IRQ_MASK_PCI_DPERR, /* 18 */
IRQ_MASK_PCI_PERR, /* 19 */
};
static void fb_mask_irq(unsigned int irq)
{
*CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(irq)];
}
static void fb_unmask_irq(unsigned int irq)
{
*CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)];
}
static struct irqchip fb_chip = {
.ack = fb_mask_irq,
.mask = fb_mask_irq,
.unmask = fb_unmask_irq,
};
static void __init __fb_init_irq(void)
{
unsigned int irq;
/*
* setup DC21285 IRQs
*/
*CSR_IRQ_DISABLE = -1;
*CSR_FIQ_DISABLE = -1;
for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
set_irq_chip(irq, &fb_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
void __init footbridge_init_irq(void)
{
__fb_init_irq();
if (!footbridge_cfn_mode())
return;
if (machine_is_ebsa285())
/* The following is dependent on which slot
* you plug the Southbridge card into. We
* currently assume that you plug it into
* the right-hand most slot.
*/
isa_init_irq(IRQ_PCI);
if (machine_is_cats())
isa_init_irq(IRQ_IN2);
if (machine_is_netwinder())
isa_init_irq(IRQ_IN3);
}
/*
* linux/arch/arm/mach-footbridge/isa-timer.c
*
* Copyright (C) 1998 Russell King.
* Copyright (C) 1998 Phil Blundell
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/time.h>
#include "common.h"
/*
* ISA timer tick support
*/
#define mSEC_10_from_14 ((14318180 + 100) / 200)
static unsigned long isa_gettimeoffset(void)
{
int count;
static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */
static unsigned long jiffies_p = 0;
/*
* cache volatile jiffies temporarily; we have IRQs turned off.
*/
unsigned long jiffies_t;
/* timer count may underflow right here */
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
/*
* We do this guaranteed double memory access instead of a _p
* postfix in the previous port access. Wheee, hackady hack
*/
jiffies_t = jiffies;
count |= inb_p(0x40) << 8;
/* Detect timer underflows. If we haven't had a timer tick since
the last time we were called, and time is apparently going
backwards, the counter must have wrapped during this routine. */
if ((jiffies_t == jiffies_p) && (count > count_p))
count -= (mSEC_10_from_14/6);
else
jiffies_p = jiffies_t;
count_p = count;
count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000);
count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
return count;
}
static irqreturn_t
isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
timer_tick(regs);
return IRQ_HANDLED;
}
static struct irqaction isa_timer_irq = {
.name = "ISA timer tick",
.handler = isa_timer_interrupt,
.flags = SA_INTERRUPT,
};
static void __init isa_timer_init(void)
{
isa_rtc_init();
/* enable PIT timer */
/* set for periodic (4) and LSB/MSB write (0x30) */
outb(0x34, 0x43);
outb((mSEC_10_from_14/6) & 0xFF, 0x40);
outb((mSEC_10_from_14/6) >> 8, 0x40);
setup_irq(IRQ_ISA_TIMER, &isa_timer_irq);
}
struct sys_timer isa_timer = {
.init = isa_timer_init,
.offset = isa_gettimeoffset,
};
......@@ -12,9 +12,15 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <asm/hardware/dec21285.h>
#include <asm/io.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/mach/arch.h>
#include "common.h"
#define IRDA_IO_BASE 0x180
#define GP1_IO_BASE 0x338
......@@ -618,3 +624,37 @@ static int __init nw_hw_init(void)
}
__initcall(nw_hw_init);
/*
* Older NeTTroms either do not provide a parameters
* page, or they don't supply correct information in
* the parameter page.
*/
static void __init
fixup_netwinder(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
#ifdef CONFIG_ISAPNP
extern int isapnp_disable;
/*
* We must not use the kernels ISAPnP code
* on the NetWinder - it will reset the settings
* for the WaveArtist chip and render it inoperable.
*/
isapnp_disable = 1;
#endif
}
MACHINE_START(NETWINDER, "Rebel-NetWinder")
MAINTAINER("Russell King/Rebel.com")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
VIDEO(0x000a0000, 0x000bffff)
DISABLE_PARPORT(0)
DISABLE_PARPORT(2)
FIXUP(fixup_netwinder)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
.timer = &isa_timer,
MACHINE_END
/*
* linux/arch/arm/mach-footbridge/personal.c
*
* Personal server (Skiff) machine fixup
*/
#include <linux/init.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "common.h"
MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
MAINTAINER("Jamey Hicks / George France")
BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
BOOT_PARAMS(0x00000100)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
.timer = &footbridge_timer,
MACHINE_END
......@@ -19,75 +19,18 @@
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/mc146818rtc.h>
#include <linux/bcd.h>
#include <asm/hardware/dec21285.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/hardware/clps7111.h>
#include <asm/mach/time.h>
#include "common.h"
static int rtc_base;
#define mSEC_10_from_14 ((14318180 + 100) / 200)
static unsigned long isa_gettimeoffset(void)
{
int count;
static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */
static unsigned long jiffies_p = 0;
/*
* cache volatile jiffies temporarily; we have IRQs turned off.
*/
unsigned long jiffies_t;
/* timer count may underflow right here */
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
/*
* We do this guaranteed double memory access instead of a _p
* postfix in the previous port access. Wheee, hackady hack
*/
jiffies_t = jiffies;
count |= inb_p(0x40) << 8;
/* Detect timer underflows. If we haven't had a timer tick since
the last time we were called, and time is apparently going
backwards, the counter must have wrapped during this routine. */
if ((jiffies_t == jiffies_p) && (count > count_p))
count -= (mSEC_10_from_14/6);
else
jiffies_p = jiffies_t;
count_p = count;
count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000);
count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
return count;
}
static irqreturn_t
isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
timer_tick(regs);
return IRQ_HANDLED;
}
static unsigned long __init get_isa_cmos_time(void)
{
unsigned int year, mon, day, hour, min, sec;
......@@ -133,8 +76,7 @@ static unsigned long __init get_isa_cmos_time(void)
return mktime(year, mon, day, hour, min, sec);
}
static int
set_isa_cmos_time(void)
static int set_isa_cmos_time(void)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
......@@ -186,34 +128,7 @@ set_isa_cmos_time(void)
return retval;
}
static unsigned long timer1_latch;
static unsigned long timer1_gettimeoffset (void)
{
unsigned long value = timer1_latch - *CSR_TIMER1_VALUE;
return ((tick_nsec / 1000) * value) / timer1_latch;
}
static irqreturn_t
timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
*CSR_TIMER1_CLR = 0;
timer_tick(regs);
return IRQ_HANDLED;
}
static struct irqaction footbridge_timer_irq = {
.flags = SA_INTERRUPT
};
/*
* Set up timer interrupt.
*/
void __init footbridge_init_time(void)
void __init isa_rtc_init(void)
{
if (machine_is_co285() ||
machine_is_personal_server())
......@@ -262,35 +177,4 @@ void __init footbridge_init_time(void)
} else
rtc_base = 0;
}
if (machine_is_ebsa285() ||
machine_is_co285() ||
machine_is_personal_server()) {
gettimeoffset = timer1_gettimeoffset;
timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
*CSR_TIMER1_CLR = 0;
*CSR_TIMER1_LOAD = timer1_latch;
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
footbridge_timer_irq.name = "Timer1 Timer Tick";
footbridge_timer_irq.handler = timer1_interrupt;
setup_irq(IRQ_TIMER1, &footbridge_timer_irq);
} else {
/* enable PIT timer */
/* set for periodic (4) and LSB/MSB write (0x30) */
outb(0x34, 0x43);
outb((mSEC_10_from_14/6) & 0xFF, 0x40);
outb((mSEC_10_from_14/6) >> 8, 0x40);
gettimeoffset = isa_gettimeoffset;
footbridge_timer_irq.name = "ISA Timer Tick";
footbridge_timer_irq.handler = isa_timer_interrupt;
setup_irq(IRQ_ISA_TIMER, &footbridge_timer_irq);
}
}
zreladdr-$(CONFIG_ARCH_H720X) := 0x40008000
zreladdr-$(CONFIG_ARCH_MX1ADS) := 0x08008000
......@@ -11,4 +11,6 @@
extern void __init imx_map_io(void);
extern void __init imx_init_irq(void);
extern void __init imx_init_time(void);
struct sys_timer;
extern struct sys_timer imx_timer;
......@@ -83,6 +83,6 @@ MACHINE_START(MX1ADS, "Motorola MX1ADS")
BOOT_PARAMS(0x08000100)
MAPIO(mx1ads_map_io)
INITIRQ(imx_init_irq)
INITTIME(imx_init_time)
.timer = &imx_timer,
INIT_MACHINE(mx1ads_init)
MACHINE_END
......@@ -76,8 +76,8 @@ static struct irqaction imx_timer_irq = {
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init
imx_init_time(void)
static void __init
imx_timer_init(void)
{
/*
* Initialise to a known state (all timers off, and timing reset)
......@@ -91,5 +91,9 @@ imx_init_time(void)
* Make irqs happen for the system timer
*/
setup_irq(TIM1_INT, &imx_timer_irq);
gettimeoffset = imx_gettimeoffset;
}
struct imx_timer = {
.init = imx_timer_init,
.offset = imx_gettimeoffset,
};
zreladdr-y := 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
extern void integrator_time_init(unsigned long, unsigned int);
extern unsigned long integrator_gettimeoffset(void);
......@@ -24,6 +24,8 @@
#include <asm/leds.h>
#include <asm/mach/time.h>
#include "common.h"
static struct amba_device rtc_device = {
.dev = {
.bus_id = "mb:15",
......@@ -163,15 +165,13 @@ typedef struct TimerStruct {
unsigned long TimerClear;
} TimerStruct_t;
extern unsigned long (*gettimeoffset)(void);
static unsigned long timer_reload;
/*
* Returns number of ms since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long integrator_gettimeoffset(void)
unsigned long integrator_gettimeoffset(void)
{
volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
unsigned long ticks1, ticks2, status;
......@@ -264,5 +264,4 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
* Make irqs happen for the system timer
*/
setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
gettimeoffset = integrator_gettimeoffset;
}
......@@ -40,7 +40,9 @@
#include <asm/mach/flash.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include "common.h"
/*
* All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
......@@ -281,17 +283,22 @@ static void __init ap_init(void)
}
}
static void ap_time_init(void)
static void __init ap_init_timer(void)
{
integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0);
}
static struct sys_timer ap_timer = {
.init = ap_init_timer,
.offset = integrator_gettimeoffset,
};
MACHINE_START(INTEGRATOR, "ARM-Integrator")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
BOOT_PARAMS(0x00000100)
MAPIO(ap_map_io)
INITIRQ(ap_init_irq)
INITTIME(ap_time_init)
.timer = &ap_timer,
INIT_MACHINE(ap_init)
MACHINE_END
......@@ -35,7 +35,9 @@
#include <asm/mach/irq.h>
#include <asm/mach/mmc.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include "common.h"
#include "clock.h"
#define INTCP_PA_MMC_BASE 0x1c000000
......@@ -496,17 +498,22 @@ static void __init intcp_init(void)
#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
static void __init intcp_init_time(void)
static void __init intcp_timer_init(void)
{
integrator_time_init(1000000 / HZ, TIMER_CTRL_IE);
}
static struct sys_timer cp_timer = {
.init = intcp_timer_init,
.offset = integrator_gettimeoffset,
};
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
BOOT_PARAMS(0x00000100)
MAPIO(intcp_map_io)
INITIRQ(intcp_init_irq)
INITTIME(intcp_init_time)
.timer = &cp_timer,
INIT_MACHINE(intcp_init)
MACHINE_END
zreladdr-y := 0xa0008000
params_phys-y := 0xa0000100
initrd_phys-y := 0xa0800000
ifeq ($(CONFIG_ARCH_IOP331),y)
zreladdr-y := 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
endif
/*
* linux/arch/arm/mach-iop3xx/arch.c
*
* Author: Nicolas Pitre <nico@cam.org>
* Copyright (C) 2001 MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/memory.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#ifdef CONFIG_ARCH_IQ80331
extern void iq80331_map_io(void);
extern void iop331_init_irq(void);
extern void iop331_init_time(void);
#endif
#ifdef CONFIG_ARCH_IQ80331
static void __init
fixup_iop331(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
}
#endif
#if defined(CONFIG_ARCH_IQ80331)
MACHINE_START(IQ80331, "Intel IQ80331")
MAINTAINER("Intel Corp.")
BOOT_MEM(PHYS_OFFSET, 0xfff01000, 0xfffff000) // virtual, physical
// BOOT_MEM(PHYS_OFFSET, IQ80331_UART0_VIRT, IQ80331_UART0_PHYS)
MAPIO(iq80331_map_io)
INITIRQ(iop331_init_irq)
INITTIME(iop331_init_time)
BOOT_PARAMS(0x0100)
MACHINE_END
#else
#error No machine descriptor defined for this IOP3xx implementation
#endif
......@@ -23,13 +23,13 @@
#ifdef CONFIG_ARCH_IQ80321
extern void iq80321_map_io(void);
extern void iop321_init_irq(void);
extern struct sys_timer iop321_timer;
extern void iop321_init_time(void);
#endif
#ifdef CONFIG_ARCH_IQ31244
extern void iq31244_map_io(void);
extern void iop321_init_irq(void);
extern struct sys_timer iop321_timer;
extern void iop321_init_time(void);
#endif
......@@ -46,7 +46,7 @@ MACHINE_START(IQ80321, "Intel IQ80321")
FIXUP(fixup_iop321)
MAPIO(iq80321_map_io)
INITIRQ(iop321_init_irq)
INITTIME(iop321_init_time)
.timer = &iop331_timer,
BOOT_PARAMS(0xa0000100)
MACHINE_END
#elif defined(CONFIG_ARCH_IQ31244)
......@@ -55,7 +55,7 @@ MACHINE_END
BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART)
MAPIO(iq31244_map_io)
INITIRQ(iop321_init_irq)
INITTIME(iop321_init_time)
.timer = &iop331_timer,
BOOT_PARAMS(0xa0000100)
MACHINE_END
#else
......
......@@ -110,14 +110,11 @@ static struct irqaction iop321_timer_irq = {
.flags = SA_INTERRUPT
};
extern int setup_arm_irq(int, struct irqaction*);
void __init iop321_init_time(void)
static void __init iop321_timer_init(void)
{
u32 timer_ctl;
iop321_latch = (CLOCK_TICK_RATE + HZ / 2) / HZ;
gettimeoffset = iop321_gettimeoffset;
setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq);
timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD |
......@@ -138,4 +135,7 @@ void __init iop321_init_time(void)
#endif
}
struct sys_timer iop321_timer = {
.init = &iop321_timer_init,
.offset = iop321_gettimeoffset,
};
......@@ -81,7 +81,7 @@ void __init iop331_map_io(void)
#ifdef CONFIG_ARCH_IQ80331
extern void iop331_init_irq(void);
extern void iop331_init_time(void);
extern struct sys_timer iop331_timer;
extern void iq80331_map_io(void);
#endif
......@@ -92,7 +92,7 @@ MACHINE_START(IQ80331, "Intel IQ80331")
//BOOT_MEM(PHYS_OFFSET, IQ80331_UART0_VIRT, IQ80331_UART0_PHYS)
MAPIO(iq80331_map_io)
INITIRQ(iop331_init_irq)
INITTIME(iop331_init_time)
.timer = &iop331_timer,
BOOT_PARAMS(0x0100)
MACHINE_END
#else
......
......@@ -110,14 +110,11 @@ static struct irqaction iop331_timer_irq = {
.flags = SA_INTERRUPT
};
extern int setup_arm_irq(int, struct irqaction*);
void __init iop331_init_time(void)
static void __init iop331_timer_init(void)
{
u32 timer_ctl;
iop331_latch = (CLOCK_TICK_RATE + HZ / 2) / HZ;
gettimeoffset = iop331_gettimeoffset;
setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq);
timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD |
......@@ -138,4 +135,7 @@ void __init iop331_init_time(void)
#endif
}
struct sys_timer iop331_timer = {
.init = iop331_timer_init,
.offset = iop331_gettimeoffset,
};
......@@ -170,7 +170,7 @@ void __init ixp2000_map_io(void)
static unsigned ticks_per_jiffy;
static unsigned ticks_per_usec;
static unsigned long ixp2000_gettimeoffset (void)
unsigned long ixp2000_gettimeoffset (void)
{
unsigned long elapsed;
......@@ -198,8 +198,6 @@ static struct irqaction ixp2000_timer_irq = {
void __init ixp2000_init_time(unsigned long tick_rate)
{
gettimeoffset = ixp2000_gettimeoffset;
ixp2000_reg_write(IXP2000_T1_CLR, 0);
ixp2000_reg_write(IXP2000_T2_CLR, 0);
......
......@@ -55,11 +55,16 @@
/*************************************************************************
* ENP-2611 timer tick configuration
*************************************************************************/
static void __init enp2611_init_time(void)
static void __init enp2611_timer_init(void)
{
ixp2000_init_time(50 * 1000 * 1000);
}
static struct enp2611_timer = {
.init = enp2611_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* ENP-2611 PCI
......@@ -202,7 +207,7 @@ MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
BOOT_PARAMS(0x00000100)
MAPIO(ixp2000_map_io)
INITIRQ(ixp2000_init_irq)
INITTIME(enp2611_init_time)
.timer = &enp2611_timer,
INIT_MACHINE(enp2611_init_machine)
MACHINE_END
#endif
......
......@@ -48,7 +48,7 @@
/*************************************************************************
* IXDP2400 timer tick
*************************************************************************/
static void __init ixdp2400_init_time(void)
static void __init ixdp2400_timer_init(void)
{
int numerator, denominator;
int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8};
......@@ -59,6 +59,11 @@ static void __init ixdp2400_init_time(void)
ixp2000_init_time(((3125000 * numerator) / (denominator)) / 2);
}
static struct timer ixdp2400_timer = {
.init = ixdp2400_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* IXDP2400 PCI
*************************************************************************/
......@@ -171,7 +176,7 @@ MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
BOOT_PARAMS(0x00000100)
MAPIO(ixdp2x00_map_io)
INITIRQ(ixdp2400_init_irq)
INITTIME(ixdp2400_init_time)
.timer = &ixdp2400_timer,
INIT_MACHINE(ixdp2x00_init_machine)
MACHINE_END
......@@ -55,11 +55,16 @@ void ixdp2400_init_irq(void)
* IXDP2800 timer tick
*************************************************************************/
static void __init ixdp2800_init_time(void)
static void __init ixdp2800_timer_init(void)
{
ixp2000_init_time(50000000);
}
static struct sys_timer ixdp2800_timer = {
.init = ixdp2800_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* IXDP2800 PCI
*************************************************************************/
......@@ -172,7 +177,7 @@ MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
BOOT_PARAMS(0x00000100)
MAPIO(ixdp2x00_map_io)
INITIRQ(ixdp2800_init_irq)
INITTIME(ixdp2800_init_time)
.timer = &ixdp2800_timer,
INIT_MACHINE(ixdp2x00_init_machine)
MACHINE_END
......@@ -193,7 +193,7 @@ static int __init ixdp2x01_clock_setup(char *str)
__setup("ixdp2x01_clock=", ixdp2x01_clock_setup);
static void __init ixdp2x01_init_time(void)
static void __init ixdp2x01_timer_init(void)
{
if (!ixdp2x01_clock)
ixdp2x01_clock = 50000000;
......@@ -201,6 +201,11 @@ static void __init ixdp2x01_init_time(void)
ixp2000_init_time(ixdp2x01_clock);
}
static struct sys_timer ixdp2x01_timer = {
.init = ixdp2x01_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* IXDP2x01 PCI
*************************************************************************/
......@@ -361,7 +366,7 @@ MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
BOOT_PARAMS(0x00000100)
MAPIO(ixdp2x01_map_io)
INITIRQ(ixdp2x01_init_irq)
INITTIME(ixdp2x01_init_time)
.timer = &ixdp2x01_timer,
INIT_MACHINE(ixdp2x01_init_machine)
MACHINE_END
#endif
......@@ -373,7 +378,7 @@ MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
BOOT_PARAMS(0x00000100)
MAPIO(ixdp2x01_map_io)
INITIRQ(ixdp2x01_init_irq)
INITTIME(ixdp2x01_init_time)
.timer = &ixdp2x01_timer,
INIT_MACHINE(ixdp2x01_init_machine)
MACHINE_END
#endif
......
zreladdr-y := 0x00008000
params_phys-y := 0x00000100
......@@ -241,10 +241,8 @@ static struct irqaction ixp4xx_timer_irq = {
.handler = ixp4xx_timer_interrupt
};
void __init ixp4xx_init_time(void)
static void __init ixp4xx_timer_init(void)
{
gettimeoffset = ixp4xx_gettimeoffset;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
......@@ -259,4 +257,7 @@ void __init ixp4xx_init_time(void)
setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
}
struct ixp4xx_timer = {
.init = ixp4xx_timer_init,
.offset = ixp4xx_gettimeoffset,
};
......@@ -88,7 +88,7 @@ MACHINE_START(ADI_COYOTE, "ADI Engineering IXP4XX Coyote Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(coyote_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
.timer = &ixp4xx_timer,
BOOT_PARAMS(0x0100)
INIT_MACHINE(coyote_init)
MACHINE_END
......
......@@ -117,7 +117,7 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
.timer = &ixp4xx_timer,
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
......@@ -128,7 +128,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
.timer = &ixp4xx_timer,
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
......@@ -146,7 +146,7 @@ MACHINE_START(AVILA, "Gateworks Avila Network Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
.timer = &ixp4xx_timer,
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
......
......@@ -88,7 +88,7 @@ MACHINE_START(PRPMC1100, "Motorola PrPMC1100")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(prpmc1100_map_io)
INITIRQ(ixp4xx_init_irq)
INITTIME(ixp4xx_init_time)
.timer = &ixp4xx_timer,
BOOT_PARAMS(0x0100)
INIT_MACHINE(prpmc1100_init)
MACHINE_END
......
zreladdr-y := 0xf0008000
zreladdr-y := 0xc0008000
params_phys-y := 0xc0000100
initrd_phys-y := 0xc4000000
......@@ -11,6 +11,7 @@
#include <linux/tty.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <asm/hardware.h>
#include <asm/setup.h>
......@@ -21,11 +22,9 @@
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <linux/interrupt.h>
#include "common.h"
/* This function calls the board specific IRQ initialization function. */
extern void lh7a400_init_irq (void);
extern void lh7a40x_init_time (void);
static struct map_desc kev7a400_io_desc[] __initdata = {
{ IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
......@@ -109,5 +108,5 @@ MACHINE_START (KEV7A400, "Sharp KEV7a400")
BOOT_PARAMS (0xc0000100)
MAPIO (kev7a400_map_io)
INITIRQ (lh7a400_init_irq)
INITTIME (lh7a40x_init_time)
.timer = &lh7a40x_timer,
MACHINE_END
......@@ -11,6 +11,7 @@
#include <linux/tty.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <asm/hardware.h>
#include <asm/setup.h>
......@@ -21,7 +22,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <linux/interrupt.h>
#include "common.h"
static struct resource smc91x_resources[] = {
[0] = {
......@@ -261,16 +262,13 @@ lpd7a400_map_io(void)
#ifdef CONFIG_MACH_LPD7A400
extern void lh7a400_init_irq (void);
extern void lh7a40x_init_time (void);
MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
MAINTAINER ("Marc Singer")
BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
BOOT_PARAMS (0xc0000100)
MAPIO (lpd7a400_map_io)
INITIRQ (lh7a400_init_irq)
INITTIME (lh7a40x_init_time)
.timer = &lpd7a40x_timer,
INIT_MACHINE (lpd7a40x_init)
MACHINE_END
......@@ -278,16 +276,13 @@ MACHINE_END
#ifdef CONFIG_MACH_LPD7A404
extern void lh7a404_init_irq (void);
extern void lh7a40x_init_time (void);
MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
MAINTAINER ("Marc Singer")
BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
BOOT_PARAMS (0xc0000100)
MAPIO (lpd7a400_map_io)
INITIRQ (lh7a404_init_irq)
INITTIME (lh7a40x_init_time)
.timer = &lpd7a40x_timer,
INIT_MACHINE (lpd7a40x_init)
MACHINE_END
......
/*
* linux/arch/arm/mach-lh7a40x/common.h
*
* Header file for common stuff.
*/
struct sys_timer;
extern struct sys_timer lh7a40x_timer;
extern void lh7a400_init_irq (void);
......@@ -20,6 +20,7 @@
#include <asm/leds.h>
#include <asm/mach/time.h>
#include "common.h"
#if HZ < 100
# define TIMER_CONTROL TIMER_CONTROL2
......@@ -52,7 +53,7 @@ static struct irqaction lh7a40x_timer_irq = {
.handler = lh7a40x_timer_interrupt
};
void __init lh7a40x_init_time(void)
static void __init lh7a40x_timer_init(void)
{
/* Stop/disable all timers */
TIMER_CONTROL1 = 0;
......@@ -65,3 +66,6 @@ void __init lh7a40x_init_time(void)
TIMER_CONTROL = TIMER_MODE;
}
struct sys_timer lh7a40x_timer = {
.init = &lh7a40x_timer,
};
zreladdr-y := 0x10008000
params_phys-y := 0x10000100
initrd_phys-y := 0x10800000
......@@ -30,8 +30,6 @@
#include "common.h"
extern void __init omap_init_time(void);
static void __init omap_generic_init_irq(void)
{
omap_init_irq();
......@@ -118,5 +116,5 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
MAPIO(omap_generic_map_io)
INITIRQ(omap_generic_init_irq)
INIT_MACHINE(omap_generic_init)
INITTIME(omap_init_time)
.timer = &omap_timer,
MACHINE_END
......@@ -35,8 +35,6 @@
#include "common.h"
extern void __init omap_init_time(void);
static struct map_desc h2_io_desc[] __initdata = {
{ OMAP1610_ETHR_BASE, OMAP1610_ETHR_START, OMAP1610_ETHR_SIZE,MT_DEVICE },
{ OMAP1610_NOR_FLASH_BASE, OMAP1610_NOR_FLASH_START, OMAP1610_NOR_FLASH_SIZE,
......@@ -111,5 +109,5 @@ MACHINE_START(OMAP_H2, "TI-H2")
MAPIO(h2_map_io)
INITIRQ(h2_init_irq)
INIT_MACHINE(h2_init)
INITTIME(omap_init_time)
.timer = &omap_timer,
MACHINE_END
......@@ -32,8 +32,6 @@
#include <asm/mach-types.h>
#include "common.h"
extern void __init omap_init_time(void);
void h3_init_irq(void)
{
omap_init_irq();
......@@ -86,5 +84,5 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
MAPIO(h3_map_io)
INITIRQ(h3_init_irq)
INIT_MACHINE(h3_init)
INITTIME(omap_init_time)
.timer = &omap_timer,
MACHINE_END
......@@ -33,8 +33,6 @@
#include "common.h"
extern void __init omap_init_time(void);
#ifdef CONFIG_ARCH_OMAP1510
extern int omap_gpio_init(void);
......@@ -203,5 +201,5 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
MAPIO(innovator_map_io)
INITIRQ(innovator_init_irq)
INIT_MACHINE(innovator_init)
INITTIME(omap_init_time)
.timer = &omap_timer,
MACHINE_END
......@@ -41,8 +41,6 @@
#include "common.h"
extern void __init omap_init_time(void);
static struct map_desc osk5912_io_desc[] __initdata = {
{ OMAP_OSK_ETHR_BASE, OMAP_OSK_ETHR_START, OMAP_OSK_ETHR_SIZE,MT_DEVICE },
{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE,
......@@ -97,5 +95,5 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
MAPIO(osk_map_io)
INITIRQ(osk_init_irq)
INIT_MACHINE(osk_init)
INITTIME(omap_init_time)
.timer = &omap_timer,
MACHINE_END
......@@ -27,8 +27,6 @@
#include "common.h"
extern void __init omap_init_time(void);
void omap_perseus2_init_irq(void)
{
omap_init_irq();
......@@ -115,5 +113,5 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
MAPIO(omap_perseus2_map_io)
INITIRQ(omap_perseus2_init_irq)
INIT_MACHINE(omap_perseus2_init)
INITTIME(omap_init_time)
.timer = &omap_timer,
MACHINE_END
......@@ -27,8 +27,9 @@
#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
#define __ARCH_ARM_MACH_OMAP_COMMON_H
struct sys_timer;
extern void omap_map_io(void);
extern struct sys_timer omap_timer;
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
......@@ -199,11 +199,9 @@ static struct irqaction omap_timer_irq = {
.handler = omap_timer_interrupt
};
void __init omap_init_time(void)
static void __init omap_timer_init(void)
{
/* Since we don't call request_irq, we must init the structure */
gettimeoffset = omap_gettimeoffset;
#ifdef OMAP1510_USE_32KHZ_TIMER
timer32k_write(TIMER32k_CR, 0x0);
timer32k_write(TIMER32k_TVR,TIMER32k_PERIOD);
......@@ -215,3 +213,7 @@ void __init omap_init_time(void)
#endif
}
struct sys_timer omap_timer = {
.init = omap_timer_init,
.offset = omap_gettimeoffset,
};
zreladdr-y := 0xa0008000
......@@ -9,9 +9,11 @@
* published by the Free Software Foundation.
*/
struct sys_timer;
extern struct sys_timer pxa_timer;
extern void __init pxa_map_io(void);
extern void __init pxa_init_irq(void);
extern void __init pxa_init_time(void);
extern unsigned int get_clk_frequency_khz(int info);
......
......@@ -119,6 +119,6 @@ MACHINE_START(PXA_IDP, "Accelent Xscale IDP")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(idp_map_io)
INITIRQ(idp_init_irq)
INITTIME(pxa_init_time)
.timer = &pxa_timer,
INIT_MACHINE(idp_init)
MACHINE_END
......@@ -38,6 +38,8 @@
#include "generic.h"
#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
{
unsigned long flags;
......@@ -221,6 +223,6 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(lubbock_map_io)
INITIRQ(lubbock_init_irq)
INITTIME(pxa_init_time)
.timer = &pxa_timer,
INIT_MACHINE(lubbock_init)
MACHINE_END
......@@ -198,6 +198,6 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(mainstone_map_io)
INITIRQ(mainstone_init_irq)
INITTIME(pxa_init_time)
.timer = &pxa_timer,
INIT_MACHINE(mainstone_init)
MACHINE_END
......@@ -47,9 +47,6 @@ extern void pxa_cpu_resume(void);
*/
enum { SLEEP_SAVE_START = 0,
SLEEP_SAVE_OIER,
SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2,
SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
......@@ -81,13 +78,6 @@ static int pxa_pm_enter(u32 state)
rtc.tv_nsec = 0;
save_time_delta(&delta, &rtc);
/* save vital registers */
SAVE(OSMR0);
SAVE(OSMR1);
SAVE(OSMR2);
SAVE(OSMR3);
SAVE(OIER);
SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
......@@ -148,15 +138,6 @@ static int pxa_pm_enter(u32 state)
PSSR = PSSR_RDH | PSSR_PH;
RESTORE(OSMR0);
RESTORE(OSMR1);
RESTORE(OSMR2);
RESTORE(OSMR3);
RESTORE(OIER);
/* OSMR0 is the system timer: make sure OSCR is sufficiently behind */
OSCR = OSMR0 - LATCH;
RESTORE(CKEN);
ICLR = 0;
......
......@@ -105,11 +105,10 @@ static struct irqaction pxa_timer_irq = {
.handler = pxa_timer_interrupt
};
void __init pxa_init_time(void)
static void __init pxa_timer_init(void)
{
struct timespec tv;
gettimeoffset = pxa_gettimeoffset;
set_rtc = pxa_set_rtc;
tv.tv_nsec = 0;
......@@ -123,3 +122,39 @@ void __init pxa_init_time(void)
OSCR = 0; /* initialize free-running timer, force first match */
}
#ifdef CONFIG_PM
static unsigned long osmr[4], oier;
static void pxa_timer_suspend(void)
{
osmr[0] = OSMR0;
osmr[1] = OSMR1;
osmr[2] = OSMR2;
osmr[3] = OSMR3;
oier = OIER;
}
static void pxa_timer_resume(void)
{
OSMR0 = osmr[0];
OSMR1 = osmr[1];
OSMR2 = osmr[2];
OSMR3 = osmr[3];
OIER = oier;
/*
* OSMR0 is the system timer: make sure OSCR is sufficiently behind
*/
OSCR = OSMR0 - LATCH;
}
#else
#define pxa_timer_suspend NULL
#define pxa_timer_resume NULL
#endif
struct sys_timer pxa_timer = {
.init = pxa_timer_init,
.suspend = pxa_timer_suspend,
.resume = pxa_timer_resume,
.offset = pxa_gettimeoffset,
};
zreladdr-y := 0x10008000
params_phys-y := 0x10000100
initrd_phys-y := 0x18000000
......@@ -15,7 +15,6 @@
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/elf.h>
#include <asm/io.h>
......@@ -85,30 +84,7 @@ void __init rpc_map_io(void)
elf_hwcap &= ~HWCAP_HALF;
}
static irqreturn_t
rpc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
timer_tick(regs);
return IRQ_HANDLED;
}
static struct irqaction rpc_timer_irq = {
.name = "RiscPC Timer Tick",
.flags = SA_INTERRUPT,
.handler = rpc_timer_interrupt
};
/*
* Set up timer interrupt.
*/
void __init rpc_init_time(void)
{
extern void ioctime_init(void);
ioctime_init();
setup_irq(IRQ_TIMER, &rpc_timer_irq);
}
extern struct sys_timer ioc_timer;
MACHINE_START(RISCPC, "Acorn-RiscPC")
MAINTAINER("Russell King")
......@@ -118,5 +94,5 @@ MACHINE_START(RISCPC, "Acorn-RiscPC")
DISABLE_PARPORT(1)
MAPIO(rpc_map_io)
INITIRQ(rpc_init_irq)
INITTIME(rpc_init_time)
.timer = &ioc_timer,
MACHINE_END
zreladdr-y := 0x30008000
params_phys-y := 0x30000100
......@@ -225,16 +225,11 @@ void __init bast_init_irq(void)
s3c2410_init_irq();
}
void __init bast_init_time(void)
{
s3c2410_init_time();
}
MACHINE_START(BAST, "Simtec-BAST")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(bast_map_io)
INITIRQ(bast_init_irq)
INITTIME(bast_init_time)
.timer = &s3c2410_timer,
MACHINE_END
......@@ -110,16 +110,11 @@ void __init h1940_init_irq(void)
}
void __init h1940_init_time(void)
{
s3c2410_init_time();
}
MACHINE_START(H1940, "IPAQ-H1940")
MAINTAINER("Ben Dooks <ben@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(h1940_map_io)
INITIRQ(h1940_init_irq)
INITTIME(h1940_init_time)
.timer = &s3c2410_timer,
MACHINE_END
......@@ -113,11 +113,6 @@ void __init smdk2410_init_irq(void)
s3c2410_init_irq();
}
void __init smdk2410_init_time(void)
{
s3c2410_init_time();
}
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
MAINTAINER("Jonas Dietsche")
......@@ -125,7 +120,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(smdk2410_map_io)
INITIRQ(smdk2410_init_irq)
INITTIME(smdk2410_init_time)
.timer = &s3c2410_timer,
MACHINE_END
......@@ -170,16 +170,11 @@ void __init vr1000_init_irq(void)
s3c2410_init_irq();
}
void __init vr1000_init_time(void)
{
s3c2410_init_time();
}
MACHINE_START(VR1000, "Thorcom-VR1000")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(vr1000_map_io)
INITIRQ(vr1000_init_irq)
INITTIME(vr1000_init_time)
.timer = &s3c2410_timer,
MACHINE_END
......@@ -23,7 +23,8 @@ extern void s3c2410_init_uarts(struct s3c2410_uartcfg *, int no);
extern void s3c2410_init_irq(void);
extern void s3c2410_init_time(void);
struct sys_timer;
extern struct sys_timer s3c2410_timer;
/* the board structure is used at first initialsation time
* to get info such as the devices to register for this
......
......@@ -105,15 +105,13 @@ static struct irqaction s3c2410_timer_irq = {
* Currently we only use timer4, as it is the only timer which has no
* other function that can be exploited externally
*/
void __init s3c2410_init_time (void)
static void __init s3c2410_timer_init (void)
{
unsigned long tcon;
unsigned long tcnt;
unsigned long tcfg1;
unsigned long tcfg0;
gettimeoffset = s3c2410_gettimeoffset;
tcnt = 0xffff; /* default value for tcnt */
/* read the current timer configuration bits */
......@@ -186,5 +184,7 @@ void __init s3c2410_init_time (void)
__raw_writel(tcon, S3C2410_TCON);
}
struct sys_timer s3c2410_timer = {
.init = s3c2410_timer_init,
.offset = s3c2410_gettimeoffset,
};
zreladdr-y := 0xc0008000
ifeq ($(CONFIG_ARCH_SA1100),y)
zreladdr-$(CONFIG_SA1111) := 0xc0208000
endif
params_phys-y := 0xc0000100
initrd_phys-y := 0xc0800000
......@@ -147,5 +147,5 @@ MACHINE_START(ADSBITSY, "ADS Bitsy")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(adsbitsy_map_io)
INITIRQ(adsbitsy_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -324,6 +324,6 @@ MACHINE_START(ASSABET, "Intel-Assabet")
FIXUP(fixup_assabet)
MAPIO(assabet_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
INIT_MACHINE(assabet_init)
MACHINE_END
......@@ -245,5 +245,5 @@ MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
BOOT_PARAMS(0xc0000100)
MAPIO(badge4_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -37,5 +37,5 @@ MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(brutus_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -92,5 +92,5 @@ MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(cerf_map_io)
INITIRQ(cerf_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -141,5 +141,5 @@ MACHINE_START(COLLIE, "Sharp-Collie")
MAPIO(collie_map_io)
INITIRQ(sa1100_init_irq)
INIT_MACHINE(collie_init)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -35,5 +35,5 @@ MACHINE_START(EMPEG, "empeg MP3 Car Audio Player")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(empeg_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -183,6 +183,6 @@ MACHINE_START(FLEXANET, "FlexaNet")
BOOT_PARAMS(0xc0000100)
MAPIO(flexanet_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -77,5 +77,5 @@ MACHINE_START(FREEBIRD, "Freebird-HPC-1.1")
#endif
MAPIO(freebird_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -4,9 +4,11 @@
* Author: Nicolas Pitre
*/
struct sys_timer;
extern struct sys_timer sa1100_timer;
extern void __init sa1100_map_io(void);
extern void __init sa1100_init_irq(void);
extern void __init sa1100_init_time(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
......
......@@ -198,5 +198,5 @@ MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(graphicsclient_map_io)
INITIRQ(graphicsclient_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -287,5 +287,5 @@ MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(graphicsmaster_map_io)
INITIRQ(graphicsmaster_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -286,7 +286,7 @@ MACHINE_START(H3100, "Compaq iPAQ H3100")
BOOT_PARAMS(0xc0000100)
MAPIO(h3100_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
#endif /* CONFIG_SA1100_H3100 */
......@@ -401,7 +401,7 @@ MACHINE_START(H3600, "Compaq iPAQ H3600")
BOOT_PARAMS(0xc0000100)
MAPIO(h3600_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
#endif /* CONFIG_SA1100_H3600 */
......@@ -785,7 +785,7 @@ MACHINE_START(H3800, "Compaq iPAQ H3800")
BOOT_PARAMS(0xc0000100)
MAPIO(h3800_map_io)
INITIRQ(h3800_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
#endif /* CONFIG_SA1100_H3800 */
......@@ -174,5 +174,5 @@ MACHINE_START(HACKKIT, "HackKit Cpu Board")
BOOT_PARAMS(0xc0000100)
MAPIO(hackkit_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -81,5 +81,5 @@ MACHINE_START(HUW_WEBPANEL, "HuW-Webpanel")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(huw_webpanel_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -37,5 +37,5 @@ MACHINE_START(ITSY, "Compaq Itsy")
BOOT_PARAMS(0xc0000100)
MAPIO(itsy_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -101,5 +101,5 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
BOOT_PARAMS(0xc0000100)
MAPIO(jornada720_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -43,5 +43,5 @@ MACHINE_START(LART, "LART")
BOOT_PARAMS(0xc0000100)
MAPIO(lart_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -49,5 +49,5 @@ MACHINE_START(NANOENGINE, "BSE nanoEngine")
FIXUP(fixup_nanoengine)
MAPIO(nanoengine_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -59,5 +59,5 @@ MACHINE_START(OMNIMETER, "OmniMeter")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(omnimeter_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -40,5 +40,5 @@ MACHINE_START(PANGOLIN, "Dialogue-Pangolin")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(pangolin_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -112,5 +112,5 @@ MACHINE_START(PFS168, "Tulsa")
BOOT_PARAMS(0xc0000100)
MAPIO(pfs168_map_io)
INITIRQ(pfs168_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -31,5 +31,5 @@ MACHINE_START(PLEB, "PLEB")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(pleb_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -45,9 +45,6 @@ extern void sa1100_cpu_resume(void);
*/
enum { SLEEP_SAVE_SP = 0,
SLEEP_SAVE_OIER,
SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
......@@ -72,12 +69,6 @@ static int sa11x0_pm_enter(u32 state)
gpio = GPLR;
/* save vital registers */
SAVE(OSMR0);
SAVE(OSMR1);
SAVE(OSMR2);
SAVE(OSMR3);
SAVE(OIER);
SAVE(GPDR);
SAVE(GAFR);
......@@ -129,15 +120,6 @@ static int sa11x0_pm_enter(u32 state)
*/
PSSR = PSSR_PH;
RESTORE(OSMR0);
RESTORE(OSMR1);
RESTORE(OSMR2);
RESTORE(OSMR3);
RESTORE(OIER);
/* OSMR0 is the system timer: make sure OSCR is sufficiently behind */
OSCR = OSMR0 - LATCH;
/* restore current time */
rtc.tv_sec = RCNR;
restore_time_delta(&delta, &rtc);
......
......@@ -41,5 +41,5 @@ MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
BOOT_PARAMS(0xc0000100)
MAPIO(shannon_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -27,5 +27,5 @@ MACHINE_START(SHERMAN, "Blazie Engineering Sherman")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(sherman_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -231,5 +231,5 @@ MACHINE_START(SIMPAD, "Simpad")
BOOT_PARAMS(0xc0000100)
MAPIO(simpad_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -70,12 +70,12 @@ ENTRY(sa1100_cpu_suspend)
@ delay 90us and set CPU PLL to lowest speed
@ fixes resume problem on high speed SA1110
mov r0, #90
bl udelay
bl __udelay
ldr r0, =PPCR
mov r1, #0
str r1, [r0]
mov r0, #90
bl udelay
bl __udelay
/*
* SA1110 SDRAM controller workaround. register values:
......
......@@ -331,7 +331,7 @@ MACHINE_START(STORK, "Stork Technologies prototype")
BOOT_PARAMS(0xc0000100)
MAPIO(stork_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......
......@@ -470,5 +470,5 @@ MACHINE_START(PT_SYSTEM3, "PT System 3")
BOOT_PARAMS(0xc0000100)
MAPIO(system3_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -99,11 +99,10 @@ static struct irqaction sa1100_timer_irq = {
.handler = sa1100_timer_interrupt
};
void __init sa1100_init_time(void)
static void __init sa1100_timer_init(void)
{
struct timespec tv;
gettimeoffset = sa1100_gettimeoffset;
set_rtc = sa1100_set_rtc;
tv.tv_nsec = 0;
......@@ -117,3 +116,40 @@ void __init sa1100_init_time(void)
OSCR = 0; /* initialize free-running timer, force first match */
}
#ifdef CONFIG_PM
unsigned long osmr[4], oier;
static void sa1100_timer_suspend(void)
{
osmr[0] = OSMR0;
osmr[1] = OSMR1;
osmr[2] = OSMR2;
osmr[3] = OSMR3;
oier = OIER;
}
static void sa1100_timer_resume(void)
{
OSSR = 0x0f;
OSMR0 = osmr[0];
OSMR1 = osmr[1];
OSMR2 = osmr[2];
OSMR3 = osmr[3];
OIER = oier;
/*
* OSMR0 is the system timer: make sure OSCR is sufficiently behind
*/
OSCR = OSMR0 - LATCH;
}
#else
#define sa1100_timer_suspend NULL
#define sa1100_timer_resume NULL
#endif
struct sys_timer sa1100_timer = {
.init = sa1100_timer_init,
.suspend = sa1100_timer_suspend,
.resume = sa1100_timer_resume,
.offset = sa1100_gettimeoffset,
};
......@@ -228,5 +228,5 @@ MACHINE_START(TRIZEPS, "TRIZEPS")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(trizeps_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -89,5 +89,5 @@ MACHINE_START(XP860, "XP860")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(xp860_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
......@@ -91,5 +91,5 @@ MACHINE_START(YOPY, "Yopy")
BOOT_PARAMS(0xc0000100)
MAPIO(yopy_map_io)
INITIRQ(sa1100_init_irq)
INITTIME(sa1100_init_time)
.timer = &sa1100_timer,
MACHINE_END
zreladdr-y := 0x08008000
......@@ -49,7 +49,7 @@ static struct irqaction shark_timer_irq = {
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init shark_init_time(void)
static void __init shark_timer_init(void)
{
unsigned long flags;
......@@ -60,6 +60,9 @@ void __init shark_init_time(void)
setup_irq(IRQ_TIMER, &shark_timer_irq);
}
static struct sys_timer shark_timer = {
.init = shark_timer_init,
};
MACHINE_START(SHARK, "Shark")
MAINTAINER("Alexander Schulz")
......@@ -67,5 +70,5 @@ MACHINE_START(SHARK, "Shark")
BOOT_PARAMS(0x08003000)
MAPIO(shark_map_io)
INITIRQ(shark_init_irq)
INITTIME(shark_init_time)
.timer = &shark_timer,
MACHINE_END
zreladdr-y := 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
......@@ -760,8 +760,6 @@ typedef struct TimerStruct {
unsigned long TimerClear;
} TimerStruct_t;
extern unsigned long (*gettimeoffset)(void);
/*
* Returns number of ms since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
......@@ -827,7 +825,7 @@ static struct irqaction versatile_timer_irq = {
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init versatile_init_time(void)
static void __init versatile_timer_init(void)
{
volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
......@@ -859,15 +857,19 @@ void __init versatile_init_time(void)
* Make irqs happen for the system timer
*/
setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
gettimeoffset = versatile_gettimeoffset;
}
static struct sys_timer versatile_timer = {
.init = versatile_timer_init,
.offset = versatile_gettimeoffset,
};
MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
BOOT_PARAMS(0x00000100)
MAPIO(versatile_map_io)
INITIRQ(versatile_init_irq)
INITTIME(versatile_init_time)
.timer = &versatile_timer,
INIT_MACHINE(versatile_init)
MACHINE_END
......@@ -630,6 +630,16 @@ am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_RETVAL(handled);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
static void am79c961_poll_controller(struct net_device *dev)
{
unsigned long flags;
local_irq_save(flags);
am79c961_interrupt(dev->irq, dev, NULL);
local_irq_restore(flags);
}
#endif
/*
* Initialise the chip. Note that we always expect
* to be entered with interrupts enabled.
......@@ -721,6 +731,9 @@ static int __init am79c961_init(void)
dev->get_stats = am79c961_getstats;
dev->set_multicast_list = am79c961_setmulticastlist;
dev->tx_timeout = am79c961_timeout;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = am79c961_poll_controller;
#endif
ret = register_netdev(dev);
if (ret == 0)
......
......@@ -457,10 +457,6 @@
#define mSEC_25 (mSEC_1 * 25)
#define SEC_1 (mSEC_1 * 1000)
#ifndef __ASSEMBLY__
extern void integrator_time_init(unsigned long, unsigned int);
#endif
#define INTEGRATOR_CSR_BASE 0x10000000
#define INTEGRATOR_CSR_SIZE 0x10000000
......
/*
* linux/include/asm-arm/arch-integrator/time.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
/*
* Where is the timer (VA)?
*/
#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000)
#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100)
#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200)
#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
/*
* How long is the timer interval?
*/
#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
#if TIMER_INTERVAL >= 0x100000
#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
#elif TIMER_INTERVAL >= 0x10000
#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
#else
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
#endif
#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
/*
* What does it look like?
*/
typedef struct TimerStruct {
unsigned long TimerLoad;
unsigned long TimerValue;
unsigned long TimerControl;
unsigned long TimerClear;
} TimerStruct_t;
extern unsigned long (*gettimeoffset)(void);
static unsigned long timer_reload;
/*
* Returns number of ms since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long integrator_gettimeoffset(void)
{
volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
unsigned long ticks1, ticks2, status;
/*
* Get the current number of ticks. Note that there is a race
* condition between us reading the timer and checking for
* an interrupt. We get around this by ensuring that the
* counter has not reloaded between our two reads.
*/
ticks2 = timer1->TimerValue & 0xffff;
do {
ticks1 = ticks2;
status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
ticks2 = timer1->TimerValue & 0xffff;
} while (ticks2 > ticks1);
/*
* Number of ticks since last interrupt.
*/
ticks1 = timer_reload - ticks2;
/*
* Interrupt pending? If so, we've reloaded once already.
*/
if (status & (1 << IRQ_TIMERINT1))
ticks1 += timer_reload;
/*
* Convert the ticks to usecs
*/
return TICKS2USECS(ticks1);
}
/*
* IRQ handler for the timer
*/
static irqreturn_t
integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
// ...clear the interrupt
timer1->TimerClear = 1;
do_leds();
do_timer(regs);
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
do_profile(regs);
return IRQ_HANDLED;
}
/*
* Set up timer interrupt, and return the current time in seconds.
*/
void __init time_init(void)
{
volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */
if (machine_is_integrator()) {
timer_reload = 1000000 * TICKS_PER_uSEC / HZ;
} else if (machine_is_cintegrator()) {
timer_reload = 1000000 / HZ;
timer_ctrl |= TIMER_CTRL_IE;
}
if (timer_reload > 0x100000) {
timer_reload >>= 8;
timer_ctrl |= 0x08; /* /256 */
} else if (timer_reload > 0x010000) {
timer_reload >>= 4;
timer_ctrl |= 0x04; /* /16 */
}
/*
* Initialise to a known state (all timers off)
*/
timer0->TimerControl = 0;
timer1->TimerControl = 0;
timer2->TimerControl = 0;
timer1->TimerLoad = timer_reload;
timer1->TimerValue = timer_reload;
timer1->TimerControl = timer_ctrl;
/*
* Make irqs happen for the system timer
*/
timer_irq.handler = integrator_timer_interrupt;
setup_irq(IRQ_TIMERINT1, &timer_irq);
gettimeoffset = integrator_gettimeoffset;
}
......@@ -117,6 +117,7 @@ static inline unsigned int ixp2000_is_pcimaster(void)
void ixp2000_map_io(void);
void ixp2000_init_irq(void);
void ixp2000_init_time(unsigned long);
unsigned long ixp2000_gettimeoffset(void);
struct pci_sys_data;
......
......@@ -53,12 +53,14 @@ struct ixp4xx_i2c_pins {
};
struct sys_timer;
/*
* Functions used by platform-level setup code
*/
extern void ixp4xx_map_io(void);
extern void ixp4xx_init_irq(void);
extern void ixp4xx_init_time(void);
extern struct sys_timer ixp4xx_timer;
extern void ixp4xx_pci_preinit(void);
struct pci_sys_data;
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
......
#ifndef __ASM_ARM_DELAY_H
#define __ASM_ARM_DELAY_H
/*
* Copyright (C) 1995 Russell King
* Copyright (C) 1995-2004 Russell King
*
* Delay routines, using a pre-computed "loops_per_second" value.
*/
#ifndef __ASM_ARM_DELAY_H
#define __ASM_ARM_DELAY_H
extern void __delay(int loops);
/*
* This function intentionally does not exist; if you see references to
* it, it means that you're calling udelay() with an out of range value.
*
* With currently imposed limits, this means that we support a max delay
* of 2000us and 671 bogomips
*/
extern void __bad_udelay(void);
/*
* division by multiplication: you don't have to worry about
* loss of precision.
......@@ -19,14 +27,16 @@ extern void __delay(int loops);
* first constant multiplications gets optimized away if the delay is
* a constant)
*/
extern void udelay(unsigned long usecs);
extern void __udelay(unsigned long usecs);
extern void __const_udelay(unsigned long);
static inline unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
{
return a * b / c;
}
#define MAX_UDELAY_MS 2
#define udelay(n) \
(__builtin_constant_p(n) ? \
((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
__const_udelay((n) * 0x68dbul)) : \
__udelay(n))
#endif /* defined(_ARM_DELAY_H) */
......@@ -12,6 +12,7 @@
struct tag;
struct meminfo;
struct sys_timer;
struct machine_desc {
/*
......@@ -39,7 +40,7 @@ struct machine_desc {
struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
void (*init_time)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};
......@@ -82,9 +83,6 @@ const struct machine_desc __mach_desc_##_type \
#define INITIRQ(_func) \
.init_irq = _func,
#define INITTIME(_func) \
.init_time = _func,
#define INIT_MACHINE(_func) \
.init_machine = _func,
......
......@@ -10,13 +10,44 @@
#ifndef __ASM_ARM_MACH_TIME_H
#define __ASM_ARM_MACH_TIME_H
extern void (*init_arch_time)(void);
#include <linux/sysdev.h>
extern int (*set_rtc)(void);
extern unsigned long (*gettimeoffset)(void);
/*
* This is our kernel timer structure.
*
* - init
* Initialise the kernels jiffy timer source, claim interrupt
* using setup_irq. This is called early on during initialisation
* while interrupts are still disabled on the local CPU.
* - suspend
* Suspend the kernel jiffy timer source, if necessary. This
* is called with interrupts disabled, after all normal devices
* have been suspended. If no action is required, set this to
* NULL.
* - resume
* Resume the kernel jiffy timer source, if necessary. This
* is called with interrupts disabled before any normal devices
* are resumed. If no action is required, set this to NULL.
* - offset
* Return the timer offset in microseconds since the last timer
* interrupt. Note: this must take account of any unprocessed
* timer interrupt which may be pending.
*/
struct sys_timer {
struct sys_device dev;
void (*init)(void);
void (*suspend)(void);
void (*resume)(void);
unsigned long (*offset)(void);
};
extern struct sys_timer *system_timer;
extern void timer_tick(struct pt_regs *);
/*
* Kernel time keeping support.
*/
extern int (*set_rtc)(void);
extern void save_time_delta(struct timespec *delta, struct timespec *rtc);
extern void restore_time_delta(struct timespec *delta, struct timespec *rtc);
......
/*
* linux/include/asm-arm/rtc.h
*
* Copyright (C) 2003 Deep Blue Solutions Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ASMARM_RTC_H
#define ASMARM_RTC_H
struct module;
struct rtc_ops {
struct module *owner;
int (*open)(void);
void (*release)(void);
int (*ioctl)(unsigned int, unsigned long);
void (*read_time)(struct rtc_time *);
int (*set_time)(struct rtc_time *);
void (*read_alarm)(struct rtc_wkalrm *);
int (*set_alarm)(struct rtc_wkalrm *);
int (*proc)(char *buf);
};
void rtc_time_to_tm(unsigned long, struct rtc_time *);
int rtc_tm_to_time(struct rtc_time *, unsigned long *);
void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *);
void rtc_update(unsigned long, unsigned long);
int register_rtc(struct rtc_ops *);
void unregister_rtc(struct rtc_ops *);
static inline int rtc_periodic_alarm(struct rtc_time *tm)
{
return (tm->tm_year == -1) ||
((unsigned)tm->tm_mon >= 12) ||
((unsigned)(tm->tm_mday - 1) >= 31) ||
((unsigned)tm->tm_hour > 23) ||
((unsigned)tm->tm_min > 59) ||
((unsigned)tm->tm_sec > 59);
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment