Commit 4b844718 authored by Linus Torvalds's avatar Linus Torvalds

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
parents a43cdf08 1604f318
...@@ -73,7 +73,7 @@ struct getdents_callback { ...@@ -73,7 +73,7 @@ struct getdents_callback {
#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
static int filldir(void * __buf, const char * name, int namlen, loff_t offset, 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 hpux_dirent * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf; struct getdents_callback * buf = (struct getdents_callback *) __buf;
......
...@@ -424,7 +424,10 @@ struct parisc_device * create_tree_node(char id, struct device *parent) ...@@ -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 */ /* make the generic dma mask a pointer to the parisc one */
dev->dev.dma_mask = &dev->dma_mask; dev->dev.dma_mask = &dev->dma_mask;
dev->dev.coherent_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; return dev;
} }
...@@ -850,8 +853,10 @@ static void print_parisc_device(struct parisc_device *dev) ...@@ -850,8 +853,10 @@ static void print_parisc_device(struct parisc_device *dev)
*/ */
void init_parisc_bus(void) void init_parisc_bus(void)
{ {
bus_register(&parisc_bus_type); if (!bus_register(&parisc_bus_type))
device_register(&root); 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); get_device(&root);
} }
......
...@@ -290,7 +290,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); ...@@ -290,7 +290,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource);
void pcibios_align_resource(void *data, struct resource *res, void pcibios_align_resource(void *data, struct resource *res,
resource_size_t size, resource_size_t alignment) 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", DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
pci_name(((struct pci_dev *) data)), pci_name(((struct pci_dev *) data)),
......
...@@ -266,30 +266,17 @@ long parisc_personality(unsigned long personality) ...@@ -266,30 +266,17 @@ long parisc_personality(unsigned long personality)
return err; return err;
} }
static inline int override_machine(char __user *mach) { long parisc_newuname(struct new_utsname __user *name)
#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)
{ {
int err = 0; int err = sys_newuname(name);
down_read(&uts_sem); #ifdef CONFIG_COMPAT
if (copy_to_user(utsname, &system_utsname, sizeof(*utsname))) if (!err && personality(current->personality) == PER_LINUX32) {
err = -EFAULT; if (__put_user(0, name->machine + 6) ||
up_read(&uts_sem); __put_user(0, name->machine + 7))
err = -EFAULT;
err = override_machine(utsname->machine); }
#endif
return (long)err; return err;
} }
...@@ -111,13 +111,14 @@ struct __sysctl_args32 { ...@@ -111,13 +111,14 @@ struct __sysctl_args32 {
asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
{ {
#ifndef CONFIG_SYSCTL_SYSCALL
return -ENOSYS;
#else
struct __sysctl_args32 tmp; struct __sysctl_args32 tmp;
int error; int error;
unsigned int oldlen32; unsigned int oldlen32;
size_t oldlen, *oldlenp = NULL; size_t oldlen, __user *oldlenp = NULL;
unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7; 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)); DBG(("sysctl32(%p)\n", args));
...@@ -144,8 +145,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) ...@@ -144,8 +145,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
} }
lock_kernel(); lock_kernel();
error = do_sysctl((int *)(u64)tmp.name, tmp.nlen, (void *)(u64)tmp.oldval, error = do_sysctl((int __user *)(u64)tmp.name, tmp.nlen,
oldlenp, (void *)(u64)tmp.newval, tmp.newlen); (void __user *)(u64)tmp.oldval, oldlenp,
(void __user *)(u64)tmp.newval, tmp.newlen);
unlock_kernel(); unlock_kernel();
if (oldlenp) { if (oldlenp) {
if (!error) { if (!error) {
...@@ -157,10 +159,11 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) ...@@ -157,10 +159,11 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
error = -EFAULT; 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; error = -EFAULT;
} }
return error; return error;
#endif
} }
#endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SYSCTL */
...@@ -310,9 +313,8 @@ struct readdir32_callback { ...@@ -310,9 +313,8 @@ struct readdir32_callback {
#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) #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))) #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
static int static int filldir32 (void *__buf, const char *name, int namlen,
filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, loff_t offset, u64 ino, unsigned int d_type)
unsigned int d_type)
{ {
struct linux32_dirent __user * dirent; struct linux32_dirent __user * dirent;
struct getdents32_callback * buf = (struct getdents32_callback *) __buf; struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
...@@ -374,9 +376,8 @@ out: ...@@ -374,9 +376,8 @@ out:
return error; return error;
} }
static int static int fillonedir32(void * __buf, const char * name, int namlen,
fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, loff_t offset, u64 ino, unsigned int d_type)
unsigned int d_type)
{ {
struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
struct old_linux32_dirent __user * dirent; struct old_linux32_dirent __user * dirent;
......
...@@ -38,11 +38,28 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */ ...@@ -38,11 +38,28 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */
extern void smp_do_timer(struct pt_regs *regs); extern void smp_do_timer(struct pt_regs *regs);
#endif #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) irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned long now; unsigned long now;
unsigned long next_tick; unsigned long next_tick;
unsigned long cycles_elapsed; unsigned long cycles_elapsed, ticks_elapsed;
unsigned long cycles_remainder; unsigned long cycles_remainder;
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
...@@ -67,11 +84,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -67,11 +84,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* of the more expensive div/mul method * of the more expensive div/mul method
*/ */
cycles_remainder = cycles_elapsed; cycles_remainder = cycles_elapsed;
ticks_elapsed = 1;
while (cycles_remainder > cpt) { while (cycles_remainder > cpt) {
cycles_remainder -= cpt; cycles_remainder -= cpt;
ticks_elapsed++;
} }
} else { } else {
cycles_remainder = cycles_elapsed % cpt; cycles_remainder = cycles_elapsed % cpt;
ticks_elapsed = 1 + cycles_elapsed / cpt;
} }
/* Can we differentiate between "early CR16" (aka Scenario 1) and /* 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) ...@@ -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 * cycles after the IT fires. But it's arbitrary how much time passes
* before we call it "late". I've picked one second. * before we call it "late". I've picked one second.
*/ */
/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */ if (ticks_elapsed > 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
{
/* Scenario 3: very long delay? bad in any case */ /* Scenario 3: very long delay? bad in any case */
printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!" printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
" cycles %lX rem %lX " " cycles %lX rem %lX "
...@@ -136,7 +145,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -136,7 +145,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#endif #endif
if (cpu == 0) { if (cpu == 0) {
write_seqlock(&xtime_lock); write_seqlock(&xtime_lock);
do_timer(regs); do_timer(ticks_elapsed);
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
} }
......
...@@ -1320,12 +1320,12 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ...@@ -1320,12 +1320,12 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
** the GART code to handshake on. ** the GART code to handshake on.
*/ */
klist_iter_init(&sba->dev.klist_children, &i); klist_iter_init(&sba->dev.klist_children, &i);
while (dev = next_device(&i)) { while ((dev = next_device(&i))) {
struct parisc_device *lba = to_parisc_device(dev); struct parisc_device *lba = to_parisc_device(dev);
if (IS_QUICKSILVER(lba)) if (IS_QUICKSILVER(lba))
agp_found = 1; agp_found = 1;
} }
klist_iter_exit(&sba->dev.klist_children, &i); klist_iter_exit(&i);
if (agp_found && sba_reserve_agpgart) { if (agp_found && sba_reserve_agpgart) {
printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
......
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