summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-05 06:08:13 +0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-05 06:08:13 +0400
commit4b8447184ae85de4ce710e5f561fbaada21b8394 (patch)
tree71aed2c654a6d8d83beff480bc84d9e63b366858 /arch
parenta43cdf08a1b1ab3c013059b5fa4c1b7561e53cb7 (diff)
parent1604f31895dcdb42edf6511ce7ef0546ff92c8e5 (diff)
downloadlinux-4b8447184ae85de4ce710e5f561fbaada21b8394.tar.xz
Merge master.kernel.org:/pub/scm/linux/kernel/git/willy/parisc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/willy/parisc-2.6: [PA-RISC] Fix time.c for new do_timer() calling convention [PA-RISC] Fix must_check warnings in drivers.c [PA-RISC] Fix parisc_newuname() [PA-RISC] Remove warning from pci.c [PA-RISC] Fix filldir warnings [PA-RISC] Fix sys32_sysctl [PA-RISC] Fix sba_iommu compilation
Diffstat (limited to 'arch')
-rw-r--r--arch/parisc/hpux/fs.c2
-rw-r--r--arch/parisc/kernel/drivers.c11
-rw-r--r--arch/parisc/kernel/pci.c2
-rw-r--r--arch/parisc/kernel/sys_parisc.c33
-rw-r--r--arch/parisc/kernel/sys_parisc32.c25
-rw-r--r--arch/parisc/kernel/time.c37
6 files changed, 56 insertions, 54 deletions
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index 2d58b92b57e3..4204cd1f3cf9 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -73,7 +73,7 @@ struct getdents_callback {
#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
- ino_t ino, unsigned d_type)
+ u64 ino, unsigned d_type)
{
struct hpux_dirent * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 3d569a485a1a..2b257e4f17df 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -424,7 +424,10 @@ struct parisc_device * create_tree_node(char id, struct device *parent)
/* make the generic dma mask a pointer to the parisc one */
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.coherent_dma_mask = dev->dma_mask;
- device_register(&dev->dev);
+ if (!device_register(&dev->dev)) {
+ kfree(dev);
+ return NULL;
+ }
return dev;
}
@@ -850,8 +853,10 @@ static void print_parisc_device(struct parisc_device *dev)
*/
void init_parisc_bus(void)
{
- bus_register(&parisc_bus_type);
- device_register(&root);
+ if (!bus_register(&parisc_bus_type))
+ panic("Could not register PA-RISC bus type\n");
+ if (!device_register(&root))
+ panic("Could not register PA-RISC root device\n");
get_device(&root);
}
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index d3b8fc52dfc1..199887a61c76 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -290,7 +290,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource);
void pcibios_align_resource(void *data, struct resource *res,
resource_size_t size, resource_size_t alignment)
{
- unsigned long mask, align;
+ resource_size_t mask, align;
DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
pci_name(((struct pci_dev *) data)),
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 1db5588ceacf..512642d8f707 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -266,30 +266,17 @@ long parisc_personality(unsigned long personality)
return err;
}
-static inline int override_machine(char __user *mach) {
-#ifdef CONFIG_COMPAT
- if (personality(current->personality) == PER_LINUX32) {
- if (__put_user(0, mach + 6) ||
- __put_user(0, mach + 7))
- return -EFAULT;
- }
-
- return 0;
-#else /*!CONFIG_COMPAT*/
- return 0;
-#endif /*CONFIG_COMPAT*/
-}
-
-long parisc_newuname(struct new_utsname __user *utsname)
+long parisc_newuname(struct new_utsname __user *name)
{
- int err = 0;
+ int err = sys_newuname(name);
- down_read(&uts_sem);
- if (copy_to_user(utsname, &system_utsname, sizeof(*utsname)))
- err = -EFAULT;
- up_read(&uts_sem);
-
- err = override_machine(utsname->machine);
+#ifdef CONFIG_COMPAT
+ if (!err && personality(current->personality) == PER_LINUX32) {
+ if (__put_user(0, name->machine + 6) ||
+ __put_user(0, name->machine + 7))
+ err = -EFAULT;
+ }
+#endif
- return (long)err;
+ return err;
}
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index e3b30bc36453..29be4377aca6 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -111,13 +111,14 @@ struct __sysctl_args32 {
asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
{
+#ifndef CONFIG_SYSCTL_SYSCALL
+ return -ENOSYS;
+#else
struct __sysctl_args32 tmp;
int error;
unsigned int oldlen32;
- size_t oldlen, *oldlenp = NULL;
+ size_t oldlen, __user *oldlenp = NULL;
unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7;
- extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
- void *newval, size_t newlen);
DBG(("sysctl32(%p)\n", args));
@@ -144,8 +145,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
}
lock_kernel();
- error = do_sysctl((int *)(u64)tmp.name, tmp.nlen, (void *)(u64)tmp.oldval,
- oldlenp, (void *)(u64)tmp.newval, tmp.newlen);
+ error = do_sysctl((int __user *)(u64)tmp.name, tmp.nlen,
+ (void __user *)(u64)tmp.oldval, oldlenp,
+ (void __user *)(u64)tmp.newval, tmp.newlen);
unlock_kernel();
if (oldlenp) {
if (!error) {
@@ -157,10 +159,11 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
error = -EFAULT;
}
}
- if (copy_to_user(&args->__unused[0], tmp.__unused, sizeof(tmp.__unused)))
+ if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
error = -EFAULT;
}
return error;
+#endif
}
#endif /* CONFIG_SYSCTL */
@@ -310,9 +313,8 @@ struct readdir32_callback {
#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-static int
-filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
- unsigned int d_type)
+static int filldir32 (void *__buf, const char *name, int namlen,
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct linux32_dirent __user * dirent;
struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
@@ -374,9 +376,8 @@ out:
return error;
}
-static int
-fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
- unsigned int d_type)
+static int fillonedir32(void * __buf, const char * name, int namlen,
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
struct old_linux32_dirent __user * dirent;
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index b3496b592a2d..1d58ce0e37ad 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -38,11 +38,28 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */
extern void smp_do_timer(struct pt_regs *regs);
#endif
+/*
+ * We keep time on PA-RISC Linux by using the Interval Timer which is
+ * a pair of registers; one is read-only and one is write-only; both
+ * accessed through CR16. The read-only register is 32 or 64 bits wide,
+ * and increments by 1 every CPU clock tick. The architecture only
+ * guarantees us a rate between 0.5 and 2, but all implementations use a
+ * rate of 1. The write-only register is 32-bits wide. When the lowest
+ * 32 bits of the read-only register compare equal to the write-only
+ * register, it raises a maskable external interrupt. Each processor has
+ * an Interval Timer of its own and they are not synchronised.
+ *
+ * We want to generate an interrupt every 1/HZ seconds. So we program
+ * CR16 to interrupt every @clocktick cycles. The it_value in cpu_data
+ * is programmed with the intended time of the next tick. We can be
+ * held off for an arbitrarily long period of time by interrupts being
+ * disabled, so we may miss one or more ticks.
+ */
irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long now;
unsigned long next_tick;
- unsigned long cycles_elapsed;
+ unsigned long cycles_elapsed, ticks_elapsed;
unsigned long cycles_remainder;
unsigned int cpu = smp_processor_id();
@@ -67,11 +84,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* of the more expensive div/mul method
*/
cycles_remainder = cycles_elapsed;
+ ticks_elapsed = 1;
while (cycles_remainder > cpt) {
cycles_remainder -= cpt;
+ ticks_elapsed++;
}
} else {
cycles_remainder = cycles_elapsed % cpt;
+ ticks_elapsed = 1 + cycles_elapsed / cpt;
}
/* Can we differentiate between "early CR16" (aka Scenario 1) and
@@ -81,18 +101,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* cycles after the IT fires. But it's arbitrary how much time passes
* before we call it "late". I've picked one second.
*/
-/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
-#if HZ == 1000
- if (cycles_elapsed > (cpt << 10) )
-#elif HZ == 250
- if (cycles_elapsed > (cpt << 8) )
-#elif HZ == 100
- if (cycles_elapsed > (cpt << 7) )
-#else
-#warn WTF is HZ set to anyway?
- if (cycles_elapsed > (HZ * cpt) )
-#endif
- {
+ if (ticks_elapsed > HZ) {
/* Scenario 3: very long delay? bad in any case */
printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
" cycles %lX rem %lX "
@@ -136,7 +145,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#endif
if (cpu == 0) {
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(ticks_elapsed);
write_sequnlock(&xtime_lock);
}