Merge bk://ppc.bkbits.net/for-linus-ppc
into home.transmeta.com:/home/torvalds/v2.5/linux
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index 6479e7e..d1e8d37 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -29,13 +29,12 @@
  * to reduce code space and undefined function references.
  */
 
-
-#include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/threads.h>
 #include <linux/kernel_stat.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
+#include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 77a8479..54cc9df 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -1304,6 +1304,9 @@
 	.long sys_io_getevents
 	.long sys_io_submit	/* 230 */
 	.long sys_io_cancel
+	.long sys_ni_syscall	/* reserved for alloc_hugepages */
+	.long sys_ni_syscall	/* reserved for free_hugepages */
+	.long sys_exit_group
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index fe17372..5909f7c 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -638,7 +638,7 @@
 
 
 int
-pcibios_enable_resources(struct pci_dev *dev)
+pcibios_enable_resources(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -647,6 +647,10 @@
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for (idx=0; idx<6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<idx)))
+			continue;
+		
 		r = &dev->resource[idx];
 		if (r->flags & IORESOURCE_UNSET) {
 			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
@@ -1191,7 +1195,7 @@
 	/* XXX FIXME - update OF device tree node interrupt property */
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -1553,6 +1557,7 @@
 			printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
 	}
 	bus.number = busnr;
+	bus.sysdata = hose;
 	bus.ops = hose? hose->ops: &null_pci_ops;
 	return &bus;
 }
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 907169a..3dfce54 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -57,7 +57,7 @@
 
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 /* this is 8kB-aligned so we can get to the thread_info struct
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 4add451..42378a9 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -659,100 +659,3 @@
 	/* this is for modules since _machine can be a define -- Cort */
 	ppc_md.ppc_machine = _machine;
 }
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-/* Convert the shorts/longs in hd_driveid from little to big endian;
- * chars are endian independant, of course, but strings need to be flipped.
- * (Despite what it says in drivers/block/ide.h, they come up as little
- * endian...)
- *
- * Changes to linux/hdreg.h may require changes here. */
-void ide_fix_driveid(struct hd_driveid *id)
-{
-        int i;
-	unsigned short *stringcast;
-
-	id->config         = __le16_to_cpu(id->config);
-	id->cyls           = __le16_to_cpu(id->cyls);
-	id->reserved2      = __le16_to_cpu(id->reserved2);
-	id->heads          = __le16_to_cpu(id->heads);
-	id->track_bytes    = __le16_to_cpu(id->track_bytes);
-	id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
-	id->sectors        = __le16_to_cpu(id->sectors);
-	id->vendor0        = __le16_to_cpu(id->vendor0);
-	id->vendor1        = __le16_to_cpu(id->vendor1);
-	id->vendor2        = __le16_to_cpu(id->vendor2);
-	stringcast = (unsigned short *)&id->serial_no[0];
-	for (i = 0; i < (20/2); i++)
-	        stringcast[i] = __le16_to_cpu(stringcast[i]);
-	id->buf_type       = __le16_to_cpu(id->buf_type);
-	id->buf_size       = __le16_to_cpu(id->buf_size);
-	id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
-	stringcast = (unsigned short *)&id->fw_rev[0];
-	for (i = 0; i < (8/2); i++)
-	        stringcast[i] = __le16_to_cpu(stringcast[i]);
-	stringcast = (unsigned short *)&id->model[0];
-	for (i = 0; i < (40/2); i++)
-	        stringcast[i] = __le16_to_cpu(stringcast[i]);
-	id->dword_io       = __le16_to_cpu(id->dword_io);
-	id->reserved50     = __le16_to_cpu(id->reserved50);
-	id->field_valid    = __le16_to_cpu(id->field_valid);
-	id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
-	id->cur_heads      = __le16_to_cpu(id->cur_heads);
-	id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
-	id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
-	id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
-	id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
-	id->dma_1word      = __le16_to_cpu(id->dma_1word);
-	id->dma_mword      = __le16_to_cpu(id->dma_mword);
-	id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
-	id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
-	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
-	id->eide_pio       = __le16_to_cpu(id->eide_pio);
-	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
-	for (i = 0; i < 2; i++)
-		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
-        for (i = 0; i < 4; i++)
-                id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
-	id->queue_depth	   = __le16_to_cpu(id->queue_depth);
-	for (i = 0; i < 4; i++)
-		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
-	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
-	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
-	id->command_set_1  = __le16_to_cpu(id->command_set_1);
-	id->command_set_2  = __le16_to_cpu(id->command_set_2);
-	id->cfsse          = __le16_to_cpu(id->cfsse);
-	id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
-	id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
-	id->csf_default    = __le16_to_cpu(id->csf_default);
-	id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
-	id->word89         = __le16_to_cpu(id->word89);
-	id->word90         = __le16_to_cpu(id->word90);
-	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
-	id->word92         = __le16_to_cpu(id->word92);
-	id->hw_config      = __le16_to_cpu(id->hw_config);
-	id->acoustic       = __le16_to_cpu(id->acoustic);
-	for (i = 0; i < 5; i++)
-		id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
-	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
-	for (i = 0; i < 22; i++)
-		id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);
-	id->last_lun       = __le16_to_cpu(id->last_lun);
-	id->word127        = __le16_to_cpu(id->word127);
-	id->dlf            = __le16_to_cpu(id->dlf);
-	id->csfo           = __le16_to_cpu(id->csfo);
-	for (i = 0; i < 26; i++)
-		id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
-	id->word156        = __le16_to_cpu(id->word156);
-	for (i = 0; i < 3; i++)
-		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
-	id->cfa_power      = __le16_to_cpu(id->cfa_power);
-	for (i = 0; i < 14; i++)
-		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
-	for (i = 0; i < 31; i++)
-		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
-	for (i = 0; i < 48; i++)
-		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
-	id->integrity_word  = __le16_to_cpu(id->integrity_word);
-}
-#endif
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 0f15c00..6690e87 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -193,7 +193,7 @@
 		 */
 		if ( ppc_md.set_rtc_time && (time_status & STA_UNSYNC) == 0 &&
 		     xtime.tv_sec - last_rtc_update >= 659 &&
-		     abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ &&
+		     abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ &&
 		     jiffies - wall_jiffies == 1) {
 		  	if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
 				last_rtc_update = xtime.tv_sec+1;
@@ -228,7 +228,7 @@
 
 	read_lock_irqsave(&xtime_lock, flags);
 	sec = xtime.tv_sec;
-	usec = xtime.tv_usec;
+	usec = (xtime.tv_nsec / 1000);
 #ifdef CONFIG_PPC_ISERIES
 	delta = tb_ticks_per_jiffy - ( next_jiffy_update_tb[0] - get_tb64() );
 #else
@@ -285,7 +285,7 @@
 		new_sec--; 
 		new_usec += 1000000;
 	}
