summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-08 00:53:00 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-08 00:53:00 +0000
commitb8553086288629b4efb77e97f5582e08bc50ad65 (patch)
tree0a19bd1c21e148f35c7a0f76baa4f7a056b966b0 /arch/sparc64/kernel
parent75b6d92f2dd5112b02f4e78cf9f35f9825946ef0 (diff)
Merge with 2.4.0-test3-pre4.
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/irq.c37
-rw-r--r--arch/sparc64/kernel/pci_sabre.c31
-rw-r--r--arch/sparc64/kernel/sys_sparc.c7
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c17
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c10
5 files changed, 55 insertions, 47 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index eb6f789f6..a4904efb3 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.87 2000/05/09 17:40:13 davem Exp $
+/* $Id: irq.c,v 1.88 2000/06/26 19:40:27 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -62,6 +62,19 @@ unsigned int __up_workvec[16] __attribute__ ((aligned (64)));
#define irq_work(__cpu, __pil) &(cpu_data[(__cpu)].irq_worklists[(__pil)])
#endif
+#ifdef CONFIG_PCI
+/* This is a table of physical addresses used to deal with SA_DMA_SYNC.
+ * It is used for PCI only to synchronize DMA transfers with IRQ delivery
+ * for devices behind busses other than APB on Sabre systems.
+ *
+ * Currently these physical addresses are just config space accesses
+ * to the command register for that device.
+ */
+unsigned long pci_dma_wsync;
+unsigned long dma_sync_reg_table[256];
+unsigned char dma_sync_reg_table_entry = 0;
+#endif
+
/* This is based upon code in the 32-bit Sparc kernel written mostly by
* David Redman (djhr@tadpole.co.uk).
*/
@@ -280,8 +293,6 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
/*
* Check wether we _should_ use DMA Write Sync
* (for devices behind bridges behind APB).
- *
- * XXX: Not implemented, yet.
*/
if (bucket->flags & IBF_DMA_SYNC)
irqflags |= SA_DMA_SYNC;
@@ -719,14 +730,14 @@ void handler_irq(int irq, struct pt_regs *regs)
/* 'cpu' is the MID (ie. UPAID), calculate the MID
* of our buddy.
*/
- if(should_forward != 0) {
+ if (should_forward != 0) {
buddy = cpu_number_map(cpu) + 1;
if (buddy >= NR_CPUS ||
(buddy = cpu_logical_map(buddy)) == -1)
buddy = cpu_logical_map(0);
/* Voo-doo programming. */
- if(cpu_data[buddy].idle_volume < FORWARD_VOLUME)
+ if (cpu_data[buddy].idle_volume < FORWARD_VOLUME)
should_forward = 0;
buddy <<= 26;
}
@@ -752,25 +763,29 @@ void handler_irq(int irq, struct pt_regs *regs)
#else
bp = __bucket(xchg32(irq_work(cpu, irq), 0));
#endif
- for( ; bp != NULL; bp = nbp) {
+ for ( ; bp != NULL; bp = nbp) {
unsigned char flags = bp->flags;
nbp = __bucket(bp->irq_chain);
- if((flags & IBF_ACTIVE) != 0) {
- if((flags & IBF_MULTI) == 0) {
+ if ((flags & IBF_ACTIVE) != 0) {
+ if ((flags & IBF_DMA_SYNC) != 0) {
+ upa_readl(dma_sync_reg_table[bp->synctab_ent]);
+ upa_readq(pci_dma_wsync);
+ }
+ if ((flags & IBF_MULTI) == 0) {
struct irqaction *ap = bp->irq_info;
ap->handler(__irq(bp), ap->dev_id, regs);
} else {
void **vector = (void **)bp->irq_info;
int ent;
- for(ent = 0; ent < 4; ent++) {
+ for (ent = 0; ent < 4; ent++) {
struct irqaction *ap = vector[ent];
- if(ap != NULL)
+ if (ap != NULL)
ap->handler(__irq(bp), ap->dev_id, regs);
}
}
/* Only the dummy bucket lacks IMAP/ICLR. */
- if(bp->pil != 0) {
+ if (bp->pil != 0) {
#ifdef CONFIG_SMP
/* Ok, here is what is going on:
* 1) Retargeting IRQs on Starfire is very
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 99f7ba8ad..f3a5adbec 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.19 2000/04/15 13:07:51 davem Exp $
+/* $Id: pci_sabre.c,v 1.20 2000/06/26 19:40:27 davem Exp $
* pci_sabre.c: Sabre specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -641,14 +641,28 @@ static unsigned int __init sabre_irq_build(struct pci_controller_info *p,
bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
bucket->flags |= IBF_PCI;
- /* XXX We still need to code up support for this in irq.c
- * XXX It's easy to code up since only one SIMBA can exist
- * XXX in a machine and this is where the sync register is. -DaveM
- */
if (pdev) {
struct pcidev_cookie *pcp = pdev->sysdata;
- if (pdev->bus->number != pcp->pbm->pci_first_busno)
+
+ /* When a device lives behind a bridge deeper in the
+ * PCI bus topology than APB, a special sequence must
+ * run to make sure all pending DMA transfers at the
+ * time of IRQ delivery are visible in the coherency
+ * domain by the cpu. This sequence is to perform
+ * a read on the far side of the non-APB bridge, then
+ * perform a read of Sabre's DMA write-sync register.
+ *
+ * Currently, the PCI_CONFIG register for the device
+ * is used for this read from the far side of the bridge.
+ */
+ if (pdev->bus->number != pcp->pbm->pci_first_busno) {
bucket->flags |= IBF_DMA_SYNC;
+ bucket->synctab_ent = dma_sync_reg_table_entry++;
+ dma_sync_reg_table[bucket->synctab_ent] =
+ (unsigned long) sabre_pci_config_mkaddr(
+ pcp->pbm,
+ pdev->bus->number, pdev->devfn, PCI_COMMAND);
+ }
}
return __irq(bucket);
}
@@ -1399,7 +1413,10 @@ void __init sabre_init(int pnode)
* First REG in property is base of entire SABRE register space.
*/
p->controller_regs = pr_regs[0].phys_addr;
- printk("PCI: Found SABRE, main regs at %016lx\n", p->controller_regs);
+ pci_dma_wsync = p->controller_regs + SABRE_WRSYNC;
+
+ printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n",
+ p->controller_regs, pci_dma_wsync);
/* Error interrupts are enabled later after the bus scan. */
sabre_write(p->controller_regs + SABRE_PCICTRL,
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 2aff3033a..42ba3907b 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.41 2000/06/22 11:42:25 davem Exp $
+/* $Id: sys_sparc.c,v 1.42 2000/06/26 23:20:24 davem Exp $
* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -92,14 +92,12 @@ asmlinkage int sparc_pipe(struct pt_regs *regs)
int fd[2];
int error;
- lock_kernel();
error = do_pipe(fd);
if (error)
goto out;
regs->u_regs[UREG_I1] = fd[1];
error = fd[0];
out:
- unlock_kernel();
return error;
}
@@ -227,8 +225,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
len = PAGE_ALIGN(len);
retval = -EINVAL;
- lock_kernel();
-
if (current->thread.flags & SPARC_FLAG_32BIT) {
if (len > 0xf0000000UL ||
((flags & MAP_FIXED) && addr > 0xf0000000UL - len))
@@ -245,7 +241,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
up(&current->mm->mmap_sem);
out_putf:
- unlock_kernel();
if (file)
fput(file);
out:
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index e27892de3..607633aec 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.152 2000/06/22 17:44:47 davem Exp $
+/* $Id: sys_sparc32.c,v 1.153 2000/06/26 23:20:24 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -1266,14 +1266,12 @@ asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent,
buf.count = 0;
buf.dirent = dirent;
- lock_kernel();
error = vfs_readdir(file, fillonedir, &buf);
if (error < 0)
goto out_putf;
error = buf.count;
out_putf:
- unlock_kernel();
fput(file);
out:
return error;
@@ -1333,7 +1331,6 @@ asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, un
buf.count = count;
buf.error = 0;
- lock_kernel();
error = vfs_readdir(file, filldir, &buf);
if (error < 0)
goto out_putf;
@@ -1344,7 +1341,6 @@ asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, un
error = count - buf.count;
}
out_putf:
- unlock_kernel();
fput(file);
out:
return error;
@@ -1587,7 +1583,6 @@ asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
struct nameidata nd;
int error;
- lock_kernel();
error = user_path_walk(filename, &nd);
if (!error) {
struct inode *inode = nd.dentry->d_inode;
@@ -1602,7 +1597,6 @@ asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
path_release(&nd);
}
- unlock_kernel();
return error;
}
@@ -1611,7 +1605,6 @@ asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
struct nameidata nd;
int error;
- lock_kernel();
error = user_path_walk_link(filename, &nd);
if (!error) {
struct inode *inode = nd.dentry->d_inode;
@@ -1626,7 +1619,6 @@ asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
path_release(&nd);
}
- unlock_kernel();
return error;
}
@@ -1635,15 +1627,13 @@ asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
struct file *f;
int err = -EBADF;
- lock_kernel();
f = fget(fd);
if (f) {
- struct dentry *dentry = f->f_dentry;
- struct inode *inode = dentry->d_inode;
+ struct inode *inode = f->f_dentry->d_inode;
if (inode->i_op &&
inode->i_op->revalidate)
- err = inode->i_op->revalidate(dentry);
+ err = inode->i_op->revalidate(f->f_dentry);
else
err = 0;
if (!err)
@@ -1651,7 +1641,6 @@ asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
fput(f);
}
- unlock_kernel();
return err;
}
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 70adfe21a..bad3d5e2f 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.49 2000/06/22 11:42:25 davem Exp $
+/* $Id: sys_sunos32.c,v 1.50 2000/06/26 23:20:24 davem Exp $
* sys_sunos32.c: SunOS binary compatability layer on sparc64.
*
* Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -68,7 +68,6 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of
struct file *file = NULL;
unsigned long retval, ret_type;
- lock_kernel();
if(flags & MAP_NORESERVE) {
static int cnt;
if (cnt++ < 10)
@@ -113,7 +112,6 @@ out_putf:
if (file)
fput(file);
out:
- unlock_kernel();
return (u32) retval;
}
@@ -321,8 +319,6 @@ asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
if(!file)
goto out;
- lock_kernel();
-
error = -EINVAL;
if(cnt < (sizeof(struct sunos_dirent) + 255))
goto out_putf;
@@ -344,7 +340,6 @@ asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
}
out_putf:
- unlock_kernel();
fput(file);
out:
return error;
@@ -406,8 +401,6 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
if(!file)
goto out;
- lock_kernel();
-
error = -EINVAL;
if(cnt < (sizeof(struct sunos_direntry) + 255))
goto out_putf;
@@ -429,7 +422,6 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
}
out_putf:
- unlock_kernel();
fput(file);
out:
return error;