diff options
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/kernel/ebus.c | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/entry.S | 7 | ||||
-rw-r--r-- | arch/sparc/kernel/irq.c | 84 | ||||
-rw-r--r-- | arch/sparc/kernel/prom.c | 15 | ||||
-rw-r--r-- | arch/sparc/kernel/sparc_ksyms.c | 1 | ||||
-rw-r--r-- | arch/sparc/mm/io-unit.c | 18 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 12 | ||||
-rw-r--r-- | arch/sparc/mm/sun4c.c | 2 |
8 files changed, 93 insertions, 47 deletions
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index ac352eb6dff..e2d02fd13f3 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -238,6 +238,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d sd = &dev->ofdev.dev.archdata; sd->prom_node = dp; sd->op = &dev->ofdev; + sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index eac38388f5f..88d2cefd01b 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1,7 +1,6 @@ -/* $Id: entry.S,v 1.170 2001/11/13 00:57:05 davem Exp $ - * arch/sparc/kernel/entry.S: Sparc trap low-level entry points. +/* arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1996-1999 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -129,7 +128,7 @@ trap_low: RESTORE_ALL #endif -#ifdef CONFIG_BLK_DEV_FD +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) .text .align 4 .globl floppy_hardint diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index 75b2240ad0f..b76dc03fc31 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -351,34 +351,14 @@ void handler_irq(int irq, struct pt_regs * regs) set_irq_regs(old_regs); } -#ifdef CONFIG_BLK_DEV_FD -extern void floppy_interrupt(int irq, void *dev_id); - -void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - struct pt_regs *old_regs; - int cpu = smp_processor_id(); - - old_regs = set_irq_regs(regs); - disable_pil_irq(irq); - irq_enter(); - kstat_cpu(cpu).irqs[irq]++; - floppy_interrupt(irq, dev_id); - irq_exit(); - enable_pil_irq(irq); - set_irq_regs(old_regs); - // XXX Eek, it's totally changed with preempt_count() and such - // if (softirq_pending(cpu)) - // do_softirq(); -} -#endif +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) /* Fast IRQs on the Sparc can only have one routine attached to them, * thus no sharing possible. */ -int request_fast_irq(unsigned int irq, - irq_handler_t handler, - unsigned long irqflags, const char *devname) +static int request_fast_irq(unsigned int irq, + void (*handler)(void), + unsigned long irqflags, const char *devname) { struct irqaction *action; unsigned long flags; @@ -457,7 +437,6 @@ int request_fast_irq(unsigned int irq, */ flush_cache_all(); - action->handler = handler; action->flags = irqflags; cpus_clear(action->mask); action->name = devname; @@ -475,6 +454,61 @@ out: return ret; } +/* These variables are used to access state from the assembler + * interrupt handler, floppy_hardint, so we cannot put these in + * the floppy driver image because that would not work in the + * modular case. + */ +volatile unsigned char *fdc_status; +EXPORT_SYMBOL(fdc_status); + +char *pdma_vaddr; +EXPORT_SYMBOL(pdma_vaddr); + +unsigned long pdma_size; +EXPORT_SYMBOL(pdma_size); + +volatile int doing_pdma; +EXPORT_SYMBOL(doing_pdma); + +char *pdma_base; +EXPORT_SYMBOL(pdma_base); + +unsigned long pdma_areasize; +EXPORT_SYMBOL(pdma_areasize); + +extern void floppy_hardint(void); + +static irqreturn_t (*floppy_irq_handler)(int irq, void *dev_id); + +void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct pt_regs *old_regs; + int cpu = smp_processor_id(); + + old_regs = set_irq_regs(regs); + disable_pil_irq(irq); + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + floppy_irq_handler(irq, dev_id); + irq_exit(); + enable_pil_irq(irq); + set_irq_regs(old_regs); + // XXX Eek, it's totally changed with preempt_count() and such + // if (softirq_pending(cpu)) + // do_softirq(); +} + +int sparc_floppy_request_irq(int irq, unsigned long flags, + irqreturn_t (*irq_handler)(int irq, void *)) +{ + floppy_irq_handler = irq_handler; + return request_fast_irq(irq, floppy_hardint, flags, "floppy"); +} +EXPORT_SYMBOL(sparc_floppy_request_irq); + +#endif + int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char * devname, void *dev_id) diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 39fbd3c8ab0..cd4fb79aa3a 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -102,6 +102,21 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len } EXPORT_SYMBOL(of_set_property); +int of_find_in_proplist(const char *list, const char *match, int len) +{ + while (len > 0) { + int l; + + if (!strcmp(list, match)) + return 1; + l = strlen(list) + 1; + list += l; + len -= l; + } + return 0; +} +EXPORT_SYMBOL(of_find_in_proplist); + static unsigned int prom_early_allocated; static void * __init prom_early_alloc(unsigned long size) diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 7b4abde4302..ef647acc479 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -143,7 +143,6 @@ EXPORT_SYMBOL(mstk48t02_regs); EXPORT_SYMBOL(set_auxio); EXPORT_SYMBOL(get_auxio); #endif -EXPORT_SYMBOL(request_fast_irq); EXPORT_SYMBOL(io_remap_pfn_range); /* P3: iounit_xxx may be needed, sun4d users */ /* EXPORT_SYMBOL(iounit_map_dma_init); */ diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 4ccda77d08d..7c89893b1fe 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -66,7 +66,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) } if(!xpt) panic("Cannot map External Page Table."); - sbus->iommu = (struct iommu_struct *)iounit; + sbus->ofdev.dev.archdata.iommu = iounit; iounit->page_table = xpt; spin_lock_init(&iounit->lock); @@ -127,7 +127,7 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus *sbus) { unsigned long ret, flags; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; spin_lock_irqsave(&iounit->lock, flags); ret = iounit_get_area(iounit, (unsigned long)vaddr, len); @@ -138,7 +138,7 @@ static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) { unsigned long flags; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; /* FIXME: Cache some resolved pages - often several sg entries are to the same page */ spin_lock_irqsave(&iounit->lock, flags); @@ -153,7 +153,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) { unsigned long flags; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; spin_lock_irqsave(&iounit->lock, flags); len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; @@ -168,7 +168,7 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_ { unsigned long flags; unsigned long vaddr, len; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; spin_lock_irqsave(&iounit->lock, flags); while (sz != 0) { @@ -211,7 +211,7 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); for_each_sbus(sbus) { - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; iopte = (iopte_t *)(iounit->page_table + i); *iopte = MKIOPTE(__pa(page)); @@ -235,7 +235,7 @@ static void iounit_unmap_dma_area(unsigned long addr, int len) static struct page *iounit_translate_dvma(unsigned long addr) { struct sbus_bus *sbus = sbus_root; /* They are all the same */ - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; int i; iopte_t *iopte; @@ -279,7 +279,7 @@ __u32 iounit_map_dma_init(struct sbus_bus *sbus, int size) unsigned long rotor, scan, limit; unsigned long flags; __u32 ret; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT; i = 0x0213; @@ -315,7 +315,7 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); __u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus) { int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK)); return vaddr + (((unsigned long)addr) & ~PAGE_MASK); diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index be042efd1ba..52e907af9d2 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -132,7 +132,7 @@ iommu_init(int iommund, struct sbus_bus *sbus) impl, vers, iommu->page_table, (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); - sbus->iommu = iommu; + sbus->ofdev.dev.archdata.iommu = iommu; } /* This begs to be btfixup-ed by srmmu. */ @@ -166,7 +166,7 @@ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte) static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus) { - struct iommu_struct *iommu = sbus->iommu; + struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; int ioptex; iopte_t *iopte, *iopte0; unsigned int busa, busa0; @@ -291,7 +291,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) { - struct iommu_struct *iommu = sbus->iommu; + struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; int ioptex; int i; @@ -334,7 +334,7 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, unsigned long addr, int len) { unsigned long page, end; - struct iommu_struct *iommu = sbus_root->iommu; + struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; iopte_t *iopte = iommu->page_table; iopte_t *first; int ioptex; @@ -399,7 +399,7 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, static void iommu_unmap_dma_area(unsigned long busa, int len) { - struct iommu_struct *iommu = sbus_root->iommu; + struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; iopte_t *iopte = iommu->page_table; unsigned long end; int ioptex = (busa - iommu->start) >> PAGE_SHIFT; @@ -420,7 +420,7 @@ static void iommu_unmap_dma_area(unsigned long busa, int len) static struct page *iommu_translate_dvma(unsigned long busa) { - struct iommu_struct *iommu = sbus_root->iommu; + struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; iopte_t *iopte = iommu->page_table; iopte += ((busa - iommu->start) >> PAGE_SHIFT); diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 79d60d86f6f..005a3e72d4f 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -268,7 +268,6 @@ static inline void sun4c_init_clean_mmu(unsigned long kernel_end) unsigned char savectx, ctx; savectx = sun4c_get_context(); - kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end); for (ctx = 0; ctx < num_contexts; ctx++) { sun4c_set_context(ctx); for (vaddr = 0; vaddr < 0x20000000; vaddr += SUN4C_REAL_PGDIR_SIZE) @@ -2064,7 +2063,6 @@ void __init sun4c_paging_init(void) unsigned long end_pfn, pages_avail; kernel_end = (unsigned long) &end; - kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4); kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end); pages_avail = 0; |