-	xtime.tv_usec = new_usec;
+	xtime.tv_nsec = (new_usec * 1000);
 	xtime.tv_sec = new_sec;
 
 	/* In case of a large backwards jump in time with NTP, we want the 
@@ -344,7 +344,7 @@
 		write_lock_irqsave(&xtime_lock, flags);
 		xtime.tv_sec = sec;
 		last_jiffy_stamp(0) = tb_last_stamp = stamp;
-		xtime.tv_usec = 0;
+		xtime.tv_nsec = 0;
 		/* No update now, we just read the time from the RTC ! */
 		last_rtc_update = xtime.tv_sec;
 		write_unlock_irqrestore(&xtime_lock, flags);
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index f67ed51..36e65a3 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -26,6 +26,7 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
@@ -202,7 +203,7 @@
 		err = map_page(v+i, p+i, flags);
 	if (err) {
 		if (mem_init_done)
-			vfree((void *)v);
+			vunmap((void *)v);
 		return NULL;
 	}
 
@@ -219,7 +220,7 @@
 	if (v_mapped_by_bats((unsigned long)addr)) return;
 
 	if (addr > high_memory && (unsigned long) addr < ioremap_bot)
-		vfree((void *) (PAGE_MASK & (unsigned long) addr));
+		vunmap((void *) (PAGE_MASK & (unsigned long)addr));
 }
 #endif /* CONFIG_PPC_ISERIES */
 
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
index 650c3e6..5f7029b 100644
--- a/arch/ppc/platforms/pmac_time.c
+++ b/arch/ppc/platforms/pmac_time.c
@@ -228,7 +228,7 @@
 	case PBOOK_WAKE:
 		write_lock_irqsave(&xtime_lock, flags);
 		xtime.tv_sec = pmac_get_rtc_time() + time_diff;
-		xtime.tv_usec = 0;
+		xtime.tv_nsec = 0;
 		last_rtc_update = xtime.tv_sec;
 		write_unlock_irqrestore(&xtime_lock, flags);
 		break;
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
index d7462ee..b51b28b 100644
--- a/arch/ppc/platforms/prep_pci.c
+++ b/arch/ppc/platforms/prep_pci.c
@@ -27,7 +27,6 @@
 #include <asm/machdep.h>
 #include <asm/open_pic.h>
 
-#define MAX_DEVNR 22
 
 /* Which PCI interrupt line does a given device [slot] use? */
 /* Note: This really should be two dimensional based in slot/pin used */
@@ -616,47 +615,79 @@
 #define ELCRM_INT7_LVL          0x80
 #define ELCRM_INT5_LVL          0x20
 
-#define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset)
-#define DEVNO(dev)  (dev>>3)                                  
+/*
+ * PCI config space access.
+ */
+#define CFGADDR(dev)	((1<<(dev>>3)) | ((dev&7)<<8))
+#define DEVNO(dev)	(dev>>3)
 
-#define cfg_read(val, addr, type, op)	*val = op((type)(addr))
-#define cfg_write(val, addr, type, op)	op((type *)(addr), (val))
+#define MIN_DEVNR	11
+#define MAX_DEVNR	22
 
-#define cfg_read_bad(val, size)		*val = bad_##size;
-#define cfg_write_bad(val, size)
+static int __prep
+prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		 int len, u32 *val)
+{
+	struct pci_controller *hose = bus->sysdata;
+	volatile unsigned char *cfg_data;
 
-#define bad_byte	0xff
-#define bad_word	0xffff
-#define bad_dword	0xffffffffU
+	if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR
+	    || DEVNO(devfn) > MAX_DEVNR)
+		return PCIBIOS_DEVICE_NOT_FOUND;
 
-#define PREP_PCI_OP(rw, size, type, op)					\
-static int __prep							\
-prep_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
-{									\
-	if ((dev->bus->number != 0) || (DEVNO(dev->devfn) > MAX_DEVNR))	\
-	{                   						\
-		cfg_##rw##_bad(val, size)				\
-		return PCIBIOS_DEVICE_NOT_FOUND;    			\
-	}								\
-	cfg_##rw(val, CFGPTR(dev->devfn), type, op);			\
-	return PCIBIOS_SUCCESSFUL;					\
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	cfg_data = hose->cfg_data + CFGADDR(devfn) + offset;
+	switch (len) {
+	case 1:
+		*val = in_8((u8 *)cfg_data);
+		break;
+	case 2:
+		*val = in_le16((u16 *)cfg_data);
+		break;
+	default:
+		*val = in_le32((u32 *)cfg_data);
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
 }
 
-PREP_PCI_OP(read, byte, u8 *, in_8)
-PREP_PCI_OP(read, word, u16 *, in_le16)
-PREP_PCI_OP(read, dword, u32 *, in_le32)
-PREP_PCI_OP(write, byte, u8, out_8)
-PREP_PCI_OP(write, word, u16, out_le16)
-PREP_PCI_OP(write, dword, u32, out_le32)
+static int __prep
+prep_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		  int len, u32 val)
+{
+	struct pci_controller *hose = bus->sysdata;
+	volatile unsigned char *cfg_data;
+
+	if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR
+	    || DEVNO(devfn) > MAX_DEVNR)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	cfg_data = hose->cfg_data + CFGADDR(devfn) + offset;
+	switch (len) {
+	case 1:
+		out_8((u8 *)cfg_data, val);
+		break;
+	case 2:
+		out_le16((u16 *)cfg_data, val);
+		break;
+	default:
+		out_le32((u32 *)cfg_data, val);
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
 
 static struct pci_ops prep_pci_ops =
 {
-	prep_read_config_byte,
-	prep_read_config_word,
-	prep_read_config_dword,
-	prep_write_config_byte,
-	prep_write_config_word,
-	prep_write_config_dword
+	prep_read_config,
+	prep_write_config
 };
 
 #define MOTOROLA_CPUTYPE_REG	0x800
@@ -1239,10 +1270,12 @@
 	hose->last_busno = 0xff;
 	hose->pci_mem_offset = PREP_ISA_MEM_BASE;
 	hose->io_base_phys = PREP_ISA_IO_BASE;
-	hose->io_base_virt = (void *)0x80000000; /* see prep_map_io() */
-	prep_init_resource(&hose->io_resource, 0, 0x00ffffff, IORESOURCE_IO);
+	hose->io_base_virt = ioremap(PREP_ISA_IO_BASE, 0x800000);
+	prep_init_resource(&hose->io_resource, 0, 0x007fffff, IORESOURCE_IO);
 	prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff,
 			   IORESOURCE_MEM);
+	/* XXX why can't we use the indirect config space access method? */
+	hose->cfg_data = ioremap(PREP_ISA_IO_BASE + 0x800000, 0x800000);
 	hose->ops = &prep_pci_ops;
 
 	printk("PReP architecture\n");
diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h
index 63e194a..def62e3 100644
--- a/include/asm-ppc/atomic.h
+++ b/include/asm-ppc/atomic.h
@@ -67,6 +67,8 @@
 	return t;
 }
 
+#define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
+
 static __inline__ void atomic_sub(int a, atomic_t *v)
 {
 	int t;
diff --git a/include/asm-ppc/highmem.h b/include/asm-ppc/highmem.h
index 472482c..98da2db 100644
--- a/include/asm-ppc/highmem.h
+++ b/include/asm-ppc/highmem.h
@@ -128,6 +128,17 @@
 	dec_preempt_count();
 }
 
+static inline struct page *kmap_atomic_to_page(void *ptr)
+{
+	unsigned long idx, vaddr = (unsigned long) ptr;
+
+	if (vaddr < KMAP_FIX_BEGIN)
+		return virt_to_page(ptr);
+
+	idx = (vaddr - KMAP_FIX_BEGIN) >> PAGE_SHIFT;
+	return pte_page(kmap_pte[idx]);
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h
index 8a95ad1..5581352 100644
--- a/include/asm-ppc/ide.h
+++ b/include/asm-ppc/ide.h
@@ -103,30 +103,10 @@
 #endif
 }
 
-#if !defined(ide_request_irq)
-#define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
-#endif
-
-#if !defined(ide_free_irq)
-#define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
-#endif
-#define ide_check_region(from,extent)		check_region((from), (extent))
-#define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
-#define ide_release_region(from,extent)		release_region((from), (extent))
-
-extern void ide_fix_driveid(struct hd_driveid *id);
-
-/*
- * The following are not needed for the non-m68k ports
- * unless direct IDE on 8xx
- */
 #if (defined CONFIG_APUS || defined CONFIG_BLK_DEV_MPC8xx_IDE )
+#define IDE_ARCH_ACK_INTR  1
 #define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
-#else
-#define ide_ack_intr(hwif)		(1)
 #endif
-#define ide_release_lock(lock)		do {} while (0)
-#define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
index b7dafa9..f852ed6 100644
--- a/include/asm-ppc/spinlock.h
+++ b/include/asm-ppc/spinlock.h
@@ -100,6 +100,8 @@
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT }
 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
 
+#define rwlock_is_locked(x)	((x)->lock != 0)
+
 #ifndef CONFIG_DEBUG_SPINLOCK
 
 static __inline__ void _raw_read_lock(rwlock_t *rw)
diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
index 4f7e364..510bfd1 100644
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-ppc/unistd.h
@@ -239,6 +239,9 @@
 #define __NR_io_getevents	229
 #define __NR_io_submit		230
 #define __NR_io_cancel		231
+#define __NR_alloc_hugepages	232
+#define __NR_free_hugepages	233
+#define __NR_exit_group		234
 
 #define __NR(n)	#n