From 2f3a2efd85b698e51e90f06a37d85066725fb4c4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 11 Apr 2007 21:38:45 -0700 Subject: [SPARC64]: Fix SBUS IOMMU allocation code. There are several IOMMU allocator bugs. Instead of trying to fix this overly complicated code, just mirror the PCI IOMMU arena allocator which is very stable and well stress tested. I tried to make the code as identical as possible so we can switch sun4u PCI and SBUS over to a common piece of IOMMU code. All that will be need are two callbacks, one to do a full IOMMU flush and one to do a streaming buffer flush. This patch gets rid of a lot of hangs and mysterious crashes on SBUS sparc64 systems, at least for me. Signed-off-by: David S. Miller --- arch/sparc64/kernel/sbus.c | 560 +++++++++++++++++++-------------------------- 1 file changed, 232 insertions(+), 328 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 01d6d869ea2..14f78fb5e89 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -24,48 +24,25 @@ #include "iommu_common.h" -/* These should be allocated on an SMP_CACHE_BYTES - * aligned boundary for optimal performance. - * - * On SYSIO, using an 8K page size we have 1GB of SBUS - * DMA space mapped. We divide this space into equally - * sized clusters. We allocate a DMA mapping from the - * cluster that matches the order of the allocation, or - * if the order is greater than the number of clusters, - * we try to allocate from the last cluster. - */ - -#define NCLUSTERS 8UL -#define ONE_GIG (1UL * 1024UL * 1024UL * 1024UL) -#define CLUSTER_SIZE (ONE_GIG / NCLUSTERS) -#define CLUSTER_MASK (CLUSTER_SIZE - 1) -#define CLUSTER_NPAGES (CLUSTER_SIZE >> IO_PAGE_SHIFT) #define MAP_BASE ((u32)0xc0000000) +struct sbus_iommu_arena { + unsigned long *map; + unsigned int hint; + unsigned int limit; +}; + struct sbus_iommu { -/*0x00*/spinlock_t lock; + spinlock_t lock; -/*0x08*/iopte_t *page_table; -/*0x10*/unsigned long strbuf_regs; -/*0x18*/unsigned long iommu_regs; -/*0x20*/unsigned long sbus_control_reg; + struct sbus_iommu_arena arena; -/*0x28*/volatile unsigned long strbuf_flushflag; + iopte_t *page_table; + unsigned long strbuf_regs; + unsigned long iommu_regs; + unsigned long sbus_control_reg; - /* If NCLUSTERS is ever decresed to 4 or lower, - * you must increase the size of the type of - * these counters. You have been duly warned. -DaveM - */ -/*0x30*/struct { - u16 next; - u16 flush; - } alloc_info[NCLUSTERS]; - - /* The lowest used consistent mapping entry. Since - * we allocate consistent maps out of cluster 0 this - * is relative to the beginning of closter 0. - */ -/*0x50*/u32 lowest_consistent_map; + volatile unsigned long strbuf_flushflag; }; /* Offsets from iommu_regs */ @@ -91,19 +68,6 @@ static void __iommu_flushall(struct sbus_iommu *iommu) tag += 8UL; } upa_readq(iommu->sbus_control_reg); - - for (entry = 0; entry < NCLUSTERS; entry++) { - iommu->alloc_info[entry].flush = - iommu->alloc_info[entry].next; - } -} - -static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) -{ - while (npages--) - upa_writeq(base + (npages << IO_PAGE_SHIFT), - iommu->iommu_regs + IOMMU_FLUSH); - upa_readq(iommu->sbus_control_reg); } /* Offsets from strbuf_regs */ @@ -156,178 +120,115 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long base, npages); } -static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) +/* Based largely upon the ppc64 iommu allocator. */ +static long sbus_arena_alloc(struct sbus_iommu *iommu, unsigned long npages) { - iopte_t *iopte, *limit, *first, *cluster; - unsigned long cnum, ent, nent, flush_point, found; - - cnum = 0; - nent = 1; - while ((1UL << cnum) < npages) - cnum++; - if(cnum >= NCLUSTERS) { - nent = 1UL << (cnum - NCLUSTERS); - cnum = NCLUSTERS - 1; - } - iopte = iommu->page_table + (cnum * CLUSTER_NPAGES); - - if (cnum == 0) - limit = (iommu->page_table + - iommu->lowest_consistent_map); - else - limit = (iopte + CLUSTER_NPAGES); - - iopte += ((ent = iommu->alloc_info[cnum].next) << cnum); - flush_point = iommu->alloc_info[cnum].flush; - - first = iopte; - cluster = NULL; - found = 0; - for (;;) { - if (iopte_val(*iopte) == 0UL) { - found++; - if (!cluster) - cluster = iopte; + struct sbus_iommu_arena *arena = &iommu->arena; + unsigned long n, i, start, end, limit; + int pass; + + limit = arena->limit; + start = arena->hint; + pass = 0; + +again: + n = find_next_zero_bit(arena->map, limit, start); + end = n + npages; + if (unlikely(end >= limit)) { + if (likely(pass < 1)) { + limit = start; + start = 0; + __iommu_flushall(iommu); + pass++; + goto again; } else { - /* Used cluster in the way */ - cluster = NULL; - found = 0; + /* Scanned the whole thing, give up. */ + return -1; } + } - if (found == nent) - break; - - iopte += (1 << cnum); - ent++; - if (iopte >= limit) { - iopte = (iommu->page_table + (cnum * CLUSTER_NPAGES)); - ent = 0; - - /* Multiple cluster allocations must not wrap */ - cluster = NULL; - found = 0; + for (i = n; i < end; i++) { + if (test_bit(i, arena->map)) { + start = i + 1; + goto again; } - if (ent == flush_point) - __iommu_flushall(iommu); - if (iopte == first) - goto bad; } - /* ent/iopte points to the last cluster entry we're going to use, - * so save our place for the next allocation. - */ - if ((iopte + (1 << cnum)) >= limit) - ent = 0; - else - ent = ent + 1; - iommu->alloc_info[cnum].next = ent; - if (ent == flush_point) - __iommu_flushall(iommu); - - /* I've got your streaming cluster right here buddy boy... */ - return cluster; - -bad: - printk(KERN_EMERG "sbus: alloc_streaming_cluster of npages(%ld) failed!\n", - npages); - return NULL; + for (i = n; i < end; i++) + __set_bit(i, arena->map); + + arena->hint = end; + + return n; } -static void free_streaming_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages) +static void sbus_arena_free(struct sbus_iommu_arena *arena, unsigned long base, unsigned long npages) { - unsigned long cnum, ent, nent; - iopte_t *iopte; + unsigned long i; - cnum = 0; - nent = 1; - while ((1UL << cnum) < npages) - cnum++; - if(cnum >= NCLUSTERS) { - nent = 1UL << (cnum - NCLUSTERS); - cnum = NCLUSTERS - 1; - } - ent = (base & CLUSTER_MASK) >> (IO_PAGE_SHIFT + cnum); - iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT); - do { - iopte_val(*iopte) = 0UL; - iopte += 1 << cnum; - } while(--nent); - - /* If the global flush might not have caught this entry, - * adjust the flush point such that we will flush before - * ever trying to reuse it. - */ -#define between(X,Y,Z) (((Z) - (Y)) >= ((X) - (Y))) - if (between(ent, iommu->alloc_info[cnum].next, iommu->alloc_info[cnum].flush)) - iommu->alloc_info[cnum].flush = ent; -#undef between + for (i = base; i < (base + npages); i++) + __clear_bit(i, arena->map); } -/* We allocate consistent mappings from the end of cluster zero. */ -static iopte_t *alloc_consistent_cluster(struct sbus_iommu *iommu, unsigned long npages) +static void sbus_iommu_table_init(struct sbus_iommu *iommu, unsigned int tsbsize) { - iopte_t *iopte; + unsigned long tsbbase, order, sz, num_tsb_entries; - iopte = iommu->page_table + (1 * CLUSTER_NPAGES); - while (iopte > iommu->page_table) { - iopte--; - if (!(iopte_val(*iopte) & IOPTE_VALID)) { - unsigned long tmp = npages; + num_tsb_entries = tsbsize / sizeof(iopte_t); - while (--tmp) { - iopte--; - if (iopte_val(*iopte) & IOPTE_VALID) - break; - } - if (tmp == 0) { - u32 entry = (iopte - iommu->page_table); + /* Setup initial software IOMMU state. */ + spin_lock_init(&iommu->lock); - if (entry < iommu->lowest_consistent_map) - iommu->lowest_consistent_map = entry; - return iopte; - } - } + /* Allocate and initialize the free area map. */ + sz = num_tsb_entries / 8; + sz = (sz + 7UL) & ~7UL; + iommu->arena.map = kzalloc(sz, GFP_KERNEL); + if (!iommu->arena.map) { + prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); + prom_halt(); + } + iommu->arena.limit = num_tsb_entries; + + /* Now allocate and setup the IOMMU page table itself. */ + order = get_order(tsbsize); + tsbbase = __get_free_pages(GFP_KERNEL, order); + if (!tsbbase) { + prom_printf("IOMMU: Error, gfp(tsb) failed.\n"); + prom_halt(); } - return NULL; + iommu->page_table = (iopte_t *)tsbbase; + memset(iommu->page_table, 0, tsbsize); } -static void free_consistent_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages) +static inline iopte_t *alloc_npages(struct sbus_iommu *iommu, unsigned long npages) { - iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT); + long entry; - if ((iopte - iommu->page_table) == iommu->lowest_consistent_map) { - iopte_t *walk = iopte + npages; - iopte_t *limit; + entry = sbus_arena_alloc(iommu, npages); + if (unlikely(entry < 0)) + return NULL; - limit = iommu->page_table + CLUSTER_NPAGES; - while (walk < limit) { - if (iopte_val(*walk) != 0UL) - break; - walk++; - } - iommu->lowest_consistent_map = - (walk - iommu->page_table); - } + return iommu->page_table + entry; +} - while (npages--) - *iopte++ = __iopte(0UL); +static inline void free_npages(struct sbus_iommu *iommu, dma_addr_t base, unsigned long npages) +{ + sbus_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages); } void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr) { - unsigned long order, first_page, flags; struct sbus_iommu *iommu; iopte_t *iopte; + unsigned long flags, order, first_page; void *ret; int npages; - if (size <= 0 || sdev == NULL || dvma_addr == NULL) - return NULL; - size = IO_PAGE_ALIGN(size); order = get_order(size); if (order >= 10) return NULL; + first_page = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); if (first_page == 0UL) return NULL; @@ -336,108 +237,121 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma iommu = sdev->bus->iommu; spin_lock_irqsave(&iommu->lock, flags); - iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT); - if (iopte == NULL) { - spin_unlock_irqrestore(&iommu->lock, flags); + iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT); + spin_unlock_irqrestore(&iommu->lock, flags); + + if (unlikely(iopte == NULL)) { free_pages(first_page, order); return NULL; } - /* Ok, we're committed at this point. */ - *dvma_addr = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT); + *dvma_addr = (MAP_BASE + + ((iopte - iommu->page_table) << IO_PAGE_SHIFT)); ret = (void *) first_page; npages = size >> IO_PAGE_SHIFT; + first_page = __pa(first_page); while (npages--) { - *iopte++ = __iopte(IOPTE_VALID | IOPTE_CACHE | IOPTE_WRITE | - (__pa(first_page) & IOPTE_PAGE)); + iopte_val(*iopte) = (IOPTE_VALID | IOPTE_CACHE | + IOPTE_WRITE | + (first_page & IOPTE_PAGE)); + iopte++; first_page += IO_PAGE_SIZE; } - iommu_flush(iommu, *dvma_addr, size >> IO_PAGE_SHIFT); - spin_unlock_irqrestore(&iommu->lock, flags); return ret; } void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma) { - unsigned long order, npages; struct sbus_iommu *iommu; - - if (size <= 0 || sdev == NULL || cpu == NULL) - return; + iopte_t *iopte; + unsigned long flags, order, npages; npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; iommu = sdev->bus->iommu; + iopte = iommu->page_table + + ((dvma - MAP_BASE) >> IO_PAGE_SHIFT); + + spin_lock_irqsave(&iommu->lock, flags); + + free_npages(iommu, dvma - MAP_BASE, npages); - spin_lock_irq(&iommu->lock); - free_consistent_cluster(iommu, dvma, npages); - iommu_flush(iommu, dvma, npages); - spin_unlock_irq(&iommu->lock); + spin_unlock_irqrestore(&iommu->lock, flags); order = get_order(size); if (order < 10) free_pages((unsigned long)cpu, order); } -dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int dir) +dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t sz, int direction) { - struct sbus_iommu *iommu = sdev->bus->iommu; - unsigned long npages, pbase, flags; - iopte_t *iopte; - u32 dma_base, offset; - unsigned long iopte_bits; + struct sbus_iommu *iommu; + iopte_t *base; + unsigned long flags, npages, oaddr; + unsigned long i, base_paddr; + u32 bus_addr, ret; + unsigned long iopte_protection; + + iommu = sdev->bus->iommu; - if (dir == SBUS_DMA_NONE) + if (unlikely(direction == SBUS_DMA_NONE)) BUG(); - pbase = (unsigned long) ptr; - offset = (u32) (pbase & ~IO_PAGE_MASK); - size = (IO_PAGE_ALIGN(pbase + size) - (pbase & IO_PAGE_MASK)); - pbase = (unsigned long) __pa(pbase & IO_PAGE_MASK); + oaddr = (unsigned long)ptr; + npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); + npages >>= IO_PAGE_SHIFT; spin_lock_irqsave(&iommu->lock, flags); - npages = size >> IO_PAGE_SHIFT; - iopte = alloc_streaming_cluster(iommu, npages); - if (iopte == NULL) - goto bad; - dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT); - npages = size >> IO_PAGE_SHIFT; - iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; - if (dir != SBUS_DMA_TODEVICE) - iopte_bits |= IOPTE_WRITE; - while (npages--) { - *iopte++ = __iopte(iopte_bits | (pbase & IOPTE_PAGE)); - pbase += IO_PAGE_SIZE; - } - npages = size >> IO_PAGE_SHIFT; + base = alloc_npages(iommu, npages); spin_unlock_irqrestore(&iommu->lock, flags); - return (dma_base | offset); + if (unlikely(!base)) + BUG(); -bad: - spin_unlock_irqrestore(&iommu->lock, flags); - BUG(); - return 0; + bus_addr = (MAP_BASE + + ((base - iommu->page_table) << IO_PAGE_SHIFT)); + ret = bus_addr | (oaddr & ~IO_PAGE_MASK); + base_paddr = __pa(oaddr & IO_PAGE_MASK); + + iopte_protection = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; + if (direction != SBUS_DMA_TODEVICE) + iopte_protection |= IOPTE_WRITE; + + for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE) + iopte_val(*base) = iopte_protection | base_paddr; + + return ret; } -void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, int direction) +void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction) { struct sbus_iommu *iommu = sdev->bus->iommu; - u32 dma_base = dma_addr & IO_PAGE_MASK; - unsigned long flags; + iopte_t *base; + unsigned long flags, npages, i; + + if (unlikely(direction == SBUS_DMA_NONE)) + BUG(); + + npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); + npages >>= IO_PAGE_SHIFT; + base = iommu->page_table + + ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT); - size = (IO_PAGE_ALIGN(dma_addr + size) - dma_base); + bus_addr &= IO_PAGE_MASK; spin_lock_irqsave(&iommu->lock, flags); - free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); - sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction); + sbus_strbuf_flush(iommu, bus_addr, npages, direction); + for (i = 0; i < npages; i++) + iopte_val(base[i]) = 0UL; + free_npages(iommu, bus_addr - MAP_BASE, npages); spin_unlock_irqrestore(&iommu->lock, flags); } #define SG_ENT_PHYS_ADDRESS(SG) \ (__pa(page_address((SG)->page)) + (SG)->offset) -static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, int nelems, unsigned long iopte_bits) +static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, + int nused, int nelems, unsigned long iopte_protection) { struct scatterlist *dma_sg = sg; struct scatterlist *sg_end = sg + nelems; @@ -462,7 +376,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in for (;;) { unsigned long tmp; - tmp = (unsigned long) SG_ENT_PHYS_ADDRESS(sg); + tmp = SG_ENT_PHYS_ADDRESS(sg); len = sg->length; if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) { pteval = tmp & IO_PAGE_MASK; @@ -478,7 +392,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in sg++; } - pteval = ((pteval & IOPTE_PAGE) | iopte_bits); + pteval = iopte_protection | (pteval & IOPTE_PAGE); while (len > 0) { *iopte++ = __iopte(pteval); pteval += IO_PAGE_SIZE; @@ -509,103 +423,111 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in } } -int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int dir) +int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) { - struct sbus_iommu *iommu = sdev->bus->iommu; - unsigned long flags, npages; - iopte_t *iopte; + struct sbus_iommu *iommu; + unsigned long flags, npages, iopte_protection; + iopte_t *base; u32 dma_base; struct scatterlist *sgtmp; int used; - unsigned long iopte_bits; - - if (dir == SBUS_DMA_NONE) - BUG(); /* Fast path single entry scatterlists. */ - if (nents == 1) { - sg->dma_address = + if (nelems == 1) { + sglist->dma_address = sbus_map_single(sdev, - (page_address(sg->page) + sg->offset), - sg->length, dir); - sg->dma_length = sg->length; + (page_address(sglist->page) + sglist->offset), + sglist->length, direction); + sglist->dma_length = sglist->length; return 1; } - npages = prepare_sg(sg, nents); + iommu = sdev->bus->iommu; + + if (unlikely(direction == SBUS_DMA_NONE)) + BUG(); + + npages = prepare_sg(sglist, nelems); spin_lock_irqsave(&iommu->lock, flags); - iopte = alloc_streaming_cluster(iommu, npages); - if (iopte == NULL) - goto bad; - dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT); + base = alloc_npages(iommu, npages); + spin_unlock_irqrestore(&iommu->lock, flags); + + if (unlikely(base == NULL)) + BUG(); + + dma_base = MAP_BASE + + ((base - iommu->page_table) << IO_PAGE_SHIFT); /* Normalize DVMA addresses. */ - sgtmp = sg; - used = nents; + used = nelems; + sgtmp = sglist; while (used && sgtmp->dma_length) { sgtmp->dma_address += dma_base; sgtmp++; used--; } - used = nents - used; + used = nelems - used; - iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; - if (dir != SBUS_DMA_TODEVICE) - iopte_bits |= IOPTE_WRITE; + iopte_protection = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; + if (direction != SBUS_DMA_TODEVICE) + iopte_protection |= IOPTE_WRITE; + + fill_sg(base, sglist, used, nelems, iopte_protection); - fill_sg(iopte, sg, used, nents, iopte_bits); #ifdef VERIFY_SG - verify_sglist(sg, nents, iopte, npages); + verify_sglist(sglist, nelems, base, npages); #endif - spin_unlock_irqrestore(&iommu->lock, flags); return used; - -bad: - spin_unlock_irqrestore(&iommu->lock, flags); - BUG(); - return 0; } -void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction) +void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) { - unsigned long size, flags; struct sbus_iommu *iommu; - u32 dvma_base; - int i; + iopte_t *base; + unsigned long flags, i, npages; + u32 bus_addr; - /* Fast path single entry scatterlists. */ - if (nents == 1) { - sbus_unmap_single(sdev, sg->dma_address, sg->dma_length, direction); - return; - } + if (unlikely(direction == SBUS_DMA_NONE)) + BUG(); + + iommu = sdev->bus->iommu; + + bus_addr = sglist->dma_address & IO_PAGE_MASK; - dvma_base = sg[0].dma_address & IO_PAGE_MASK; - for (i = 0; i < nents; i++) { - if (sg[i].dma_length == 0) + for (i = 1; i < nelems; i++) + if (sglist[i].dma_length == 0) break; - } i--; - size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - dvma_base; + npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - + bus_addr) >> IO_PAGE_SHIFT; + + base = iommu->page_table + + ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT); - iommu = sdev->bus->iommu; spin_lock_irqsave(&iommu->lock, flags); - free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); - sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction); + sbus_strbuf_flush(iommu, bus_addr, npages, direction); + for (i = 0; i < npages; i++) + iopte_val(base[i]) = 0UL; + free_npages(iommu, bus_addr - MAP_BASE, npages); spin_unlock_irqrestore(&iommu->lock, flags); } -void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t size, int direction) +void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct sbus_iommu *iommu = sdev->bus->iommu; - unsigned long flags; + struct sbus_iommu *iommu; + unsigned long flags, npages; + + iommu = sdev->bus->iommu; - size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); + npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); + npages >>= IO_PAGE_SHIFT; + bus_addr &= IO_PAGE_MASK; spin_lock_irqsave(&iommu->lock, flags); - sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction); + sbus_strbuf_flush(iommu, bus_addr, npages, direction); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -613,23 +535,25 @@ void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t base, siz { } -void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction) +void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) { - struct sbus_iommu *iommu = sdev->bus->iommu; - unsigned long flags, size; - u32 base; - int i; + struct sbus_iommu *iommu; + unsigned long flags, npages, i; + u32 bus_addr; + + iommu = sdev->bus->iommu; - base = sg[0].dma_address & IO_PAGE_MASK; - for (i = 0; i < nents; i++) { - if (sg[i].dma_length == 0) + bus_addr = sglist[0].dma_address & IO_PAGE_MASK; + for (i = 0; i < nelems; i++) { + if (!sglist[i].dma_length) break; } i--; - size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; + npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) + - bus_addr) >> IO_PAGE_SHIFT; spin_lock_irqsave(&iommu->lock, flags); - sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction); + sbus_strbuf_flush(iommu, bus_addr, npages, direction); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -1104,7 +1028,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) struct linux_prom64_registers *pr; struct device_node *dp; struct sbus_iommu *iommu; - unsigned long regs, tsb_base; + unsigned long regs; u64 control; int i; @@ -1132,14 +1056,6 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) memset(iommu, 0, sizeof(*iommu)); - /* We start with no consistent mappings. */ - iommu->lowest_consistent_map = CLUSTER_NPAGES; - - for (i = 0; i < NCLUSTERS; i++) { - iommu->alloc_info[i].flush = 0; - iommu->alloc_info[i].next = 0; - } - /* Setup spinlock. */ spin_lock_init(&iommu->lock); @@ -1159,25 +1075,13 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) sbus->portid, regs); /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */ + sbus_iommu_table_init(iommu, IO_TSB_SIZE); + control = upa_readq(iommu->iommu_regs + IOMMU_CONTROL); control = ((7UL << 16UL) | (0UL << 2UL) | (1UL << 1UL) | (1UL << 0UL)); - - /* Using the above configuration we need 1MB iommu page - * table (128K ioptes * 8 bytes per iopte). This is - * page order 7 on UltraSparc. - */ - tsb_base = __get_free_pages(GFP_ATOMIC, get_order(IO_TSB_SIZE)); - if (tsb_base == 0UL) { - prom_printf("sbus_iommu_init: Fatal error, cannot alloc TSB table.\n"); - prom_halt(); - } - - iommu->page_table = (iopte_t *) tsb_base; - memset(iommu->page_table, 0, IO_TSB_SIZE); - upa_writeq(control, iommu->iommu_regs + IOMMU_CONTROL); /* Clean out any cruft in the IOMMU using @@ -1195,7 +1099,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) upa_readq(iommu->sbus_control_reg); /* Give the TSB to SYSIO. */ - upa_writeq(__pa(tsb_base), iommu->iommu_regs + IOMMU_TSBBASE); + upa_writeq(__pa(iommu->page_table), iommu->iommu_regs + IOMMU_TSBBASE); /* Setup streaming buffer, DE=1 SB_EN=1 */ control = (1UL << 1UL) | (1UL << 0UL); -- cgit v1.2.3 From 6df7d40682242b52c3ed1ea4bbdb594c2d8737c5 Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Tue, 10 Apr 2007 21:51:53 +0400 Subject: [PPC] MPC8272 ADS compile fixed, defconfig refreshed. Fix compilation of mpc8272ads_setup.c Signed-off-by: Vitaly Bordug Signed-off-by: Kumar Gala --- arch/ppc/configs/ads8272_defconfig | 592 +++++++++++++++++++++++++++------- arch/ppc/platforms/mpc8272ads_setup.c | 17 +- 2 files changed, 479 insertions(+), 130 deletions(-) (limited to 'arch') diff --git a/arch/ppc/configs/ads8272_defconfig b/arch/ppc/configs/ads8272_defconfig index d1db7d14780..6619f9118b0 100644 --- a/arch/ppc/configs/ads8272_defconfig +++ b/arch/ppc/configs/ads8272_defconfig @@ -1,109 +1,194 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc5 +# Wed Apr 4 20:55:16 2007 # CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_HAVE_DEC_LOCK=y +CONFIG_ARCH_HAS_ILOG2_U32=y +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_PPC=y CONFIG_PPC32=y CONFIG_GENERIC_NVRAM=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_HOTPLUG is not set # CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y # CONFIG_EPOLL is not set -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support # # CONFIG_MODULES is not set +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + # # Processor # CONFIG_6xx=y # CONFIG_40x is not set # CONFIG_44x is not set -# CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set +# CONFIG_E200 is not set +# CONFIG_E500 is not set +CONFIG_PPC_FPU=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_KEXEC is not set # CONFIG_CPU_FREQ is not set +# CONFIG_WANT_EARLY_SERIAL is not set CONFIG_EMBEDDEDBOOT=y CONFIG_PPC_STD_MMU=y # # Platform options # -# CONFIG_PPC_MULTIPLATFORM is not set + +# +# Freescale Ethernet driver platform-specific options +# +# CONFIG_PPC_PREP is not set # CONFIG_APUS is not set +# CONFIG_KATANA is not set # CONFIG_WILLOW is not set -# CONFIG_PCORE is not set +# CONFIG_CPCI690 is not set # CONFIG_POWERPMC250 is not set -# CONFIG_EV64260 is not set +# CONFIG_CHESTNUT is not set # CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set # CONFIG_LOPEC is not set -# CONFIG_MCPN765 is not set # CONFIG_MVME5100 is not set # CONFIG_PPLUS is not set # CONFIG_PRPMC750 is not set # CONFIG_PRPMC800 is not set # CONFIG_SANDPOINT is not set -# CONFIG_ADIR is not set -# CONFIG_K2 is not set +# CONFIG_RADSTONE_PPC7D is not set # CONFIG_PAL4 is not set -# CONFIG_GEMINI is not set # CONFIG_EST8260 is not set # CONFIG_SBC82xx is not set # CONFIG_SBS8260 is not set -# CONFIG_RPX6 is not set +# CONFIG_RPX8260 is not set # CONFIG_TQM8260 is not set CONFIG_ADS8272=y +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_MPC834x_SYS is not set +# CONFIG_EV64360 is not set CONFIG_PQ2ADS=y CONFIG_8260=y CONFIG_8272=y CONFIG_CPM2=y # CONFIG_PC_KEYBOARD is not set -CONFIG_SERIAL_CONSOLE=y # CONFIG_SMP is not set -# CONFIG_PREEMPT is not set # CONFIG_HIGHMEM is not set -CONFIG_KERNEL_ELF=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y +# CONFIG_PPC_I8259 is not set +CONFIG_PPC_INDIRECT_PCI=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set -# CONFIG_PCI_NAMES is not set +CONFIG_PCI_8260=y + +# +# PCCARD (PCMCIA/CardBus) support +# # # Advanced setup @@ -119,6 +204,96 @@ CONFIG_KERNEL_START=0xc0000000 CONFIG_TASK_SIZE=0x80000000 CONFIG_BOOT_LOAD=0x00400000 +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + # # Device Drivers # @@ -126,6 +301,14 @@ CONFIG_BOOT_LOAD=0x00400000 # # Generic Driver Options # +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -140,6 +323,7 @@ CONFIG_BOOT_LOAD=0x00400000 # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -149,14 +333,23 @@ CONFIG_BOOT_LOAD=0x00400000 # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_CARMEL is not set +# CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_LBD is not set +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set # # ATA/ATAPI/MFM/RLL support @@ -166,7 +359,14 @@ CONFIG_BLK_DEV_INITRD=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -176,6 +376,7 @@ CONFIG_BLK_DEV_INITRD=y # # Fusion MPT device support # +# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -190,70 +391,12 @@ CONFIG_BLK_DEV_INITRD=y # # Macintosh device drivers # +# CONFIG_MAC_EMUMOUSEBTN is not set +# CONFIG_WINDFARM is not set # -# Networking support -# -CONFIG_NET=y - -# -# Networking options +# Network device support # -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -265,14 +408,32 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set +# +# PHY device support +# +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +CONFIG_DAVICOM_PHY=y +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_FIXED_PHY is not set + # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_OAKNET is not set +CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # @@ -281,6 +442,9 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set +CONFIG_FS_ENET=y +# CONFIG_FS_ENET_HAS_SCC is not set +CONFIG_FS_ENET_HAS_FCC=y # # Ethernet (1000 Mbit) @@ -292,14 +456,24 @@ CONFIG_NET_ETHERNET=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -321,6 +495,8 @@ CONFIG_NET_ETHERNET=y # CONFIG_SLIP is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -336,6 +512,7 @@ CONFIG_NET_ETHERNET=y # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -346,14 +523,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -# CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set - # # Input Device Drivers # @@ -363,6 +532,12 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -377,10 +552,21 @@ CONFIG_SOUND_GAMEPORT=y # # Non-8250 serial port support # +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_CPM=y +CONFIG_SERIAL_CPM_CONSOLE=y +CONFIG_SERIAL_CPM_SCC1=y +# CONFIG_SERIAL_CPM_SCC2 is not set +# CONFIG_SERIAL_CPM_SCC3 is not set +CONFIG_SERIAL_CPM_SCC4=y +# CONFIG_SERIAL_CPM_SMC1 is not set +# CONFIG_SERIAL_CPM_SMC2 is not set +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_QIC02_TAPE is not set # # IPMI @@ -391,29 +577,53 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + # # I2C support # # CONFIG_I2C is not set # -# Misc devices +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + # +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set # # Multimedia devices @@ -428,43 +638,120 @@ CONFIG_GEN_RTC=y # # Graphics support # +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_FB is not set +# CONFIG_FB_IBM_GXT4500 is not set # # Sound # # CONFIG_SOUND is not set +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB is not set +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + # # USB Gadget Support # # CONFIG_USB_GADGET is not set +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -475,7 +762,8 @@ CONFIG_FS_MBCACHE=y # # DOS/FAT/NT Filesystems # -# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set # CONFIG_NTFS_FS is not set # @@ -483,12 +771,13 @@ CONFIG_FS_MBCACHE=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -511,20 +800,26 @@ CONFIG_RAMFS=y # Network File Systems # CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y -# CONFIG_EXPORTFS is not set +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -537,46 +832,99 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set # CONFIG_LDM_PARTITION is not set -# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # # Native Language Support # # CONFIG_NLS is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set # CONFIG_SCC_ENET is not set -CONFIG_FEC_ENET=y -# CONFIG_USE_MDIO is not set +# CONFIG_FEC_ENET is not set # # CPM2 Options # -CONFIG_SCC_CONSOLE=y -CONFIG_FCC1_ENET=y -# CONFIG_FCC2_ENET is not set -# CONFIG_FCC3_ENET is not set # # Library routines # +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set # CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +# CONFIG_PROFILING is not set # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_KGDB_CONSOLE is not set # # Security options # +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # # Cryptographic options # -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c index 0bc06768cf2..47f4b38edb5 100644 --- a/arch/ppc/platforms/mpc8272ads_setup.c +++ b/arch/ppc/platforms/mpc8272ads_setup.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -30,10 +31,10 @@ #include "pq2ads_pd.h" -static void init_fcc1_ioports(void); -static void init_fcc2_ioports(void); -static void init_scc1_uart_ioports(void); -static void init_scc4_uart_ioports(void); +static void init_fcc1_ioports(struct fs_platform_info*); +static void init_fcc2_ioports(struct fs_platform_info*); +static void init_scc1_uart_ioports(struct fs_uart_platform_info*); +static void init_scc4_uart_ioports(struct fs_uart_platform_info*); static struct fs_uart_platform_info mpc8272_uart_pdata[] = { [fsid_scc1_uart] = { @@ -103,7 +104,7 @@ static struct fs_platform_info mpc82xx_enet_pdata[] = { }, }; -static void init_fcc1_ioports(struct fs_platform_info*) +static void init_fcc1_ioports(struct fs_platform_info* pdata) { struct io_port *io; u32 tempval; @@ -144,7 +145,7 @@ static void init_fcc1_ioports(struct fs_platform_info*) iounmap(immap); } -static void init_fcc2_ioports(struct fs_platform_info*) +static void init_fcc2_ioports(struct fs_platform_info* pdata) { cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32)); @@ -229,7 +230,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev, } } -static void init_scc1_uart_ioports(struct fs_uart_platform_info*) +static void init_scc1_uart_ioports(struct fs_uart_platform_info* pdata) { cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); @@ -246,7 +247,7 @@ static void init_scc1_uart_ioports(struct fs_uart_platform_info*) iounmap(immap); } -static void init_scc4_uart_ioports(struct fs_uart_platform_info*) +static void init_scc4_uart_ioports(struct fs_uart_platform_info* pdata) { cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); -- cgit v1.2.3 From fa76abac9271e314c02aff9b407116b783e0ccbb Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Tue, 10 Apr 2007 21:52:02 +0400 Subject: [PPC] Fix compilation and linking errors of mpc885ads build. Fix compilation of mpc885ads_setup.c Signed-off-by: Vitaly Bordug Signed-off-by: Kumar Gala --- arch/ppc/platforms/mpc885ads_setup.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c index f8161f3557f..87deaefd6c5 100644 --- a/arch/ppc/platforms/mpc885ads_setup.c +++ b/arch/ppc/platforms/mpc885ads_setup.c @@ -35,13 +35,13 @@ #include extern unsigned char __res[]; -static void setup_smc1_ioports(void); -static void setup_smc2_ioports(void); +static void setup_smc1_ioports(struct fs_uart_platform_info*); +static void setup_smc2_ioports(struct fs_uart_platform_info*); static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; -static void setup_fec1_ioports(void); -static void setup_fec2_ioports(void); -static void setup_scc3_ioports(void); +static void setup_fec1_ioports(struct fs_platform_info*); +static void setup_fec2_ioports(struct fs_platform_info*); +static void setup_scc3_ioports(struct fs_platform_info*); static struct fs_uart_platform_info mpc885_uart_pdata[] = { [fsid_smc1_uart] = { @@ -161,7 +161,7 @@ void __init board_init(void) #endif } -static void setup_fec1_ioports(struct fs_platform_info*) +static void setup_fec1_ioports(struct fs_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -181,7 +181,7 @@ static void setup_fec1_ioports(struct fs_platform_info*) clrbits32(&immap->im_cpm.cp_cptr, 0x00000100); } -static void setup_fec2_ioports(struct fs_platform_info*) +static void setup_fec2_ioports(struct fs_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -193,7 +193,7 @@ static void setup_fec2_ioports(struct fs_platform_info*) clrbits32(&immap->im_cpm.cp_cptr, 0x00000080); } -static void setup_scc3_ioports(struct fs_platform_info*) +static void setup_scc3_ioports(struct fs_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -315,7 +315,7 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev, mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); } -static void setup_smc1_ioports(struct fs_uart_platform_info*) +static void setup_smc1_ioports(struct fs_uart_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -335,7 +335,7 @@ static void setup_smc1_ioports(struct fs_uart_platform_info*) clrbits16(&immap->im_cpm.cp_pbodr, iobits); } -static void setup_smc2_ioports(struct fs_uart_platform_info*) +static void setup_smc2_ioports(struct fs_uart_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; -- cgit v1.2.3 From 7a6491dffb5bf86ae86c90895c0f40aacceb7083 Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Tue, 10 Apr 2007 21:52:04 +0400 Subject: [PPC] Fix compilation and linking errors of mpc86xads build. Fix compilation of mpc866ads_setup.c Signed-off-by: Vitaly Bordug Signed-off-by: Kumar Gala --- arch/ppc/8xx_io/commproc.c | 26 ++++++++++++++++++++++++++ arch/ppc/platforms/mpc866ads_setup.c | 17 +++++++++-------- 2 files changed, 35 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index 3b23bcb35b7..7a8722beac1 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c @@ -39,6 +39,21 @@ #include #include +#define immr_map(member) \ +({ \ + u32 offset = offsetof(immap_t, member); \ + void *addr = ioremap (IMAP_ADDR + offset, \ + sizeof( ((immap_t*)0)->member)); \ + addr; \ +}) + +#define immr_map_size(member, size) \ +({ \ + u32 offset = offsetof(immap_t, member); \ + void *addr = ioremap (IMAP_ADDR + offset, size); \ + addr; \ +}) + static void m8xx_cpm_dpinit(void); static uint host_buffer; /* One page of host buffer */ static uint host_end; /* end + 1 */ @@ -364,11 +379,16 @@ static rh_block_t cpm_boot_dpmem_rh_block[16]; static rh_info_t cpm_dpmem_info; #define CPM_DPMEM_ALIGNMENT 8 +static u8* dpram_vbase; +static uint dpram_pbase; void m8xx_cpm_dpinit(void) { spin_lock_init(&cpm_dpmem_lock); + dpram_vbase = immr_map_size(im_cpm.cp_dpmem, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE); + dpram_pbase = (uint)&((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem; + /* Initialize the info header */ rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT, sizeof(cpm_boot_dpmem_rh_block) / @@ -442,3 +462,9 @@ void *cpm_dpram_addr(uint offset) return ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem + offset; } EXPORT_SYMBOL(cpm_dpram_addr); + +uint cpm_dpram_phys(u8* addr) +{ + return (dpram_pbase + (uint)(addr - dpram_vbase)); +} +EXPORT_SYMBOL(cpm_dpram_phys); diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c index 5b05d4bd0df..7ce5364fdb3 100644 --- a/arch/ppc/platforms/mpc866ads_setup.c +++ b/arch/ppc/platforms/mpc866ads_setup.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -37,10 +38,10 @@ extern unsigned char __res[]; -static void setup_fec1_ioports(void); -static void setup_scc1_ioports(void); -static void setup_smc1_ioports(void); -static void setup_smc2_ioports(void); +static void setup_fec1_ioports(struct fs_platform_info*); +static void setup_scc1_ioports(struct fs_platform_info*); +static void setup_smc1_ioports(struct fs_uart_platform_info*); +static void setup_smc2_ioports(struct fs_uart_platform_info*); static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; @@ -137,7 +138,7 @@ void __init board_init(void) iounmap(bcsr_io); } -static void setup_fec1_ioports(struct fs_platform_info*) +static void setup_fec1_ioports(struct fs_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -145,7 +146,7 @@ static void setup_fec1_ioports(struct fs_platform_info*) setbits16(&immap->im_ioport.iop_pddir, 0x1fff); } -static void setup_scc1_ioports(struct fs_platform_info*) +static void setup_scc1_ioports(struct fs_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -194,7 +195,7 @@ static void setup_scc1_ioports(struct fs_platform_info*) } -static void setup_smc1_ioports(struct fs_uart_platform_info*) +static void setup_smc1_ioports(struct fs_uart_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -216,7 +217,7 @@ static void setup_smc1_ioports(struct fs_uart_platform_info*) } -static void setup_smc2_ioports(struct fs_uart_platform_info*) +static void setup_smc2_ioports(struct fs_uart_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; -- cgit v1.2.3 From 1d51c69fb6e61054cd6cc485f9bef77d19d82751 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 12 Apr 2007 13:13:42 -0700 Subject: [SPARC]: avoid CHILD_MAX and OPEN_MAX constants I don't figure anyone really cares about SunOS syscall emulation, and I certainly don't. But I'm getting rid of uses of the OPEN_MAX and CHILD_MAX compile-time constant, and these are almost the only ones. OPEN_MAX is a bogus constant with no meaning about anything. The RLIMIT_NOFILE resource limit is what sysconf (_SC_OPEN_MAX) actually wants to return. The CHILD_MAX cases weren't actually using anything I want to get rid of, but I noticed that they are there and are wrong too. The CHILD_MAX value is not really unlimited as a -1 return from sysconf indicates. The RLIMIT_NPROC resource limit is what sysconf (_SC_CHILD_MAX) wants to return. Signed-off-by: Roland McGrath Signed-off-by: David S. Miller --- arch/sparc/kernel/sys_sunos.c | 4 ++-- arch/sparc64/kernel/sys_sunos32.c | 4 ++-- arch/sparc64/solaris/misc.c | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index da6606f0cff..f807172cab0 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -910,7 +910,7 @@ asmlinkage long sunos_sysconf (int name) ret = ARG_MAX; break; case _SC_CHILD_MAX: - ret = -1; /* no limit */ + ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur; break; case _SC_CLK_TCK: ret = HZ; @@ -919,7 +919,7 @@ asmlinkage long sunos_sysconf (int name) ret = NGROUPS_MAX; break; case _SC_OPEN_MAX: - ret = OPEN_MAX; + ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur; break; case _SC_JOB_CONTROL: ret = 1; /* yes, we do support job control */ diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 4cff95b7b3a..8f7a06e2c7e 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -871,7 +871,7 @@ asmlinkage s32 sunos_sysconf (int name) ret = ARG_MAX; break; case _SC_CHILD_MAX: - ret = -1; /* no limit */ + ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur; break; case _SC_CLK_TCK: ret = HZ; @@ -880,7 +880,7 @@ asmlinkage s32 sunos_sysconf (int name) ret = NGROUPS_MAX; break; case _SC_OPEN_MAX: - ret = OPEN_MAX; + ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur; break; case _SC_JOB_CONTROL: ret = 1; /* yes, we do support job control */ diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index bca16e8c95c..9fcaad6dd11 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -363,8 +363,10 @@ asmlinkage int solaris_sysconf(int id) { switch (id) { case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX; - case SOLARIS_CONFIG_CHILD_MAX: return -1; /* no limit */ - case SOLARIS_CONFIG_OPEN_FILES: return OPEN_MAX; + case SOLARIS_CONFIG_CHILD_MAX: + return current->signal->rlim[RLIMIT_NPROC].rlim_cur; + case SOLARIS_CONFIG_OPEN_FILES: + return current->signal->rlim[RLIMIT_NOFILE].rlim_cur; case SOLARIS_CONFIG_POSIX_VER: return 199309; case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE; case SOLARIS_CONFIG_XOPEN_VER: return 3; -- cgit v1.2.3 From f6b45da1299f1f2e92a1446cfa400be53fdc5c99 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Thu, 12 Apr 2007 13:47:37 -0700 Subject: [SPARC]: Fix section mismatch warnings in pci.c and pcic.c Fix section mismatch in arch/sparc/kernel/pcic.c and arch/sparc64/kernel/pci.c. Signed-off-by: Robert Reif Signed-off-by: David S. Miller --- arch/sparc/kernel/pcic.c | 4 ++-- arch/sparc64/kernel/pci.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 3fa5f95c461..1c927c538b8 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -601,7 +601,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node) /* * Normally called from {do_}pci_scan_bus... */ -void __init pcibios_fixup_bus(struct pci_bus *bus) +void __devinit pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev; int i, has_io, has_mem; @@ -842,7 +842,7 @@ static void watchdog_reset() { /* * Other archs parse arguments here. */ -char * __init pcibios_setup(char *str) +char * __devinit pcibios_setup(char *str) { return str; } diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 196b4b72482..12109886bb1 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -327,7 +327,7 @@ static int __init pcibios_init(void) subsys_initcall(pcibios_init); -void pcibios_fixup_bus(struct pci_bus *pbus) +void __devinit pcibios_fixup_bus(struct pci_bus *pbus) { struct pci_pbm_info *pbm = pbus->sysdata; @@ -405,7 +405,7 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, } EXPORT_SYMBOL(pcibios_bus_to_resource); -char * __init pcibios_setup(char *str) +char * __devinit pcibios_setup(char *str) { return str; } -- cgit v1.2.3 From 5c7aa6ffae514bfeb7ec0f249dde949863d895ac Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 13 Apr 2007 13:27:08 -0700 Subject: [SPARC64]: Fix arg passing to compat_sys_ipc(). Do not sign extend args using the sys32_ipc stub, that is buggy and unnecessary. Based upon an excellent report by Mikael Pettersson. Signed-off-by: David S. Miller --- arch/sparc64/kernel/sys32.S | 1 - arch/sparc64/kernel/systbls.S | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index c09ab4b9431..010a737908e 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -91,7 +91,6 @@ SIGN1(sys32_select, compat_sys_select, %o0) SIGN1(sys32_mkdir, sys_mkdir, %o1) SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) SIGN1(sys32_sysfs, compat_sys_sysfs, %o0) -SIGN3(sys32_ipc, compat_sys_ipc, %o1, %o2, %o3) SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1) SIGN1(sys32_prctl, sys_prctl, %o0) diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index aaeb5e06735..48c36fe6dc6 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -62,7 +62,7 @@ sys_call_table32: /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 /*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, compat_sys_sysinfo - .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex + .word compat_sys_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 /*230*/ .word sys32_select, compat_sys_time, sys32_splice, compat_sys_stime, compat_sys_statfs64 -- cgit v1.2.3 From 24fc6f00b64985773b5abd592c4cb2e30bad7584 Mon Sep 17 00:00:00 2001 From: "Tom \"spot\" Callaway" Date: Fri, 13 Apr 2007 13:35:35 -0700 Subject: [SPARC64]: Fix inline directive in pci_iommu.c While building a test kernel for the new esp driver (against git-current), I hit this bug. Trivial fix, put the inline declaration in the right place. :) Signed-off-by: Tom "spot" Callaway Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 2e7f1427088..7aca0f33f88 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -64,7 +64,7 @@ static void __iommu_flushall(struct pci_iommu *iommu) #define IOPTE_IS_DUMMY(iommu, iopte) \ ((iopte_val(*iopte) & IOPTE_PAGE) == (iommu)->dummy_page_pa) -static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) +static inline void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) { unsigned long val = iopte_val(*iopte); -- cgit v1.2.3 From c9c57929d23e44f258d1b6e7f089e72c85f0bd1c Mon Sep 17 00:00:00 2001 From: Ravikiran G Thirumalai Date: Fri, 13 Apr 2007 16:28:20 -0700 Subject: failsafe mechanism to HPET clock calibration Provide a failsafe mechanism to avoid kernel spinning forever at read_hpet_tsc during early kernel bootup. This failsafe mechanism was originally introduced in commit 2f7a2a79c3ebb44f8b1b7d9b4fd3a650eb69e544, but looks like the hpet split from time.c lost it again. This reintroduces the failsafe mechanism Signed-off-by: Ravikiran Thirumalai Signed-off-by: Shai Fultheim Cc: Jack Steiner Cc: john stultz Cc: Andi Kleen Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/hpet.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/hpet.c b/arch/x86_64/kernel/hpet.c index 8cf0b8a1377..b8286968662 100644 --- a/arch/x86_64/kernel/hpet.c +++ b/arch/x86_64/kernel/hpet.c @@ -191,6 +191,7 @@ int hpet_reenable(void) #define TICK_COUNT 100000000 #define TICK_MIN 5000 +#define MAX_TRIES 5 /* * Some platforms take periodic SMI interrupts with 5ms duration. Make sure none @@ -198,13 +199,15 @@ int hpet_reenable(void) */ static void __init read_hpet_tsc(int *hpet, int *tsc) { - int tsc1, tsc2, hpet1; + int tsc1, tsc2, hpet1, i; - do { + for (i = 0; i < MAX_TRIES; i++) { tsc1 = get_cycles_sync(); hpet1 = hpet_readl(HPET_COUNTER); tsc2 = get_cycles_sync(); - } while (tsc2 - tsc1 > TICK_MIN); + if (tsc2 - tsc1 > TICK_MIN) + break; + } *hpet = hpet1; *tsc = tsc2; } -- cgit v1.2.3 From 0492c371372ef5eac3a952509391dea231b0de89 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Thu, 12 Apr 2007 19:28:46 -0700 Subject: Fix VMI relocation processing logic error Fix logic error in VMI relocation processing. NOPs would always cause a BUG_ON to fire because the != RELOCATION_NONE in the first if clause precluding the == VMI_RELOCATION_NOP in the second clause. Make these direct equality tests and just warn for unsupported relocation types (which should never happen), falling back to native in that case. Thanks to Anthony Liguori for noting this! Signed-off-by: Zachary Amsden Signed-off-by: Linus Torvalds --- arch/i386/kernel/vmi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index edc339fa503..697a70e8c0c 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -712,11 +712,14 @@ static void *vmi_get_function(int vmicall) do { \ reloc = call_vrom_long_func(vmi_rom, get_reloc, \ VMI_CALL_##vmicall); \ - if (rel->type != VMI_RELOCATION_NONE) { \ - BUG_ON(rel->type != VMI_RELOCATION_CALL_REL); \ + if (rel->type == VMI_RELOCATION_CALL_REL) \ paravirt_ops.opname = (void *)rel->eip; \ - } else if (rel->type == VMI_RELOCATION_NOP) \ + else if (rel->type == VMI_RELOCATION_NOP) \ paravirt_ops.opname = (void *)vmi_nop; \ + else if (rel->type != VMI_RELOCATION_NONE) \ + printk(KERN_WARNING "VMI: Unknown relocation " \ + "type %d for " #vmicall"\n",\ + rel->type); \ } while (0) /* -- cgit v1.2.3 From 08269c6d38e003adb12f55c6d795daa89bdc1bae Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 16 Apr 2007 10:30:27 +0200 Subject: [PATCH] x86: Fix gcc 4.2 _proxy_pda workaround Due to an over aggressive optimizer gcc 4.2 cannot optimize away _proxy_pda in all cases (counter intuitive, but true). This breaks loading of some modules. The earlier workaround to just export a dummy symbol didn't work unfortunately because the module code ignores exports with 0 value. Make it 1 instead. Signed-off-by: Andi Kleen --- arch/i386/kernel/vmlinux.lds.S | 2 +- arch/x86_64/kernel/vmlinux.lds.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index ca51610955d..6f38f818380 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -26,7 +26,7 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(phys_startup_32) jiffies = jiffies_64; -_proxy_pda = 0; +_proxy_pda = 1; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index b73212c0a55..5176ecf006e 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -13,7 +13,7 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(phys_startup_64) jiffies_64 = jiffies; -_proxy_pda = 0; +_proxy_pda = 1; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(7); /* RWE */ -- cgit v1.2.3 From 1714f9bfc92d6ee67e84127332a1fae27772acfe Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 16 Apr 2007 10:30:27 +0200 Subject: [PATCH] x86: Fix potential overflow in perfctr reservation While reviewing this code again I found a potential overflow of the bitmap. The p4 oprofile can theoretically set bits beyond the reservation bitmap for specific configurations. Avoid that by sizing the bitmaps properly. Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 9 +++++---- arch/x86_64/kernel/nmi.c | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index a98ba88a8c0..9f1e8c1afab 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -41,16 +41,17 @@ int nmi_watchdog_enabled; * different subsystems this reservation system just tries to coordinate * things a little */ -static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner); -static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]); - -static cpumask_t backtrace_mask = CPU_MASK_NONE; /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ #define NMI_MAX_COUNTER_BITS 66 +#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS) +static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]); +static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]); + +static cpumask_t backtrace_mask = CPU_MASK_NONE; /* nmi_active: * >0: the lapic NMI watchdog is active, but can be disabled * <0: the lapic NMI watchdog has not been set up, and cannot diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index a90996c27dc..dfab9f16736 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -39,15 +39,17 @@ int panic_on_unrecovered_nmi; * different subsystems this reservation system just tries to coordinate * things a little */ -static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner); -static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]); - -static cpumask_t backtrace_mask = CPU_MASK_NONE; /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ #define NMI_MAX_COUNTER_BITS 66 +#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS) + +static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]); +static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]); + +static cpumask_t backtrace_mask = CPU_MASK_NONE; /* nmi_active: * >0: the lapic NMI watchdog is active, but can be disabled -- cgit v1.2.3 From 4c467e758a55e455264a994646b789ddb625fcaa Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 8 Apr 2007 09:57:26 +0100 Subject: [ARM] Update mach-types Signed-off-by: Russell King --- arch/arm/tools/mach-types | 99 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index bd78058b717..b1142ce4ac4 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Tue Jan 16 16:52:56 2007 +# Last update: Mon Apr 16 21:01:04 2007 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1190,13 +1190,12 @@ g500 MACH_G500 G500 1178 bug MACH_BUG BUG 1179 mx33ads MACH_MX33ADS MX33ADS 1180 chub MACH_CHUB CHUB 1181 -gta01 MACH_GTA01 GTA01 1182 +neo1973_gta01 MACH_NEO1973_GTA01 NEO1973_GTA01 1182 w90n740 MACH_W90N740 W90N740 1183 medallion_sa2410 MACH_MEDALLION_SA2410 MEDALLION_SA2410 1184 ia_cpu_9200_2 MACH_IA_CPU_9200_2 IA_CPU_9200_2 1185 dimmrm9200 MACH_DIMMRM9200 DIMMRM9200 1186 pm9261 MACH_PM9261 PM9261 1187 -mx21 MACH_MX21 MX21 1188 ml7304 MACH_ML7304 ML7304 1189 ucp250 MACH_UCP250 UCP250 1190 intboard MACH_INTBOARD INTBOARD 1191 @@ -1242,3 +1241,97 @@ xscale_treo680 MACH_XSCALE_TREO680 XSCALE_TREO680 1230 tecon_tmezon MACH_TECON_TMEZON TECON_TMEZON 1231 zylonite MACH_ZYLONITE ZYLONITE 1233 gene1270 MACH_GENE1270 GENE1270 1234 +zir2412 MACH_ZIR2412 ZIR2412 1235 +mx31lite MACH_MX31LITE MX31LITE 1236 +t700wx MACH_T700WX T700WX 1237 +vf100 MACH_VF100 VF100 1238 +nsb2 MACH_NSB2 NSB2 1239 +nxhmi_bb MACH_NXHMI_BB NXHMI_BB 1240 +nxhmi_re MACH_NXHMI_RE NXHMI_RE 1241 +n4100pro MACH_N4100PRO N4100PRO 1242 +sam9260 MACH_SAM9260 SAM9260 1243 +omap_treo600 MACH_OMAP_TREO600 OMAP_TREO600 1244 +indy2410 MACH_INDY2410 INDY2410 1245 +nelt_a MACH_NELT_A NELT_A 1246 +n311 MACH_N311 N311 1248 +at91sam9260vgk MACH_AT91SAM9260VGK AT91SAM9260VGK 1249 +at91leppe MACH_AT91LEPPE AT91LEPPE 1250 +at91lepccn MACH_AT91LEPCCN AT91LEPCCN 1251 +apc7100 MACH_APC7100 APC7100 1252 +stargazer MACH_STARGAZER STARGAZER 1253 +sonata MACH_SONATA SONATA 1254 +schmoogie MACH_SCHMOOGIE SCHMOOGIE 1255 +aztool MACH_AZTOOL AZTOOL 1256 +mioa701 MACH_MIOA701 MIOA701 1257 +sxni9260 MACH_SXNI9260 SXNI9260 1258 +mxc27520evb MACH_MXC27520EVB MXC27520EVB 1259 +armadillo5x0 MACH_ARMADILLO5X0 ARMADILLO5X0 1260 +mb9260 MACH_MB9260 MB9260 1261 +mb9263 MACH_MB9263 MB9263 1262 +ipac9302 MACH_IPAC9302 IPAC9302 1263 +cc9p9360js MACH_CC9P9360JS CC9P9360JS 1264 +gallium MACH_GALLIUM GALLIUM 1265 +msc2410 MACH_MSC2410 MSC2410 1266 +ghi270 MACH_GHI270 GHI270 1267 +davinci_leonardo MACH_DAVINCI_LEONARDO DAVINCI_LEONARDO 1268 +oiab MACH_OIAB OIAB 1269 +smdk6400 MACH_SMDK6400 SMDK6400 1270 +nokia_n800 MACH_NOKIA_N800 NOKIA_N800 1271 +greenphone MACH_GREENPHONE GREENPHONE 1272 +compex42x MACH_COMPEXWP18 COMPEXWP18 1273 +xmate MACH_XMATE XMATE 1274 +energizer MACH_ENERGIZER ENERGIZER 1275 +ime1 MACH_IME1 IME1 1276 +sweda_tms MACH_SWEDATMS SWEDATMS 1277 +ntnp435c MACH_NTNP435C NTNP435C 1278 +spectro2 MACH_SPECTRO2 SPECTRO2 1279 +h6039 MACH_H6039 H6039 1280 +ep80219 MACH_EP80219 EP80219 1281 +samoa_ii MACH_SAMOA_II SAMOA_II 1282 +cwmxl MACH_CWMXL CWMXL 1283 +as9200 MACH_AS9200 AS9200 1284 +sfx1149 MACH_SFX1149 SFX1149 1285 +navi010 MACH_NAVI010 NAVI010 1286 +multmdp MACH_MULTMDP MULTMDP 1287 +scb9520 MACH_SCB9520 SCB9520 1288 +htcathena MACH_HTCATHENA HTCATHENA 1289 +xp179 MACH_XP179 XP179 1290 +h4300 MACH_H4300 H4300 1291 +goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292 +mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293 +adsbitsymx MACH_ADSBITSIMX ADSBITSIMX 1294 +adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295 +mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296 +em_x270 MACH_EM_X270 EM_X270 1297 +tpp302 MACH_TPP302 TPP302 1298 +tpp104 MACH_TPM104 TPM104 1299 +tpm102 MACH_TPM102 TPM102 1300 +tpm109 MACH_TPM109 TPM109 1301 +fbxo1 MACH_FBXO1 FBXO1 1302 +hxd8 MACH_HXD8 HXD8 1303 +neo1973_gta02 MACH_NEO1973_GTA02 NEO1973_GTA02 1304 +emtest MACH_EMTEST EMTEST 1305 +ad6900 MACH_AD6900 AD6900 1306 +europa MACH_EUROPA EUROPA 1307 +metroconnect MACH_METROCONNECT METROCONNECT 1308 +ez_s2410 MACH_EZ_S2410 EZ_S2410 1309 +ez_s2440 MACH_EZ_S2440 EZ_S2440 1310 +ez_ep9312 MACH_EZ_EP9312 EZ_EP9312 1311 +ez_ep9315 MACH_EZ_EP9315 EZ_EP9315 1312 +ez_x7 MACH_EZ_X7 EZ_X7 1313 +godotdb MACH_GODOTDB GODOTDB 1314 +mistral MACH_MISTRAL MISTRAL 1315 +msm MACH_MSM MSM 1316 +ct5910 MACH_CT5910 CT5910 1317 +ct5912 MACH_CT5912 CT5912 1318 +hynet_ine MACH_HYNET_INE HYNET_INE 1319 +hynet_app MACH_HYNET_APP HYNET_APP 1320 +msm7200 MACH_MSM7200 MSM7200 1321 +msm7600 MACH_MSM7600 MSM7600 1322 +ceb255 MACH_CEB255 CEB255 1323 +ciel MACH_CIEL CIEL 1324 +slm5650 MACH_SLM5650 SLM5650 1325 +at91sam9rlek MACH_AT91SAM9RLEK AT91SAM9RLEK 1326 +comtech_router MACH_COMTECH_ROUTER COMTECH_ROUTER 1327 +sbc2410x MACH_SBC2410X SBC2410X 1328 +at4x0bd MACH_AT4X0BD AT4X0BD 1329 -- cgit v1.2.3 From 1af1e32adef775dfc103f9679417009f2cf838ab Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 9 Apr 2007 10:15:20 +0100 Subject: [ARM] 4313/1: S3C24XX: Update s3c2410 defconfig to 2.6.21-rc6 Update defconfig to the latest kernel version and enable the h1940 LED driver Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/configs/s3c2410_defconfig | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index d4ca0f06be5..a850da377a2 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc1 -# Wed Feb 21 16:48:01 2007 +# Linux kernel version: 2.6.21-rc6 +# Mon Apr 9 10:12:58 2007 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y # CONFIG_GENERIC_TIME is not set CONFIG_MMU=y CONFIG_NO_IOPORT=y @@ -45,6 +46,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_IKCONFIG is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y @@ -531,7 +533,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m @@ -560,7 +561,6 @@ CONFIG_IDE_GENERIC=y CONFIG_BLK_DEV_IDE_BAST=y # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set # @@ -941,6 +941,7 @@ CONFIG_LEDS_CLASS=m # LED drivers # CONFIG_LEDS_S3C24XX=m +CONFIG_LEDS_H1940=m # # LED Triggers @@ -1125,6 +1126,7 @@ CONFIG_USB_MON=y # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # @@ -1169,7 +1171,6 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_RS5C372 is not set CONFIG_RTC_DRV_S3C=y -- cgit v1.2.3 From 6f29e35e2d4cdbc3e8785982314e54ec5df4ad37 Mon Sep 17 00:00:00 2001 From: Badari Pulavarty Date: Fri, 13 Apr 2007 08:13:42 -0700 Subject: cache_k8_northbridges() overflows beyond allocation cache_k8_northbridges() is storing config values to incorrect locations (in flush_words) and also its overflowing beyond the allocation, causing slab verification failures. Signed-off-by: Badari Pulavarty Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/k8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/k8.c b/arch/x86_64/kernel/k8.c index 6416682d33d..bc11b32e8b4 100644 --- a/arch/x86_64/kernel/k8.c +++ b/arch/x86_64/kernel/k8.c @@ -61,8 +61,8 @@ int cache_k8_northbridges(void) dev = NULL; i = 0; while ((dev = next_k8_northbridge(dev)) != NULL) { - k8_northbridges[i++] = dev; - pci_read_config_dword(dev, 0x9c, &flush_words[i]); + k8_northbridges[i] = dev; + pci_read_config_dword(dev, 0x9c, &flush_words[i++]); } k8_northbridges[i] = NULL; return 0; -- cgit v1.2.3 From b4dfa0b1fb39c7ffe74741d60668825de6a47b69 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 17 Apr 2007 12:28:27 -0700 Subject: [NET]: Get rid of alloc_skb_from_cache Since this was added originally for Xen, and Xen has recently (~2.6.18) stopped using this function, we can safely get rid of it. Good timing too since this function has started to bit rot. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- arch/x86_64/kernel/functionlist | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/functionlist b/arch/x86_64/kernel/functionlist index 01fa23580c8..7ae18ec1245 100644 --- a/arch/x86_64/kernel/functionlist +++ b/arch/x86_64/kernel/functionlist @@ -514,7 +514,6 @@ *(.text.dentry_open) *(.text.dentry_iput) *(.text.bio_alloc) -*(.text.alloc_skb_from_cache) *(.text.wait_on_page_bit) *(.text.vfs_readdir) *(.text.vfs_lstat) -- cgit v1.2.3 From 1b75b05b73cdefd1d10074e9dad60812f9731a5e Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Mon, 16 Apr 2007 22:53:17 -0700 Subject: alpha: fixes for specific machine types Files: arch/alpha/kernel/core_mcpcia.c arch/alpha/kernel/sys_rawhide.c include/asm-alpha/core_mcpcia.h Determine correct hose configuration; RAWHIDE family can have 2 or 4 hoses, so make sure non-existent hoses are ignored. arch/alpha/kernel/err_titan.c Supply a needed #include arch/alpha/kernel/module.c Add some useful output to the relocation overflow messages. arch/alpha/kernel/sys_noritake.c Supply necessary noritake_end_irq() to correct interrupt handling. This fixes a problem first noted by hangs during boot probing with a DE500-BA TULIP NIC present. arch/alpha/kernel/sys_sio.c Correct saving of original PIRQ register (PCI IRQ routing); change default PIRQ setting to leave PCI IRQs 9 and 14 free to be used for sound (Multia) and IDE (any), respectively. include/asm-alpha/io.h Supply the "isa_virt_to_bus" routine. Signed-off-by: Jay Estabrook Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/core_mcpcia.c | 2 -- arch/alpha/kernel/err_titan.c | 1 + arch/alpha/kernel/module.c | 8 ++++---- arch/alpha/kernel/sys_noritake.c | 9 ++++++++- arch/alpha/kernel/sys_rawhide.c | 15 +++++++++++++++ arch/alpha/kernel/sys_sio.c | 14 +++++++++----- 6 files changed, 37 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c index 8d019071190..381fec0af52 100644 --- a/arch/alpha/kernel/core_mcpcia.c +++ b/arch/alpha/kernel/core_mcpcia.c @@ -40,8 +40,6 @@ # define DBG_CFG(args) #endif -#define MCPCIA_MAX_HOSES 4 - /* * Given a bus, device, and function number, compute resulting * configuration space address and setup the MCPCIA_HAXR2 register diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c index febe71c6869..543d96d7fa2 100644 --- a/arch/alpha/kernel/err_titan.c +++ b/arch/alpha/kernel/err_titan.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "err_impl.h" #include "proto.h" diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index aac6d4b22f7..bd03dc94c72 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -285,12 +285,12 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab, reloc_overflow: if (ELF64_ST_TYPE (sym->st_info) == STT_SECTION) printk(KERN_ERR - "module %s: Relocation overflow vs section %d\n", - me->name, sym->st_shndx); + "module %s: Relocation (type %lu) overflow vs section %d\n", + me->name, r_type, sym->st_shndx); else printk(KERN_ERR - "module %s: Relocation overflow vs %s\n", - me->name, strtab + sym->st_name); + "module %s: Relocation (type %lu) overflow vs %s\n", + me->name, r_type, strtab + sym->st_name); return -ENOEXEC; } } diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index de6ba3432e8..eb2a1d63f48 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -66,6 +66,13 @@ noritake_startup_irq(unsigned int irq) return 0; } +static void +noritake_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + noritake_enable_irq(irq); +} + static struct hw_interrupt_type noritake_irq_type = { .typename = "NORITAKE", .startup = noritake_startup_irq, @@ -73,7 +80,7 @@ static struct hw_interrupt_type noritake_irq_type = { .enable = noritake_enable_irq, .disable = noritake_disable_irq, .ack = noritake_disable_irq, - .end = noritake_enable_irq, + .end = noritake_end_irq, }; static void diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 581d08c70b9..672cb2df53d 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -52,6 +52,9 @@ rawhide_update_irq_hw(int hose, int mask) *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose)); } +#define hose_exists(h) \ + (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0)) + static inline void rawhide_enable_irq(unsigned int irq) { @@ -59,6 +62,9 @@ rawhide_enable_irq(unsigned int irq) irq -= 16; hose = irq / 24; + if (!hose_exists(hose)) /* if hose non-existent, exit */ + return; + irq -= hose * 24; mask = 1 << irq; @@ -76,6 +82,9 @@ rawhide_disable_irq(unsigned int irq) irq -= 16; hose = irq / 24; + if (!hose_exists(hose)) /* if hose non-existent, exit */ + return; + irq -= hose * 24; mask = ~(1 << irq) | hose_irq_masks[hose]; @@ -93,6 +102,9 @@ rawhide_mask_and_ack_irq(unsigned int irq) irq -= 16; hose = irq / 24; + if (!hose_exists(hose)) /* if hose non-existent, exit */ + return; + irq -= hose * 24; mask1 = 1 << irq; mask = ~mask1 | hose_irq_masks[hose]; @@ -169,6 +181,9 @@ rawhide_init_irq(void) mcpcia_init_hoses(); + /* Clear them all; only hoses that exist will be non-zero. */ + for (i = 0; i < MCPCIA_MAX_HOSES; i++) cached_irq_masks[i] = 0; + for (hose = hose_head; hose; hose = hose->next) { unsigned int h = hose->index; unsigned int mask = hose_irq_masks[h]; diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index a654014d202..14b5a753aba 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -84,12 +84,16 @@ alphabook1_init_arch(void) static void __init sio_pci_route(void) { -#if defined(ALPHA_RESTORE_SRM_SETUP) - /* First, read and save the original setting. */ + unsigned int orig_route_tab; + + /* First, ALWAYS read and print the original setting. */ pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60, - &saved_config.orig_route_tab); + &orig_route_tab); printk("%s: PIRQ original 0x%x new 0x%x\n", __FUNCTION__, - saved_config.orig_route_tab, alpha_mv.sys.sio.route_tab); + orig_route_tab, alpha_mv.sys.sio.route_tab); + +#if defined(ALPHA_RESTORE_SRM_SETUP) + saved_config.orig_route_tab = orig_route_tab; #endif /* Now override with desired setting. */ @@ -334,7 +338,7 @@ struct alpha_machine_vector avanti_mv __initmv = { .pci_swizzle = common_swizzle, .sys = { .sio = { - .route_tab = 0x0b0a0e0f, + .route_tab = 0x0b0a050f, /* leave 14 for IDE, 9 for SND */ }} }; ALIAS_MV(avanti) -- cgit v1.2.3 From 7fc1a1abc1eca1278d6d37ec54b72005d15b5c1e Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Mon, 16 Apr 2007 22:53:21 -0700 Subject: alpha: more fixes for specific machine types arch/alpha/kernel/sys_sx164.c Earlier firmware revisions need MVI fix as well. arch/alpha/kernel/sys_nautilus.c On UP1500 firmware reports wrong AGP IRQ (10 instead of 5). This causes interrupt storm if there is a PCI device that uses IRQ 5. Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/sys_nautilus.c | 6 ++++++ arch/alpha/kernel/sys_sx164.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index e7594a7cf58..920196bcbb6 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -70,6 +70,12 @@ nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin) /* Preserve the IRQ set up by the console. */ u8 irq; + /* UP1500: AGP INTA is actually routed to IRQ 5, not IRQ 10 as + console reports. Check the device id of AGP bridge to distinguish + UP1500 from UP1000/1100. Note: 'pin' is 2 due to bridge swizzle. */ + if (slot == 1 && pin == 2 && + dev->bus->self && dev->bus->self->device == 0x700f) + return 5; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); return irq; } diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c index 94ad68b7c0a..41d4ad4c7c4 100644 --- a/arch/alpha/kernel/sys_sx164.c +++ b/arch/alpha/kernel/sys_sx164.c @@ -132,7 +132,7 @@ sx164_init_arch(void) if (amask(AMASK_MAX) != 0 && alpha_using_srm - && (cpu->pal_revision & 0xffff) == 0x117) { + && (cpu->pal_revision & 0xffff) <= 0x117) { __asm__ __volatile__( "lda $16,8($31)\n" "call_pal 9\n" /* Allow PALRES insns in kernel mode */ -- cgit v1.2.3 From 88ed39b064575b4f42ecb737ec2daa66717de173 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Mon, 16 Apr 2007 22:53:21 -0700 Subject: alpha: build fixes - force architecture Override compiler .arch directive for generic kernel build. Signed-off-by: Ivan Kokshaysky Signed-off-by: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/sys_titan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 29ab7db81c3..f009b7bc094 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -257,8 +257,7 @@ titan_dispatch_irqs(u64 mask) */ while (mask) { /* convert to SRM vector... priority is <63> -> <0> */ - __asm__("ctlz %1, %0" : "=r"(vector) : "r"(mask)); - vector = 63 - vector; + vector = 63 - __kernel_ctlz(mask); mask &= ~(1UL << vector); /* clear it out */ vector = 0x900 + (vector << 4); /* convert to SRM vector */ -- cgit v1.2.3 From 9a9943575ade643368849e2c963094ac637867e0 Mon Sep 17 00:00:00 2001 From: Mark Mason Date: Fri, 13 Apr 2007 10:32:25 -0700 Subject: [MIPS] Add missing silicon revisions for BCM112x Recent versions of the BCM112X processors aren't recognized by Linux (preventing Linux from booting on those processors). This patch adds support for those that are missing. Signed-off-by: Mark Mason Signed-off-by: Ralf Baechle --- arch/mips/sibyte/sb1250/setup.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index 87188f0f6fb..f4a6169aa0a 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c @@ -141,6 +141,18 @@ static int __init setup_bcm112x(void) periph_rev = 3; pass_str = "A2"; break; + case K_SYS_REVISION_BCM112x_A3: + periph_rev = 3; + pass_str = "A3"; + break; + case K_SYS_REVISION_BCM112x_A4: + periph_rev = 3; + pass_str = "A4"; + break; + case K_SYS_REVISION_BCM112x_B0: + periph_rev = 3; + pass_str = "B0"; + break; default: printk("Unknown %s rev %x\n", soc_str, soc_pass); ret = 1; -- cgit v1.2.3 From 5323180db75d562a287cb2020b07c9422df13df6 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 14 Apr 2007 02:37:26 +0900 Subject: [MIPS] Disallow CpU exception in kernel again. The commit 4d40bff7110e9e1a97ff8c01bdd6350e9867cc10 ("Allow CpU exception in kernel partially") was broken. The commit was to fix theoretical problem but broke usual case. Revert it for now. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/r2300_switch.S | 10 ++++------ arch/mips/kernel/r4k_switch.S | 10 ++++------ arch/mips/kernel/signal.c | 10 +++++----- arch/mips/kernel/signal32.c | 10 +++++----- arch/mips/kernel/traps.c | 21 +++------------------ 5 files changed, 21 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 28c2e2e6af7..656bde2e11b 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -49,7 +49,8 @@ LEAF(resume) #ifndef CONFIG_CPU_HAS_LLSC sw zero, ll_bit #endif - mfc0 t2, CP0_STATUS + mfc0 t1, CP0_STATUS + sw t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 sw ra, THREAD_REG31(a0) @@ -59,8 +60,8 @@ LEAF(resume) lw t3, TASK_THREAD_INFO(a0) lw t0, TI_FLAGS(t3) li t1, _TIF_USEDFPU - and t1, t0 - beqz t1, 1f + and t2, t0, t1 + beqz t2, 1f nor t1, zero, t1 and t0, t0, t1 @@ -73,13 +74,10 @@ LEAF(resume) li t1, ~ST0_CU1 and t0, t0, t1 sw t0, ST_OFF(t3) - /* clear thread_struct CU1 bit */ - and t2, t1 fpu_save_single a0, t0 # clobbers t0 1: - sw t2, THREAD_STATUS(a0) /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index c7698fd9955..cc566cf1224 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -48,7 +48,8 @@ #ifndef CONFIG_CPU_HAS_LLSC sw zero, ll_bit #endif - mfc0 t2, CP0_STATUS + mfc0 t1, CP0_STATUS + LONG_S t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 LONG_S ra, THREAD_REG31(a0) @@ -58,8 +59,8 @@ PTR_L t3, TASK_THREAD_INFO(a0) LONG_L t0, TI_FLAGS(t3) li t1, _TIF_USEDFPU - and t1, t0 - beqz t1, 1f + and t2, t0, t1 + beqz t2, 1f nor t1, zero, t1 and t0, t0, t1 @@ -72,13 +73,10 @@ li t1, ~ST0_CU1 and t0, t0, t1 LONG_S t0, ST_OFF(t3) - /* clear thread_struct CU1 bit */ - and t2, t1 fpu_save_double a0 t0 t1 # c0_status passed in t0 # clobbers t1 1: - LONG_S t2, THREAD_STATUS(a0) /* * The order of restoring the registers takes care of the race diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 8c3c5a5789b..fa581192de2 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -113,10 +113,10 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) * Save FPU state to signal context. Signal handler * will "inherit" current FPU state. */ + preempt_disable(); own_fpu(1); - enable_fp_in_kernel(); err |= save_fp_context(sc); - disable_fp_in_kernel(); + preempt_enable(); } return err; } @@ -148,7 +148,10 @@ check_and_restore_fp_context(struct sigcontext __user *sc) err = sig = fpcsr_pending(&sc->sc_fpc_csr); if (err > 0) err = 0; + preempt_disable(); + own_fpu(0); err |= restore_fp_context(sc); + preempt_enable(); return err ?: sig; } @@ -187,11 +190,8 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) if (used_math) { /* restore fpu context if we have used it before */ - own_fpu(0); - enable_fp_in_kernel(); if (!err) err = check_and_restore_fp_context(sc); - disable_fp_in_kernel(); } else { /* signal handler may have used FPU. Give it up. */ lose_fpu(0); diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 151fd2f0893..53a337cfeb6 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -209,10 +209,10 @@ static int setup_sigcontext32(struct pt_regs *regs, * Save FPU state to signal context. Signal handler * will "inherit" current FPU state. */ + preempt_disable(); own_fpu(1); - enable_fp_in_kernel(); err |= save_fp_context32(sc); - disable_fp_in_kernel(); + preempt_enable(); } return err; } @@ -225,7 +225,10 @@ check_and_restore_fp_context32(struct sigcontext32 __user *sc) err = sig = fpcsr_pending(&sc->sc_fpc_csr); if (err > 0) err = 0; + preempt_disable(); + own_fpu(0); err |= restore_fp_context32(sc); + preempt_enable(); return err ?: sig; } @@ -261,11 +264,8 @@ static int restore_sigcontext32(struct pt_regs *regs, if (used_math) { /* restore fpu context if we have used it before */ - own_fpu(0); - enable_fp_in_kernel(); if (!err) err = check_and_restore_fp_context32(sc); - disable_fp_in_kernel(); } else { /* signal handler may have used FPU. Give it up. */ lose_fpu(0); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 7d76a85422b..6b356f62289 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -757,11 +757,12 @@ asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; + die_if_kernel("do_cpu invoked from kernel context!", regs); + cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; switch (cpid) { case 0: - die_if_kernel("do_cpu invoked from kernel context!", regs); if (!cpu_has_llsc) if (!simulate_llsc(regs)) return; @@ -772,9 +773,6 @@ asmlinkage void do_cpu(struct pt_regs *regs) break; case 1: - if (!test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) - die_if_kernel("do_cpu invoked from kernel context!", - regs); if (used_math()) /* Using the FPU again. */ own_fpu(1); else { /* First time FPU user. */ @@ -782,19 +780,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) set_used_math(); } - if (raw_cpu_has_fpu) { - if (test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) { - local_irq_disable(); - if (cpu_has_fpu) - regs->cp0_status |= ST0_CU1; - /* - * We must return without enabling - * interrupts to ensure keep FPU - * ownership until resume. - */ - return; - } - } else { + if (!raw_cpu_has_fpu) { int sig; sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 0); @@ -836,7 +822,6 @@ asmlinkage void do_cpu(struct pt_regs *regs) case 2: case 3: - die_if_kernel("do_cpu invoked from kernel context!", regs); break; } -- cgit v1.2.3 From faea62346444ce5b1dba8fb5291d95b676522c42 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 16 Apr 2007 23:19:44 +0900 Subject: [MIPS] Retry {save,restore}_fp_context if failed in atomic context. The save_fp_context()/restore_fp_context() might sleep on accessing user stack and therefore might lose FPU ownership in middle of them. If these function failed due to "in_atomic" test in do_page_fault, touch the sigcontext area in non-atomic context and retry these save/restore operation. This is a replacement of a (broken) fix which was titled "Allow CpU exception in kernel partially". Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal-common.h | 9 +++++++ arch/mips/kernel/signal.c | 52 +++++++++++++++++++++++++++++++++------- arch/mips/kernel/signal32.c | 52 +++++++++++++++++++++++++++++++++------- 3 files changed, 95 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 297dfcb9752..c0faabd5201 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h @@ -34,4 +34,13 @@ extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall); /* Check and clear pending FPU exceptions in saved CSR */ extern int fpcsr_pending(unsigned int __user *fpcsr); +/* Make sure we will not lose FPU ownership */ +#ifdef CONFIG_PREEMPT +#define lock_fpu_owner() preempt_disable() +#define unlock_fpu_owner() preempt_enable() +#else +#define lock_fpu_owner() pagefault_disable() +#define unlock_fpu_owner() pagefault_enable() +#endif + #endif /* __SIGNAL_COMMON_H */ diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index fa581192de2..07d67309451 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -78,6 +78,46 @@ struct rt_sigframe { /* * Helper routines */ +static int protected_save_fp_context(struct sigcontext __user *sc) +{ + int err; + while (1) { + lock_fpu_owner(); + own_fpu_inatomic(1); + err = save_fp_context(sc); /* this might fail */ + unlock_fpu_owner(); + if (likely(!err)) + break; + /* touch the sigcontext and try again */ + err = __put_user(0, &sc->sc_fpregs[0]) | + __put_user(0, &sc->sc_fpregs[31]) | + __put_user(0, &sc->sc_fpc_csr); + if (err) + break; /* really bad sigcontext */ + } + return err; +} + +static int protected_restore_fp_context(struct sigcontext __user *sc) +{ + int err, tmp; + while (1) { + lock_fpu_owner(); + own_fpu_inatomic(0); + err = restore_fp_context(sc); /* this might fail */ + unlock_fpu_owner(); + if (likely(!err)) + break; + /* touch the sigcontext and try again */ + err = __get_user(tmp, &sc->sc_fpregs[0]) | + __get_user(tmp, &sc->sc_fpregs[31]) | + __get_user(tmp, &sc->sc_fpc_csr); + if (err) + break; /* really bad sigcontext */ + } + return err; +} + int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) { int err = 0; @@ -113,10 +153,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) * Save FPU state to signal context. Signal handler * will "inherit" current FPU state. */ - preempt_disable(); - own_fpu(1); - err |= save_fp_context(sc); - preempt_enable(); + err |= protected_save_fp_context(sc); } return err; } @@ -148,10 +185,7 @@ check_and_restore_fp_context(struct sigcontext __user *sc) err = sig = fpcsr_pending(&sc->sc_fpc_csr); if (err > 0) err = 0; - preempt_disable(); - own_fpu(0); - err |= restore_fp_context(sc); - preempt_enable(); + err |= protected_restore_fp_context(sc); return err ?: sig; } diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 53a337cfeb6..b9a014411f8 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -176,6 +176,46 @@ struct rt_sigframe32 { /* * sigcontext handlers */ +static int protected_save_fp_context32(struct sigcontext32 __user *sc) +{ + int err; + while (1) { + lock_fpu_owner(); + own_fpu_inatomic(1); + err = save_fp_context32(sc); /* this might fail */ + unlock_fpu_owner(); + if (likely(!err)) + break; + /* touch the sigcontext and try again */ + err = __put_user(0, &sc->sc_fpregs[0]) | + __put_user(0, &sc->sc_fpregs[31]) | + __put_user(0, &sc->sc_fpc_csr); + if (err) + break; /* really bad sigcontext */ + } + return err; +} + +static int protected_restore_fp_context32(struct sigcontext32 __user *sc) +{ + int err, tmp; + while (1) { + lock_fpu_owner(); + own_fpu_inatomic(0); + err = restore_fp_context32(sc); /* this might fail */ + unlock_fpu_owner(); + if (likely(!err)) + break; + /* touch the sigcontext and try again */ + err = __get_user(tmp, &sc->sc_fpregs[0]) | + __get_user(tmp, &sc->sc_fpregs[31]) | + __get_user(tmp, &sc->sc_fpc_csr); + if (err) + break; /* really bad sigcontext */ + } + return err; +} + static int setup_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc) { @@ -209,10 +249,7 @@ static int setup_sigcontext32(struct pt_regs *regs, * Save FPU state to signal context. Signal handler * will "inherit" current FPU state. */ - preempt_disable(); - own_fpu(1); - err |= save_fp_context32(sc); - preempt_enable(); + err |= protected_save_fp_context32(sc); } return err; } @@ -225,10 +262,7 @@ check_and_restore_fp_context32(struct sigcontext32 __user *sc) err = sig = fpcsr_pending(&sc->sc_fpc_csr); if (err > 0) err = 0; - preempt_disable(); - own_fpu(0); - err |= restore_fp_context32(sc); - preempt_enable(); + err |= protected_restore_fp_context32(sc); return err ?: sig; } -- cgit v1.2.3 From ba755f8ec80fdbf2b5212622eabf7355464c6327 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 12 Apr 2007 20:02:54 +0900 Subject: [MIPS] Fix BUG(), BUG_ON() handling With commit 63dc68a8cf60cb110b147dab1704d990808b39e2, kernel can not handle BUG() and BUG_ON() properly since get_user() returns false for kernel code. Use __get_user() to skip unnecessary access_ok(). This patch also make BRK_BUG code encoded in the TNE instruction. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 6b356f62289..493cb29b8a4 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -650,7 +650,7 @@ asmlinkage void do_bp(struct pt_regs *regs) unsigned int opcode, bcode; siginfo_t info; - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; /* @@ -700,7 +700,7 @@ asmlinkage void do_tr(struct pt_regs *regs) unsigned int opcode, tcode = 0; siginfo_t info; - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; /* Immediate versions don't provide a code. */ -- cgit v1.2.3 From 7ab77e03c1f665d5dee78f1248fffd11fa0c5154 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 20 Apr 2007 15:58:00 -0400 Subject: Longhaul - Revert ACPI C3 on Longhaul ver. 2 Support for Longhaul ver. 2 broke driver for VIA C3 Eden 600MHz with Samuel 2 core. Processor is not able to switch frequency anymore. I don't know much about this issue at the moment, but until (if ever) I will know why, this part should be reversed. Signed-off-by: Rafal Bilski Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/cpufreq/longhaul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index a1f1b715bcf..2b030d6ccbf 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -758,7 +758,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) NULL, (void *)&pr); /* Check ACPI support for C3 state */ - if (pr != NULL && longhaul_version != TYPE_LONGHAUL_V1) { + if (pr != NULL && longhaul_version == TYPE_POWERSAVER) { cx = &pr->power.states[ACPI_STATE_C3]; if (cx->address > 0 && cx->latency <= 1000) { longhaul_flags |= USE_ACPI_C3; -- cgit v1.2.3 From cf6387daf8858bdcb3e123034ca422e8979d73f1 Mon Sep 17 00:00:00 2001 From: Joachim Deguara Date: Tue, 24 Apr 2007 13:05:36 +0200 Subject: [PATCH] x86-64: make GART PTEs uncacheable This patches fixes the silent data corruption problems being seen using the GART iommu where 4kB of data where incorrect (seen mostly on Nvidia CK804 systems). This fix, to mark the memory regin the GART PTEs reside on as uncacheable, also brings the code in line with the AGP specification. Signed-off-by: Joachim Deguara Signed-off-by: Andi Kleen --- arch/x86_64/kernel/pci-gart.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index 2bac8c60ad6..0bae862e9a5 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -519,7 +519,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info) gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32); gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size)); if (!gatt) - panic("Cannot allocate GATT table"); + panic("Cannot allocate GATT table"); + if (change_page_attr_addr((unsigned long)gatt, gatt_size >> PAGE_SHIFT, PAGE_KERNEL_NOCACHE)) + panic("Could not set GART PTEs to uncacheable pages"); + global_flush_tlb(); + memset(gatt, 0, gatt_size); agp_gatt_table = gatt; -- cgit v1.2.3 From 9ce883becb83190061369940de9c415595836c9b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 24 Apr 2007 13:05:37 +0200 Subject: [PATCH] x86: Remove noreplacement option noreplacement is dangerous on modern systems because it will not replace the context switch FNSAVE with SSE aware FXSAVE. But other places in the kernel still assume SSE and do FXSAVE and the CPU will then access FXSAVE information with FNSAVE and cause corruption. Easiest way to avoid this is to remove the option. It was mostly for paranoia reasons anyways and alternative()s have been stable for some time. Thanks to Jeremy F. for reporting and helping debug it. Signed-off-by: Andi Kleen --- arch/i386/kernel/alternative.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 9eca21b49f6..426f59b0106 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -5,15 +5,9 @@ #include #include -static int no_replacement = 0; static int smp_alt_once = 0; static int debug_alternative = 0; -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 1; -} static int __init bootonly(char *str) { smp_alt_once = 1; @@ -25,7 +19,6 @@ static int __init debug_alt(char *str) return 1; } -__setup("noreplacement", noreplacement_setup); __setup("smp-alt-boot", bootonly); __setup("debug-alternative", debug_alt); @@ -252,9 +245,6 @@ void alternatives_smp_module_add(struct module *mod, char *name, struct smp_alt_module *smp; unsigned long flags; - if (no_replacement) - return; - if (smp_alt_once) { if (boot_cpu_has(X86_FEATURE_UP)) alternatives_smp_unlock(locks, locks_end, @@ -289,7 +279,7 @@ void alternatives_smp_module_del(struct module *mod) struct smp_alt_module *item; unsigned long flags; - if (no_replacement || smp_alt_once) + if (smp_alt_once) return; spin_lock_irqsave(&smp_alt, flags); @@ -320,7 +310,7 @@ void alternatives_smp_switch(int smp) return; #endif - if (no_replacement || smp_alt_once) + if (smp_alt_once) return; BUG_ON(!smp && (num_online_cpus() > 1)); @@ -386,13 +376,6 @@ extern struct paravirt_patch __start_parainstructions[], void __init alternative_instructions(void) { unsigned long flags; - if (no_replacement) { - printk(KERN_INFO "(SMP-)alternatives turned off\n"); - free_init_pages("SMP alternatives", - (unsigned long)__smp_alt_begin, - (unsigned long)__smp_alt_end); - return; - } local_irq_save(flags); apply_alternatives(__alt_instructions, __alt_instructions_end); -- cgit v1.2.3 From 90767bd13febfdf8a5f5077e2bb975f79d6b919c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 24 Apr 2007 13:05:37 +0200 Subject: [PATCH] x86-64: Always flush all pages in change_page_attr change_page_attr on x86-64 only flushed the TLB for pages that got reverted. That's not correct: it has to be flushed in all cases. This bug was added in some earlier changes. Just flush all pages for now. This could be done more efficiently, but for this late in the release this seem to be the best fix. Pointed out by Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/mm/pageattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 65c5eaa5990..081409aa345 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -81,8 +81,8 @@ static void flush_kernel_map(void *arg) void *adr = page_address(pg); if (cpu_has_clflush) cache_flush_page(adr); - __flush_tlb_one(adr); } + __flush_tlb_all(); } static inline void flush_map(struct list_head *l) -- cgit v1.2.3 From 8689b517be3e3f65f8ba20490beccca13c5879fa Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 24 Apr 2007 13:05:37 +0200 Subject: [PATCH] i386: Fix some warnings added by earlier patch Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 9f1e8c1afab..84c3497efb6 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -126,7 +126,7 @@ int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) int cpu; BUG_ON(counter > NMI_MAX_COUNTER_BITS); for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) return 0; } return 1; @@ -142,7 +142,7 @@ int avail_to_resrv_perfctr_nmi(unsigned int msr) BUG_ON(counter > NMI_MAX_COUNTER_BITS); for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) return 0; } return 1; @@ -157,7 +157,7 @@ static int __reserve_perfctr_nmi(int cpu, unsigned int msr) counter = nmi_perfctr_msr_to_bit(msr); BUG_ON(counter > NMI_MAX_COUNTER_BITS); - if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) return 1; return 0; } @@ -171,7 +171,7 @@ static void __release_perfctr_nmi(int cpu, unsigned int msr) counter = nmi_perfctr_msr_to_bit(msr); BUG_ON(counter > NMI_MAX_COUNTER_BITS); - clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)); + clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]); } int reserve_perfctr_nmi(unsigned int msr) -- cgit v1.2.3 From 6f4c5bdef2943d9ec074be32c437ca897016aaad Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 24 Apr 2007 21:42:20 +0100 Subject: [MIPS] Fix oprofile logic to physical counter remapping This did cause oprofile to fail on non-multithreaded systems with more than 2 processors such as the BCM1480. Reported by Manish Lachwani (mlachwani@mvista.com). Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_mipsxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 69a8bcfe72b..4f94fa261aa 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -35,7 +35,7 @@ #define vpe_id() smp_processor_id() #else #define WHAT 0 -#define vpe_id() smp_processor_id() +#define vpe_id() 0 #endif #define __define_perf_accessors(r, n, np) \ -- cgit v1.2.3 From 4c13eb6657fe9ef7b4dc8f1a405c902e9e5234e0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 25 Apr 2007 17:40:23 -0700 Subject: [ETH]: Make eth_type_trans set skb->dev like the other *_type_trans One less thing for drivers writers to worry about. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- arch/ia64/hp/sim/simeth.c | 1 - arch/ia64/sn/kernel/xpnet.c | 1 - arch/ppc/8260_io/enet.c | 1 - arch/ppc/8260_io/fcc_enet.c | 1 - arch/ppc/8xx_io/enet.c | 1 - arch/ppc/8xx_io/fec.c | 1 - 6 files changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index 424e9257c9a..edef008c2b4 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -427,7 +427,6 @@ make_new_skb(struct net_device *dev) printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name); return NULL; } - nskb->dev = dev; skb_reserve(nskb, 2); /* Align IP on 16 byte boundaries */ diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index c8173db0d84..68d59d912c9 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c @@ -267,7 +267,6 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) (void *) skb->data, (void *) skb->tail, (void *) skb->end, skb->len); - skb->dev = xpnet_device; skb->protocol = eth_type_trans(skb, xpnet_device); skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index a6056c29cf0..48ce84f5be9 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -477,7 +477,6 @@ for (;;) { cep->stats.rx_dropped++; } else { - skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, (unsigned char *)__va(bdp->cbd_bufaddr), diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index 06b84c372e5..9db825fe37f 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -734,7 +734,6 @@ for (;;) { cep->stats.rx_dropped++; } else { - skb->dev = dev; skb_put(skb,pkt_len); /* Make room */ eth_copy_and_sum(skb, (unsigned char *)__va(bdp->cbd_bufaddr), diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index b23c45bc151..bfa3f52996d 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -506,7 +506,6 @@ for (;;) { cep->stats.rx_dropped++; } else { - skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, cep->rx_vaddr[bdp - cep->rx_bd_base], diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index e6c28fb423b..57a9a61e54b 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -724,7 +724,6 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); fep->stats.rx_dropped++; } else { - skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, data, pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); -- cgit v1.2.3 From 459a98ed881802dee55897441bc7f77af614368e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Mar 2007 15:30:44 -0700 Subject: [SK_BUFF]: Introduce skb_reset_mac_header(skb) For the common, open coded 'skb->mac.raw = skb->data' operation, so that we can later turn skb->mac.raw into a offset, reducing the size of struct sk_buff in 64bit land while possibly keeping it as a pointer on 32bit. This one touches just the most simple case, next will handle the slightly more "complex" cases. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- arch/um/drivers/net_kern.c | 2 +- arch/xtensa/platform-iss/network.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 04e31f86c10..859303730b2 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -55,7 +55,7 @@ static int uml_net_rx(struct net_device *dev) skb->dev = dev; skb_put(skb, dev->mtu); - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); pkt_len = (*lp->read)(lp->fd, &skb, lp); if (pkt_len > 0) { diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index 8ebfc876122..ab05bff4010 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c @@ -386,7 +386,7 @@ static int iss_net_rx(struct net_device *dev) /* Setup skb */ skb->dev = dev; - skb->mac.raw = skb->data; + skb_reset_mac_header(skb); pkt_len = lp->tp.read(lp, &skb); skb_put(skb, pkt_len); -- cgit v1.2.3 From 98e399f82ab3a6d863d1d4a7ea48925cc91c830e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Mar 2007 15:33:04 -0700 Subject: [SK_BUFF]: Introduce skb_mac_header() For the places where we need a pointer to the mac header, it is still legal to touch skb->mac.raw directly if just adding to, subtracting from or setting it to another layer header. This one also converts some more cases to skb_reset_mac_header() that my regex missed as it had no spaces before nor after '=', ugh. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- arch/um/drivers/daemon_kern.c | 2 +- arch/um/drivers/mcast_kern.c | 2 +- arch/um/drivers/pcap_kern.c | 2 +- arch/um/drivers/slip_kern.c | 2 +- arch/um/drivers/slirp_kern.c | 2 +- arch/um/os-Linux/drivers/ethertap_kern.c | 2 +- arch/um/os-Linux/drivers/tuntap_kern.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c index 9c2e7a758f2..adeece11e59 100644 --- a/arch/um/drivers/daemon_kern.c +++ b/arch/um/drivers/daemon_kern.c @@ -46,7 +46,7 @@ static int daemon_read(int fd, struct sk_buff **skb, { *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); if(*skb == NULL) return(-ENOMEM); - return(net_recvfrom(fd, (*skb)->mac.raw, + return(net_recvfrom(fd, skb_mac_header(*skb), (*skb)->dev->mtu + ETH_HEADER_OTHER)); } diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c index 52ccb7b53cd..e6b8e0dd72a 100644 --- a/arch/um/drivers/mcast_kern.c +++ b/arch/um/drivers/mcast_kern.c @@ -50,7 +50,7 @@ static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) { *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); if(*skb == NULL) return(-ENOMEM); - return(net_recvfrom(fd, (*skb)->mac.raw, + return(net_recvfrom(fd, skb_mac_header(*skb), (*skb)->dev->mtu + ETH_HEADER_OTHER)); } diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c index e67362acf0e..948849343ca 100644 --- a/arch/um/drivers/pcap_kern.c +++ b/arch/um/drivers/pcap_kern.c @@ -36,7 +36,7 @@ static int pcap_read(int fd, struct sk_buff **skb, { *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); if(*skb == NULL) return(-ENOMEM); - return(pcap_user_read(fd, (*skb)->mac.raw, + return(pcap_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu + ETH_HEADER_OTHER, (struct pcap_data *) &lp->user)); } diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c index 25634bd1f58..125c44f7763 100644 --- a/arch/um/drivers/slip_kern.c +++ b/arch/um/drivers/slip_kern.c @@ -49,7 +49,7 @@ static unsigned short slip_protocol(struct sk_buff *skbuff) static int slip_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) { - return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, + return(slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, (struct slip_data *) &lp->user)); } diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c index b3ed8fb874a..0a0324a6d29 100644 --- a/arch/um/drivers/slirp_kern.c +++ b/arch/um/drivers/slirp_kern.c @@ -53,7 +53,7 @@ static unsigned short slirp_protocol(struct sk_buff *skbuff) static int slirp_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) { - return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, + return(slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, (struct slirp_data *) &lp->user)); } diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c index 70541821775..12689141414 100644 --- a/arch/um/os-Linux/drivers/ethertap_kern.c +++ b/arch/um/os-Linux/drivers/ethertap_kern.c @@ -43,7 +43,7 @@ static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); if(*skb == NULL) return(-ENOMEM); - len = net_recvfrom(fd, (*skb)->mac.raw, + len = net_recvfrom(fd, skb_mac_header(*skb), (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); if(len <= 0) return(len); skb_pull(*skb, 2); diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c index 76570a2c25c..f1714e7fb1d 100644 --- a/arch/um/os-Linux/drivers/tuntap_kern.c +++ b/arch/um/os-Linux/drivers/tuntap_kern.c @@ -43,7 +43,7 @@ static int tuntap_read(int fd, struct sk_buff **skb, { *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); if(*skb == NULL) return(-ENOMEM); - return(net_read(fd, (*skb)->mac.raw, + return(net_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu + ETH_HEADER_OTHER)); } -- cgit v1.2.3 From 27a884dc3cb63b93c2b3b643f5b31eed5f8a4d26 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 19 Apr 2007 20:29:13 -0700 Subject: [SK_BUFF]: Convert skb->tail to sk_buff_data_t So that it is also an offset from skb->head, reduces its size from 8 to 4 bytes on 64bit architectures, allowing us to combine the 4 bytes hole left by the layer headers conversion, reducing struct sk_buff size to 256 bytes, i.e. 4 64byte cachelines, and since the sk_buff slab cache is SLAB_HWCACHE_ALIGN... :-) Many calculations that previously required that skb->{transport,network, mac}_header be first converted to a pointer now can be done directly, being meaningful as offsets or pointers. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- arch/ia64/sn/kernel/xpnet.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index 68d59d912c9..eb416c95967 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c @@ -264,7 +264,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) dev_dbg(xpnet, "head=0x%p skb->data=0x%p skb->tail=0x%p " "skb->end=0x%p skb->len=%d\n", (void *) skb->head, - (void *) skb->data, (void *) skb->tail, (void *) skb->end, + (void *)skb->data, skb_tail_pointer(skb), (void *)skb->end, skb->len); skb->protocol = eth_type_trans(skb, xpnet_device); @@ -272,7 +272,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p " "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n", - (void *) skb->head, (void *) skb->data, (void *) skb->tail, + (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), (void *) skb->end, skb->len); @@ -475,7 +475,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p " "skb->end=0x%p skb->len=%d\n", (void *) skb->head, - (void *) skb->data, (void *) skb->tail, (void *) skb->end, + (void *)skb->data, skb_tail_pointer(skb), (void *)skb->end, skb->len); @@ -497,7 +497,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) /* get the beginning of the first cacheline and end of last */ start_addr = ((u64) skb->data & ~(L1_CACHE_BYTES - 1)); - end_addr = L1_CACHE_ALIGN((u64) skb->tail); + end_addr = L1_CACHE_ALIGN((u64)skb_tail_pointer(skb)); /* calculate how many bytes to embed in the XPC message */ embedded_bytes = 0; @@ -573,7 +573,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) msg->magic = XPNET_MAGIC; msg->size = end_addr - start_addr; msg->leadin_ignore = (u64) skb->data - start_addr; - msg->tailout_ignore = end_addr - (u64) skb->tail; + msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb); msg->buf_pa = __pa(start_addr); dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa=" -- cgit v1.2.3 From 4305b541357ddbd205aa145dc378926b7cb12283 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 19 Apr 2007 20:43:29 -0700 Subject: [SK_BUFF]: Convert skb->end to sk_buff_data_t Now to convert the last one, skb->data, that will allow many simplifications and removal of some of the offset helpers. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- arch/ia64/sn/kernel/xpnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index eb416c95967..98d79142f32 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c @@ -264,7 +264,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) dev_dbg(xpnet, "head=0x%p skb->data=0x%p skb->tail=0x%p " "skb->end=0x%p skb->len=%d\n", (void *) skb->head, - (void *)skb->data, skb_tail_pointer(skb), (void *)skb->end, + (void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len); skb->protocol = eth_type_trans(skb, xpnet_device); @@ -273,7 +273,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p " "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n", (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), - (void *) skb->end, skb->len); + skb_end_pointer(skb), skb->len); xpnet_device->last_rx = jiffies; @@ -475,7 +475,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p " "skb->end=0x%p skb->len=%d\n", (void *) skb->head, - (void *)skb->data, skb_tail_pointer(skb), (void *)skb->end, + (void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len); -- cgit v1.2.3 From d626f62b11e00c16e81e4308ab93d3f13551812a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 27 Mar 2007 18:55:52 -0300 Subject: [SK_BUFF]: Introduce skb_copy_from_linear_data{_offset} To clearly state the intent of copying from linear sk_buffs, _offset being a overly long variant but interesting for the sake of saving some bytes. Signed-off-by: Arnaldo Carvalho de Melo --- arch/ia64/sn/kernel/xpnet.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index 98d79142f32..9fc02654f0f 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c @@ -566,7 +566,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) msg->version = XPNET_VERSION_EMBED; dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n", &msg->data, skb->data, (size_t) embedded_bytes); - memcpy(&msg->data, skb->data, (size_t) embedded_bytes); + skb_copy_from_linear_data(skb, &msg->data, + (size_t)embedded_bytes); } else { msg->version = XPNET_VERSION; } -- cgit v1.2.3 From c45d286e72dd72c0229dc9e2849743ba427fee84 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 28 Mar 2007 14:29:08 -0700 Subject: [NET]: Inline net_device_stats Network drivers which keep stats allocate their own stats structure then write a get_stats() function to return them. It would be nice if this were done by default. 1) Add a new "stats" field to "struct net_device". 2) Add a new feature field to say "this driver uses the internal one" 3) Have a default "get_stats" which returns NULL if that feature not set. 4) Change callers to check result of get_stats call for NULL, not if ->get_stats is set. This should not break backwards compatibility with older drivers, yet allow modern drivers to shed some boilerplate code. Lightly tested: works for a modified lguest network driver. Signed-off-by: Rusty Russell Signed-off-by: David S. Miller --- arch/s390/appldata/appldata_net_sum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index f64b8c867ae..516b3ac9a9b 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -108,10 +108,10 @@ static void appldata_get_net_sum_data(void *data) collisions = 0; read_lock(&dev_base_lock); for (dev = dev_base; dev != NULL; dev = dev->next) { - if (dev->get_stats == NULL) { + stats = dev->get_stats(dev); + if (stats == NULL) { continue; } - stats = dev->get_stats(dev); rx_packets += stats->rx_packets; tx_packets += stats->tx_packets; rx_bytes += stats->rx_bytes; -- cgit v1.2.3 From 27d7ff46a3498d3debc6ba68fb8014c702b81170 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 31 Mar 2007 11:55:19 -0300 Subject: [SK_BUFF]: Introduce skb_copy_to_linear_data{_offset} To clearly state the intent of copying to linear sk_buffs, _offset being a overly long variant but interesting for the sake of saving some bytes. Signed-off-by: Arnaldo Carvalho de Melo --- arch/ia64/hp/sim/simeth.c | 2 +- arch/ia64/sn/kernel/xpnet.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index edef008c2b4..f26077a773d 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -473,7 +473,7 @@ simeth_rx(struct net_device *dev) * XXX Fix me * Should really do a csum+copy here */ - memcpy(skb->data, frame, len); + skb_copy_to_linear_data(skb, frame, len); #endif skb->protocol = eth_type_trans(skb, dev); diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index 9fc02654f0f..5419acb89a8 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c @@ -233,7 +233,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) "%lu)\n", skb->data, &msg->data, (size_t) msg->embedded_bytes); - memcpy(skb->data, &msg->data, (size_t) msg->embedded_bytes); + skb_copy_to_linear_data(skb, &msg->data, (size_t)msg->embedded_bytes); } else { dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t" "bte_copy(0x%p, 0x%p, %hu)\n", (void *)msg->buf_pa, -- cgit v1.2.3 From cb8c181f288a1157bc717cc7a02412d4d1dc19bc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 10 Apr 2007 22:10:39 -0700 Subject: [S390]: Fix build on 31-bit. Allow s390 to properly override the generic __div64_32() implementation by: 1) Using obj-y for div64.o in s390's makefile instead of lib-y 2) Adding the weak attribute to the generic implementation. Signed-off-by: David S. Miller --- arch/s390/lib/Makefile | 2 +- arch/s390/lib/div64.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index 7a44fed21b3..59aea65ce99 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -5,6 +5,6 @@ EXTRA_AFLAGS := -traditional lib-y += delay.o string.o uaccess_std.o uaccess_pt.o qrnnd.o -lib-$(CONFIG_32BIT) += div64.o +obj-$(CONFIG_32BIT) += div64.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o lib-$(CONFIG_SMP) += spinlock.o diff --git a/arch/s390/lib/div64.c b/arch/s390/lib/div64.c index 0481f3424a1..a5f8300bf3e 100644 --- a/arch/s390/lib/div64.c +++ b/arch/s390/lib/div64.c @@ -147,5 +147,3 @@ uint32_t __div64_32(uint64_t *n, uint32_t base) } #endif /* MARCH_G5 */ - -EXPORT_SYMBOL(__div64_32); -- cgit v1.2.3 From a58c9f3c1e929c3c323c26dbdafef46373a719d4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 22 Feb 2007 04:16:21 -0800 Subject: [SPARC64]: Synchronize RTC clock via timer just like x86. Signed-off-by: David S. Miller --- arch/sparc64/kernel/time.c | 66 +++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index f84da4f1b70..d457079118d 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -435,22 +435,56 @@ static unsigned long timer_ticks_per_nsec_quotient __read_mostly; #define TICK_SIZE (tick_nsec / 1000) -static inline void timer_check_rtc(void) +#define USEC_AFTER 500000 +#define USEC_BEFORE 500000 + +static void sync_cmos_clock(unsigned long dummy); + +static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0); + +static void sync_cmos_clock(unsigned long dummy) { - /* last time the cmos clock got updated */ - static long last_rtc_update; - - /* Determine when to update the Mostek clock. */ - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && - (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; - /* do it again in 60 s */ + struct timeval now, next; + int fail = 1; + + /* + * If we have an externally synchronized Linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + * This code is run on a timer. If the clock is set, that timer + * may not expire at the correct time. Thus, we adjust... + */ + if (!ntp_synced()) + /* + * Not synced, exit, do not restart a timer (if one is + * running, let it run out). + */ + return; + + do_gettimeofday(&now); + if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 && + now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) + fail = set_rtc_mmss(now.tv_sec); + + next.tv_usec = USEC_AFTER - now.tv_usec; + if (next.tv_usec <= 0) + next.tv_usec += USEC_PER_SEC; + + if (!fail) + next.tv_sec = 659; + else + next.tv_sec = 0; + + if (next.tv_usec >= USEC_PER_SEC) { + next.tv_sec++; + next.tv_usec -= USEC_PER_SEC; } + mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next)); +} + +void notify_arch_cmos_timer(void) +{ + mod_timer(&sync_cmos_timer, jiffies + 1); } irqreturn_t timer_interrupt(int irq, void *dev_id) @@ -483,8 +517,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) : "r" (pstate)); } while (time_after_eq(ticks, compare)); - timer_check_rtc(); - write_sequnlock(&xtime_lock); return IRQ_HANDLED; @@ -497,8 +529,6 @@ void timer_tick_interrupt(struct pt_regs *regs) do_timer(1); - timer_check_rtc(); - write_sequnlock(&xtime_lock); } #endif -- cgit v1.2.3 From 777a447529ad138f5fceb9c9ad28bab19848f277 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 22 Feb 2007 06:24:10 -0800 Subject: [SPARC64]: Unify timer interrupt handler. Things were scattered all over the place, split between SMP and non-SMP. Unify it all so that dyntick support is easier to add. Signed-off-by: David S. Miller --- arch/sparc64/kernel/irq.c | 26 ------------- arch/sparc64/kernel/smp.c | 87 +------------------------------------------- arch/sparc64/kernel/time.c | 43 +++++++++------------- arch/sparc64/kernel/ttable.S | 6 +-- 4 files changed, 21 insertions(+), 141 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index c443db18437..d1bb3b3f263 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -589,32 +589,6 @@ void ack_bad_irq(unsigned int virt_irq) ino, virt_irq); } -#ifndef CONFIG_SMP -extern irqreturn_t timer_interrupt(int, void *); - -void timer_irq(int irq, struct pt_regs *regs) -{ - unsigned long clr_mask = 1 << irq; - unsigned long tick_mask = tick_ops->softint_mask; - struct pt_regs *old_regs; - - if (get_softint() & tick_mask) { - irq = 0; - clr_mask = tick_mask; - } - clear_softint(clr_mask); - - old_regs = set_irq_regs(regs); - irq_enter(); - - kstat_this_cpu.irqs[0]++; - timer_interrupt(irq, NULL); - - irq_exit(); - set_irq_regs(old_regs); -} -#endif - void handler_irq(int irq, struct pt_regs *regs) { struct ino_bucket *bucket; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index fc99f7b8012..39deb0346eb 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -45,7 +45,7 @@ extern void calibrate_delay(void); /* Please don't make this stuff initdata!!! --DaveM */ -static unsigned char boot_cpu_id; +unsigned char boot_cpu_id; cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; @@ -81,8 +81,6 @@ void __init smp_store_cpu_info(int id) struct device_node *dp; int def; - /* multiplier and counter set by - smp_setup_percpu_timer() */ cpu_data(id).udelay_val = loops_per_jiffy; cpu_find_by_mid(id, &dp); @@ -1180,75 +1178,10 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) preempt_enable(); } -#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier -#define prof_counter(__cpu) cpu_data(__cpu).counter - -void smp_percpu_timer_interrupt(struct pt_regs *regs) -{ - unsigned long compare, tick, pstate; - int cpu = smp_processor_id(); - int user = user_mode(regs); - struct pt_regs *old_regs; - - /* - * Check for level 14 softint. - */ - { - unsigned long tick_mask = tick_ops->softint_mask; - - if (!(get_softint() & tick_mask)) { - extern void handler_irq(int, struct pt_regs *); - - handler_irq(14, regs); - return; - } - clear_softint(tick_mask); - } - - old_regs = set_irq_regs(regs); - do { - profile_tick(CPU_PROFILING); - if (!--prof_counter(cpu)) { - irq_enter(); - - if (cpu == boot_cpu_id) { - kstat_this_cpu.irqs[0]++; - timer_tick_interrupt(regs); - } - - update_process_times(user); - - irq_exit(); - - prof_counter(cpu) = prof_multiplier(cpu); - } - - /* Guarantee that the following sequences execute - * uninterrupted. - */ - __asm__ __volatile__("rdpr %%pstate, %0\n\t" - "wrpr %0, %1, %%pstate" - : "=r" (pstate) - : "i" (PSTATE_IE)); - - compare = tick_ops->add_compare(current_tick_offset); - tick = tick_ops->get_tick(); - - /* Restore PSTATE_IE. */ - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" - : /* no outputs */ - : "r" (pstate)); - } while (time_after_eq(tick, compare)); - set_irq_regs(old_regs); -} - static void __init smp_setup_percpu_timer(void) { - int cpu = smp_processor_id(); unsigned long pstate; - prof_counter(cpu) = prof_multiplier(cpu) = 1; - /* Guarantee that the following sequences execute * uninterrupted. */ @@ -1269,28 +1202,12 @@ void __init smp_tick_init(void) { boot_cpu_id = hard_smp_processor_id(); current_tick_offset = timer_tick_offset; - - prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1; } /* /proc/profile writes can call this, don't __init it please. */ -static DEFINE_SPINLOCK(prof_setup_lock); - int setup_profiling_timer(unsigned int multiplier) { - unsigned long flags; - int i; - - if ((!multiplier) || (timer_tick_offset / multiplier) < 1000) - return -EINVAL; - - spin_lock_irqsave(&prof_setup_lock, flags); - for_each_possible_cpu(i) - prof_multiplier(i) = multiplier; - current_tick_offset = (timer_tick_offset / multiplier); - spin_unlock_irqrestore(&prof_setup_lock, flags); - - return 0; + return -EINVAL; } static void __init smp_tune_scheduling(void) diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index d457079118d..48e1217c1e4 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -423,12 +424,6 @@ static struct sparc64_tick_ops hbtick_operations __read_mostly = { .softint_mask = 1UL << 0, }; -/* timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - * - * NOTE: On SUN5 systems the ticker interrupt comes in using 2 - * interrupts, one at level14 and one with softint bit 0. - */ unsigned long timer_tick_offset __read_mostly; static unsigned long timer_ticks_per_nsec_quotient __read_mostly; @@ -487,18 +482,27 @@ void notify_arch_cmos_timer(void) mod_timer(&sync_cmos_timer, jiffies + 1); } -irqreturn_t timer_interrupt(int irq, void *dev_id) +void timer_interrupt(int irq, struct pt_regs *regs) { + struct pt_regs *old_regs = set_irq_regs(regs); unsigned long ticks, compare, pstate; + unsigned long tick_mask = tick_ops->softint_mask; + + clear_softint(tick_mask); + + irq_enter(); - write_seqlock(&xtime_lock); + kstat_this_cpu.irqs[0]++; do { -#ifndef CONFIG_SMP profile_tick(CPU_PROFILING); update_process_times(user_mode(get_irq_regs())); -#endif - do_timer(1); + + if (smp_processor_id() == boot_cpu_id) { + write_seqlock(&xtime_lock); + do_timer(1); + write_sequnlock(&xtime_lock); + } /* Guarantee that the following sequences execute * uninterrupted. @@ -515,24 +519,13 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : /* no outputs */ : "r" (pstate)); - } while (time_after_eq(ticks, compare)); + } while (unlikely(time_after_eq(ticks, compare))); - write_sequnlock(&xtime_lock); + irq_exit(); - return IRQ_HANDLED; + set_irq_regs(old_regs); } -#ifdef CONFIG_SMP -void timer_tick_interrupt(struct pt_regs *regs) -{ - write_seqlock(&xtime_lock); - - do_timer(1); - - write_sequnlock(&xtime_lock); -} -#endif - /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ static void __init kick_start_clock(void) { diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index d7d2a8bdc66..7575aa371da 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S @@ -60,11 +60,7 @@ tl0_irq4: BTRAP(0x44) tl0_irq5: TRAP_IRQ(handler_irq, 5) tl0_irq6: BTRAP(0x46) BTRAP(0x47) BTRAP(0x48) BTRAP(0x49) tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) -#ifndef CONFIG_SMP -tl0_irq14: TRAP_IRQ(timer_irq, 14) -#else -tl0_irq14: TICK_SMP_IRQ -#endif +tl0_irq14: TRAP_IRQ(timer_interrupt, 14) tl0_irq15: TRAP_IRQ(handler_irq, 15) tl0_resv050: BTRAP(0x50) BTRAP(0x51) BTRAP(0x52) BTRAP(0x53) BTRAP(0x54) BTRAP(0x55) tl0_resv056: BTRAP(0x56) BTRAP(0x57) BTRAP(0x58) BTRAP(0x59) BTRAP(0x5a) BTRAP(0x5b) -- cgit v1.2.3 From 038cb01ea69cb24ecf30e3ec882e429c84badbeb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 22 Feb 2007 06:24:45 -0800 Subject: [SPARC64]: Add tick_nohz_{stop,restart}_sched_tick() calls to cpu_idle(). Signed-off-by: David S. Miller --- arch/sparc64/kernel/process.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index b291060c25a..a114151f9fb 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -88,12 +89,14 @@ void cpu_idle(void) set_thread_flag(TIF_POLLING_NRFLAG); while(1) { - if (need_resched()) { - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } - sparc64_yield(); + tick_nohz_stop_sched_tick(); + while (!need_resched()) + sparc64_yield(); + tick_nohz_restart_sched_tick(); + + preempt_enable_no_resched(); + schedule(); + preempt_disable(); } } -- cgit v1.2.3 From 112f48716d9f292c92a033cff9e3ce7405ed4280 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 5 Mar 2007 15:28:37 -0800 Subject: [SPARC64]: Add clocksource/clockevents support. I'd like to thank John Stul and others for helping me along the way. A lot of cleanups fell out of this. For example, the get_compare() tick_op was totally unused, so was deleted. And the most often used tick_op members were grouped together for cache-friendlyness. The sparc64 TSC is given to the kernel as a one-shot timer. tick_ops->init_timer() simply turns off the privileged bit in the tick register (when possible), and disables the interrupt by setting bit 63 in the compare register. The ->disable_irq() op also sets this bit. tick_ops->add_compare() is changed to: 1) Add the given delta to "tick" not to "compare" 2) Return a boolean which, if true, means that the tick value read after writing the compare value was found to have incremented past the initial tick value. This mirrors logic used in the HPET driver's ->next_event() method. Each tick_ops implementation also now provides a name string. And we feed this into the clocksource and clockevents layers. Signed-off-by: David S. Miller --- arch/sparc64/Kconfig | 14 +- arch/sparc64/kernel/smp.c | 29 +--- arch/sparc64/kernel/time.c | 408 ++++++++++++++++++++++++--------------------- 3 files changed, 231 insertions(+), 220 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 1a6348b565f..51c87fdd998 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -19,6 +19,14 @@ config SPARC64 SPARC64 ports; its web page is available at . +config GENERIC_TIME + bool + default y + +config GENERIC_CLOCKEVENTS + bool + default y + config 64BIT def_bool y @@ -34,10 +42,6 @@ config LOCKDEP_SUPPORT bool default y -config TIME_INTERPOLATION - bool - default y - config ARCH_MAY_HAVE_PC_FDC bool default y @@ -113,6 +117,8 @@ config GENERIC_HARDIRQS menu "General machine setup" +source "kernel/time/Kconfig" + config SMP bool "Symmetric multi-processing support" ---help--- diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 39deb0346eb..d4f0a70f484 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -123,7 +123,7 @@ void __init smp_store_cpu_info(int id) cpu_data(id).ecache_size, cpu_data(id).ecache_line_size); } -static void smp_setup_percpu_timer(void); +extern void setup_sparc64_timer(void); static volatile unsigned long callin_flag = 0; @@ -138,7 +138,7 @@ void __init smp_callin(void) __flush_tlb_all(); - smp_setup_percpu_timer(); + setup_sparc64_timer(); if (cheetah_pcache_forced_on) cheetah_enable_pcache(); @@ -175,8 +175,6 @@ void cpu_panic(void) panic("SMP bolixed\n"); } -static unsigned long current_tick_offset __read_mostly; - /* This tick register synchronization scheme is taken entirely from * the ia64 port, see arch/ia64/kernel/smpboot.c for details and credit. * @@ -259,7 +257,7 @@ void smp_synchronize_tick_client(void) } else adj = -delta; - tick_ops->add_tick(adj, current_tick_offset); + tick_ops->add_tick(adj); } #if DEBUG_TICK_SYNC t[i].rt = rt; @@ -1178,30 +1176,9 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) preempt_enable(); } -static void __init smp_setup_percpu_timer(void) -{ - unsigned long pstate; - - /* Guarantee that the following sequences execute - * uninterrupted. - */ - __asm__ __volatile__("rdpr %%pstate, %0\n\t" - "wrpr %0, %1, %%pstate" - : "=r" (pstate) - : "i" (PSTATE_IE)); - - tick_ops->init_tick(current_tick_offset); - - /* Restore PSTATE_IE. */ - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" - : /* no outputs */ - : "r" (pstate)); -} - void __init smp_tick_init(void) { boot_cpu_id = hard_smp_processor_id(); - current_tick_offset = timer_tick_offset; } /* /proc/profile writes can call this, don't __init it please. */ diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 48e1217c1e4..21e3b0b9d9c 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include @@ -61,6 +63,7 @@ static void __iomem *mstk48t59_regs; static int set_rtc_mmss(unsigned long); #define TICK_PRIV_BIT (1UL << 63) +#define TICKCMP_IRQ_BIT (1UL << 63) #ifdef CONFIG_SMP unsigned long profile_pc(struct pt_regs *regs) @@ -94,21 +97,22 @@ static void tick_disable_protection(void) : "g2"); } -static void tick_init_tick(unsigned long offset) +static void tick_disable_irq(void) { - tick_disable_protection(); - __asm__ __volatile__( - " rd %%tick, %%g1\n" - " andn %%g1, %1, %%g1\n" " ba,pt %%xcc, 1f\n" - " add %%g1, %0, %%g1\n" + " nop\n" " .align 64\n" - "1: wr %%g1, 0x0, %%tick_cmpr\n" + "1: wr %0, 0x0, %%tick_cmpr\n" " rd %%tick_cmpr, %%g0" : /* no outputs */ - : "r" (offset), "r" (TICK_PRIV_BIT) - : "g1"); + : "r" (TICKCMP_IRQ_BIT)); +} + +static void tick_init_tick(void) +{ + tick_disable_protection(); + tick_disable_irq(); } static unsigned long tick_get_tick(void) @@ -122,20 +126,14 @@ static unsigned long tick_get_tick(void) return ret & ~TICK_PRIV_BIT; } -static unsigned long tick_get_compare(void) +static int tick_add_compare(unsigned long adj) { - unsigned long ret; + unsigned long orig_tick, new_tick, new_compare; - __asm__ __volatile__("rd %%tick_cmpr, %0\n\t" - "mov %0, %0" - : "=r" (ret)); + __asm__ __volatile__("rd %%tick, %0" + : "=r" (orig_tick)); - return ret; -} - -static unsigned long tick_add_compare(unsigned long adj) -{ - unsigned long new_compare; + orig_tick &= ~TICKCMP_IRQ_BIT; /* Workaround for Spitfire Errata (#54 I think??), I discovered * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch @@ -146,44 +144,41 @@ static unsigned long tick_add_compare(unsigned long adj) * at the start of an I-cache line, and perform a dummy * read back from %tick_cmpr right after writing to it. -DaveM */ - __asm__ __volatile__("rd %%tick_cmpr, %0\n\t" - "ba,pt %%xcc, 1f\n\t" - " add %0, %1, %0\n\t" + __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" + " add %1, %2, %0\n\t" ".align 64\n" "1:\n\t" "wr %0, 0, %%tick_cmpr\n\t" - "rd %%tick_cmpr, %%g0" - : "=&r" (new_compare) - : "r" (adj)); + "rd %%tick_cmpr, %%g0\n\t" + : "=r" (new_compare) + : "r" (orig_tick), "r" (adj)); + + __asm__ __volatile__("rd %%tick, %0" + : "=r" (new_tick)); + new_tick &= ~TICKCMP_IRQ_BIT; - return new_compare; + return ((long)(new_tick - (orig_tick+adj))) > 0L; } -static unsigned long tick_add_tick(unsigned long adj, unsigned long offset) +static unsigned long tick_add_tick(unsigned long adj) { - unsigned long new_tick, tmp; + unsigned long new_tick; /* Also need to handle Blackbird bug here too. */ __asm__ __volatile__("rd %%tick, %0\n\t" - "add %0, %2, %0\n\t" + "add %0, %1, %0\n\t" "wrpr %0, 0, %%tick\n\t" - "andn %0, %4, %1\n\t" - "ba,pt %%xcc, 1f\n\t" - " add %1, %3, %1\n\t" - ".align 64\n" - "1:\n\t" - "wr %1, 0, %%tick_cmpr\n\t" - "rd %%tick_cmpr, %%g0" - : "=&r" (new_tick), "=&r" (tmp) - : "r" (adj), "r" (offset), "r" (TICK_PRIV_BIT)); + : "=&r" (new_tick) + : "r" (adj)); return new_tick; } static struct sparc64_tick_ops tick_operations __read_mostly = { + .name = "tick", .init_tick = tick_init_tick, + .disable_irq = tick_disable_irq, .get_tick = tick_get_tick, - .get_compare = tick_get_compare, .add_tick = tick_add_tick, .add_compare = tick_add_compare, .softint_mask = 1UL << 0, @@ -191,7 +186,15 @@ static struct sparc64_tick_ops tick_operations __read_mostly = { struct sparc64_tick_ops *tick_ops __read_mostly = &tick_operations; -static void stick_init_tick(unsigned long offset) +static void stick_disable_irq(void) +{ + __asm__ __volatile__( + "wr %0, 0x0, %%asr25" + : /* no outputs */ + : "r" (TICKCMP_IRQ_BIT)); +} + +static void stick_init_tick(void) { /* Writes to the %tick and %stick register are not * allowed on sun4v. The Hypervisor controls that @@ -199,6 +202,7 @@ static void stick_init_tick(unsigned long offset) */ if (tlb_type != hypervisor) { tick_disable_protection(); + tick_disable_irq(); /* Let the user get at STICK too. */ __asm__ __volatile__( @@ -210,14 +214,7 @@ static void stick_init_tick(unsigned long offset) : "g1", "g2"); } - __asm__ __volatile__( - " rd %%asr24, %%g1\n" - " andn %%g1, %1, %%g1\n" - " add %%g1, %0, %%g1\n" - " wr %%g1, 0x0, %%asr25" - : /* no outputs */ - : "r" (offset), "r" (TICK_PRIV_BIT) - : "g1"); + stick_disable_irq(); } static unsigned long stick_get_tick(void) @@ -230,49 +227,43 @@ static unsigned long stick_get_tick(void) return ret & ~TICK_PRIV_BIT; } -static unsigned long stick_get_compare(void) -{ - unsigned long ret; - - __asm__ __volatile__("rd %%asr25, %0" - : "=r" (ret)); - - return ret; -} - -static unsigned long stick_add_tick(unsigned long adj, unsigned long offset) +static unsigned long stick_add_tick(unsigned long adj) { - unsigned long new_tick, tmp; + unsigned long new_tick; __asm__ __volatile__("rd %%asr24, %0\n\t" - "add %0, %2, %0\n\t" + "add %0, %1, %0\n\t" "wr %0, 0, %%asr24\n\t" - "andn %0, %4, %1\n\t" - "add %1, %3, %1\n\t" - "wr %1, 0, %%asr25" - : "=&r" (new_tick), "=&r" (tmp) - : "r" (adj), "r" (offset), "r" (TICK_PRIV_BIT)); + : "=&r" (new_tick) + : "r" (adj)); return new_tick; } -static unsigned long stick_add_compare(unsigned long adj) +static int stick_add_compare(unsigned long adj) { - unsigned long new_compare; + unsigned long orig_tick, new_tick; - __asm__ __volatile__("rd %%asr25, %0\n\t" - "add %0, %1, %0\n\t" - "wr %0, 0, %%asr25" - : "=&r" (new_compare) - : "r" (adj)); + __asm__ __volatile__("rd %%asr24, %0" + : "=r" (orig_tick)); + orig_tick &= ~TICKCMP_IRQ_BIT; + + __asm__ __volatile__("wr %0, 0, %%asr25" + : /* no outputs */ + : "r" (orig_tick + adj)); + + __asm__ __volatile__("rd %%asr24, %0" + : "=r" (new_tick)); + new_tick &= ~TICKCMP_IRQ_BIT; - return new_compare; + return ((long)(new_tick - (orig_tick+adj))) > 0L; } static struct sparc64_tick_ops stick_operations __read_mostly = { + .name = "stick", .init_tick = stick_init_tick, + .disable_irq = stick_disable_irq, .get_tick = stick_get_tick, - .get_compare = stick_get_compare, .add_tick = stick_add_tick, .add_compare = stick_add_compare, .softint_mask = 1UL << 16, @@ -321,20 +312,6 @@ static unsigned long __hbird_read_stick(void) return ret; } -static unsigned long __hbird_read_compare(void) -{ - unsigned long low, high; - unsigned long addr = HBIRD_STICKCMP_ADDR; - - __asm__ __volatile__("ldxa [%2] %3, %0\n\t" - "add %2, 0x8, %2\n\t" - "ldxa [%2] %3, %1" - : "=&r" (low), "=&r" (high), "=&r" (addr) - : "i" (ASI_PHYS_BYPASS_EC_E), "2" (addr)); - - return (high << 32UL) | low; -} - static void __hbird_write_stick(unsigned long val) { unsigned long low = (val & 0xffffffffUL); @@ -365,10 +342,13 @@ static void __hbird_write_compare(unsigned long val) "i" (ASI_PHYS_BYPASS_EC_E)); } -static void hbtick_init_tick(unsigned long offset) +static void hbtick_disable_irq(void) { - unsigned long val; + __hbird_write_compare(TICKCMP_IRQ_BIT); +} +static void hbtick_init_tick(void) +{ tick_disable_protection(); /* XXX This seems to be necessary to 'jumpstart' Hummingbird @@ -378,8 +358,7 @@ static void hbtick_init_tick(unsigned long offset) */ __hbird_write_stick(__hbird_read_stick()); - val = __hbird_read_stick() & ~TICK_PRIV_BIT; - __hbird_write_compare(val + offset); + hbtick_disable_irq(); } static unsigned long hbtick_get_tick(void) @@ -387,45 +366,40 @@ static unsigned long hbtick_get_tick(void) return __hbird_read_stick() & ~TICK_PRIV_BIT; } -static unsigned long hbtick_get_compare(void) -{ - return __hbird_read_compare(); -} - -static unsigned long hbtick_add_tick(unsigned long adj, unsigned long offset) +static unsigned long hbtick_add_tick(unsigned long adj) { unsigned long val; val = __hbird_read_stick() + adj; __hbird_write_stick(val); - val &= ~TICK_PRIV_BIT; - __hbird_write_compare(val + offset); - return val; } -static unsigned long hbtick_add_compare(unsigned long adj) +static int hbtick_add_compare(unsigned long adj) { - unsigned long val = __hbird_read_compare() + adj; + unsigned long val = __hbird_read_stick(); + unsigned long val2; - val &= ~TICK_PRIV_BIT; + val &= ~TICKCMP_IRQ_BIT; + val += adj; __hbird_write_compare(val); - return val; + val2 = __hbird_read_stick() & ~TICKCMP_IRQ_BIT; + + return ((long)(val2 - val)) > 0L; } static struct sparc64_tick_ops hbtick_operations __read_mostly = { + .name = "hbtick", .init_tick = hbtick_init_tick, + .disable_irq = hbtick_disable_irq, .get_tick = hbtick_get_tick, - .get_compare = hbtick_get_compare, .add_tick = hbtick_add_tick, .add_compare = hbtick_add_compare, .softint_mask = 1UL << 0, }; -unsigned long timer_tick_offset __read_mostly; - static unsigned long timer_ticks_per_nsec_quotient __read_mostly; #define TICK_SIZE (tick_nsec / 1000) @@ -482,50 +456,6 @@ void notify_arch_cmos_timer(void) mod_timer(&sync_cmos_timer, jiffies + 1); } -void timer_interrupt(int irq, struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - unsigned long ticks, compare, pstate; - unsigned long tick_mask = tick_ops->softint_mask; - - clear_softint(tick_mask); - - irq_enter(); - - kstat_this_cpu.irqs[0]++; - - do { - profile_tick(CPU_PROFILING); - update_process_times(user_mode(get_irq_regs())); - - if (smp_processor_id() == boot_cpu_id) { - write_seqlock(&xtime_lock); - do_timer(1); - write_sequnlock(&xtime_lock); - } - - /* Guarantee that the following sequences execute - * uninterrupted. - */ - __asm__ __volatile__("rdpr %%pstate, %0\n\t" - "wrpr %0, %1, %%pstate" - : "=r" (pstate) - : "i" (PSTATE_IE)); - - compare = tick_ops->add_compare(timer_tick_offset); - ticks = tick_ops->get_tick(); - - /* Restore PSTATE_IE. */ - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" - : /* no outputs */ - : "r" (pstate)); - } while (unlikely(time_after_eq(ticks, compare))); - - irq_exit(); - - set_irq_regs(old_regs); -} - /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ static void __init kick_start_clock(void) { @@ -923,7 +853,6 @@ static unsigned long sparc64_init_timers(void) prop = of_find_property(dp, "stick-frequency", NULL); } clock = *(unsigned int *) prop->value; - timer_tick_offset = clock / HZ; #ifdef CONFIG_SMP smp_tick_init(); @@ -932,26 +861,6 @@ static unsigned long sparc64_init_timers(void) return clock; } -static void sparc64_start_timers(void) -{ - unsigned long pstate; - - /* Guarantee that the following sequences execute - * uninterrupted. - */ - __asm__ __volatile__("rdpr %%pstate, %0\n\t" - "wrpr %0, %1, %%pstate" - : "=r" (pstate) - : "i" (PSTATE_IE)); - - tick_ops->init_tick(timer_tick_offset); - - /* Restore PSTATE_IE. */ - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" - : /* no outputs */ - : "r" (pstate)); -} - struct freq_table { unsigned long clock_tick_ref; unsigned int ref_freq; @@ -998,29 +907,148 @@ static struct notifier_block sparc64_cpufreq_notifier_block = { #endif /* CONFIG_CPU_FREQ */ -static struct time_interpolator sparc64_cpu_interpolator = { - .source = TIME_SOURCE_CPU, - .shift = 16, - .mask = 0xffffffffffffffffLL +static int sparc64_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + return tick_ops->add_compare(delta); +} + +static void sparc64_timer_setup(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_ONESHOT: + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + tick_ops->disable_irq(); + break; + + case CLOCK_EVT_MODE_PERIODIC: + case CLOCK_EVT_MODE_UNUSED: + WARN_ON(1); + break; + }; +} + +static struct clock_event_device sparc64_clockevent = { + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_mode = sparc64_timer_setup, + .set_next_event = sparc64_next_event, + .rating = 100, + .shift = 30, + .irq = -1, }; +static DEFINE_PER_CPU(struct clock_event_device, sparc64_events); -/* The quotient formula is taken from the IA64 port. */ -#define SPARC64_NSEC_PER_CYC_SHIFT 10UL -void __init time_init(void) +void timer_interrupt(int irq, struct pt_regs *regs) { - unsigned long clock = sparc64_init_timers(); + struct pt_regs *old_regs = set_irq_regs(regs); + unsigned long tick_mask = tick_ops->softint_mask; + int cpu = smp_processor_id(); + struct clock_event_device *evt = &per_cpu(sparc64_events, cpu); + + clear_softint(tick_mask); + + irq_enter(); + + kstat_this_cpu.irqs[0]++; + + if (unlikely(!evt->event_handler)) { + printk(KERN_WARNING + "Spurious SPARC64 timer interrupt on cpu %d\n", cpu); + } else + evt->event_handler(evt); + + irq_exit(); + + set_irq_regs(old_regs); +} - sparc64_cpu_interpolator.frequency = clock; - register_time_interpolator(&sparc64_cpu_interpolator); +void __devinit setup_sparc64_timer(void) +{ + struct clock_event_device *sevt; + unsigned long pstate; - /* Now that the interpolator is registered, it is - * safe to start the timer ticking. + /* Guarantee that the following sequences execute + * uninterrupted. */ - sparc64_start_timers(); + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + tick_ops->init_tick(); + + /* Restore PSTATE_IE. */ + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : /* no outputs */ + : "r" (pstate)); + + sevt = &__get_cpu_var(sparc64_events); + + memcpy(sevt, &sparc64_clockevent, sizeof(*sevt)); + sevt->cpumask = cpumask_of_cpu(smp_processor_id()); + + clockevents_register_device(sevt); +} + +#define SPARC64_NSEC_PER_CYC_SHIFT 32UL + +static struct clocksource clocksource_tick = { + .rating = 100, + .mask = CLOCKSOURCE_MASK(64), + .shift = 16, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void __init setup_clockevent_multiplier(unsigned long hz) +{ + unsigned long mult, shift = 32; + + while (1) { + mult = div_sc(hz, NSEC_PER_SEC, shift); + if (mult && (mult >> 32UL) == 0UL) + break; + + shift--; + } + + sparc64_clockevent.shift = shift; + sparc64_clockevent.mult = mult; +} + +void __init time_init(void) +{ + unsigned long clock = sparc64_init_timers(); timer_ticks_per_nsec_quotient = - (((NSEC_PER_SEC << SPARC64_NSEC_PER_CYC_SHIFT) + - (clock / 2)) / clock); + clocksource_hz2mult(clock, SPARC64_NSEC_PER_CYC_SHIFT); + + clocksource_tick.name = tick_ops->name; + clocksource_tick.mult = + clocksource_hz2mult(clock, + clocksource_tick.shift); + clocksource_tick.read = tick_ops->get_tick; + + printk("clocksource: mult[%x] shift[%d]\n", + clocksource_tick.mult, clocksource_tick.shift); + + clocksource_register(&clocksource_tick); + + sparc64_clockevent.name = tick_ops->name; + + setup_clockevent_multiplier(clock); + + sparc64_clockevent.max_delta_ns = + clockevent_delta2ns(0x7fffffffffffffff, &sparc64_clockevent); + sparc64_clockevent.min_delta_ns = + clockevent_delta2ns(0xF, &sparc64_clockevent); + + printk("clockevent: mult[%lx] shift[%d]\n", + sparc64_clockevent.mult, sparc64_clockevent.shift); + + setup_sparc64_timer(); #ifdef CONFIG_CPU_FREQ cpufreq_register_notifier(&sparc64_cpufreq_notifier_block, -- cgit v1.2.3 From d62c6f093a1ef8fa5f8951e8da93c8ddd3ce193a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 27 Mar 2007 01:20:14 -0700 Subject: [SPARC64]: Fix sparc64_next_event() error return. It should return an error code not a boolean. Based upon an hpet timer fix by Thomas Gleixner. Signed-off-by: David S. Miller --- arch/sparc64/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 21e3b0b9d9c..0eb846534ff 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -910,7 +910,7 @@ static struct notifier_block sparc64_cpufreq_notifier_block = { static int sparc64_next_event(unsigned long delta, struct clock_event_device *evt) { - return tick_ops->add_compare(delta); + return tick_ops->add_compare(delta) ? -ETIME : 0; } static void sparc64_timer_setup(enum clock_event_mode mode, -- cgit v1.2.3 From 644923d4a5f117d437aefd47688d1141cc8361ed Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Wed, 28 Mar 2007 19:10:12 -0700 Subject: [SPARC64]: Small cleanups time.c - Removes days_in_mo[], as it's almost identical to month_days[] - Use the leapyear() macro - Line length wrapping. Signed-off-by: Tony Breeds Signed-off-by: David S. Miller --- arch/sparc64/kernel/time.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 0eb846534ff..3cb761ec895 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -1177,10 +1177,6 @@ static int set_rtc_mmss(unsigned long nowtime) #define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ static unsigned char mini_rtc_status; /* bitmapped status byte. */ -/* months start at 0 now */ -static unsigned char days_in_mo[] = -{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - #define FEBRUARY 2 #define STARTOFTIME 1970 #define SECDAY 86400L @@ -1329,8 +1325,7 @@ static int mini_rtc_ioctl(struct inode *inode, struct file *file, case RTC_SET_TIME: /* Set the RTC */ { - int year; - unsigned char leap_yr; + int year, days; if (!capable(CAP_SYS_TIME)) return -EACCES; @@ -1339,14 +1334,14 @@ static int mini_rtc_ioctl(struct inode *inode, struct file *file, return -EFAULT; year = wtime.tm_year + 1900; - leap_yr = ((!(year % 4) && (year % 100)) || - !(year % 400)); + days = month_days[wtime.tm_mon] + + ((wtime.tm_mon == 1) && leapyear(year)); - if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || (wtime.tm_mday < 1)) + if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || + (wtime.tm_mday < 1)) return -EINVAL; - if (wtime.tm_mday < 0 || wtime.tm_mday > - (days_in_mo[wtime.tm_mon] + ((wtime.tm_mon == 1) && leap_yr))) + if (wtime.tm_mday < 0 || wtime.tm_mday > days) return -EINVAL; if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 || -- cgit v1.2.3 From 8271f04242af8ddf8390f289cd6ef78fb3e3c6d9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Mar 2007 00:47:23 -0700 Subject: [SPARC]: constify of_get_property return: arch/sparc Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- arch/sparc/kernel/ebus.c | 10 +++++----- arch/sparc/kernel/of_device.c | 21 +++++++++++---------- arch/sparc/kernel/prom.c | 6 +++--- arch/sparc/kernel/time.c | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index ba58c3a061f..7724e206715 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -86,8 +86,8 @@ int __init ebus_blacklist_irq(char *name) void __init fill_ebus_child(struct device_node *dp, struct linux_ebus_child *dev) { - int *regs; - int *irqs; + const int *regs; + const int *irqs; int i, len; dev->prom_node = dp; @@ -146,9 +146,9 @@ void __init fill_ebus_child(struct device_node *dp, void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) { - struct linux_prom_registers *regs; + const struct linux_prom_registers *regs; struct linux_ebus_child *child; - int *irqs; + const int *irqs; int i, n, len; unsigned long baseaddr; @@ -269,7 +269,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d void __init ebus_init(void) { - struct linux_prom_pci_registers *regs; + const struct linux_prom_pci_registers *regs; struct linux_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 48c24f7518c..fd7f8cb668a 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -210,7 +210,7 @@ struct of_bus { int *addrc, int *sizec); int (*map)(u32 *addr, const u32 *range, int na, int ns, int pna); - unsigned int (*get_flags)(u32 *addr); + unsigned int (*get_flags)(const u32 *addr); }; /* @@ -270,7 +270,7 @@ static int of_bus_default_map(u32 *addr, const u32 *range, return 0; } -static unsigned int of_bus_default_get_flags(u32 *addr) +static unsigned int of_bus_default_get_flags(const u32 *addr) { return IORESOURCE_MEM; } @@ -334,7 +334,7 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, return 0; } -static unsigned int of_bus_pci_get_flags(u32 *addr) +static unsigned int of_bus_pci_get_flags(const u32 *addr) { unsigned int flags = 0; u32 w = addr[0]; @@ -375,7 +375,7 @@ static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) return of_bus_default_map(addr, range, na, ns, pna); } -static unsigned int of_bus_sbus_get_flags(u32 *addr) +static unsigned int of_bus_sbus_get_flags(const u32 *addr) { return IORESOURCE_MEM; } @@ -432,7 +432,7 @@ static int __init build_one_resource(struct device_node *parent, u32 *addr, int na, int ns, int pna) { - u32 *ranges; + const u32 *ranges; unsigned int rlen; int rone; @@ -470,7 +470,7 @@ static void __init build_device_resources(struct of_device *op, struct of_bus *bus; int na, ns; int index, num_reg; - void *preg; + const void *preg; if (!parent) return; @@ -492,7 +492,7 @@ static void __init build_device_resources(struct of_device *op, for (index = 0; index < num_reg; index++) { struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; - u32 *reg = (preg + (index * ((na + ns) * 4))); + const u32 *reg = (preg + (index * ((na + ns) * 4))); struct device_node *dp = op->node; struct device_node *pp = p_op->node; struct of_bus *pbus, *dbus; @@ -559,7 +559,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, struct device *parent) { struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); - struct linux_prom_irqs *intr; + const struct linux_prom_irqs *intr; int len, i; if (!op) @@ -579,7 +579,8 @@ static struct of_device * __init scan_one_device(struct device_node *dp, for (i = 0; i < op->num_irqs; i++) op->irqs[i] = intr[i].pri; } else { - unsigned int *irq = of_get_property(dp, "interrupts", &len); + const unsigned int *irq = + of_get_property(dp, "interrupts", &len); if (irq) { op->num_irqs = len / sizeof(unsigned int); @@ -594,7 +595,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, }; struct device_node *io_unit, *sbi = dp->parent; - struct linux_prom_registers *regs; + const struct linux_prom_registers *regs; int board, slot; while (sbi) { diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 2cc302b6bec..8359d00a248 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -37,7 +37,7 @@ int of_device_is_compatible(struct device_node *device, const char *compat) const char* cp; int cplen, l; - cp = (char *) of_get_property(device, "compatible", &cplen); + cp = of_get_property(device, "compatible", &cplen); if (cp == NULL) return 0; while (cplen > 0) { @@ -192,7 +192,7 @@ EXPORT_SYMBOL(of_getintprop_default); int of_n_addr_cells(struct device_node *np) { - int* ip; + const int* ip; do { if (np->parent) np = np->parent; @@ -207,7 +207,7 @@ EXPORT_SYMBOL(of_n_addr_cells); int of_n_size_cells(struct device_node *np) { - int* ip; + const int* ip; do { if (np->parent) np = np->parent; diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 9bb1240aaf8..f1401b57ccc 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -301,7 +301,7 @@ static __inline__ void sun4_clock_probe(void) static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->node; - char *model = of_get_property(dp, "model", NULL); + const char *model = of_get_property(dp, "model", NULL); if (!model) return -ENODEV; -- cgit v1.2.3 From 6a23acf3905287eb952a6f1dbbc8fb3e4eeae2f6 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 23 Apr 2007 15:53:27 -0700 Subject: [SPARC64]: constify of_get_property return: arch/sparc64 Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- arch/sparc64/kernel/central.c | 12 +++++++----- arch/sparc64/kernel/chmc.c | 4 ++-- arch/sparc64/kernel/ebus.c | 2 +- arch/sparc64/kernel/irq.c | 2 +- arch/sparc64/kernel/isa.c | 2 +- arch/sparc64/kernel/of_device.c | 24 ++++++++++++------------ arch/sparc64/kernel/pci_sun4v.c | 8 ++++---- arch/sparc64/kernel/prom.c | 24 ++++++++++++------------ arch/sparc64/kernel/sbus.c | 4 ++-- arch/sparc64/kernel/time.c | 4 ++-- arch/sparc64/solaris/misc.c | 3 ++- 11 files changed, 46 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c index e724c54af02..c65b2f9c98d 100644 --- a/arch/sparc64/kernel/central.c +++ b/arch/sparc64/kernel/central.c @@ -32,7 +32,7 @@ static void central_probe_failure(int line) static void central_ranges_init(struct linux_central *central) { struct device_node *dp = central->prom_node; - void *pval; + const void *pval; int len; central->num_central_ranges = 0; @@ -47,7 +47,7 @@ static void central_ranges_init(struct linux_central *central) static void fhc_ranges_init(struct linux_fhc *fhc) { struct device_node *dp = fhc->prom_node; - void *pval; + const void *pval; int len; fhc->num_fhc_ranges = 0; @@ -119,7 +119,7 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r) static void probe_other_fhcs(void) { struct device_node *dp; - struct linux_prom64_registers *fpregs; + const struct linux_prom64_registers *fpregs; for_each_node_by_name(dp, "fhc") { struct linux_fhc *fhc; @@ -190,7 +190,8 @@ static void probe_clock_board(struct linux_central *central, struct device_node *fp) { struct device_node *dp; - struct linux_prom_registers cregs[3], *pr; + struct linux_prom_registers cregs[3]; + const struct linux_prom_registers *pr; int nslots, tmp, nregs; dp = fp->child; @@ -299,7 +300,8 @@ static void init_all_fhc_hw(void) void central_probe(void) { - struct linux_prom_registers fpregs[6], *pr; + struct linux_prom_registers fpregs[6]; + const struct linux_prom_registers *pr; struct linux_fhc *fhc; struct device_node *dp, *fp; int err; diff --git a/arch/sparc64/kernel/chmc.c b/arch/sparc64/kernel/chmc.c index 9699abeb990..777d3457704 100644 --- a/arch/sparc64/kernel/chmc.c +++ b/arch/sparc64/kernel/chmc.c @@ -343,8 +343,8 @@ static int init_one_mctrl(struct device_node *dp) { struct mctrl_info *mp = kzalloc(sizeof(*mp), GFP_KERNEL); int portid = of_getintprop_default(dp, "portid", -1); - struct linux_prom64_registers *regs; - void *pval; + const struct linux_prom64_registers *regs; + const void *pval; int len; if (!mp) diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 35bf895fdee..1962bfa4ef3 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -285,7 +285,7 @@ static void __init fill_ebus_child(struct device_node *dp, int non_standard_regs) { struct of_device *op; - int *regs; + const int *regs; int i, len; dev->prom_node = dp; diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index d1bb3b3f263..6241e3dbbd5 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -627,7 +627,7 @@ static u64 prom_limit0, prom_limit1; static void map_prom_timers(void) { struct device_node *dp; - unsigned int *addr; + const unsigned int *addr; /* PROM timer node hangs out in the top level of device siblings... */ dp = of_find_node_by_path("/"); diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index 98721a8f861..791eeb7e387 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c @@ -24,7 +24,7 @@ static void __init report_dev(struct sparc_isa_device *isa_dev, int child) static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev) { - struct linux_prom_registers *pregs; + const struct linux_prom_registers *pregs; unsigned long base, len; int prop_len; diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index fb9bf1e4d03..6b8798141f2 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -245,7 +245,7 @@ struct of_bus { int *addrc, int *sizec); int (*map)(u32 *addr, const u32 *range, int na, int ns, int pna); - unsigned int (*get_flags)(u32 *addr); + unsigned int (*get_flags)(const u32 *addr); }; /* @@ -305,7 +305,7 @@ static int of_bus_default_map(u32 *addr, const u32 *range, return 0; } -static unsigned int of_bus_default_get_flags(u32 *addr) +static unsigned int of_bus_default_get_flags(const u32 *addr) { return IORESOURCE_MEM; } @@ -369,7 +369,7 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, return 0; } -static unsigned int of_bus_pci_get_flags(u32 *addr) +static unsigned int of_bus_pci_get_flags(const u32 *addr) { unsigned int flags = 0; u32 w = addr[0]; @@ -482,7 +482,7 @@ static int __init build_one_resource(struct device_node *parent, u32 *addr, int na, int ns, int pna) { - u32 *ranges; + const u32 *ranges; unsigned int rlen; int rone; @@ -513,7 +513,7 @@ static int __init build_one_resource(struct device_node *parent, static int __init use_1to1_mapping(struct device_node *pp) { - char *model; + const char *model; /* If this is on the PMU bus, don't try to translate it even * if a ranges property exists. @@ -548,7 +548,7 @@ static void __init build_device_resources(struct of_device *op, struct of_bus *bus; int na, ns; int index, num_reg; - void *preg; + const void *preg; if (!parent) return; @@ -578,7 +578,7 @@ static void __init build_device_resources(struct of_device *op, for (index = 0; index < num_reg; index++) { struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; - u32 *reg = (preg + (index * ((na + ns) * 4))); + const u32 *reg = (preg + (index * ((na + ns) * 4))); struct device_node *dp = op->node; struct device_node *pp = p_op->node; struct of_bus *pbus, *dbus; @@ -643,14 +643,14 @@ static void __init build_device_resources(struct of_device *op, static struct device_node * __init apply_interrupt_map(struct device_node *dp, struct device_node *pp, - u32 *imap, int imlen, u32 *imask, + const u32 *imap, int imlen, const u32 *imask, unsigned int *irq_p) { struct device_node *cp; unsigned int irq = *irq_p; struct of_bus *bus; phandle handle; - u32 *reg; + const u32 *reg; int na, num_reg, i; bus = of_match_bus(pp); @@ -705,7 +705,7 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp, struct device_node *pp, unsigned int irq) { - struct linux_prom_pci_registers *regs; + const struct linux_prom_pci_registers *regs; unsigned int bus, devfn, slot, ret; if (irq < 1 || irq > 4) @@ -794,7 +794,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, pp = dp->parent; ip = NULL; while (pp) { - void *imap, *imsk; + const void *imap, *imsk; int imlen; imap = of_get_property(pp, "interrupt-map", &imlen); @@ -859,7 +859,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, struct device *parent) { struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); - unsigned int *irq; + const unsigned int *irq; int len, i; if (!op) diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index ec22cd61ec8..bd74c155519 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1281,7 +1281,7 @@ h_error: static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) { - u32 *val; + const u32 *val; int len; val = of_get_property(pbm->prom_node, "#msi-eqs", &len); @@ -1289,16 +1289,16 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) goto no_msi; pbm->msiq_num = *val; if (pbm->msiq_num) { - struct msiq_prop { + const struct msiq_prop { u32 first_msiq; u32 num_msiq; u32 first_devino; } *mqp; - struct msi_range_prop { + const struct msi_range_prop { u32 first_msi; u32 num_msi; } *mrng; - struct addr_range_prop { + const struct addr_range_prop { u32 msi32_high; u32 msi32_low; u32 msi32_len; diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 0917c24c4f0..25b70368973 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -196,7 +196,7 @@ EXPORT_SYMBOL(of_getintprop_default); int of_n_addr_cells(struct device_node *np) { - int* ip; + const int* ip; do { if (np->parent) np = np->parent; @@ -211,7 +211,7 @@ EXPORT_SYMBOL(of_n_addr_cells); int of_n_size_cells(struct device_node *np) { - int* ip; + const int* ip; do { if (np->parent) np = np->parent; @@ -397,7 +397,7 @@ static unsigned int psycho_irq_build(struct device_node *dp, static void psycho_irq_trans_init(struct device_node *dp) { - struct linux_prom64_registers *regs; + const struct linux_prom64_registers *regs; dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); dp->irq_trans->irq_build = psycho_irq_build; @@ -547,7 +547,7 @@ static unsigned long __sabre_onboard_imap_off[] = { static int sabre_device_needs_wsync(struct device_node *dp) { struct device_node *parent = dp->parent; - char *parent_model, *parent_compat; + const char *parent_model, *parent_compat; /* This traversal up towards the root is meant to * handle two cases: @@ -589,7 +589,7 @@ static unsigned int sabre_irq_build(struct device_node *dp, { struct sabre_irq_data *irq_data = _data; unsigned long controller_regs = irq_data->controller_regs; - struct linux_prom_pci_registers *regs; + const struct linux_prom_pci_registers *regs; unsigned long imap, iclr; unsigned long imap_off, iclr_off; int inofixup = 0; @@ -639,9 +639,9 @@ static unsigned int sabre_irq_build(struct device_node *dp, static void sabre_irq_trans_init(struct device_node *dp) { - struct linux_prom64_registers *regs; + const struct linux_prom64_registers *regs; struct sabre_irq_data *irq_data; - u32 *busrange; + const u32 *busrange; dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); dp->irq_trans->irq_build = sabre_irq_build; @@ -795,7 +795,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) { - struct linux_prom64_registers *regs; + const struct linux_prom64_registers *regs; struct schizo_irq_data *irq_data; dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); @@ -836,7 +836,7 @@ static unsigned int pci_sun4v_irq_build(struct device_node *dp, static void pci_sun4v_irq_trans_init(struct device_node *dp) { - struct linux_prom64_registers *regs; + const struct linux_prom64_registers *regs; dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); dp->irq_trans->irq_build = pci_sun4v_irq_build; @@ -940,7 +940,7 @@ static unsigned int sbus_of_build_irq(struct device_node *dp, void *_data) { unsigned long reg_base = (unsigned long) _data; - struct linux_prom_registers *regs; + const struct linux_prom_registers *regs; unsigned long imap, iclr; int sbus_slot = 0; int sbus_level = 0; @@ -994,7 +994,7 @@ static unsigned int sbus_of_build_irq(struct device_node *dp, static void sbus_irq_trans_init(struct device_node *dp) { - struct linux_prom64_registers *regs; + const struct linux_prom64_registers *regs; dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); dp->irq_trans->irq_build = sbus_of_build_irq; @@ -1080,7 +1080,7 @@ static unsigned int sun4v_vdev_irq_build(struct device_node *dp, static void sun4v_vdev_irq_trans_init(struct device_node *dp) { - struct linux_prom64_registers *regs; + const struct linux_prom64_registers *regs; dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); dp->irq_trans->irq_build = sun4v_vdev_irq_build; diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 14f78fb5e89..d403f3df2dc 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -1025,7 +1025,7 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) /* Boot time initialization. */ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) { - struct linux_prom64_registers *pr; + const struct linux_prom64_registers *pr; struct device_node *dp; struct sbus_iommu *iommu; unsigned long regs; @@ -1133,7 +1133,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) void sbus_fill_device_irq(struct sbus_dev *sdev) { struct device_node *dp = of_find_node_by_phandle(sdev->prom_node); - struct linux_prom_irqs *irqs; + const struct linux_prom_irqs *irqs; irqs = of_get_property(dp, "interrupts", NULL); if (!irqs) { diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 3cb761ec895..259063f41f9 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -704,7 +704,7 @@ retry: return -EOPNOTSUPP; } -static int __init clock_model_matches(char *model) +static int __init clock_model_matches(const char *model) { if (strcmp(model, "mk48t02") && strcmp(model, "mk48t08") && @@ -721,7 +721,7 @@ static int __init clock_model_matches(char *model) static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->node; - char *model = of_get_property(dp, "model", NULL); + const char *model = of_get_property(dp, "model", NULL); unsigned long size, flags; void __iomem *regs; diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 9fcaad6dd11..542c808ec2c 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -224,7 +224,8 @@ static char *serial(char *buffer, int sz) *buffer = 0; if (dp) { - char *val = of_get_property(dp, "system-board-serial#", &len); + const char *val = + of_get_property(dp, "system-board-serial#", &len); if (val && len > 0) { if (len > sz) -- cgit v1.2.3 From 64b94701c0714f814e640ff351d5f784fdc0381e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Mar 2007 00:53:28 -0700 Subject: [SPARC/64]: constify of_get_property return Finally, we actually change the functions themselves. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- arch/sparc/kernel/prom.c | 2 +- arch/sparc64/kernel/prom.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 8359d00a248..d2a8297d56f 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -170,7 +170,7 @@ EXPORT_SYMBOL(of_find_property); * Find a property with a given name for a given node * and return the value. */ -void *of_get_property(struct device_node *np, const char *name, int *lenp) +const void *of_get_property(struct device_node *np, const char *name, int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 25b70368973..493db961a1f 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -174,7 +174,7 @@ EXPORT_SYMBOL(of_find_property); * Find a property with a given name for a given node * and return the value. */ -void *of_get_property(struct device_node *np, const char *name, int *lenp) +const void *of_get_property(struct device_node *np, const char *name, int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; -- cgit v1.2.3 From 357418e7cac16fed4ca558c6037d189d2109c9c2 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Mar 2007 00:54:04 -0700 Subject: [SPARC]: constify some paramaters of OF routines This starts bringing the PowerPC and Sparc implemetations back closer together. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- arch/sparc/kernel/prom.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index d2a8297d56f..9ddf6035915 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -32,7 +32,8 @@ static struct device_node *allnodes; */ static DEFINE_RWLOCK(devtree_lock); -int of_device_is_compatible(struct device_node *device, const char *compat) +int of_device_is_compatible(const struct device_node *device, + const char *compat) { const char* cp; int cplen, l; @@ -150,7 +151,8 @@ struct device_node *of_find_compatible_node(struct device_node *from, } EXPORT_SYMBOL(of_find_compatible_node); -struct property *of_find_property(struct device_node *np, const char *name, +struct property *of_find_property(const struct device_node *np, + const char *name, int *lenp) { struct property *pp; @@ -170,7 +172,8 @@ EXPORT_SYMBOL(of_find_property); * Find a property with a given name for a given node * and return the value. */ -const void *of_get_property(struct device_node *np, const char *name, int *lenp) +const void *of_get_property(const struct device_node *np, const char *name, + int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; -- cgit v1.2.3 From ded220bd8f0823771fc0a9bdf7f5bcbe543197b6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 29 Mar 2007 01:18:42 -0700 Subject: [STRING]: Move strcasecmp/strncasecmp to lib/string.c We have several platforms using local copies of identical code. Signed-off-by: David S. Miller --- arch/alpha/lib/Makefile | 1 - arch/alpha/lib/strcasecmp.c | 26 -------------------------- arch/powerpc/kernel/ppc_ksyms.c | 2 -- arch/powerpc/lib/Makefile | 5 ++--- arch/powerpc/lib/strcase.c | 25 ------------------------- arch/ppc/kernel/ppc_ksyms.c | 2 -- arch/ppc/lib/Makefile | 2 +- arch/ppc/lib/strcase.c | 24 ------------------------ arch/sh/lib/Makefile | 2 +- arch/sh/lib/strcasecmp.c | 26 -------------------------- arch/xtensa/lib/Makefile | 2 +- arch/xtensa/lib/strcasecmp.c | 32 -------------------------------- 12 files changed, 5 insertions(+), 144 deletions(-) delete mode 100644 arch/alpha/lib/strcasecmp.c delete mode 100644 arch/powerpc/lib/strcase.c delete mode 100644 arch/ppc/lib/strcase.c delete mode 100644 arch/sh/lib/strcasecmp.c delete mode 100644 arch/xtensa/lib/strcasecmp.c (limited to 'arch') diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index 21cf624d732..ea098f3b629 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile @@ -36,7 +36,6 @@ lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \ $(ev6-y)csum_ipv6_magic.o \ $(ev6-y)clear_page.o \ $(ev6-y)copy_page.o \ - strcasecmp.o \ fpreg.o \ callback_srm.o srm_puts.o srm_printk.o diff --git a/arch/alpha/lib/strcasecmp.c b/arch/alpha/lib/strcasecmp.c deleted file mode 100644 index 4e57a216fea..00000000000 --- a/arch/alpha/lib/strcasecmp.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * linux/arch/alpha/lib/strcasecmp.c - */ - -#include - - -/* We handle nothing here except the C locale. Since this is used in - only one place, on strings known to contain only 7 bit ASCII, this - is ok. */ - -int strcasecmp(const char *a, const char *b) -{ - int ca, cb; - - do { - ca = *a++ & 0xff; - cb = *b++ & 0xff; - if (ca >= 'A' && ca <= 'Z') - ca += 'a' - 'A'; - if (cb >= 'A' && cb <= 'Z') - cb += 'a' - 'A'; - } while (ca == cb && ca != '\0'); - - return ca - cb; -} diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index ecee596d28f..2f8e9c02c92 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -84,8 +84,6 @@ EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strcat); EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strcasecmp); -EXPORT_SYMBOL(strncasecmp); EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 4b1ba49fbd9..450258de7ca 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -7,13 +7,12 @@ EXTRA_CFLAGS += -mno-minimal-toc endif ifeq ($(CONFIG_PPC_MERGE),y) -obj-y := string.o strcase.o +obj-y := string.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o endif obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ - memcpy_64.o usercopy_64.o mem_64.o string.o \ - strcase.o + memcpy_64.o usercopy_64.o mem_64.o string.o obj-$(CONFIG_QUICC_ENGINE) += rheap.o obj-$(CONFIG_XMON) += sstep.o obj-$(CONFIG_KPROBES) += sstep.o diff --git a/arch/powerpc/lib/strcase.c b/arch/powerpc/lib/strcase.c deleted file mode 100644 index f8ec1eba3fd..00000000000 --- a/arch/powerpc/lib/strcase.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -int strcasecmp(const char *s1, const char *s2) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while (c1 == c2 && c1 != 0); - return c1 - c2; -} - -int strncasecmp(const char *s1, const char *s2, size_t n) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while ((--n > 0) && c1 == c2 && c1 != 0); - return c1 - c2; -} diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 1318b6f4c3d..4ad499605d0 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -93,8 +93,6 @@ EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strcat); EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strcasecmp); -EXPORT_SYMBOL(strncasecmp); EXPORT_SYMBOL(__div64_32); EXPORT_SYMBOL(csum_partial); diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index 50358e4ea15..422bef9bae7 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for ppc-specific library files.. # -obj-y := checksum.o string.o strcase.o div64.o +obj-y := checksum.o string.o div64.o obj-$(CONFIG_8xx) += rheap.o obj-$(CONFIG_CPM2) += rheap.o diff --git a/arch/ppc/lib/strcase.c b/arch/ppc/lib/strcase.c deleted file mode 100644 index 3b0094cc2b5..00000000000 --- a/arch/ppc/lib/strcase.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -int strcasecmp(const char *s1, const char *s2) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while (c1 == c2 && c1 != 0); - return c1 - c2; -} - -int strncasecmp(const char *s1, const char *s2, size_t n) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while ((--n > 0) && c1 == c2 && c1 != 0); - return c1 - c2; -} diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index b5681e3f968..0b9cca5c7cb 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -3,7 +3,7 @@ # lib-y = delay.o memset.o memmove.o memchr.o \ - checksum.o strcasecmp.o strlen.o div64.o udivdi3.o \ + checksum.o strlen.o div64.o udivdi3.o \ div64-generic.o memcpy-y := memcpy.o diff --git a/arch/sh/lib/strcasecmp.c b/arch/sh/lib/strcasecmp.c deleted file mode 100644 index 4e57a216fea..00000000000 --- a/arch/sh/lib/strcasecmp.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * linux/arch/alpha/lib/strcasecmp.c - */ - -#include - - -/* We handle nothing here except the C locale. Since this is used in - only one place, on strings known to contain only 7 bit ASCII, this - is ok. */ - -int strcasecmp(const char *a, const char *b) -{ - int ca, cb; - - do { - ca = *a++ & 0xff; - cb = *b++ & 0xff; - if (ca >= 'A' && ca <= 'Z') - ca += 'a' - 'A'; - if (cb >= 'A' && cb <= 'Z') - cb += 'a' - 'A'; - } while (ca == cb && ca != '\0'); - - return ca - cb; -} diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile index ed935b58e8a..6c4fdd86acd 100644 --- a/arch/xtensa/lib/Makefile +++ b/arch/xtensa/lib/Makefile @@ -2,6 +2,6 @@ # Makefile for Xtensa-specific library files. # -lib-y += memcopy.o memset.o checksum.o strcasecmp.o \ +lib-y += memcopy.o memset.o checksum.o \ usercopy.o strncpy_user.o strnlen_user.o lib-$(CONFIG_PCI) += pci-auto.o diff --git a/arch/xtensa/lib/strcasecmp.c b/arch/xtensa/lib/strcasecmp.c deleted file mode 100644 index 165b2d6effa..00000000000 --- a/arch/xtensa/lib/strcasecmp.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * linux/arch/xtensa/lib/strcasecmp.c - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file "COPYING" in the main directory of - * this archive for more details. - * - * Copyright (C) 2002 Tensilica Inc. - */ - -#include - - -/* We handle nothing here except the C locale. Since this is used in - only one place, on strings known to contain only 7 bit ASCII, this - is ok. */ - -int strcasecmp(const char *a, const char *b) -{ - int ca, cb; - - do { - ca = *a++ & 0xff; - cb = *b++ & 0xff; - if (ca >= 'A' && ca <= 'Z') - ca += 'a' - 'A'; - if (cb >= 'A' && cb <= 'Z') - cb += 'a' - 'A'; - } while (ca == cb && ca != '\0'); - - return ca - cb; -} -- cgit v1.2.3 From a8b8814bdfe3bb2bdfa23722de947bad8283037c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 29 Mar 2007 01:28:51 -0700 Subject: [SPARC]: Use strcasecmp for OFW property name comparisons. This allows us to simplify sharing code with powerpc which has properties that have various forms of capitalization when on the sparc64 side the property is all lower-case. Signed-off-by: David S. Miller --- arch/sparc/kernel/prom.c | 4 ++-- arch/sparc64/kernel/prom.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 9ddf6035915..eed140b3c73 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -158,7 +158,7 @@ struct property *of_find_property(const struct device_node *np, struct property *pp; for (pp = np->properties; pp != 0; pp = pp->next) { - if (strcmp(pp->name, name) == 0) { + if (strcasecmp(pp->name, name) == 0) { if (lenp != 0) *lenp = pp->length; break; @@ -242,7 +242,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len while (*prevp) { struct property *prop = *prevp; - if (!strcmp(prop->name, name)) { + if (!strcasecmp(prop->name, name)) { void *old_val = prop->value; int ret; diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 493db961a1f..13734b50a6e 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -160,7 +160,7 @@ struct property *of_find_property(struct device_node *np, const char *name, struct property *pp; for (pp = np->properties; pp != 0; pp = pp->next) { - if (strcmp(pp->name, name) == 0) { + if (strcasecmp(pp->name, name) == 0) { if (lenp != 0) *lenp = pp->length; break; @@ -243,7 +243,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len while (*prevp) { struct property *prop = *prevp; - if (!strcmp(prop->name, name)) { + if (!strcasecmp(prop->name, name)) { void *old_val = prop->value; int ret; -- cgit v1.2.3 From 1327e9b62fc88e64ffbbd42d61fccd34e521bb86 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 28 Feb 2007 17:55:46 -0800 Subject: [SPARC64] ebus: Convert to use pci_device_to_OF_node(). Also, we don't need to store or use the PBM so kill that from the linux_ebus. Signed-off-by: David S. Miller --- arch/sparc64/kernel/ebus.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 1962bfa4ef3..0ace17bafba 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -438,11 +438,9 @@ static struct pci_dev *find_next_ebus(struct pci_dev *start, int *is_rio_p) void __init ebus_init(void) { - struct pci_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; struct pci_dev *pdev; - struct pcidev_cookie *cookie; struct device_node *dp; int is_rio; int num_ebus = 0; @@ -453,8 +451,7 @@ void __init ebus_init(void) return; } - cookie = pdev->sysdata; - dp = cookie->prom_node; + dp = pci_device_to_OF_node(pdev); ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); ebus->next = NULL; @@ -480,8 +477,7 @@ void __init ebus_init(void) break; } ebus->is_rio = is_rio; - cookie = pdev->sysdata; - dp = cookie->prom_node; + dp = pci_device_to_OF_node(pdev); continue; } printk("ebus%d:", num_ebus); @@ -489,7 +485,6 @@ void __init ebus_init(void) ebus->index = num_ebus; ebus->prom_node = dp; ebus->self = pdev; - ebus->parent = pbm = cookie->pbm; ebus->ofdev.node = dp; ebus->ofdev.dev.parent = &pdev->dev; @@ -531,8 +526,7 @@ void __init ebus_init(void) if (!pdev) break; - cookie = pdev->sysdata; - dp = cookie->prom_node; + dp = pci_device_to_OF_node(pdev); ebus->next = ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; -- cgit v1.2.3 From deb66c4521e119442aa266553e8cbfc86eb71232 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 28 Feb 2007 18:01:38 -0800 Subject: [SPARC64] isa: Convert to use pci_device_to_OF_node(). Also, do not try to compute resources by hand, instead use the pre-computed ones in the of_device. Signed-off-by: David S. Miller --- arch/sparc64/kernel/isa.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index 791eeb7e387..6a6882e57ff 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c @@ -24,27 +24,9 @@ static void __init report_dev(struct sparc_isa_device *isa_dev, int child) static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev) { - const struct linux_prom_registers *pregs; - unsigned long base, len; - int prop_len; - - pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len); - if (!pregs) - return; - - /* Only the first one is interesting. */ - len = pregs[0].reg_size; - base = (((unsigned long)pregs[0].which_io << 32) | - (unsigned long)pregs[0].phys_addr); - base += isa_dev->bus->parent->io_space.start; - - isa_dev->resource.start = base; - isa_dev->resource.end = (base + len - 1UL); - isa_dev->resource.flags = IORESOURCE_IO; - isa_dev->resource.name = isa_dev->prom_node->name; + struct of_device *op = of_find_device_by_node(isa_dev->prom_node); - request_resource(&isa_dev->bus->parent->io_space, - &isa_dev->resource); + memcpy(&isa_dev->resource, &op->resource[0], sizeof(struct resource)); } static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev) @@ -158,19 +140,10 @@ void __init isa_init(void) pdev = NULL; while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) { - struct pcidev_cookie *pdev_cookie; - struct pci_pbm_info *pbm; struct sparc_isa_bridge *isa_br; struct device_node *dp; - pdev_cookie = pdev->sysdata; - if (!pdev_cookie) { - printk("ISA: Warning, ISA bridge ignored due to " - "lack of OBP data.\n"); - continue; - } - pbm = pdev_cookie->pbm; - dp = pdev_cookie->prom_node; + dp = pci_device_to_OF_node(pdev); isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL); if (!isa_br) { @@ -195,10 +168,9 @@ void __init isa_init(void) isa_br->next = isa_chain; isa_chain = isa_br; - isa_br->parent = pbm; isa_br->self = pdev; isa_br->index = index++; - isa_br->prom_node = pdev_cookie->prom_node; + isa_br->prom_node = dp; printk("isa%d:", isa_br->index); -- cgit v1.2.3 From a2fb23af1c31ad6e0c281e56d385f803229d57fa Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 28 Feb 2007 23:35:04 -0800 Subject: [SPARC64]: Probe PCI bus using OF device tree. Almost entirely taken from the 64-bit PowerPC PCI code. This allowed to eliminate a ton of cruft from the sparc64 PCI layer. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 375 ++++++++++++++++++++- arch/sparc64/kernel/pci_common.c | 707 --------------------------------------- arch/sparc64/kernel/pci_impl.h | 15 +- arch/sparc64/kernel/pci_iommu.c | 47 +-- arch/sparc64/kernel/pci_psycho.c | 26 +- arch/sparc64/kernel/pci_sabre.c | 53 +-- arch/sparc64/kernel/pci_schizo.c | 26 +- arch/sparc64/kernel/pci_sun4v.c | 199 ++--------- 8 files changed, 409 insertions(+), 1039 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 12109886bb1..246b8009a2b 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1,9 +1,11 @@ -/* $Id: pci.c,v 1.39 2002/01/05 01:13:43 davem Exp $ - * pci.c: UltraSparc PCI controller support. +/* pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) + * + * OF tree based PCI bus probing taken from the PowerPC port + * with minor modifications, see there for credits. */ #include @@ -300,6 +302,329 @@ static void __init pci_controller_probe(void) pci_controller_scan(pci_controller_init); } +static unsigned long pci_parse_of_flags(u32 addr0) +{ + unsigned long flags = 0; + + if (addr0 & 0x02000000) { + flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; + flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; + flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; + if (addr0 & 0x40000000) + flags |= IORESOURCE_PREFETCH + | PCI_BASE_ADDRESS_MEM_PREFETCH; + } else if (addr0 & 0x01000000) + flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; + return flags; +} + +/* The of_device layer has translated all of the assigned-address properties + * into physical address resources, we only have to figure out the register + * mapping. + */ +static void pci_parse_of_addrs(struct of_device *op, + struct device_node *node, + struct pci_dev *dev) +{ + struct resource *op_res; + const u32 *addrs; + int proplen; + + addrs = of_get_property(node, "assigned-addresses", &proplen); + if (!addrs) + return; + printk(" parse addresses (%d bytes) @ %p\n", proplen, addrs); + op_res = &op->resource[0]; + for (; proplen >= 20; proplen -= 20, addrs += 5, op_res++) { + struct resource *res; + unsigned long flags; + int i; + + flags = pci_parse_of_flags(addrs[0]); + if (!flags) + continue; + i = addrs[0] & 0xff; + printk(" start: %lx, end: %lx, i: %x\n", + op_res->start, op_res->end, i); + + if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { + res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; + } else if (i == dev->rom_base_reg) { + res = &dev->resource[PCI_ROM_RESOURCE]; + flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; + } else { + printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); + continue; + } + res->start = op_res->start; + res->end = op_res->end; + res->flags = flags; + res->name = pci_name(dev); + } +} + +struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus, int devfn) +{ + struct dev_archdata *sd; + struct pci_dev *dev; + const char *type; + + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + if (!dev) + return NULL; + + sd = &dev->dev.archdata; + sd->iommu = pbm->iommu; + sd->stc = &pbm->stc; + sd->host_controller = pbm; + sd->prom_node = node; + sd->op = of_find_device_by_node(node); + sd->msi_num = 0xffffffff; + + type = of_get_property(node, "device_type", NULL); + if (type == NULL) + type = ""; + + printk(" create device, devfn: %x, type: %s\n", devfn, type); + + dev->bus = bus; + dev->sysdata = node; + dev->dev.parent = bus->bridge; + dev->dev.bus = &pci_bus_type; + dev->devfn = devfn; + dev->multifunction = 0; /* maybe a lie? */ + + dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); + dev->device = of_getintprop_default(node, "device-id", 0xffff); + dev->subsystem_vendor = + of_getintprop_default(node, "subsystem-vendor-id", 0); + dev->subsystem_device = + of_getintprop_default(node, "subsystem-id", 0); + + dev->cfg_size = pci_cfg_space_size(dev); + + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); + dev->class = of_getintprop_default(node, "class-code", 0); + + printk(" class: 0x%x\n", dev->class); + + dev->current_state = 4; /* unknown power state */ + dev->error_state = pci_channel_io_normal; + + if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + /* a PCI-PCI bridge */ + dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; + dev->rom_base_reg = PCI_ROM_ADDRESS1; + } else if (!strcmp(type, "cardbus")) { + dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; + } else { + dev->hdr_type = PCI_HEADER_TYPE_NORMAL; + dev->rom_base_reg = PCI_ROM_ADDRESS; + + dev->irq = sd->op->irqs[0]; + if (dev->irq == 0xffffffff) + dev->irq = PCI_IRQ_NONE; + } + + pci_parse_of_addrs(sd->op, node, dev); + + printk(" adding to system ...\n"); + + pci_device_add(dev, bus); + + return dev; +} + +static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus); + +#define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) + +void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_dev *dev) +{ + struct pci_bus *bus; + const u32 *busrange, *ranges; + int len, i; + struct resource *res; + unsigned int flags; + u64 size; + + printk("of_scan_pci_bridge(%s)\n", node->full_name); + + /* parse bus-range property */ + busrange = of_get_property(node, "bus-range", &len); + if (busrange == NULL || len != 8) { + printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", + node->full_name); + return; + } + ranges = of_get_property(node, "ranges", &len); + if (ranges == NULL) { + printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", + node->full_name); + return; + } + + bus = pci_add_new_bus(dev->bus, dev, busrange[0]); + if (!bus) { + printk(KERN_ERR "Failed to create pci bus for %s\n", + node->full_name); + return; + } + + bus->primary = dev->bus->number; + bus->subordinate = busrange[1]; + bus->bridge_ctl = 0; + + /* parse ranges property */ + /* PCI #address-cells == 3 and #size-cells == 2 always */ + res = &dev->resource[PCI_BRIDGE_RESOURCES]; + for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { + res->flags = 0; + bus->resource[i] = res; + ++res; + } + i = 1; + for (; len >= 32; len -= 32, ranges += 8) { + struct resource *root; + + flags = pci_parse_of_flags(ranges[0]); + size = GET_64BIT(ranges, 6); + if (flags == 0 || size == 0) + continue; + if (flags & IORESOURCE_IO) { + res = bus->resource[0]; + if (res->flags) { + printk(KERN_ERR "PCI: ignoring extra I/O range" + " for bridge %s\n", node->full_name); + continue; + } + root = &pbm->io_space; + } else { + if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { + printk(KERN_ERR "PCI: too many memory ranges" + " for bridge %s\n", node->full_name); + continue; + } + res = bus->resource[i]; + ++i; + root = &pbm->mem_space; + } + + res->start = GET_64BIT(ranges, 1); + res->end = res->start + size - 1; + res->flags = flags; + + /* Another way to implement this would be to add an of_device + * layer routine that can calculate a resource for a given + * range property value in a PCI device. + */ + pbm->parent->resource_adjust(dev, res, root); + } + sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), + bus->number); + printk(" bus name: %s\n", bus->name); + + pci_of_scan_bus(pbm, node, bus); +} + +static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus) +{ + struct device_node *child; + const u32 *reg; + int reglen, devfn; + struct pci_dev *dev; + + printk("PCI: scan_bus[%s] bus no %d\n", + node->full_name, bus->number); + + child = NULL; + while ((child = of_get_next_child(node, child)) != NULL) { + printk(" * %s\n", child->full_name); + reg = of_get_property(child, "reg", ®len); + if (reg == NULL || reglen < 20) + continue; + devfn = (reg[0] >> 8) & 0xff; + + /* create a new pci_dev for this device */ + dev = of_create_pci_dev(pbm, child, bus, devfn); + if (!dev) + continue; + printk("PCI: dev header type: %x\n", dev->hdr_type); + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) + of_scan_pci_bridge(pbm, child, dev); + } +} + +static ssize_t +show_pciobppath_attr(struct device * dev, struct device_attribute * attr, char * buf) +{ + struct pci_dev *pdev; + struct device_node *dp; + + pdev = to_pci_dev(dev); + dp = pdev->dev.archdata.prom_node; + + return snprintf (buf, PAGE_SIZE, "%s\n", dp->full_name); +} + +static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_pciobppath_attr, NULL); + +static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) +{ + struct pci_dev *dev; + int err; + + list_for_each_entry(dev, &bus->devices, bus_list) { + /* we don't really care if we can create this file or + * not, but we need to assign the result of the call + * or the world will fall under alien invasion and + * everybody will be frozen on a spaceship ready to be + * eaten on alpha centauri by some green and jelly + * humanoid. + */ + err = sysfs_create_file(&dev->dev.kobj, &dev_attr_obppath.attr); + } +} + +struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) +{ + struct pci_controller_info *p = pbm->parent; + struct device_node *node = pbm->prom_node; + struct pci_bus *bus; + + printk("PCI: Scanning PBM %s\n", node->full_name); + + /* XXX parent device? XXX */ + bus = pci_create_bus(NULL, pbm->pci_first_busno, p->pci_ops, pbm); + if (!bus) { + printk(KERN_ERR "Failed to create bus for %s\n", + node->full_name); + return NULL; + } + bus->secondary = pbm->pci_first_busno; + bus->subordinate = pbm->pci_last_busno; + + bus->resource[0] = &pbm->io_space; + bus->resource[1] = &pbm->mem_space; + + pci_of_scan_bus(pbm, node, bus); + pci_bus_add_devices(bus); + pci_bus_register_of_sysfs(bus); + + return bus; +} + static void __init pci_scan_each_controller_bus(void) { struct pci_controller_info *p; @@ -360,8 +685,33 @@ void pcibios_align_resource(void *data, struct resource *res, { } -int pcibios_enable_device(struct pci_dev *pdev, int mask) +int pcibios_enable_device(struct pci_dev *dev, int mask) { + u16 cmd, oldcmd; + int i; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + oldcmd = cmd; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *res = &dev->resource[i]; + + /* Only set up the requested stuff */ + if (!(mask & (1<flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (res->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + + if (cmd != oldcmd) { + printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n", + pci_name(dev), cmd); + /* Enable the appropriate bits in the PCI command register. */ + pci_write_config_word(dev, PCI_COMMAND, cmd); + } return 0; } @@ -422,17 +772,10 @@ char * __devinit pcibios_setup(char *str) static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; struct pci_controller_info *p; unsigned long space_size, user_offset, user_size; - if (!pcp) - return -ENXIO; - pbm = pcp->pbm; - if (!pbm) - return -ENXIO; - p = pbm->parent; if (p->pbms_same_domain) { unsigned long lowest, highest; @@ -651,8 +994,7 @@ EXPORT_SYMBOL(pci_domain_nr); #ifdef CONFIG_PCI_MSI int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; struct pci_controller_info *p = pbm->parent; int virt_irq, err; @@ -670,8 +1012,7 @@ void arch_teardown_msi_irq(unsigned int virt_irq) { struct msi_desc *entry = get_irq_msi(virt_irq); struct pci_dev *pdev = entry->dev; - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; struct pci_controller_info *p = pbm->parent; if (!pbm->msi_num || !p->setup_msi_irq) @@ -683,9 +1024,7 @@ void arch_teardown_msi_irq(unsigned int virt_irq) struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) { - struct pcidev_cookie *pc = pdev->sysdata; - - return pc->op->node; + return pdev->dev.archdata.prom_node; } EXPORT_SYMBOL(pci_device_to_OF_node); diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 5a92cb90ebe..0d3c95df0d9 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -16,713 +16,6 @@ #include "pci_impl.h" -/* Fix self device of BUS and hook it into BUS->self. - * The pci_scan_bus does not do this for the host bridge. - */ -void __init pci_fixup_host_bridge_self(struct pci_bus *pbus) -{ - struct pci_dev *pdev; - - list_for_each_entry(pdev, &pbus->devices, bus_list) { - if (pdev->class >> 8 == PCI_CLASS_BRIDGE_HOST) { - pbus->self = pdev; - return; - } - } - - prom_printf("PCI: Critical error, cannot find host bridge PDEV.\n"); - prom_halt(); -} - -/* Find the OBP PROM device tree node for a PCI device. */ -static struct device_node * __init -find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev, - struct device_node *bus_node, - struct linux_prom_pci_registers **pregs, - int *nregs) -{ - struct device_node *dp; - - *nregs = 0; - - /* - * Return the PBM's PROM node in case we are it's PCI device, - * as the PBM's reg property is different to standard PCI reg - * properties. We would delete this device entry otherwise, - * which confuses XFree86's device probing... - */ - if ((pdev->bus->number == pbm->pci_bus->number) && (pdev->devfn == 0) && - (pdev->vendor == PCI_VENDOR_ID_SUN) && - (pdev->device == PCI_DEVICE_ID_SUN_PBM || - pdev->device == PCI_DEVICE_ID_SUN_SCHIZO || - pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || - pdev->device == PCI_DEVICE_ID_SUN_SABRE || - pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) - return bus_node; - - dp = bus_node->child; - while (dp) { - struct linux_prom_pci_registers *regs; - struct property *prop; - int len; - - prop = of_find_property(dp, "reg", &len); - if (!prop) - goto do_next_sibling; - - regs = prop->value; - if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { - *pregs = regs; - *nregs = len / sizeof(struct linux_prom_pci_registers); - return dp; - } - - do_next_sibling: - dp = dp->sibling; - } - - return NULL; -} - -/* Older versions of OBP on PCI systems encode 64-bit MEM - * space assignments incorrectly, this fixes them up. We also - * take the opportunity here to hide other kinds of bogus - * assignments. - */ -static void __init fixup_obp_assignments(struct pci_dev *pdev, - struct pcidev_cookie *pcp) -{ - int i; - - if (pdev->vendor == PCI_VENDOR_ID_AL && - (pdev->device == PCI_DEVICE_ID_AL_M7101 || - pdev->device == PCI_DEVICE_ID_AL_M1533)) { - int i; - - /* Zap all of the normal resources, they are - * meaningless and generate bogus resource collision - * messages. This is OpenBoot's ill-fated attempt to - * represent the implicit resources that these devices - * have. - */ - pcp->num_prom_assignments = 0; - for (i = 0; i < 6; i++) { - pdev->resource[i].start = - pdev->resource[i].end = - pdev->resource[i].flags = 0; - } - pdev->resource[PCI_ROM_RESOURCE].start = - pdev->resource[PCI_ROM_RESOURCE].end = - pdev->resource[PCI_ROM_RESOURCE].flags = 0; - return; - } - - for (i = 0; i < pcp->num_prom_assignments; i++) { - struct linux_prom_pci_registers *ap; - int space; - - ap = &pcp->prom_assignments[i]; - space = ap->phys_hi >> 24; - if ((space & 0x3) == 2 && - (space & 0x4) != 0) { - ap->phys_hi &= ~(0x7 << 24); - ap->phys_hi |= 0x3 << 24; - } - } -} - -static ssize_t -show_pciobppath_attr(struct device * dev, struct device_attribute * attr, char * buf) -{ - struct pci_dev *pdev; - struct pcidev_cookie *sysdata; - - pdev = to_pci_dev(dev); - sysdata = pdev->sysdata; - - return snprintf (buf, PAGE_SIZE, "%s\n", sysdata->prom_node->full_name); -} - -static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_pciobppath_attr, NULL); - -/* Fill in the PCI device cookie sysdata for the given - * PCI device. This cookie is the means by which one - * can get to OBP and PCI controller specific information - * for a PCI device. - */ -static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, - struct pci_dev *pdev, - struct device_node *bus_node) -{ - struct linux_prom_pci_registers *pregs = NULL; - struct pcidev_cookie *pcp; - struct device_node *dp; - struct property *prop; - int nregs, len, err; - - dp = find_device_prom_node(pbm, pdev, bus_node, - &pregs, &nregs); - if (!dp) { - /* If it is not in the OBP device tree then - * there must be a damn good reason for it. - * - * So what we do is delete the device from the - * PCI device tree completely. This scenario - * is seen, for example, on CP1500 for the - * second EBUS/HappyMeal pair if the external - * connector for it is not present. - */ - pci_remove_bus_device(pdev); - return; - } - - pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC); - if (pcp == NULL) { - prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n"); - prom_halt(); - } - pcp->pbm = pbm; - pcp->prom_node = dp; - pcp->op = of_find_device_by_node(dp); - memcpy(pcp->prom_regs, pregs, - nregs * sizeof(struct linux_prom_pci_registers)); - pcp->num_prom_regs = nregs; - - /* We can't have the pcidev_cookie assignments be just - * direct pointers into the property value, since they - * are potentially modified by the probing process. - */ - prop = of_find_property(dp, "assigned-addresses", &len); - if (!prop) { - pcp->num_prom_assignments = 0; - } else { - memcpy(pcp->prom_assignments, prop->value, len); - pcp->num_prom_assignments = - (len / sizeof(pcp->prom_assignments[0])); - } - - if (strcmp(dp->name, "ebus") == 0) { - struct linux_prom_ebus_ranges *erng; - int iter; - - /* EBUS is special... */ - prop = of_find_property(dp, "ranges", &len); - if (!prop) { - prom_printf("EBUS: Fatal error, no range property\n"); - prom_halt(); - } - erng = prop->value; - len = (len / sizeof(erng[0])); - for (iter = 0; iter < len; iter++) { - struct linux_prom_ebus_ranges *ep = &erng[iter]; - struct linux_prom_pci_registers *ap; - - ap = &pcp->prom_assignments[iter]; - - ap->phys_hi = ep->parent_phys_hi; - ap->phys_mid = ep->parent_phys_mid; - ap->phys_lo = ep->parent_phys_lo; - ap->size_hi = 0; - ap->size_lo = ep->size; - } - pcp->num_prom_assignments = len; - } - - fixup_obp_assignments(pdev, pcp); - - pdev->sysdata = pcp; - - /* we don't really care if we can create this file or not, - * but we need to assign the result of the call or the world will fall - * under alien invasion and everybody will be frozen on a spaceship - * ready to be eaten on alpha centauri by some green and jelly humanoid. - */ - err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_obppath.attr); -} - -void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, - struct pci_pbm_info *pbm, - struct device_node *dp) -{ - struct pci_dev *pdev, *pdev_next; - struct pci_bus *this_pbus, *pbus_next; - - /* This must be _safe because the cookie fillin - routine can delete devices from the tree. */ - list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list) - pdev_cookie_fillin(pbm, pdev, dp); - - list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) { - struct pcidev_cookie *pcp = this_pbus->self->sysdata; - - pci_fill_in_pbm_cookies(this_pbus, pbm, pcp->prom_node); - } -} - -static void __init bad_assignment(struct pci_dev *pdev, - struct linux_prom_pci_registers *ap, - struct resource *res, - int do_prom_halt) -{ - prom_printf("PCI: Bogus PROM assignment. BUS[%02x] DEVFN[%x]\n", - pdev->bus->number, pdev->devfn); - if (ap) - prom_printf("PCI: phys[%08x:%08x:%08x] size[%08x:%08x]\n", - ap->phys_hi, ap->phys_mid, ap->phys_lo, - ap->size_hi, ap->size_lo); - if (res) - prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n", - res->start, res->end, res->flags); - if (do_prom_halt) - prom_halt(); -} - -static struct resource * -__init get_root_resource(struct linux_prom_pci_registers *ap, - struct pci_pbm_info *pbm) -{ - int space = (ap->phys_hi >> 24) & 3; - - switch (space) { - case 0: - /* Configuration space, silently ignore it. */ - return NULL; - - case 1: - /* 16-bit IO space */ - return &pbm->io_space; - - case 2: - /* 32-bit MEM space */ - return &pbm->mem_space; - - case 3: - /* 64-bit MEM space, these are allocated out of - * the 32-bit mem_space range for the PBM, ie. - * we just zero out the upper 32-bits. - */ - return &pbm->mem_space; - - default: - printk("PCI: What is resource space %x?\n", space); - return NULL; - }; -} - -static struct resource * -__init get_device_resource(struct linux_prom_pci_registers *ap, - struct pci_dev *pdev) -{ - struct resource *res; - int breg = (ap->phys_hi & 0xff); - - switch (breg) { - case PCI_ROM_ADDRESS: - /* Unfortunately I have seen several cases where - * buggy FCODE uses a space value of '1' (I/O space) - * in the register property for the ROM address - * so disable this sanity check for now. - */ -#if 0 - { - int space = (ap->phys_hi >> 24) & 3; - - /* It had better be MEM space. */ - if (space != 2) - bad_assignment(pdev, ap, NULL, 0); - } -#endif - res = &pdev->resource[PCI_ROM_RESOURCE]; - break; - - case PCI_BASE_ADDRESS_0: - case PCI_BASE_ADDRESS_1: - case PCI_BASE_ADDRESS_2: - case PCI_BASE_ADDRESS_3: - case PCI_BASE_ADDRESS_4: - case PCI_BASE_ADDRESS_5: - res = &pdev->resource[(breg - PCI_BASE_ADDRESS_0) / 4]; - break; - - default: - bad_assignment(pdev, ap, NULL, 0); - res = NULL; - break; - }; - - return res; -} - -static void __init pdev_record_assignments(struct pci_pbm_info *pbm, - struct pci_dev *pdev) -{ - struct pcidev_cookie *pcp = pdev->sysdata; - int i; - - for (i = 0; i < pcp->num_prom_assignments; i++) { - struct linux_prom_pci_registers *ap; - struct resource *root, *res; - - /* The format of this property is specified in - * the PCI Bus Binding to IEEE1275-1994. - */ - ap = &pcp->prom_assignments[i]; - root = get_root_resource(ap, pbm); - res = get_device_resource(ap, pdev); - if (root == NULL || res == NULL || - res->flags == 0) - continue; - - /* Ok we know which resource this PROM assignment is - * for, sanity check it. - */ - if ((res->start & 0xffffffffUL) != ap->phys_lo) - bad_assignment(pdev, ap, res, 1); - - /* If it is a 64-bit MEM space assignment, verify that - * the resource is too and that the upper 32-bits match. - */ - if (((ap->phys_hi >> 24) & 3) == 3) { - if (((res->flags & IORESOURCE_MEM) == 0) || - ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) - != PCI_BASE_ADDRESS_MEM_TYPE_64)) - bad_assignment(pdev, ap, res, 1); - if ((res->start >> 32) != ap->phys_mid) - bad_assignment(pdev, ap, res, 1); - - /* PBM cannot generate cpu initiated PIOs - * to the full 64-bit space. Therefore the - * upper 32-bits better be zero. If it is - * not, just skip it and we will assign it - * properly ourselves. - */ - if ((res->start >> 32) != 0UL) { - printk(KERN_ERR "PCI: OBP assigns out of range MEM address " - "%016lx for region %ld on device %s\n", - res->start, (res - &pdev->resource[0]), pci_name(pdev)); - continue; - } - } - - /* Adjust the resource into the physical address space - * of this PBM. - */ - pbm->parent->resource_adjust(pdev, res, root); - - if (request_resource(root, res) < 0) { - int rnum; - - /* OK, there is some conflict. But this is fine - * since we'll reassign it in the fixup pass. - * - * Do not print the warning for ROM resources - * as such a conflict is quite common and - * harmless as the ROM bar is disabled. - */ - rnum = (res - &pdev->resource[0]); - if (rnum != PCI_ROM_RESOURCE) - printk(KERN_ERR "PCI: Resource collision, " - "region %d " - "[%016lx:%016lx] of device %s\n", - rnum, - res->start, res->end, - pci_name(pdev)); - } - } -} - -void __init pci_record_assignments(struct pci_pbm_info *pbm, - struct pci_bus *pbus) -{ - struct pci_dev *dev; - struct pci_bus *bus; - - list_for_each_entry(dev, &pbus->devices, bus_list) - pdev_record_assignments(pbm, dev); - - list_for_each_entry(bus, &pbus->children, node) - pci_record_assignments(pbm, bus); -} - -/* Return non-zero if PDEV has implicit I/O resources even - * though it may not have an I/O base address register - * active. - */ -static int __init has_implicit_io(struct pci_dev *pdev) -{ - int class = pdev->class >> 8; - - if (class == PCI_CLASS_NOT_DEFINED || - class == PCI_CLASS_NOT_DEFINED_VGA || - class == PCI_CLASS_STORAGE_IDE || - (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) - return 1; - - return 0; -} - -static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm, - struct pci_dev *pdev) -{ - u32 reg; - u16 cmd; - int i, io_seen, mem_seen; - - io_seen = mem_seen = 0; - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *root, *res; - unsigned long size, min, max, align; - - res = &pdev->resource[i]; - - if (res->flags & IORESOURCE_IO) - io_seen++; - else if (res->flags & IORESOURCE_MEM) - mem_seen++; - - /* If it is already assigned or the resource does - * not exist, there is nothing to do. - */ - if (res->parent != NULL || res->flags == 0UL) - continue; - - /* Determine the root we allocate from. */ - if (res->flags & IORESOURCE_IO) { - root = &pbm->io_space; - min = root->start + 0x400UL; - max = root->end; - } else { - root = &pbm->mem_space; - min = root->start; - max = min + 0x80000000UL; - } - - size = res->end - res->start; - align = size + 1; - if (allocate_resource(root, res, size + 1, min, max, align, NULL, NULL) < 0) { - /* uh oh */ - prom_printf("PCI: Failed to allocate resource %d for %s\n", - i, pci_name(pdev)); - prom_halt(); - } - - /* Update PCI config space. */ - pbm->parent->base_address_update(pdev, i); - } - - /* Special case, disable the ROM. Several devices - * act funny (ie. do not respond to memory space writes) - * when it is left enabled. A good example are Qlogic,ISP - * adapters. - */ - pci_read_config_dword(pdev, PCI_ROM_ADDRESS, ®); - reg &= ~PCI_ROM_ADDRESS_ENABLE; - pci_write_config_dword(pdev, PCI_ROM_ADDRESS, reg); - - /* If we saw I/O or MEM resources, enable appropriate - * bits in PCI command register. - */ - if (io_seen || mem_seen) { - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - if (io_seen || has_implicit_io(pdev)) - cmd |= PCI_COMMAND_IO; - if (mem_seen) - cmd |= PCI_COMMAND_MEMORY; - pci_write_config_word(pdev, PCI_COMMAND, cmd); - } - - /* If this is a PCI bridge or an IDE controller, - * enable bus mastering. In the former case also - * set the cache line size correctly. - */ - if (((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) || - (((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) && - ((pdev->class & 0x80) != 0))) { - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - pci_write_config_word(pdev, PCI_COMMAND, cmd); - - if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) - pci_write_config_byte(pdev, - PCI_CACHE_LINE_SIZE, - (64 / sizeof(u32))); - } -} - -void __init pci_assign_unassigned(struct pci_pbm_info *pbm, - struct pci_bus *pbus) -{ - struct pci_dev *dev; - struct pci_bus *bus; - - list_for_each_entry(dev, &pbus->devices, bus_list) - pdev_assign_unassigned(pbm, dev); - - list_for_each_entry(bus, &pbus->children, node) - pci_assign_unassigned(pbm, bus); -} - -static void __init pdev_fixup_irq(struct pci_dev *pdev) -{ - struct pcidev_cookie *pcp = pdev->sysdata; - struct of_device *op = pcp->op; - - if (op->irqs[0] == 0xffffffff) { - pdev->irq = PCI_IRQ_NONE; - return; - } - - pdev->irq = op->irqs[0]; - - pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, - pdev->irq & PCI_IRQ_INO); -} - -void __init pci_fixup_irq(struct pci_pbm_info *pbm, - struct pci_bus *pbus) -{ - struct pci_dev *dev; - struct pci_bus *bus; - - list_for_each_entry(dev, &pbus->devices, bus_list) - pdev_fixup_irq(dev); - - list_for_each_entry(bus, &pbus->children, node) - pci_fixup_irq(pbm, bus); -} - -static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz) -{ - u16 cmd; - u8 hdr_type, min_gnt, ltimer; - - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - pci_write_config_word(pdev, PCI_COMMAND, cmd); - - /* Read it back, if the mastering bit did not - * get set, the device does not support bus - * mastering so we have nothing to do here. - */ - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - if ((cmd & PCI_COMMAND_MASTER) == 0) - return; - - /* Set correct cache line size, 64-byte on all - * Sparc64 PCI systems. Note that the value is - * measured in 32-bit words. - */ - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - 64 / sizeof(u32)); - - pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr_type); - hdr_type &= ~0x80; - if (hdr_type != PCI_HEADER_TYPE_NORMAL) - return; - - /* If the latency timer is already programmed with a non-zero - * value, assume whoever set it (OBP or whoever) knows what - * they are doing. - */ - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, <imer); - if (ltimer != 0) - return; - - /* XXX Since I'm tipping off the min grant value to - * XXX choose a suitable latency timer value, I also - * XXX considered making use of the max latency value - * XXX as well. Unfortunately I've seen too many bogusly - * XXX low settings for it to the point where it lacks - * XXX any usefulness. In one case, an ethernet card - * XXX claimed a min grant of 10 and a max latency of 5. - * XXX Now, if I had two such cards on the same bus I - * XXX could not set the desired burst period (calculated - * XXX from min grant) without violating the max latency - * XXX bound. Duh... - * XXX - * XXX I blame dumb PC bios implementors for stuff like - * XXX this, most of them don't even try to do something - * XXX sensible with latency timer values and just set some - * XXX default value (usually 32) into every device. - */ - - pci_read_config_byte(pdev, PCI_MIN_GNT, &min_gnt); - - if (min_gnt == 0) { - /* If no min_gnt setting then use a default - * value. - */ - if (is_66mhz) - ltimer = 16; - else - ltimer = 32; - } else { - int shift_factor; - - if (is_66mhz) - shift_factor = 2; - else - shift_factor = 3; - - /* Use a default value when the min_gnt value - * is erroneously high. - */ - if (((unsigned int) min_gnt << shift_factor) > 512 || - ((min_gnt << shift_factor) & 0xff) == 0) { - ltimer = 8 << shift_factor; - } else { - ltimer = min_gnt << shift_factor; - } - } - - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ltimer); -} - -void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm, - struct pci_bus *pbus) -{ - struct pci_dev *pdev; - int all_are_66mhz; - u16 status; - - if (pbm->is_66mhz_capable == 0) { - all_are_66mhz = 0; - goto out; - } - - all_are_66mhz = 1; - list_for_each_entry(pdev, &pbus->devices, bus_list) { - pci_read_config_word(pdev, PCI_STATUS, &status); - if (!(status & PCI_STATUS_66MHZ)) { - all_are_66mhz = 0; - break; - } - } -out: - pbm->all_devs_66mhz = all_are_66mhz; - - printk("PCI%d(PBM%c): Bus running at %dMHz\n", - pbm->parent->index, - (pbm == &pbm->parent->pbm_A) ? 'A' : 'B', - (all_are_66mhz ? 66 : 33)); -} - -void pci_setup_busmastering(struct pci_pbm_info *pbm, - struct pci_bus *pbus) -{ - struct pci_dev *dev; - struct pci_bus *bus; - int is_66mhz; - - is_66mhz = pbm->is_66mhz_capable && pbm->all_devs_66mhz; - - list_for_each_entry(dev, &pbus->devices, bus_list) - pdev_setup_busmastering(dev, is_66mhz); - - list_for_each_entry(bus, &pbus->children, node) - pci_setup_busmastering(pbm, bus); -} - void pci_register_legacy_regions(struct resource *io_res, struct resource *mem_res) { diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 971e2bea30b..ea8a6bd146a 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -17,20 +17,7 @@ extern struct pci_controller_info *pci_controller_root; extern int pci_num_controllers; /* PCI bus scanning and fixup support. */ -extern void pci_fixup_host_bridge_self(struct pci_bus *pbus); -extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus, - struct pci_pbm_info *pbm, - struct device_node *prom_node); -extern void pci_record_assignments(struct pci_pbm_info *pbm, - struct pci_bus *pbus); -extern void pci_assign_unassigned(struct pci_pbm_info *pbm, - struct pci_bus *pbus); -extern void pci_fixup_irq(struct pci_pbm_info *pbm, - struct pci_bus *pbus); -extern void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm, - struct pci_bus *pbus); -extern void pci_setup_busmastering(struct pci_pbm_info *pbm, - struct pci_bus *pbus); +extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_register_legacy_regions(struct resource *io_res, struct resource *mem_res); diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 7aca0f33f88..554daabb381 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -220,7 +220,6 @@ static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx) */ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; iopte_t *iopte; unsigned long flags, order, first_page; @@ -237,8 +236,7 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr return NULL; memset((char *)first_page, 0, PAGE_SIZE << order); - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; + iommu = pdev->dev.archdata.iommu; spin_lock_irqsave(&iommu->lock, flags); iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT); @@ -268,14 +266,12 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr /* Free and unmap a consistent DMA translation. */ static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; iopte_t *iopte; unsigned long flags, order, npages; npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; + iommu = pdev->dev.archdata.iommu; iopte = iommu->page_table + ((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT); @@ -295,7 +291,6 @@ static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, */ static dma_addr_t pci_4u_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; struct pci_strbuf *strbuf; iopte_t *base; @@ -304,9 +299,8 @@ static dma_addr_t pci_4u_map_single(struct pci_dev *pdev, void *ptr, size_t sz, u32 bus_addr, ret; unsigned long iopte_protection; - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - strbuf = &pcp->pbm->stc; + iommu = pdev->dev.archdata.iommu; + strbuf = pdev->dev.archdata.stc; if (unlikely(direction == PCI_DMA_NONE)) goto bad_no_ctx; @@ -416,7 +410,6 @@ do_flush_sync: /* Unmap a single streaming mode DMA translation. */ static void pci_4u_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; struct pci_strbuf *strbuf; iopte_t *base; @@ -428,9 +421,8 @@ static void pci_4u_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_ return; } - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - strbuf = &pcp->pbm->stc; + iommu = pdev->dev.archdata.iommu; + strbuf = pdev->dev.archdata.stc; npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; @@ -549,7 +541,6 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, */ static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; struct pci_strbuf *strbuf; unsigned long flags, ctx, npages, iopte_protection; @@ -570,9 +561,8 @@ static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int n return 1; } - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - strbuf = &pcp->pbm->stc; + iommu = pdev->dev.archdata.iommu; + strbuf = pdev->dev.archdata.stc; if (unlikely(direction == PCI_DMA_NONE)) goto bad_no_ctx; @@ -636,7 +626,6 @@ bad_no_ctx: /* Unmap a set of streaming mode DMA translations. */ static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; struct pci_strbuf *strbuf; iopte_t *base; @@ -648,9 +637,8 @@ static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, in WARN_ON(1); } - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - strbuf = &pcp->pbm->stc; + iommu = pdev->dev.archdata.iommu; + strbuf = pdev->dev.archdata.stc; bus_addr = sglist->dma_address & IO_PAGE_MASK; @@ -696,14 +684,12 @@ static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, in */ static void pci_4u_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; struct pci_strbuf *strbuf; unsigned long flags, ctx, npages; - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - strbuf = &pcp->pbm->stc; + iommu = pdev->dev.archdata.iommu; + strbuf = pdev->dev.archdata.stc; if (!strbuf->strbuf_enabled) return; @@ -736,15 +722,13 @@ static void pci_4u_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_ */ static void pci_4u_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; struct pci_strbuf *strbuf; unsigned long flags, ctx, npages, i; u32 bus_addr; - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - strbuf = &pcp->pbm->stc; + iommu = pdev->dev.archdata.iommu; + strbuf = pdev->dev.archdata.stc; if (!strbuf->strbuf_enabled) return; @@ -809,13 +793,12 @@ static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit) int pci_dma_supported(struct pci_dev *pdev, u64 device_mask) { - struct pcidev_cookie *pcp = pdev->sysdata; u64 dma_addr_mask; if (pdev == NULL) { dma_addr_mask = 0xffffffff; } else { - struct pci_iommu *iommu = pcp->pbm->iommu; + struct pci_iommu *iommu = pdev->dev.archdata.iommu; dma_addr_mask = iommu->dma_addr_mask; diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index fda5db223d9..12ea30d30b2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -905,8 +905,7 @@ static void psycho_resource_adjust(struct pci_dev *pdev, static void psycho_base_address_update(struct pci_dev *pdev, int resource) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; struct resource *res, *root; u32 reg; int where, size, is_64bit; @@ -968,28 +967,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) static void pbm_scan_bus(struct pci_controller_info *p, struct pci_pbm_info *pbm) { - struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); - - if (!cookie) { - prom_printf("PSYCHO: Critical allocation failure.\n"); - prom_halt(); - } - - /* All we care about is the PBM. */ - cookie->pbm = pbm; - - pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, - p->pci_ops, - pbm); - pci_fixup_host_bridge_self(pbm->pci_bus); - pbm->pci_bus->self->sysdata = cookie; - - pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); - pci_record_assignments(pbm, pbm->pci_bus); - pci_assign_unassigned(pbm, pbm->pci_bus); - pci_fixup_irq(pbm, pbm->pci_bus); - pci_determine_66mhz_disposition(pbm, pbm->pci_bus); - pci_setup_busmastering(pbm, pbm->pci_bus); + pbm->pci_bus = pci_scan_one_pbm(pbm); } static void psycho_scan_bus(struct pci_controller_info *p) diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 94bb681f232..bbf62451750 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -710,8 +710,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) p->index); ret = IRQ_HANDLED; } - pci_read_config_word(sabre_root_bus->self, - PCI_STATUS, &stat); + pci_bus_read_config_word(sabre_root_bus, 0, + PCI_STATUS, &stat); if (stat & (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_REC_TARGET_ABORT | @@ -719,8 +719,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) PCI_STATUS_SIG_SYSTEM_ERROR)) { printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n", p->index, stat); - pci_write_config_word(sabre_root_bus->self, - PCI_STATUS, 0xffff); + pci_bus_write_config_word(sabre_root_bus, 0, + PCI_STATUS, 0xffff); ret = IRQ_HANDLED; } return ret; @@ -887,8 +887,7 @@ static void sabre_resource_adjust(struct pci_dev *pdev, static void sabre_base_address_update(struct pci_dev *pdev, int resource) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; struct resource *res; unsigned long base; u32 reg; @@ -978,27 +977,11 @@ static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) } } -static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm) -{ - struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); - - if (!cookie) { - prom_printf("SABRE: Critical allocation failure.\n"); - prom_halt(); - } - - /* All we care about is the PBM. */ - cookie->pbm = pbm; - - return cookie; -} - static void sabre_scan_bus(struct pci_controller_info *p) { static int once; struct pci_bus *sabre_bus, *pbus; struct pci_pbm_info *pbm; - struct pcidev_cookie *cookie; int sabres_scanned; /* The APB bridge speaks to the Sabre host PCI bridge @@ -1020,13 +1003,9 @@ static void sabre_scan_bus(struct pci_controller_info *p) } once++; - cookie = alloc_bridge_cookie(&p->pbm_A); - - sabre_bus = pci_scan_bus(p->pci_first_busno, - p->pci_ops, - &p->pbm_A); - pci_fixup_host_bridge_self(sabre_bus); - sabre_bus->self->sysdata = cookie; + sabre_bus = pci_scan_one_pbm(&p->pbm_A); + if (!sabre_bus) + return; sabre_root_bus = sabre_bus; @@ -1043,19 +1022,9 @@ static void sabre_scan_bus(struct pci_controller_info *p) } else continue; - cookie = alloc_bridge_cookie(pbm); - pbus->self->sysdata = cookie; - sabres_scanned++; - pbus->sysdata = pbm; pbm->pci_bus = pbus; - pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node); - pci_record_assignments(pbm, pbus); - pci_assign_unassigned(pbm, pbus); - pci_fixup_irq(pbm, pbus); - pci_determine_66mhz_disposition(pbm, pbus); - pci_setup_busmastering(pbm, pbus); } if (!sabres_scanned) { @@ -1063,12 +1032,6 @@ static void sabre_scan_bus(struct pci_controller_info *p) pbm = &p->pbm_A; sabre_bus->sysdata = pbm; pbm->pci_bus = sabre_bus; - pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node); - pci_record_assignments(pbm, sabre_bus); - pci_assign_unassigned(pbm, sabre_bus); - pci_fixup_irq(pbm, sabre_bus); - pci_determine_66mhz_disposition(pbm, sabre_bus); - pci_setup_busmastering(pbm, sabre_bus); } sabre_register_error_handlers(p); diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 66911b126ae..48dea52ac52 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1232,28 +1232,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) static void pbm_scan_bus(struct pci_controller_info *p, struct pci_pbm_info *pbm) { - struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); - - if (!cookie) { - prom_printf("%s: Critical allocation failure.\n", pbm->name); - prom_halt(); - } - - /* All we care about is the PBM. */ - cookie->pbm = pbm; - - pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, - p->pci_ops, - pbm); - pci_fixup_host_bridge_self(pbm->pci_bus); - pbm->pci_bus->self->sysdata = cookie; - - pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); - pci_record_assignments(pbm, pbm->pci_bus); - pci_assign_unassigned(pbm, pbm->pci_bus); - pci_fixup_irq(pbm, pbm->pci_bus); - pci_determine_66mhz_disposition(pbm, pbm->pci_bus); - pci_setup_busmastering(pbm, pbm->pci_bus); + pbm->pci_bus = pci_scan_one_pbm(pbm); } static void __schizo_scan_bus(struct pci_controller_info *p, @@ -1297,8 +1276,7 @@ static void tomatillo_scan_bus(struct pci_controller_info *p) static void schizo_base_address_update(struct pci_dev *pdev, int resource) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; struct resource *res, *root; u32 reg; int where, size, is_64bit; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index bd74c155519..eec7def379d 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -53,8 +53,8 @@ static inline void pci_iommu_batch_start(struct pci_dev *pdev, unsigned long pro /* Interrupts must be disabled. */ static long pci_iommu_batch_flush(struct pci_iommu_batch *p) { - struct pcidev_cookie *pcp = p->pdev->sysdata; - unsigned long devhandle = pcp->pbm->devhandle; + struct pci_pbm_info *pbm = p->pdev->dev.archdata.host_controller; + unsigned long devhandle = pbm->devhandle; unsigned long prot = p->prot; unsigned long entry = p->entry; u64 *pglist = p->pglist; @@ -159,7 +159,6 @@ static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, un static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; unsigned long flags, order, first_page, npages, n; void *ret; @@ -178,8 +177,7 @@ static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr memset((char *)first_page, 0, PAGE_SIZE << order); - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; + iommu = pdev->dev.archdata.iommu; spin_lock_irqsave(&iommu->lock, flags); entry = pci_arena_alloc(&iommu->arena, npages); @@ -226,15 +224,15 @@ arena_alloc_fail: static void pci_4v_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) { - struct pcidev_cookie *pcp; + struct pci_pbm_info *pbm; struct pci_iommu *iommu; unsigned long flags, order, npages, entry; u32 devhandle; npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - devhandle = pcp->pbm->devhandle; + iommu = pdev->dev.archdata.iommu; + pbm = pdev->dev.archdata.host_controller; + devhandle = pbm->devhandle; entry = ((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT); spin_lock_irqsave(&iommu->lock, flags); @@ -259,7 +257,6 @@ static void pci_4v_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, static dma_addr_t pci_4v_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; unsigned long flags, npages, oaddr; unsigned long i, base_paddr; @@ -267,8 +264,7 @@ static dma_addr_t pci_4v_map_single(struct pci_dev *pdev, void *ptr, size_t sz, unsigned long prot; long entry; - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; + iommu = pdev->dev.archdata.iommu; if (unlikely(direction == PCI_DMA_NONE)) goto bad; @@ -324,7 +320,7 @@ iommu_map_fail: static void pci_4v_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct pcidev_cookie *pcp; + struct pci_pbm_info *pbm; struct pci_iommu *iommu; unsigned long flags, npages; long entry; @@ -336,9 +332,9 @@ static void pci_4v_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_ return; } - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - devhandle = pcp->pbm->devhandle; + iommu = pdev->dev.archdata.iommu; + pbm = pdev->dev.archdata.host_controller; + devhandle = pbm->devhandle; npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; @@ -460,7 +456,6 @@ iommu_map_failed: static int pci_4v_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pcidev_cookie *pcp; struct pci_iommu *iommu; unsigned long flags, npages, prot; u32 dma_base; @@ -480,8 +475,7 @@ static int pci_4v_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int n return 1; } - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; + iommu = pdev->dev.archdata.iommu; if (unlikely(direction == PCI_DMA_NONE)) goto bad; @@ -537,7 +531,7 @@ iommu_map_failed: static void pci_4v_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pcidev_cookie *pcp; + struct pci_pbm_info *pbm; struct pci_iommu *iommu; unsigned long flags, i, npages; long entry; @@ -548,9 +542,9 @@ static void pci_4v_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, in WARN_ON(1); } - pcp = pdev->sysdata; - iommu = pcp->pbm->iommu; - devhandle = pcp->pbm->devhandle; + iommu = pdev->dev.archdata.iommu; + pbm = pdev->dev.archdata.host_controller; + devhandle = pbm->devhandle; bus_addr = sglist->dma_address & IO_PAGE_MASK; @@ -600,132 +594,12 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = { .dma_sync_sg_for_cpu = pci_4v_dma_sync_sg_for_cpu, }; -/* SUN4V PCI configuration space accessors. */ - -struct pdev_entry { - struct pdev_entry *next; - u32 devhandle; - unsigned int bus; - unsigned int device; - unsigned int func; -}; - -#define PDEV_HTAB_SIZE 16 -#define PDEV_HTAB_MASK (PDEV_HTAB_SIZE - 1) -static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE]; - -static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) -{ - unsigned int val; - - val = (devhandle ^ (devhandle >> 4)); - val ^= bus; - val ^= device; - val ^= func; - - return val & PDEV_HTAB_MASK; -} - -static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) -{ - struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL); - struct pdev_entry **slot; - - if (!p) - return -ENOMEM; - - slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; - p->next = *slot; - *slot = p; - - p->devhandle = devhandle; - p->bus = bus; - p->device = device; - p->func = func; - - return 0; -} - -/* Recursively descend into the OBP device tree, rooted at toplevel_node, - * looking for a PCI device matching bus and devfn. - */ -static int obp_find(struct device_node *toplevel_node, unsigned int bus, unsigned int devfn) -{ - toplevel_node = toplevel_node->child; - - while (toplevel_node != NULL) { - struct linux_prom_pci_registers *regs; - struct property *prop; - int ret; - - ret = obp_find(toplevel_node, bus, devfn); - if (ret != 0) - return ret; - - prop = of_find_property(toplevel_node, "reg", NULL); - if (!prop) - goto next_sibling; - - regs = prop->value; - if (((regs->phys_hi >> 16) & 0xff) == bus && - ((regs->phys_hi >> 8) & 0xff) == devfn) - break; - - next_sibling: - toplevel_node = toplevel_node->sibling; - } - - return toplevel_node != NULL; -} - -static int pdev_htab_populate(struct pci_pbm_info *pbm) -{ - u32 devhandle = pbm->devhandle; - unsigned int bus; - - for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) { - unsigned int devfn; - - for (devfn = 0; devfn < 256; devfn++) { - unsigned int device = PCI_SLOT(devfn); - unsigned int func = PCI_FUNC(devfn); - - if (obp_find(pbm->prom_node, bus, devfn)) { - int err = pdev_htab_add(devhandle, bus, - device, func); - if (err) - return err; - } - } - } - - return 0; -} - -static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) -{ - struct pdev_entry *p; - - p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; - while (p) { - if (p->devhandle == devhandle && - p->bus == bus && - p->device == device && - p->func == func) - break; - - p = p->next; - } - - return p; -} - static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) { if (bus < pbm->pci_first_busno || bus > pbm->pci_last_busno) return 1; - return pdev_find(pbm->devhandle, bus, device, func) == NULL; + return 0; } static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, @@ -800,27 +674,7 @@ static struct pci_ops pci_sun4v_ops = { static void pbm_scan_bus(struct pci_controller_info *p, struct pci_pbm_info *pbm) { - struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); - - if (!cookie) { - prom_printf("%s: Critical allocation failure.\n", pbm->name); - prom_halt(); - } - - /* All we care about is the PBM. */ - cookie->pbm = pbm; - - pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); -#if 0 - pci_fixup_host_bridge_self(pbm->pci_bus); - pbm->pci_bus->self->sysdata = cookie; -#endif - pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); - pci_record_assignments(pbm, pbm->pci_bus); - pci_assign_unassigned(pbm, pbm->pci_bus); - pci_fixup_irq(pbm, pbm->pci_bus); - pci_determine_66mhz_disposition(pbm, pbm->pci_bus); - pci_setup_busmastering(pbm, pbm->pci_bus); + pbm->pci_bus = pci_scan_one_pbm(pbm); } static void pci_sun4v_scan_bus(struct pci_controller_info *p) @@ -846,8 +700,7 @@ static void pci_sun4v_scan_bus(struct pci_controller_info *p) static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; struct resource *res, *root; u32 reg; int where, size, is_64bit; @@ -1410,8 +1263,7 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, struct pci_dev *pdev, struct msi_desc *entry) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; unsigned long devino, msiqid; struct msi_msg msg; int msi_num, err; @@ -1455,7 +1307,7 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, if (pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_VALID)) goto out_err; - pcp->msi_num = msi_num; + pdev->dev.archdata.msi_num = msi_num; if (entry->msi_attrib.is_64) { msg.address_hi = pbm->msi64_start >> 32; @@ -1484,12 +1336,11 @@ out_err: static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq, struct pci_dev *pdev) { - struct pcidev_cookie *pcp = pdev->sysdata; - struct pci_pbm_info *pbm = pcp->pbm; + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; unsigned long msiqid, err; unsigned int msi_num; - msi_num = pcp->msi_num; + msi_num = pdev->dev.archdata.msi_num; err = pci_sun4v_msi_getmsiq(pbm->devhandle, msi_num, &msiqid); if (err) { printk(KERN_ERR "%s: getmsiq gives error %lu\n", @@ -1559,8 +1410,6 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pci_sun4v_get_bus_range(pbm); pci_sun4v_iommu_init(pbm); pci_sun4v_msi_init(pbm); - - pdev_htab_populate(pbm); } void sun4v_pci_init(struct device_node *dp, char *model_name) -- cgit v1.2.3 From 1e8a8cc52daa95e702303ca3ce67955a4c051d7d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 28 Feb 2007 23:38:38 -0800 Subject: [SPARC64]: Internalize pci_memspace_mask. The only user was bus_dvma_to_mem() which is no longer used by any driver, so kill that, and the export of pci_memspace_mask. The only user now is the PCI mmap support code. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 2 ++ arch/sparc64/kernel/pci_impl.h | 1 + arch/sparc64/kernel/sparc64_ksyms.c | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 246b8009a2b..ec0d12a48c2 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -27,6 +27,8 @@ #include #include +#include "pci_impl.h" + unsigned long pci_memspace_mask = 0xffffffffUL; #ifndef CONFIG_PCI diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index ea8a6bd146a..c4ba702e1fd 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -13,6 +13,7 @@ #include extern struct pci_controller_info *pci_controller_root; +extern unsigned long pci_memspace_mask; extern int pci_num_controllers; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index beffc82a1e8..d00f51a5683 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -212,7 +212,6 @@ EXPORT_SYMBOL(insl); #ifdef CONFIG_PCI EXPORT_SYMBOL(ebus_chain); EXPORT_SYMBOL(isa_chain); -EXPORT_SYMBOL(pci_memspace_mask); EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); EXPORT_SYMBOL(pci_map_single); -- cgit v1.2.3 From bc606f3c917aa453fca62b76c8e9998b4171f4fa Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 1 Mar 2007 11:20:37 -0800 Subject: [SPARC64]: Minor cleanups to schizo pci controller driver. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_schizo.c | 110 +++++++++++---------------------------- 1 file changed, 31 insertions(+), 79 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 48dea52ac52..332cfd9736b 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1229,21 +1229,8 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void pbm_scan_bus(struct pci_controller_info *p, - struct pci_pbm_info *pbm) -{ - pbm->pci_bus = pci_scan_one_pbm(pbm); -} - -static void __schizo_scan_bus(struct pci_controller_info *p, - int chip_type) +static void schizo_scan_bus(struct pci_controller_info *p) { - if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) { - printk("PCI: Only one PCI bus module of controller found.\n"); - printk("PCI: Ignoring entire controller.\n"); - return; - } - pbm_config_busmastering(&p->pbm_B); p->pbm_B.is_66mhz_capable = (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL) @@ -1252,28 +1239,19 @@ static void __schizo_scan_bus(struct pci_controller_info *p, p->pbm_A.is_66mhz_capable = (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL) != NULL); - pbm_scan_bus(p, &p->pbm_B); - pbm_scan_bus(p, &p->pbm_A); + + p->pbm_B.pci_bus = pci_scan_one_pbm(&p->pbm_B); + p->pbm_A.pci_bus = pci_scan_one_pbm(&p->pbm_A); /* After the PCI bus scan is complete, we can register * the error interrupt handlers. */ - if (chip_type == PBM_CHIP_TYPE_TOMATILLO) + if (p->pbm_B.chip_type == PBM_CHIP_TYPE_TOMATILLO) tomatillo_register_error_handlers(p); else schizo_register_error_handlers(p); } -static void schizo_scan_bus(struct pci_controller_info *p) -{ - __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO); -} - -static void tomatillo_scan_bus(struct pci_controller_info *p) -{ - __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO); -} - static void schizo_base_address_update(struct pci_dev *pdev, int resource) { struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; @@ -1633,7 +1611,6 @@ static void schizo_pbm_init(struct pci_controller_info *p, int chip_type) { struct linux_prom64_registers *regs; - struct property *prop; unsigned int *busrange; struct pci_pbm_info *pbm; const char *chipset_name; @@ -1667,11 +1644,9 @@ static void schizo_pbm_init(struct pci_controller_info *p, * 3) PBM PCI config space * 4) Ichip regs */ - prop = of_find_property(dp, "reg", NULL); - regs = prop->value; + regs = of_get_property(dp, "reg", NULL); is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); - if (is_pbm_a) pbm = &p->pbm_A; else @@ -1683,14 +1658,8 @@ static void schizo_pbm_init(struct pci_controller_info *p, pbm->pci_first_slot = 1; pbm->chip_type = chip_type; - pbm->chip_version = 0; - prop = of_find_property(dp, "version#", NULL); - if (prop) - pbm->chip_version = *(int *) prop->value; - pbm->chip_revision = 0; - prop = of_find_property(dp, "module-revision#", NULL); - if (prop) - pbm->chip_revision = *(int *) prop->value; + pbm->chip_version = of_getintprop_default(dp, "version#", 0); + pbm->chip_revision = of_getintprop_default(dp, "module-version#", 0); pbm->pbm_regs = regs[0].phys_addr; pbm->controller_regs = regs[1].phys_addr - 0x10000UL; @@ -1701,40 +1670,31 @@ static void schizo_pbm_init(struct pci_controller_info *p, pbm->name = dp->full_name; printk("%s: %s PCI Bus Module ver[%x:%x]\n", - pbm->name, - (chip_type == PBM_CHIP_TYPE_TOMATILLO ? - "TOMATILLO" : "SCHIZO"), + pbm->name, chipset_name, pbm->chip_version, pbm->chip_revision); schizo_pbm_hw_init(pbm); - prop = of_find_property(dp, "ranges", &len); - pbm->pbm_ranges = prop->value; + pbm->pbm_ranges = of_get_property(dp, "ranges", &len); pbm->num_pbm_ranges = (len / sizeof(struct linux_prom_pci_ranges)); schizo_determine_mem_io_space(pbm); pbm_register_toplevel_resources(p, pbm); - prop = of_find_property(dp, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; + pbm->pbm_intmap = of_get_property(dp, "interrupt-map", &len); + if (pbm->pbm_intmap) { pbm->num_pbm_intmap = (len / sizeof(struct linux_prom_pci_intmap)); - - prop = of_find_property(dp, "interrupt-map-mask", NULL); - pbm->pbm_intmask = prop->value; - } else { - pbm->num_pbm_intmap = 0; + pbm->pbm_intmask = + of_get_property(dp, "interrupt-map-mask", NULL); } - prop = of_find_property(dp, "ino-bitmap", NULL); - ino_bitmap = prop->value; + ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | ((u64)ino_bitmap[0] << 0UL)); - prop = of_find_property(dp, "bus-range", NULL); - busrange = prop->value; + busrange = of_get_property(dp, "bus-range", NULL); pbm->pci_first_busno = busrange[0]; pbm->pci_last_busno = busrange[1]; @@ -1756,14 +1716,9 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ { struct pci_controller_info *p; struct pci_iommu *iommu; - struct property *prop; - int is_pbm_a; u32 portid; - portid = 0xff; - prop = of_find_property(dp, "portid", NULL); - if (prop) - portid = *(u32 *) prop->value; + portid = of_getintprop_default(dp, "portid", 0xff); for (p = pci_controller_root; p; p = p->next) { struct pci_pbm_info *pbm; @@ -1776,40 +1731,32 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ &p->pbm_B); if (portid_compare(pbm->portid, portid, chip_type)) { - is_pbm_a = (p->pbm_A.prom_node == NULL); schizo_pbm_init(p, dp, portid, chip_type); return; } } p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) { - prom_printf("SCHIZO: Fatal memory allocation error.\n"); - prom_halt(); - } + if (!p) + goto memfail; iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); - if (!iommu) { - prom_printf("SCHIZO: Fatal memory allocation error.\n"); - prom_halt(); - } + if (!iommu) + goto memfail; + p->pbm_A.iommu = iommu; iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); - if (!iommu) { - prom_printf("SCHIZO: Fatal memory allocation error.\n"); - prom_halt(); - } + if (!iommu) + goto memfail; + p->pbm_B.iommu = iommu; p->next = pci_controller_root; pci_controller_root = p; p->index = pci_num_controllers++; - p->pbms_same_domain = 0; - p->scan_bus = (chip_type == PBM_CHIP_TYPE_TOMATILLO ? - tomatillo_scan_bus : - schizo_scan_bus); + p->scan_bus = schizo_scan_bus; p->base_address_update = schizo_base_address_update; p->resource_adjust = schizo_resource_adjust; p->pci_ops = &schizo_ops; @@ -1818,6 +1765,11 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ pci_memspace_mask = 0x7fffffffUL; schizo_pbm_init(p, dp, portid, chip_type); + return; + +memfail: + prom_printf("SCHIZO: Fatal memory allocation error.\n"); + prom_halt(); } void schizo_init(struct device_node *dp, char *model_name) -- cgit v1.2.3 From a378fd0ee8ea6af5dafd0ab3d634f22b926b5ac4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 1 Mar 2007 11:46:13 -0800 Subject: [SPARC64]: Fix obppath pci device sysfs creation. Need to traverse recursively down child busses else we only get the file created under devices at the top-level. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index ec0d12a48c2..425e883e7e3 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -585,6 +585,7 @@ static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_pciobppath_attr, N static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) { struct pci_dev *dev; + struct pci_bus *child_bus; int err; list_for_each_entry(dev, &bus->devices, bus_list) { @@ -597,6 +598,8 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) */ err = sysfs_create_file(&dev->dev.kobj, &dev_attr_obppath.attr); } + list_for_each_entry(child_bus, &bus->children, node) + pci_bus_register_of_sysfs(child_bus); } struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) -- cgit v1.2.3 From 01f94c4a6ced476ce69b895426fc29bfc48c69bd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 4 Mar 2007 12:53:19 -0800 Subject: [SPARC64]: Fix sabre pci controllers with new probing scheme. The SIMBA APB bridge is strange, it is a PCI bridge but it lacks some standard OF properties, in particular it lacks a 'ranges' property. What you have to do is read the IO and MEM range registers in the APB bridge to determine the ranges handled by each bridge. So fill in the bus resources by doing that. Since we now handle this quirk in the generic PCI and OF device probing layers, we can flat out eliminate all of that code from the sabre pci controller driver. In fact we can thus eliminate completely another quirk of the sabre driver. It tried to make the two APB bridges look like PBMs but that makes zero sense now (and it's questionable whether it ever made sense). So now just use pbm_A and probe the whole PCI hierarchy using that as the root. This simplification allows many future cleanups to occur. Also, I've found yet another quirk that needs to be worked around while testing this. You can't use the 'class-code' OF firmware property, especially for IDE controllers. We have to read the value out of PCI config space or else we'll see the value the device was showing before it was programmed into native mode. I'm starting to think it might be wise to just read all of the values out of PCI config space instead of using the OF properties. :-/ Signed-off-by: David S. Miller --- arch/sparc64/kernel/of_device.c | 29 ++++ arch/sparc64/kernel/pci.c | 80 +++++++++- arch/sparc64/kernel/pci_sabre.c | 340 ++++++++-------------------------------- 3 files changed, 165 insertions(+), 284 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 6b8798141f2..8964eacb004 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -317,6 +317,11 @@ static unsigned int of_bus_default_get_flags(const u32 *addr) static int of_bus_pci_match(struct device_node *np) { if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { + char *model = of_get_property(np, "model", NULL); + + if (model && !strcmp(model, "SUNW,simba")) + return 0; + /* Do not do PCI specific frobbing if the * PCI bridge lacks a ranges property. We * want to pass it through up to the next @@ -332,6 +337,21 @@ static int of_bus_pci_match(struct device_node *np) return 0; } +static int of_bus_simba_match(struct device_node *np) +{ + char *model = of_get_property(np, "model", NULL); + + if (model && !strcmp(model, "SUNW,simba")) + return 1; + return 0; +} + +static int of_bus_simba_map(u32 *addr, const u32 *range, + int na, int ns, int pna) +{ + return 0; +} + static void of_bus_pci_count_cells(struct device_node *np, int *addrc, int *sizec) { @@ -436,6 +456,15 @@ static struct of_bus of_busses[] = { .map = of_bus_pci_map, .get_flags = of_bus_pci_get_flags, }, + /* SIMBA */ + { + .name = "simba", + .addr_prop_name = "assigned-addresses", + .match = of_bus_simba_match, + .count_cells = of_bus_pci_count_cells, + .map = of_bus_simba_map, + .get_flags = of_bus_pci_get_flags, + }, /* SBUS */ { .name = "sbus", diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 425e883e7e3..b63341c2a33 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "pci_impl.h" @@ -372,6 +373,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, struct dev_archdata *sd; struct pci_dev *dev; const char *type; + u32 class; dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) @@ -409,7 +411,15 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - dev->class = of_getintprop_default(node, "class-code", 0); + + /* dev->class = of_getintprop_default(node, "class-code", 0); */ + /* We can't actually use the firmware value, we have to read what + * is in the register right now. One reason is that in the case + * of IDE interfaces the firmware can sample the value before the + * the IDE interface is programmed into native mode. + */ + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); + dev->class = class >> 8; printk(" class: 0x%x\n", dev->class); @@ -440,6 +450,53 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, return dev; } +static void __init apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) +{ + u32 idx, first, last; + + first = 8; + last = 0; + for (idx = 0; idx < 8; idx++) { + if ((map & (1 << idx)) != 0) { + if (first > idx) + first = idx; + if (last < idx) + last = idx; + } + } + + *first_p = first; + *last_p = last; +} + +/* Cook up fake bus resources for SUNW,simba PCI bridges which lack + * a proper 'ranges' property. + */ +static void __init apb_fake_ranges(struct pci_dev *dev, + struct pci_bus *bus, + struct pci_pbm_info *pbm) +{ + struct resource *res; + u32 first, last; + u8 map; + + pci_read_config_byte(dev, APB_IO_ADDRESS_MAP, &map); + apb_calc_first_last(map, &first, &last); + res = bus->resource[0]; + res->start = (first << 21); + res->end = (last << 21) + ((1 << 21) - 1); + res->flags = IORESOURCE_IO; + pbm->parent->resource_adjust(dev, res, &pbm->io_space); + + pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map); + apb_calc_first_last(map, &first, &last); + res = bus->resource[1]; + res->start = (first << 21); + res->end = (last << 21) + ((1 << 21) - 1); + res->flags = IORESOURCE_MEM; + pbm->parent->resource_adjust(dev, res, &pbm->mem_space); +} + static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, struct device_node *node, struct pci_bus *bus); @@ -452,7 +509,7 @@ void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, { struct pci_bus *bus; const u32 *busrange, *ranges; - int len, i; + int len, i, simba; struct resource *res; unsigned int flags; u64 size; @@ -467,10 +524,16 @@ void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, return; } ranges = of_get_property(node, "ranges", &len); + simba = 0; if (ranges == NULL) { - printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", - node->full_name); - return; + char *model = of_get_property(node, "model", NULL); + if (model && !strcmp(model, "SUNW,simba")) { + simba = 1; + } else { + printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", + node->full_name); + return; + } } bus = pci_add_new_bus(dev->bus, dev, busrange[0]); @@ -484,7 +547,7 @@ void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, bus->subordinate = busrange[1]; bus->bridge_ctl = 0; - /* parse ranges property */ + /* parse ranges property, or cook one up by hand for Simba */ /* PCI #address-cells == 3 and #size-cells == 2 always */ res = &dev->resource[PCI_BRIDGE_RESOURCES]; for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { @@ -492,6 +555,10 @@ void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, bus->resource[i] = res; ++res; } + if (simba) { + apb_fake_ranges(dev, bus, pbm); + goto simba_cont; + } i = 1; for (; len >= 32; len -= 32, ranges += 8) { struct resource *root; @@ -529,6 +596,7 @@ void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, */ pbm->parent->resource_adjust(dev, res, root); } +simba_cont: sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), bus->number); printk(" bus name: %s\n", bus->name); diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index bbf62451750..f4e346092a5 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -254,9 +254,6 @@ static int __sabre_out_of_range(struct pci_pbm_info *pbm, return 0; return ((pbm->parent == 0) || - ((pbm == &pbm->parent->pbm_B) && - (bus == pbm->pci_first_busno) && - PCI_SLOT(devfn) > 8) || ((pbm == &pbm->parent->pbm_A) && (bus == pbm->pci_first_busno) && PCI_SLOT(devfn) > 8)); @@ -800,12 +797,10 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) if (error_bits & (SABRE_PIOAFSR_PTA | SABRE_PIOAFSR_STA)) { sabre_check_iommu_error(p, afsr, afar); pci_scan_for_target_abort(p, &p->pbm_A, p->pbm_A.pci_bus); - pci_scan_for_target_abort(p, &p->pbm_B, p->pbm_B.pci_bus); } - if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) { + if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) pci_scan_for_master_abort(p, &p->pbm_A, p->pbm_A.pci_bus); - pci_scan_for_master_abort(p, &p->pbm_B, p->pbm_B.pci_bus); - } + /* For excessive retries, SABRE/PBM will abort the device * and there is no way to specifically check for excessive * retries in the config space status registers. So what @@ -813,10 +808,8 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) * abort events. */ - if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) { + if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) pci_scan_for_parity_error(p, &p->pbm_A, p->pbm_A.pci_bus); - pci_scan_for_parity_error(p, &p->pbm_B, p->pbm_B.pci_bus); - } return IRQ_HANDLED; } @@ -935,44 +928,33 @@ static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) struct pci_dev *pdev; list_for_each_entry(pdev, &sabre_bus->devices, bus_list) { - if (pdev->vendor == PCI_VENDOR_ID_SUN && pdev->device == PCI_DEVICE_ID_SUN_SIMBA) { - u32 word32; u16 word16; - sabre_read_pci_cfg(pdev->bus, pdev->devfn, - PCI_COMMAND, 2, &word32); - word16 = (u16) word32; + pci_read_config_word(pdev, PCI_COMMAND, &word16); word16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; - word32 = (u32) word16; - sabre_write_pci_cfg(pdev->bus, pdev->devfn, - PCI_COMMAND, 2, word32); + pci_write_config_word(pdev, PCI_COMMAND, word16); /* Status register bits are "write 1 to clear". */ - sabre_write_pci_cfg(pdev->bus, pdev->devfn, - PCI_STATUS, 2, 0xffff); - sabre_write_pci_cfg(pdev->bus, pdev->devfn, - PCI_SEC_STATUS, 2, 0xffff); + pci_write_config_word(pdev, PCI_STATUS, 0xffff); + pci_write_config_word(pdev, PCI_SEC_STATUS, 0xffff); /* Use a primary/seconday latency timer value * of 64. */ - sabre_write_pci_cfg(pdev->bus, pdev->devfn, - PCI_LATENCY_TIMER, 1, 64); - sabre_write_pci_cfg(pdev->bus, pdev->devfn, - PCI_SEC_LATENCY_TIMER, 1, 64); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); + pci_write_config_byte(pdev, PCI_SEC_LATENCY_TIMER, 64); /* Enable reporting/forwarding of master aborts, * parity, and SERR. */ - sabre_write_pci_cfg(pdev->bus, pdev->devfn, - PCI_BRIDGE_CONTROL, 1, - (PCI_BRIDGE_CTL_PARITY | - PCI_BRIDGE_CTL_SERR | - PCI_BRIDGE_CTL_MASTER_ABORT)); + pci_write_config_byte(pdev, PCI_BRIDGE_CONTROL, + (PCI_BRIDGE_CTL_PARITY | + PCI_BRIDGE_CTL_SERR | + PCI_BRIDGE_CTL_MASTER_ABORT)); } } } @@ -980,16 +962,13 @@ static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) static void sabre_scan_bus(struct pci_controller_info *p) { static int once; - struct pci_bus *sabre_bus, *pbus; - struct pci_pbm_info *pbm; - int sabres_scanned; + struct pci_bus *pbus; /* The APB bridge speaks to the Sabre host PCI bridge * at 66Mhz, but the front side of APB runs at 33Mhz * for both segments. */ p->pbm_A.is_66mhz_capable = 0; - p->pbm_B.is_66mhz_capable = 0; /* This driver has not been verified to handle * multiple SABREs yet, so trap this. @@ -1003,36 +982,13 @@ static void sabre_scan_bus(struct pci_controller_info *p) } once++; - sabre_bus = pci_scan_one_pbm(&p->pbm_A); - if (!sabre_bus) + pbus = pci_scan_one_pbm(&p->pbm_A); + if (!pbus) return; - sabre_root_bus = sabre_bus; - - apb_init(p, sabre_bus); - - sabres_scanned = 0; + sabre_root_bus = pbus; - list_for_each_entry(pbus, &sabre_bus->children, node) { - - if (pbus->number == p->pbm_A.pci_first_busno) { - pbm = &p->pbm_A; - } else if (pbus->number == p->pbm_B.pci_first_busno) { - pbm = &p->pbm_B; - } else - continue; - - sabres_scanned++; - pbus->sysdata = pbm; - pbm->pci_bus = pbus; - } - - if (!sabres_scanned) { - /* Hummingbird, no APBs. */ - pbm = &p->pbm_A; - sabre_bus->sysdata = pbm; - pbm->pci_bus = sabre_bus; - } + apb_init(p, pbus); sabre_register_error_handlers(p); } @@ -1089,213 +1045,54 @@ static void sabre_iommu_init(struct pci_controller_info *p, sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); } -static void pbm_register_toplevel_resources(struct pci_controller_info *p, - struct pci_pbm_info *pbm) +static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end) { - char *name = pbm->name; - unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE; - unsigned long mbase = p->pbm_A.controller_regs + SABRE_MEMSPACE; - unsigned int devfn; - unsigned long first, last, i; - u8 *addr, map; - - sprintf(name, "SABRE%d PBM%c", - p->index, - (pbm == &p->pbm_A ? 'A' : 'B')); - pbm->io_space.name = pbm->mem_space.name = name; - - devfn = PCI_DEVFN(1, (pbm == &p->pbm_A) ? 0 : 1); - addr = sabre_pci_config_mkaddr(pbm, 0, devfn, APB_IO_ADDRESS_MAP); - map = 0; - pci_config_read8(addr, &map); - - first = 8; - last = 0; - for (i = 0; i < 8; i++) { - if ((map & (1 << i)) != 0) { - if (first > i) - first = i; - if (last < i) - last = i; - } - } - pbm->io_space.start = ibase + (first << 21UL); - pbm->io_space.end = ibase + (last << 21UL) + ((1 << 21UL) - 1); + struct pci_pbm_info *pbm; + struct resource *rp; + + pbm = &p->pbm_A; + pbm->name = dp->full_name; + printk("%s: SABRE PCI Bus Module\n", pbm->name); + + pbm->chip_type = PBM_CHIP_TYPE_SABRE; + pbm->parent = p; + pbm->prom_node = dp; + pbm->pci_first_slot = 1; + pbm->pci_first_busno = p->pci_first_busno; + pbm->pci_last_busno = p->pci_last_busno; + + pbm->io_space.name = pbm->mem_space.name = pbm->name; + + pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE; + pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; pbm->io_space.flags = IORESOURCE_IO; - addr = sabre_pci_config_mkaddr(pbm, 0, devfn, APB_MEM_ADDRESS_MAP); - map = 0; - pci_config_read8(addr, &map); - - first = 8; - last = 0; - for (i = 0; i < 8; i++) { - if ((map & (1 << i)) != 0) { - if (first > i) - first = i; - if (last < i) - last = i; - } - } - pbm->mem_space.start = mbase + (first << 29UL); - pbm->mem_space.end = mbase + (last << 29UL) + ((1 << 29UL) - 1); + pbm->mem_space.start = (p->pbm_A.controller_regs + SABRE_MEMSPACE); + pbm->mem_space.end = (pbm->mem_space.start + ((1UL << 32UL) - 1UL)); pbm->mem_space.flags = IORESOURCE_MEM; if (request_resource(&ioport_resource, &pbm->io_space) < 0) { - prom_printf("Cannot register PBM-%c's IO space.\n", - (pbm == &p->pbm_A ? 'A' : 'B')); + prom_printf("Cannot register Sabre's IO space.\n"); prom_halt(); } if (request_resource(&iomem_resource, &pbm->mem_space) < 0) { - prom_printf("Cannot register PBM-%c's MEM space.\n", - (pbm == &p->pbm_A ? 'A' : 'B')); + prom_printf("Cannot register Sabre's MEM space.\n"); prom_halt(); } - /* Register legacy regions if this PBM covers that area. */ - if (pbm->io_space.start == ibase && - pbm->mem_space.start == mbase) - pci_register_legacy_regions(&pbm->io_space, - &pbm->mem_space); -} - -static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end) -{ - struct pci_pbm_info *pbm; - struct device_node *node; - struct property *prop; - u32 *busrange; - int len, simbas_found; - - simbas_found = 0; - node = dp->child; - while (node != NULL) { - if (strcmp(node->name, "pci")) - goto next_pci; - - prop = of_find_property(node, "model", NULL); - if (!prop || strncmp(prop->value, "SUNW,simba", prop->length)) - goto next_pci; - - simbas_found++; - - prop = of_find_property(node, "bus-range", NULL); - busrange = prop->value; - if (busrange[0] == 1) - pbm = &p->pbm_B; - else - pbm = &p->pbm_A; - - pbm->name = node->full_name; - printk("%s: SABRE PCI Bus Module\n", pbm->name); - - pbm->chip_type = PBM_CHIP_TYPE_SABRE; - pbm->parent = p; - pbm->prom_node = node; - pbm->pci_first_slot = 1; - pbm->pci_first_busno = busrange[0]; - pbm->pci_last_busno = busrange[1]; - - prop = of_find_property(node, "ranges", &len); - if (prop) { - pbm->pbm_ranges = prop->value; - pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - } else { - pbm->num_pbm_ranges = 0; - } - - prop = of_find_property(node, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - - prop = of_find_property(node, "interrupt-map-mask", - NULL); - pbm->pbm_intmask = prop->value; - } else { - pbm->num_pbm_intmap = 0; - } - - pbm_register_toplevel_resources(p, pbm); - - next_pci: - node = node->sibling; - } - if (simbas_found == 0) { - struct resource *rp; - - /* No APBs underneath, probably this is a hummingbird - * system. - */ - pbm = &p->pbm_A; - pbm->parent = p; - pbm->prom_node = dp; - pbm->pci_first_busno = p->pci_first_busno; - pbm->pci_last_busno = p->pci_last_busno; - - prop = of_find_property(dp, "ranges", &len); - if (prop) { - pbm->pbm_ranges = prop->value; - pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - } else { - pbm->num_pbm_ranges = 0; - } - - prop = of_find_property(dp, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - - prop = of_find_property(dp, "interrupt-map-mask", - NULL); - pbm->pbm_intmask = prop->value; - } else { - pbm->num_pbm_intmap = 0; - } - - pbm->name = dp->full_name; - printk("%s: SABRE PCI Bus Module\n", pbm->name); - - pbm->io_space.name = pbm->mem_space.name = pbm->name; - - /* Hack up top-level resources. */ - pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE; - pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; - pbm->io_space.flags = IORESOURCE_IO; - - pbm->mem_space.start = - (p->pbm_A.controller_regs + SABRE_MEMSPACE); - pbm->mem_space.end = - (pbm->mem_space.start + ((1UL << 32UL) - 1UL)); - pbm->mem_space.flags = IORESOURCE_MEM; - - if (request_resource(&ioport_resource, &pbm->io_space) < 0) { - prom_printf("Cannot register Hummingbird's IO space.\n"); - prom_halt(); - } - if (request_resource(&iomem_resource, &pbm->mem_space) < 0) { - prom_printf("Cannot register Hummingbird's MEM space.\n"); - prom_halt(); - } - - rp = kmalloc(sizeof(*rp), GFP_KERNEL); - if (!rp) { - prom_printf("Cannot allocate IOMMU resource.\n"); - prom_halt(); - } - rp->name = "IOMMU"; - rp->start = pbm->mem_space.start + (unsigned long) dma_start; - rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL; - rp->flags = IORESOURCE_BUSY; - request_resource(&pbm->mem_space, rp); - - pci_register_legacy_regions(&pbm->io_space, - &pbm->mem_space); + rp = kmalloc(sizeof(*rp), GFP_KERNEL); + if (!rp) { + prom_printf("Cannot allocate IOMMU resource.\n"); + prom_halt(); } + rp->name = "IOMMU"; + rp->start = pbm->mem_space.start + (unsigned long) dma_start; + rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL; + rp->flags = IORESOURCE_BUSY; + request_resource(&pbm->mem_space, rp); + + pci_register_legacy_regions(&pbm->io_space, + &pbm->mem_space); } void sabre_init(struct device_node *dp, char *model_name) @@ -1303,7 +1100,6 @@ void sabre_init(struct device_node *dp, char *model_name) struct linux_prom64_registers *pr_regs; struct pci_controller_info *p; struct pci_iommu *iommu; - struct property *prop; int tsbsize; u32 *busrange; u32 *vdma; @@ -1314,13 +1110,9 @@ void sabre_init(struct device_node *dp, char *model_name) if (!strcmp(model_name, "pci108e,a001")) hummingbird_p = 1; else if (!strcmp(model_name, "SUNW,sabre")) { - prop = of_find_property(dp, "compatible", NULL); - if (prop) { - const char *compat = prop->value; - - if (!strcmp(compat, "pci108e,a001")) - hummingbird_p = 1; - } + const char *compat = of_get_property(dp, "compatible", NULL); + if (compat && !strcmp(compat, "pci108e,a001")) + hummingbird_p = 1; if (!hummingbird_p) { struct device_node *dp; @@ -1344,18 +1136,14 @@ void sabre_init(struct device_node *dp, char *model_name) prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n"); prom_halt(); } - p->pbm_A.iommu = p->pbm_B.iommu = iommu; + p->pbm_A.iommu = iommu; - upa_portid = 0xff; - prop = of_find_property(dp, "upa-portid", NULL); - if (prop) - upa_portid = *(u32 *) prop->value; + upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); p->next = pci_controller_root; pci_controller_root = p; p->pbm_A.portid = upa_portid; - p->pbm_B.portid = upa_portid; p->index = pci_num_controllers++; p->pbms_same_domain = 1; p->scan_bus = sabre_scan_bus; @@ -1367,14 +1155,12 @@ void sabre_init(struct device_node *dp, char *model_name) * Map in SABRE register set and report the presence of this SABRE. */ - prop = of_find_property(dp, "reg", NULL); - pr_regs = prop->value; + pr_regs = of_get_property(dp, "reg", NULL); /* * First REG in property is base of entire SABRE register space. */ p->pbm_A.controller_regs = pr_regs[0].phys_addr; - p->pbm_B.controller_regs = pr_regs[0].phys_addr; /* Clear interrupts */ @@ -1392,11 +1178,10 @@ void sabre_init(struct device_node *dp, char *model_name) SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); /* Now map in PCI config space for entire SABRE. */ - p->pbm_A.config_space = p->pbm_B.config_space = + p->pbm_A.config_space = (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); - prop = of_find_property(dp, "virtual-dma", NULL); - vdma = prop->value; + vdma = of_get_property(dp, "virtual-dma", NULL); dma_mask = vdma[0]; switch(vdma[1]) { @@ -1420,8 +1205,7 @@ void sabre_init(struct device_node *dp, char *model_name) sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); - prop = of_find_property(dp, "bus-range", NULL); - busrange = prop->value; + busrange = of_get_property(dp, "bus-range", NULL); p->pci_first_busno = busrange[0]; p->pci_last_busno = busrange[1]; -- cgit v1.2.3 From 9fd8b64761d3fe7e4ef567161be57e4234af5c1c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 8 Mar 2007 21:55:49 -0800 Subject: [SPARC64]: Consolidate PCI mem/io resource determination. It can be done for every PCI configuration using OF properties. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_common.c | 94 +++++++++++++++++++++++++++++++++++++--- arch/sparc64/kernel/pci_impl.h | 8 ++-- arch/sparc64/kernel/pci_psycho.c | 29 ++----------- arch/sparc64/kernel/pci_sabre.c | 38 ++-------------- arch/sparc64/kernel/pci_schizo.c | 81 ++-------------------------------- arch/sparc64/kernel/pci_sun4v.c | 71 +----------------------------- 6 files changed, 103 insertions(+), 218 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 0d3c95df0d9..4945d700a76 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -1,7 +1,6 @@ -/* $Id: pci_common.c,v 1.29 2002/02/01 00:56:03 davem Exp $ - * pci_common.c: PCI controller common support. +/* pci_common.c: PCI controller common support. * - * Copyright (C) 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -16,8 +15,8 @@ #include "pci_impl.h" -void pci_register_legacy_regions(struct resource *io_res, - struct resource *mem_res) +static void pci_register_legacy_regions(struct resource *io_res, + struct resource *mem_res) { struct resource *p; @@ -53,6 +52,91 @@ void pci_register_legacy_regions(struct resource *io_res, request_resource(mem_res, p); } +static void pci_register_iommu_region(struct pci_pbm_info *pbm) +{ + u32 *vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL); + + if (vdma) { + struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); + + if (!rp) { + prom_printf("Cannot allocate IOMMU resource.\n"); + prom_halt(); + } + rp->name = "IOMMU"; + rp->start = pbm->mem_space.start + (unsigned long) vdma[0]; + rp->end = rp->start + (unsigned long) vdma[1] - 1UL; + rp->flags = IORESOURCE_BUSY; + request_resource(&pbm->mem_space, rp); + } +} + +void pci_determine_mem_io_space(struct pci_pbm_info *pbm) +{ + int i, saw_mem, saw_io; + + saw_mem = saw_io = 0; + for (i = 0; i < pbm->num_pbm_ranges; i++) { + struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i]; + unsigned long a; + int type; + + type = (pr->child_phys_hi >> 24) & 0x3; + a = (((unsigned long)pr->parent_phys_hi << 32UL) | + ((unsigned long)pr->parent_phys_lo << 0UL)); + + switch (type) { + case 0: + /* PCI config space, 16MB */ + pbm->config_space = a; + break; + + case 1: + /* 16-bit IO space, 16MB */ + pbm->io_space.start = a; + pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); + pbm->io_space.flags = IORESOURCE_IO; + saw_io = 1; + break; + + case 2: + /* 32-bit MEM space, 2GB */ + pbm->mem_space.start = a; + pbm->mem_space.end = a + (0x80000000UL - 1UL); + pbm->mem_space.flags = IORESOURCE_MEM; + saw_mem = 1; + break; + + case 3: + /* XXX 64-bit MEM handling XXX */ + + default: + break; + }; + } + + if (!saw_io || !saw_mem) { + prom_printf("%s: Fatal error, missing %s PBM range.\n", + pbm->name, + (!saw_io ? "IO" : "MEM")); + prom_halt(); + } + + printk("%s: PCI IO[%lx] MEM[%lx]\n", + pbm->name, + pbm->io_space.start, + pbm->mem_space.start); + + pbm->io_space.name = pbm->mem_space.name = pbm->name; + + request_resource(&ioport_resource, &pbm->io_space); + request_resource(&iomem_resource, &pbm->mem_space); + + pci_register_legacy_regions(&pbm->io_space, + &pbm->mem_space); + pci_register_iommu_region(pbm); +} + /* Generic helper routines for PCI error reporting. */ void pci_scan_for_target_abort(struct pci_controller_info *p, struct pci_pbm_info *pbm, diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index c4ba702e1fd..c6714548d82 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -1,7 +1,6 @@ -/* $Id: pci_impl.h,v 1.9 2001/06/13 06:34:30 davem Exp $ - * pci_impl.h: Helper definitions for PCI controller support. +/* pci_impl.h: Helper definitions for PCI controller support. * - * Copyright (C) 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #ifndef PCI_IMPL_H @@ -19,8 +18,7 @@ extern int pci_num_controllers; /* PCI bus scanning and fixup support. */ extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); -extern void pci_register_legacy_regions(struct resource *io_res, - struct resource *mem_res); +extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); /* Error reporting support. */ extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 12ea30d30b2..c08681b7a44 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1,7 +1,6 @@ -/* $Id: pci_psycho.c,v 1.33 2002/02/01 00:58:33 davem Exp $ - * pci_psycho.c: PSYCHO/U2P specific PCI controller support. +/* pci_psycho.c: PSYCHO/U2P specific PCI controller support. * - * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) + * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) */ @@ -1072,19 +1071,6 @@ static void psycho_controller_hwinit(struct pci_controller_info *p) psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); } -static void pbm_register_toplevel_resources(struct pci_controller_info *p, - struct pci_pbm_info *pbm) -{ - char *name = pbm->name; - - pbm->io_space.name = pbm->mem_space.name = name; - - request_resource(&ioport_resource, &pbm->io_space); - request_resource(&iomem_resource, &pbm->mem_space); - pci_register_legacy_regions(&pbm->io_space, - &pbm->mem_space); -} - static void psycho_pbm_strbuf_init(struct pci_controller_info *p, struct pci_pbm_info *pbm, int is_pbm_a) @@ -1155,13 +1141,9 @@ static void psycho_pbm_init(struct pci_controller_info *p, if (is_pbm_a) { pbm = &p->pbm_A; pbm->pci_first_slot = 1; - pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_A; - pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_A; } else { pbm = &p->pbm_B; pbm->pci_first_slot = 2; - pbm->io_space.start = pbm->controller_regs + PSYCHO_IOSPACE_B; - pbm->mem_space.start = pbm->controller_regs + PSYCHO_MEMSPACE_B; } pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; @@ -1174,17 +1156,12 @@ static void psycho_pbm_init(struct pci_controller_info *p, if (prop) pbm->chip_revision = *(int *) prop->value; - pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE; - pbm->io_space.flags = IORESOURCE_IO; - pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE; - pbm->mem_space.flags = IORESOURCE_MEM; + pci_determine_mem_io_space(pbm); pbm->parent = p; pbm->prom_node = dp; pbm->name = dp->full_name; - pbm_register_toplevel_resources(p, pbm); - printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n", pbm->name, pbm->chip_version, pbm->chip_revision); diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index f4e346092a5..2dad171b54e 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1045,10 +1045,9 @@ static void sabre_iommu_init(struct pci_controller_info *p, sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); } -static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end) +static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp) { struct pci_pbm_info *pbm; - struct resource *rp; pbm = &p->pbm_A; pbm->name = dp->full_name; @@ -1061,38 +1060,7 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp pbm->pci_first_busno = p->pci_first_busno; pbm->pci_last_busno = p->pci_last_busno; - pbm->io_space.name = pbm->mem_space.name = pbm->name; - - pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE; - pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; - pbm->io_space.flags = IORESOURCE_IO; - - pbm->mem_space.start = (p->pbm_A.controller_regs + SABRE_MEMSPACE); - pbm->mem_space.end = (pbm->mem_space.start + ((1UL << 32UL) - 1UL)); - pbm->mem_space.flags = IORESOURCE_MEM; - - if (request_resource(&ioport_resource, &pbm->io_space) < 0) { - prom_printf("Cannot register Sabre's IO space.\n"); - prom_halt(); - } - if (request_resource(&iomem_resource, &pbm->mem_space) < 0) { - prom_printf("Cannot register Sabre's MEM space.\n"); - prom_halt(); - } - - rp = kmalloc(sizeof(*rp), GFP_KERNEL); - if (!rp) { - prom_printf("Cannot allocate IOMMU resource.\n"); - prom_halt(); - } - rp->name = "IOMMU"; - rp->start = pbm->mem_space.start + (unsigned long) dma_start; - rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL; - rp->flags = IORESOURCE_BUSY; - request_resource(&pbm->mem_space, rp); - - pci_register_legacy_regions(&pbm->io_space, - &pbm->mem_space); + pci_determine_mem_io_space(pbm); } void sabre_init(struct device_node *dp, char *model_name) @@ -1212,5 +1180,5 @@ void sabre_init(struct device_node *dp, char *model_name) /* * Look for APB underneath. */ - sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]); + sabre_pbm_init(p, dp); } diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 332cfd9736b..79ad2688317 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1,7 +1,6 @@ -/* $Id: pci_schizo.c,v 1.24 2002/01/23 11:27:32 davem Exp $ - * pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support. +/* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support. * - * Copyright (C) 2001, 2002, 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2001, 2002, 2003, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -1304,79 +1303,6 @@ static void schizo_resource_adjust(struct pci_dev *pdev, res->end += root->start; } -/* Use ranges property to determine where PCI MEM, I/O, and Config - * space are for this PCI bus module. - */ -static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm) -{ - int i, saw_cfg, saw_mem, saw_io; - - saw_cfg = saw_mem = saw_io = 0; - for (i = 0; i < pbm->num_pbm_ranges; i++) { - struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i]; - unsigned long a; - int type; - - type = (pr->child_phys_hi >> 24) & 0x3; - a = (((unsigned long)pr->parent_phys_hi << 32UL) | - ((unsigned long)pr->parent_phys_lo << 0UL)); - - switch (type) { - case 0: - /* PCI config space, 16MB */ - pbm->config_space = a; - saw_cfg = 1; - break; - - case 1: - /* 16-bit IO space, 16MB */ - pbm->io_space.start = a; - pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); - pbm->io_space.flags = IORESOURCE_IO; - saw_io = 1; - break; - - case 2: - /* 32-bit MEM space, 2GB */ - pbm->mem_space.start = a; - pbm->mem_space.end = a + (0x80000000UL - 1UL); - pbm->mem_space.flags = IORESOURCE_MEM; - saw_mem = 1; - break; - - default: - break; - }; - } - - if (!saw_cfg || !saw_io || !saw_mem) { - prom_printf("%s: Fatal error, missing %s PBM range.\n", - pbm->name, - ((!saw_cfg ? - "CFG" : - (!saw_io ? - "IO" : "MEM")))); - prom_halt(); - } - - printk("%s: PCI CFG[%lx] IO[%lx] MEM[%lx]\n", - pbm->name, - pbm->config_space, - pbm->io_space.start, - pbm->mem_space.start); -} - -static void pbm_register_toplevel_resources(struct pci_controller_info *p, - struct pci_pbm_info *pbm) -{ - pbm->io_space.name = pbm->mem_space.name = pbm->name; - - request_resource(&ioport_resource, &pbm->io_space); - request_resource(&iomem_resource, &pbm->mem_space); - pci_register_legacy_regions(&pbm->io_space, - &pbm->mem_space); -} - #define SCHIZO_STRBUF_CONTROL (0x02800UL) #define SCHIZO_STRBUF_FLUSH (0x02808UL) #define SCHIZO_STRBUF_FSYNC (0x02810UL) @@ -1679,8 +1605,7 @@ static void schizo_pbm_init(struct pci_controller_info *p, pbm->num_pbm_ranges = (len / sizeof(struct linux_prom_pci_ranges)); - schizo_determine_mem_io_space(pbm); - pbm_register_toplevel_resources(p, pbm); + pci_determine_mem_io_space(pbm); pbm->pbm_intmap = of_get_property(dp, "interrupt-map", &len); if (pbm->pbm_intmap) { diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index eec7def379d..e1af009617c 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1,6 +1,6 @@ /* pci_sun4v.c: SUN4V specific PCI controller support. * - * Copyright (C) 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -751,72 +751,6 @@ static void pci_sun4v_resource_adjust(struct pci_dev *pdev, res->end += root->start; } -/* Use ranges property to determine where PCI MEM, I/O, and Config - * space are for this PCI bus module. - */ -static void pci_sun4v_determine_mem_io_space(struct pci_pbm_info *pbm) -{ - int i, saw_mem, saw_io; - - saw_mem = saw_io = 0; - for (i = 0; i < pbm->num_pbm_ranges; i++) { - struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i]; - unsigned long a; - int type; - - type = (pr->child_phys_hi >> 24) & 0x3; - a = (((unsigned long)pr->parent_phys_hi << 32UL) | - ((unsigned long)pr->parent_phys_lo << 0UL)); - - switch (type) { - case 1: - /* 16-bit IO space, 16MB */ - pbm->io_space.start = a; - pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); - pbm->io_space.flags = IORESOURCE_IO; - saw_io = 1; - break; - - case 2: - /* 32-bit MEM space, 2GB */ - pbm->mem_space.start = a; - pbm->mem_space.end = a + (0x80000000UL - 1UL); - pbm->mem_space.flags = IORESOURCE_MEM; - saw_mem = 1; - break; - - case 3: - /* XXX 64-bit MEM handling XXX */ - - default: - break; - }; - } - - if (!saw_io || !saw_mem) { - prom_printf("%s: Fatal error, missing %s PBM range.\n", - pbm->name, - (!saw_io ? "IO" : "MEM")); - prom_halt(); - } - - printk("%s: PCI IO[%lx] MEM[%lx]\n", - pbm->name, - pbm->io_space.start, - pbm->mem_space.start); -} - -static void pbm_register_toplevel_resources(struct pci_controller_info *p, - struct pci_pbm_info *pbm) -{ - pbm->io_space.name = pbm->mem_space.name = pbm->name; - - request_resource(&ioport_resource, &pbm->io_space); - request_resource(&iomem_resource, &pbm->mem_space); - pci_register_legacy_regions(&pbm->io_space, - &pbm->mem_space); -} - static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, struct pci_iommu *iommu) { @@ -1396,8 +1330,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node for (i = 0; i < pbm->num_pbm_ranges; i++) pbm->pbm_ranges[i].parent_phys_hi &= 0x0fffffff; - pci_sun4v_determine_mem_io_space(pbm); - pbm_register_toplevel_resources(p, pbm); + pci_determine_mem_io_space(pbm); prop = of_find_property(dp, "interrupt-map", &len); pbm->pbm_intmap = prop->value; -- cgit v1.2.3 From 229177c7f38d6a2b1285b42da4b19d76346b4bac Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 8 Mar 2007 22:11:00 -0800 Subject: [SPARC64]: Kill PBM intmap software state. Set but never used. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_psycho.c | 12 ------------ arch/sparc64/kernel/pci_schizo.c | 8 -------- arch/sparc64/kernel/pci_sun4v.c | 8 -------- 3 files changed, 28 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index c08681b7a44..7b7010a1eb2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1175,18 +1175,6 @@ static void psycho_pbm_init(struct pci_controller_info *p, pbm->num_pbm_ranges = 0; } - prop = of_find_property(dp, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - - prop = of_find_property(dp, "interrupt-map-mask", NULL); - pbm->pbm_intmask = prop->value; - } else { - pbm->num_pbm_intmap = 0; - } - prop = of_find_property(dp, "bus-range", NULL); busrange = prop->value; pbm->pci_first_busno = busrange[0]; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 79ad2688317..81daf903bdf 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1607,14 +1607,6 @@ static void schizo_pbm_init(struct pci_controller_info *p, pci_determine_mem_io_space(pbm); - pbm->pbm_intmap = of_get_property(dp, "interrupt-map", &len); - if (pbm->pbm_intmap) { - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - pbm->pbm_intmask = - of_get_property(dp, "interrupt-map-mask", NULL); - } - ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | ((u64)ino_bitmap[0] << 0UL)); diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index e1af009617c..7bee6b19272 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1332,14 +1332,6 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pci_determine_mem_io_space(pbm); - prop = of_find_property(dp, "interrupt-map", &len); - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - - prop = of_find_property(dp, "interrupt-map-mask", NULL); - pbm->pbm_intmask = prop->value; - pci_sun4v_get_bus_range(pbm); pci_sun4v_iommu_init(pbm); pci_sun4v_msi_init(pbm); -- cgit v1.2.3 From 3487a1f9e719d36c9b2d4d492994b2dd815a58b7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 8 Mar 2007 22:28:17 -0800 Subject: [SPARC64]: Kill PBM ranges software state. It is only used in one spot and we can just fetch the OF property right there. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_common.c | 19 +++++++++++++++---- arch/sparc64/kernel/pci_psycho.c | 10 ---------- arch/sparc64/kernel/pci_schizo.c | 5 ----- arch/sparc64/kernel/pci_sun4v.c | 13 ------------- 4 files changed, 15 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 4945d700a76..6b5c8e7a3eb 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -73,17 +73,28 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) void pci_determine_mem_io_space(struct pci_pbm_info *pbm) { + struct linux_prom_pci_ranges *pbm_ranges; int i, saw_mem, saw_io; + int num_pbm_ranges; saw_mem = saw_io = 0; - for (i = 0; i < pbm->num_pbm_ranges; i++) { - struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i]; + pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i); + num_pbm_ranges = i / sizeof(*pbm_ranges); + + for (i = 0; i < num_pbm_ranges; i++) { + struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; unsigned long a; + u32 parent_phys_hi, parent_phys_lo; int type; + parent_phys_hi = pr->parent_phys_hi; + parent_phys_lo = pr->parent_phys_lo; + if (tlb_type == hypervisor) + parent_phys_hi &= 0x0fffffff; + type = (pr->child_phys_hi >> 24) & 0x3; - a = (((unsigned long)pr->parent_phys_hi << 32UL) | - ((unsigned long)pr->parent_phys_lo << 0UL)); + a = (((unsigned long)parent_phys_hi << 32UL) | + ((unsigned long)parent_phys_lo << 0UL)); switch (type) { case 0: diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 7b7010a1eb2..1717df54948 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1136,7 +1136,6 @@ static void psycho_pbm_init(struct pci_controller_info *p, unsigned int *busrange; struct property *prop; struct pci_pbm_info *pbm; - int len; if (is_pbm_a) { pbm = &p->pbm_A; @@ -1166,15 +1165,6 @@ static void psycho_pbm_init(struct pci_controller_info *p, pbm->name, pbm->chip_version, pbm->chip_revision); - prop = of_find_property(dp, "ranges", &len); - if (prop) { - pbm->pbm_ranges = prop->value; - pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - } else { - pbm->num_pbm_ranges = 0; - } - prop = of_find_property(dp, "bus-range", NULL); busrange = prop->value; pbm->pci_first_busno = busrange[0]; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 81daf903bdf..dec8dc9499e 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1542,7 +1542,6 @@ static void schizo_pbm_init(struct pci_controller_info *p, const char *chipset_name; u32 *ino_bitmap; int is_pbm_a; - int len; switch (chip_type) { case PBM_CHIP_TYPE_TOMATILLO: @@ -1601,10 +1600,6 @@ static void schizo_pbm_init(struct pci_controller_info *p, schizo_pbm_hw_init(pbm); - pbm->pbm_ranges = of_get_property(dp, "ranges", &len); - pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - pci_determine_mem_io_space(pbm); ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 7bee6b19272..9b57ba1cb94 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1301,8 +1301,6 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) { struct pci_pbm_info *pbm; - struct property *prop; - int len, i; if (devhandle & 0x40) pbm = &p->pbm_B; @@ -1319,17 +1317,6 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node printk("%s: SUN4V PCI Bus Module\n", pbm->name); - prop = of_find_property(dp, "ranges", &len); - pbm->pbm_ranges = prop->value; - pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - - /* Mask out the top 8 bits of the ranges, leaving the real - * physical address. - */ - for (i = 0; i < pbm->num_pbm_ranges; i++) - pbm->pbm_ranges[i].parent_phys_hi &= 0x0fffffff; - pci_determine_mem_io_space(pbm); pci_sun4v_get_bus_range(pbm); -- cgit v1.2.3 From 0bae5f81b6f8130f5197e59b0e2ad6820c766b2b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 8 Mar 2007 22:42:19 -0800 Subject: [SPARC64]: Kill pci_controller->resource_adjust() All the implementations can be identical and generic, so no need for controller specific methods. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 17 ++++++++++++----- arch/sparc64/kernel/pci_psycho.c | 9 --------- arch/sparc64/kernel/pci_sabre.c | 17 ----------------- arch/sparc64/kernel/pci_schizo.c | 9 --------- arch/sparc64/kernel/pci_sun4v.c | 9 --------- 5 files changed, 12 insertions(+), 49 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index b63341c2a33..6b94d97e56a 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -469,6 +469,13 @@ static void __init apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) *last_p = last; } +static void __init pci_resource_adjust(struct resource *res, + struct resource *root) +{ + res->start += root->start; + res->end += root->start; +} + /* Cook up fake bus resources for SUNW,simba PCI bridges which lack * a proper 'ranges' property. */ @@ -486,7 +493,7 @@ static void __init apb_fake_ranges(struct pci_dev *dev, res->start = (first << 21); res->end = (last << 21) + ((1 << 21) - 1); res->flags = IORESOURCE_IO; - pbm->parent->resource_adjust(dev, res, &pbm->io_space); + pci_resource_adjust(res, &pbm->io_space); pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map); apb_calc_first_last(map, &first, &last); @@ -494,7 +501,7 @@ static void __init apb_fake_ranges(struct pci_dev *dev, res->start = (first << 21); res->end = (last << 21) + ((1 << 21) - 1); res->flags = IORESOURCE_MEM; - pbm->parent->resource_adjust(dev, res, &pbm->mem_space); + pci_resource_adjust(res, &pbm->mem_space); } static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, @@ -594,7 +601,7 @@ void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, * layer routine that can calculate a resource for a given * range property value in a PCI device. */ - pbm->parent->resource_adjust(dev, res, root); + pci_resource_adjust(res, root); } simba_cont: sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), @@ -803,7 +810,7 @@ void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region else root = &pbm->mem_space; - pbm->parent->resource_adjust(pdev, &zero_res, root); + pci_resource_adjust(&zero_res, root); region->start = res->start - zero_res.start; region->end = res->end - zero_res.start; @@ -824,7 +831,7 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, else root = &pbm->mem_space; - pbm->parent->resource_adjust(pdev, res, root); + pci_resource_adjust(res, root); } EXPORT_SYMBOL(pcibios_bus_to_resource); diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 1717df54948..c3f212725b0 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -894,14 +894,6 @@ static void psycho_register_error_handlers(struct pci_controller_info *p) } /* PSYCHO boot time probing and initialization. */ -static void psycho_resource_adjust(struct pci_dev *pdev, - struct resource *res, - struct resource *root) -{ - res->start += root->start; - res->end += root->start; -} - static void psycho_base_address_update(struct pci_dev *pdev, int resource) { struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; @@ -1218,7 +1210,6 @@ void psycho_init(struct device_node *dp, char *model_name) p->pbms_same_domain = 0; p->scan_bus = psycho_scan_bus; p->base_address_update = psycho_base_address_update; - p->resource_adjust = psycho_resource_adjust; p->pci_ops = &psycho_ops; prop = of_find_property(dp, "reg", NULL); diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 2dad171b54e..64cdce81d86 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -862,22 +862,6 @@ static void sabre_register_error_handlers(struct pci_controller_info *p) sabre_write(base + SABRE_PCICTRL, tmp); } -static void sabre_resource_adjust(struct pci_dev *pdev, - struct resource *res, - struct resource *root) -{ - struct pci_pbm_info *pbm = pdev->bus->sysdata; - unsigned long base; - - if (res->flags & IORESOURCE_IO) - base = pbm->controller_regs + SABRE_IOSPACE; - else - base = pbm->controller_regs + SABRE_MEMSPACE; - - res->start += base; - res->end += base; -} - static void sabre_base_address_update(struct pci_dev *pdev, int resource) { struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; @@ -1116,7 +1100,6 @@ void sabre_init(struct device_node *dp, char *model_name) p->pbms_same_domain = 1; p->scan_bus = sabre_scan_bus; p->base_address_update = sabre_base_address_update; - p->resource_adjust = sabre_resource_adjust; p->pci_ops = &sabre_ops; /* diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index dec8dc9499e..ba9206eb951 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1295,14 +1295,6 @@ static void schizo_base_address_update(struct pci_dev *pdev, int resource) pci_write_config_dword(pdev, where + 4, 0); } -static void schizo_resource_adjust(struct pci_dev *pdev, - struct resource *res, - struct resource *root) -{ - res->start += root->start; - res->end += root->start; -} - #define SCHIZO_STRBUF_CONTROL (0x02800UL) #define SCHIZO_STRBUF_FLUSH (0x02808UL) #define SCHIZO_STRBUF_FSYNC (0x02810UL) @@ -1670,7 +1662,6 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ p->index = pci_num_controllers++; p->scan_bus = schizo_scan_bus; p->base_address_update = schizo_base_address_update; - p->resource_adjust = schizo_resource_adjust; p->pci_ops = &schizo_ops; /* Like PSYCHO we have a 2GB aligned area for memory space. */ diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 9b57ba1cb94..ce0417e776a 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -743,14 +743,6 @@ static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) pci_write_config_dword(pdev, where + 4, 0); } -static void pci_sun4v_resource_adjust(struct pci_dev *pdev, - struct resource *res, - struct resource *root) -{ - res->start += root->start; - res->end += root->start; -} - static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, struct pci_iommu *iommu) { @@ -1387,7 +1379,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) p->scan_bus = pci_sun4v_scan_bus; p->base_address_update = pci_sun4v_base_address_update; - p->resource_adjust = pci_sun4v_resource_adjust; #ifdef CONFIG_PCI_MSI p->setup_msi_irq = pci_sun4v_setup_msi_irq; p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; -- cgit v1.2.3 From 8d3aee937596d2ca6676c2c27789751445bf0bc9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 8 Mar 2007 22:46:02 -0800 Subject: [SPARC64]: Kill pci_controller->base_address_update(). Implemented but never actually used. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_psycho.c | 45 --------------------------------------- arch/sparc64/kernel/pci_sabre.c | 46 ---------------------------------------- arch/sparc64/kernel/pci_schizo.c | 45 --------------------------------------- arch/sparc64/kernel/pci_sun4v.c | 46 ---------------------------------------- 4 files changed, 182 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index c3f212725b0..64bd3579f1c 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -894,50 +894,6 @@ static void psycho_register_error_handlers(struct pci_controller_info *p) } /* PSYCHO boot time probing and initialization. */ -static void psycho_base_address_update(struct pci_dev *pdev, int resource) -{ - struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - struct resource *res, *root; - u32 reg; - int where, size, is_64bit; - - res = &pdev->resource[resource]; - if (resource < 6) { - where = PCI_BASE_ADDRESS_0 + (resource * 4); - } else if (resource == PCI_ROM_RESOURCE) { - where = pdev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - is_64bit = 0; - if (res->flags & IORESOURCE_IO) - root = &pbm->io_space; - else { - root = &pbm->mem_space; - if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) - == PCI_BASE_ADDRESS_MEM_TYPE_64) - is_64bit = 1; - } - - size = res->end - res->start; - pci_read_config_dword(pdev, where, ®); - reg = ((reg & size) | - (((u32)(res->start - root->start)) & ~size)); - if (resource == PCI_ROM_RESOURCE) { - reg |= PCI_ROM_ADDRESS_ENABLE; - res->flags |= IORESOURCE_ROM_ENABLE; - } - pci_write_config_dword(pdev, where, reg); - - /* This knows that the upper 32-bits of the address - * must be zero. Our PCI common layer enforces this. - */ - if (is_64bit) - pci_write_config_dword(pdev, where + 4, 0); -} - static void pbm_config_busmastering(struct pci_pbm_info *pbm) { u8 *addr; @@ -1209,7 +1165,6 @@ void psycho_init(struct device_node *dp, char *model_name) p->index = pci_num_controllers++; p->pbms_same_domain = 0; p->scan_bus = psycho_scan_bus; - p->base_address_update = psycho_base_address_update; p->pci_ops = &psycho_ops; prop = of_find_property(dp, "reg", NULL); diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 64cdce81d86..f3ec7bdacdc 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -862,51 +862,6 @@ static void sabre_register_error_handlers(struct pci_controller_info *p) sabre_write(base + SABRE_PCICTRL, tmp); } -static void sabre_base_address_update(struct pci_dev *pdev, int resource) -{ - struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - struct resource *res; - unsigned long base; - u32 reg; - int where, size, is_64bit; - - res = &pdev->resource[resource]; - if (resource < 6) { - where = PCI_BASE_ADDRESS_0 + (resource * 4); - } else if (resource == PCI_ROM_RESOURCE) { - where = pdev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - is_64bit = 0; - if (res->flags & IORESOURCE_IO) - base = pbm->controller_regs + SABRE_IOSPACE; - else { - base = pbm->controller_regs + SABRE_MEMSPACE; - if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) - == PCI_BASE_ADDRESS_MEM_TYPE_64) - is_64bit = 1; - } - - size = res->end - res->start; - pci_read_config_dword(pdev, where, ®); - reg = ((reg & size) | - (((u32)(res->start - base)) & ~size)); - if (resource == PCI_ROM_RESOURCE) { - reg |= PCI_ROM_ADDRESS_ENABLE; - res->flags |= IORESOURCE_ROM_ENABLE; - } - pci_write_config_dword(pdev, where, reg); - - /* This knows that the upper 32-bits of the address - * must be zero. Our PCI common layer enforces this. - */ - if (is_64bit) - pci_write_config_dword(pdev, where + 4, 0); -} - static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) { struct pci_dev *pdev; @@ -1099,7 +1054,6 @@ void sabre_init(struct device_node *dp, char *model_name) p->index = pci_num_controllers++; p->pbms_same_domain = 1; p->scan_bus = sabre_scan_bus; - p->base_address_update = sabre_base_address_update; p->pci_ops = &sabre_ops; /* diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index ba9206eb951..99912db4e7e 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1251,50 +1251,6 @@ static void schizo_scan_bus(struct pci_controller_info *p) schizo_register_error_handlers(p); } -static void schizo_base_address_update(struct pci_dev *pdev, int resource) -{ - struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - struct resource *res, *root; - u32 reg; - int where, size, is_64bit; - - res = &pdev->resource[resource]; - if (resource < 6) { - where = PCI_BASE_ADDRESS_0 + (resource * 4); - } else if (resource == PCI_ROM_RESOURCE) { - where = pdev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - is_64bit = 0; - if (res->flags & IORESOURCE_IO) - root = &pbm->io_space; - else { - root = &pbm->mem_space; - if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) - == PCI_BASE_ADDRESS_MEM_TYPE_64) - is_64bit = 1; - } - - size = res->end - res->start; - pci_read_config_dword(pdev, where, ®); - reg = ((reg & size) | - (((u32)(res->start - root->start)) & ~size)); - if (resource == PCI_ROM_RESOURCE) { - reg |= PCI_ROM_ADDRESS_ENABLE; - res->flags |= IORESOURCE_ROM_ENABLE; - } - pci_write_config_dword(pdev, where, reg); - - /* This knows that the upper 32-bits of the address - * must be zero. Our PCI common layer enforces this. - */ - if (is_64bit) - pci_write_config_dword(pdev, where + 4, 0); -} - #define SCHIZO_STRBUF_CONTROL (0x02800UL) #define SCHIZO_STRBUF_FLUSH (0x02808UL) #define SCHIZO_STRBUF_FSYNC (0x02810UL) @@ -1661,7 +1617,6 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ p->index = pci_num_controllers++; p->scan_bus = schizo_scan_bus; - p->base_address_update = schizo_base_address_update; p->pci_ops = &schizo_ops; /* Like PSYCHO we have a 2GB aligned area for memory space. */ diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index ce0417e776a..f9cd9f620d4 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -698,51 +698,6 @@ static void pci_sun4v_scan_bus(struct pci_controller_info *p) /* XXX register error interrupt handlers XXX */ } -static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) -{ - struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - struct resource *res, *root; - u32 reg; - int where, size, is_64bit; - - res = &pdev->resource[resource]; - if (resource < 6) { - where = PCI_BASE_ADDRESS_0 + (resource * 4); - } else if (resource == PCI_ROM_RESOURCE) { - where = pdev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - /* XXX 64-bit MEM handling is not %100 correct... XXX */ - is_64bit = 0; - if (res->flags & IORESOURCE_IO) - root = &pbm->io_space; - else { - root = &pbm->mem_space; - if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) - == PCI_BASE_ADDRESS_MEM_TYPE_64) - is_64bit = 1; - } - - size = res->end - res->start; - pci_read_config_dword(pdev, where, ®); - reg = ((reg & size) | - (((u32)(res->start - root->start)) & ~size)); - if (resource == PCI_ROM_RESOURCE) { - reg |= PCI_ROM_ADDRESS_ENABLE; - res->flags |= IORESOURCE_ROM_ENABLE; - } - pci_write_config_dword(pdev, where, reg); - - /* This knows that the upper 32-bits of the address - * must be zero. Our PCI common layer enforces this. - */ - if (is_64bit) - pci_write_config_dword(pdev, where + 4, 0); -} - static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, struct pci_iommu *iommu) { @@ -1378,7 +1333,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) p->pbms_same_domain = 0; p->scan_bus = pci_sun4v_scan_bus; - p->base_address_update = pci_sun4v_base_address_update; #ifdef CONFIG_PCI_MSI p->setup_msi_irq = pci_sun4v_setup_msi_irq; p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; -- cgit v1.2.3 From 3875c5c02d7112aa85f815d65d8add2e39ae9e34 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 8 Mar 2007 22:52:11 -0800 Subject: [SPARC64]: Kill pci_controller->pbms_same_domain We don't do the "Simba APB is a PBM" bogosity for Sabre controllers any longer, so this pbms_same_domain thing is no longer necessary. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 75 +++++++--------------------------------- arch/sparc64/kernel/pci_psycho.c | 1 - arch/sparc64/kernel/pci_sabre.c | 1 - arch/sparc64/kernel/pci_sun4v.c | 1 - 4 files changed, 12 insertions(+), 66 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 6b94d97e56a..a7809a00324 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -857,43 +857,12 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc unsigned long space_size, user_offset, user_size; p = pbm->parent; - if (p->pbms_same_domain) { - unsigned long lowest, highest; - - lowest = ~0UL; highest = 0UL; - if (mmap_state == pci_mmap_io) { - if (p->pbm_A.io_space.flags) { - lowest = p->pbm_A.io_space.start; - highest = p->pbm_A.io_space.end + 1; - } - if (p->pbm_B.io_space.flags) { - if (lowest > p->pbm_B.io_space.start) - lowest = p->pbm_B.io_space.start; - if (highest < p->pbm_B.io_space.end + 1) - highest = p->pbm_B.io_space.end + 1; - } - space_size = highest - lowest; - } else { - if (p->pbm_A.mem_space.flags) { - lowest = p->pbm_A.mem_space.start; - highest = p->pbm_A.mem_space.end + 1; - } - if (p->pbm_B.mem_space.flags) { - if (lowest > p->pbm_B.mem_space.start) - lowest = p->pbm_B.mem_space.start; - if (highest < p->pbm_B.mem_space.end + 1) - highest = p->pbm_B.mem_space.end + 1; - } - space_size = highest - lowest; - } + if (mmap_state == pci_mmap_io) { + space_size = (pbm->io_space.end - + pbm->io_space.start) + 1; } else { - if (mmap_state == pci_mmap_io) { - space_size = (pbm->io_space.end - - pbm->io_space.start) + 1; - } else { - space_size = (pbm->mem_space.end - - pbm->mem_space.start) + 1; - } + space_size = (pbm->mem_space.end - + pbm->mem_space.start) + 1; } /* Make sure the request is in range. */ @@ -904,31 +873,12 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc (user_offset + user_size) > space_size) return -EINVAL; - if (p->pbms_same_domain) { - unsigned long lowest = ~0UL; - - if (mmap_state == pci_mmap_io) { - if (p->pbm_A.io_space.flags) - lowest = p->pbm_A.io_space.start; - if (p->pbm_B.io_space.flags && - lowest > p->pbm_B.io_space.start) - lowest = p->pbm_B.io_space.start; - } else { - if (p->pbm_A.mem_space.flags) - lowest = p->pbm_A.mem_space.start; - if (p->pbm_B.mem_space.flags && - lowest > p->pbm_B.mem_space.start) - lowest = p->pbm_B.mem_space.start; - } - vma->vm_pgoff = (lowest + user_offset) >> PAGE_SHIFT; + if (mmap_state == pci_mmap_io) { + vma->vm_pgoff = (pbm->io_space.start + + user_offset) >> PAGE_SHIFT; } else { - if (mmap_state == pci_mmap_io) { - vma->vm_pgoff = (pbm->io_space.start + - user_offset) >> PAGE_SHIFT; - } else { - vma->vm_pgoff = (pbm->mem_space.start + - user_offset) >> PAGE_SHIFT; - } + vma->vm_pgoff = (pbm->mem_space.start + + user_offset) >> PAGE_SHIFT; } return 0; @@ -1062,9 +1012,8 @@ int pci_domain_nr(struct pci_bus *pbus) struct pci_controller_info *p = pbm->parent; ret = p->index; - if (p->pbms_same_domain == 0) - ret = ((ret << 1) + - ((pbm == &pbm->parent->pbm_B) ? 1 : 0)); + ret = ((ret << 1) + + ((pbm == &pbm->parent->pbm_B) ? 1 : 0)); } return ret; diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 64bd3579f1c..0ab2aa0261c 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1163,7 +1163,6 @@ void psycho_init(struct device_node *dp, char *model_name) p->pbm_A.portid = upa_portid; p->pbm_B.portid = upa_portid; p->index = pci_num_controllers++; - p->pbms_same_domain = 0; p->scan_bus = psycho_scan_bus; p->pci_ops = &psycho_ops; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index f3ec7bdacdc..cef81c88548 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1052,7 +1052,6 @@ void sabre_init(struct device_node *dp, char *model_name) p->pbm_A.portid = upa_portid; p->index = pci_num_controllers++; - p->pbms_same_domain = 1; p->scan_bus = sabre_scan_bus; p->pci_ops = &sabre_ops; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index f9cd9f620d4..b63ef26abf0 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1330,7 +1330,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) pci_controller_root = p; p->index = pci_num_controllers++; - p->pbms_same_domain = 0; p->scan_bus = pci_sun4v_scan_bus; #ifdef CONFIG_PCI_MSI -- cgit v1.2.3 From 0bba2dd823fd995ed805ae5cbd5a1c1381257a12 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 8 Mar 2007 23:06:39 -0800 Subject: [SPARC64]: Kill pbm->pci_first_slot. Set but never used. Signed-off-by: David S. Miller --- arch/sparc64/kernel/of_device.c | 6 ------ arch/sparc64/kernel/pci_psycho.c | 7 ++----- arch/sparc64/kernel/pci_sabre.c | 1 - arch/sparc64/kernel/pci_schizo.c | 1 - arch/sparc64/kernel/pci_sun4v.c | 1 - 5 files changed, 2 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 8964eacb004..f18eec6ad69 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -759,12 +759,6 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp, * D: 2-bit slot number, derived from PCI device number as * (dev - 1) for bus A, or (dev - 2) for bus B * L: 2-bit line number - * - * Actually, more "portable" way to calculate the funky - * slot number is to subtract pbm->pci_first_slot from the - * device number, and that's exactly what the pre-OF - * sparc64 code did, but we're building this stuff generically - * using the OBP tree, not in the PCI controller layer. */ if (bus & 0x80) { /* PBM-A */ diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 0ab2aa0261c..2e5d40a26db 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1085,13 +1085,10 @@ static void psycho_pbm_init(struct pci_controller_info *p, struct property *prop; struct pci_pbm_info *pbm; - if (is_pbm_a) { + if (is_pbm_a) pbm = &p->pbm_A; - pbm->pci_first_slot = 1; - } else { + else pbm = &p->pbm_B; - pbm->pci_first_slot = 2; - } pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; pbm->chip_version = 0; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index cef81c88548..1bd7fc7c05e 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -995,7 +995,6 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp pbm->chip_type = PBM_CHIP_TYPE_SABRE; pbm->parent = p; pbm->prom_node = dp; - pbm->pci_first_slot = 1; pbm->pci_first_busno = p->pci_first_busno; pbm->pci_last_busno = p->pci_last_busno; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 99912db4e7e..f1f105af8d3 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1528,7 +1528,6 @@ static void schizo_pbm_init(struct pci_controller_info *p, pbm->portid = portid; pbm->parent = p; pbm->prom_node = dp; - pbm->pci_first_slot = 1; pbm->chip_type = chip_type; pbm->chip_version = of_getintprop_default(dp, "version#", 0); diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index b63ef26abf0..c6feae6e969 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1256,7 +1256,6 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pbm->parent = p; pbm->prom_node = dp; - pbm->pci_first_slot = 1; pbm->devhandle = devhandle; -- cgit v1.2.3 From c6e87566ea080bbbe926c0e429fed48e6f680d93 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 9 Mar 2007 16:58:43 -0800 Subject: [SPARC64]: Const'ify pci_iommu_ops. Based upon a similar patch for x86_64 written by Stephen Hemminger. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 4 ++-- arch/sparc64/kernel/pci_iommu.c | 2 +- arch/sparc64/kernel/pci_sun4v.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index a7809a00324..914a216da33 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -282,10 +282,10 @@ int __init pcic_present(void) return pci_controller_scan(pci_is_controller); } -struct pci_iommu_ops *pci_iommu_ops; +const struct pci_iommu_ops *pci_iommu_ops; EXPORT_SYMBOL(pci_iommu_ops); -extern struct pci_iommu_ops pci_sun4u_iommu_ops, +extern const struct pci_iommu_ops pci_sun4u_iommu_ops, pci_sun4v_iommu_ops; /* Find each controller in the system, attach and initialize diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 554daabb381..aefdcc51045 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -759,7 +759,7 @@ static void pci_4u_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist spin_unlock_irqrestore(&iommu->lock, flags); } -struct pci_iommu_ops pci_sun4u_iommu_ops = { +const struct pci_iommu_ops pci_sun4u_iommu_ops = { .alloc_consistent = pci_4u_alloc_consistent, .free_consistent = pci_4u_free_consistent, .map_single = pci_4u_map_single, diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index c6feae6e969..a8c12c1e803 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -583,7 +583,7 @@ static void pci_4v_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist /* Nothing to do... */ } -struct pci_iommu_ops pci_sun4v_iommu_ops = { +const struct pci_iommu_ops pci_sun4v_iommu_ops = { .alloc_consistent = pci_4v_alloc_consistent, .free_consistent = pci_4v_free_consistent, .map_single = pci_4v_map_single, -- cgit v1.2.3 From 97b3cf050b467dda571943ceadff5452bed04549 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 11 Mar 2007 16:42:53 -0700 Subject: [SPARC64]: Add dummy host controller to root of all PCI domains. We fake up a dummy one in all cases because that is the simplest thing to do and it happens to be necessary for hypervisor systems. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 119 +++++++++++++++++++++++++++++---------- arch/sparc64/kernel/pci_impl.h | 9 +++ arch/sparc64/kernel/pci_psycho.c | 7 +++ arch/sparc64/kernel/pci_sabre.c | 12 ++++ arch/sparc64/kernel/pci_schizo.c | 6 ++ arch/sparc64/kernel/pci_sun4v.c | 6 ++ 6 files changed, 129 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 914a216da33..ec5f85b030e 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -368,7 +368,8 @@ static void pci_parse_of_addrs(struct of_device *op, struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, struct device_node *node, - struct pci_bus *bus, int devfn) + struct pci_bus *bus, int devfn, + int host_controller) { struct dev_archdata *sd; struct pci_dev *dev; @@ -400,47 +401,62 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ - dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); - dev->device = of_getintprop_default(node, "device-id", 0xffff); - dev->subsystem_vendor = - of_getintprop_default(node, "subsystem-vendor-id", 0); - dev->subsystem_device = - of_getintprop_default(node, "subsystem-id", 0); - - dev->cfg_size = pci_cfg_space_size(dev); - + if (host_controller) { + dev->vendor = 0x108e; + dev->device = 0x8000; + dev->subsystem_vendor = 0x0000; + dev->subsystem_device = 0x0000; + dev->cfg_size = 256; + } else { + dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); + dev->device = of_getintprop_default(node, "device-id", 0xffff); + dev->subsystem_vendor = + of_getintprop_default(node, "subsystem-vendor-id", 0); + dev->subsystem_device = + of_getintprop_default(node, "subsystem-id", 0); + + dev->cfg_size = pci_cfg_space_size(dev); + } sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - /* dev->class = of_getintprop_default(node, "class-code", 0); */ - /* We can't actually use the firmware value, we have to read what - * is in the register right now. One reason is that in the case - * of IDE interfaces the firmware can sample the value before the - * the IDE interface is programmed into native mode. - */ - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); - dev->class = class >> 8; - + if (host_controller) { + dev->class = PCI_CLASS_BRIDGE_HOST << 8; + } else { + /* We can't actually use the firmware value, we have + * to read what is in the register right now. One + * reason is that in the case of IDE interfaces the + * firmware can sample the value before the the IDE + * interface is programmed into native mode. + */ + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); + dev->class = class >> 8; + } printk(" class: 0x%x\n", dev->class); dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; - if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { - /* a PCI-PCI bridge */ + if (host_controller) { dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; - } else if (!strcmp(type, "cardbus")) { - dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; + dev->irq = PCI_IRQ_NONE; } else { - dev->hdr_type = PCI_HEADER_TYPE_NORMAL; - dev->rom_base_reg = PCI_ROM_ADDRESS; + if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + /* a PCI-PCI bridge */ + dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; + dev->rom_base_reg = PCI_ROM_ADDRESS1; + } else if (!strcmp(type, "cardbus")) { + dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; + } else { + dev->hdr_type = PCI_HEADER_TYPE_NORMAL; + dev->rom_base_reg = PCI_ROM_ADDRESS; - dev->irq = sd->op->irqs[0]; - if (dev->irq == 0xffffffff) - dev->irq = PCI_IRQ_NONE; + dev->irq = sd->op->irqs[0]; + if (dev->irq == 0xffffffff) + dev->irq = PCI_IRQ_NONE; + } } - pci_parse_of_addrs(sd->op, node, dev); printk(" adding to system ...\n"); @@ -632,7 +648,7 @@ static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, devfn = (reg[0] >> 8) & 0xff; /* create a new pci_dev for this device */ - dev = of_create_pci_dev(pbm, child, bus, devfn); + dev = of_create_pci_dev(pbm, child, bus, devfn, 0); if (!dev) continue; printk("PCI: dev header type: %x\n", dev->hdr_type); @@ -677,10 +693,49 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } +int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 *value) +{ + static u8 fake_pci_config[] = { + 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ + 0x00, 0x80, /* Device: 0x8000 (PBM) */ + 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ + 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ + 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ + 0x00, /* Cacheline: 0x00 */ + 0x40, /* Latency: 0x40 */ + 0x00, /* Header-Type: 0x00 normal */ + }; + + *value = 0; + if (where >= 0 && where < sizeof(fake_pci_config) && + (where + size) >= 0 && + (where + size) < sizeof(fake_pci_config) && + size <= sizeof(u32)) { + while (size--) { + *value <<= 8; + *value |= fake_pci_config[where + size]; + } + } + + return PCIBIOS_SUCCESSFUL; +} + +int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 value) +{ + return PCIBIOS_SUCCESSFUL; +} + struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) { struct pci_controller_info *p = pbm->parent; struct device_node *node = pbm->prom_node; + struct pci_dev *host_pdev; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); @@ -698,6 +753,10 @@ struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) bus->resource[0] = &pbm->io_space; bus->resource[1] = &pbm->mem_space; + /* Create the dummy host bridge and link it in. */ + host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); + bus->self = host_pdev; + pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); pci_bus_register_of_sysfs(bus); diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index c6714548d82..1208583fcb8 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -20,6 +20,15 @@ extern int pci_num_controllers; extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); +extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 *value); +extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 value); + /* Error reporting support. */ extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 2e5d40a26db..154c03290d5 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -118,6 +118,10 @@ static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, u16 tmp16; u8 tmp8; + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, + size, value); + switch (size) { case 1: *value = 0xff; @@ -171,6 +175,9 @@ static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned char bus = bus_dev->number; u32 *addr; + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, + size, value); addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 1bd7fc7c05e..a2f129d29c2 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -319,6 +319,12 @@ static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { + struct pci_pbm_info *pbm = bus->sysdata; + + if (bus == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_read_pci_cfg(bus, devfn, where, + size, value); + if (!bus->number && sabre_out_of_range(devfn)) { switch (size) { case 1: @@ -435,6 +441,12 @@ static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { + struct pci_pbm_info *pbm = bus->sysdata; + + if (bus == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_write_pci_cfg(bus, devfn, where, + size, value); + if (bus->number) return __sabre_write_pci_cfg(bus, devfn, where, size, value); diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index f1f105af8d3..322cdbf50ef 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -125,6 +125,9 @@ static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, u16 tmp16; u8 tmp8; + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, + size, value); switch (size) { case 1: *value = 0xff; @@ -178,6 +181,9 @@ static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned char bus = bus_dev->number; u32 *addr; + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, + size, value); addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index a8c12c1e803..52bd4563492 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -612,6 +612,9 @@ static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, + size, value); if (pci_sun4v_out_of_range(pbm, bus, device, func)) { ret = ~0UL; } else { @@ -650,6 +653,9 @@ static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; + if (bus_dev == pbm->pci_bus && devfn == 0x00) + return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, + size, value); if (pci_sun4v_out_of_range(pbm, bus, device, func)) { /* Do nothing. */ } else { -- cgit v1.2.3 From 28f57e774d91ce01e03ff65caa2313bc8786b66f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 12 Mar 2007 19:40:26 -0700 Subject: [SPARC64]: Force dummy host controller onto bus zero. This helps deal with the invisible bridge that sits between the host controller and the top-most visisble PCI devices on hypervisor systems. For example, on T1000 the bus-range property says 2 --> 4 and so there is a PCI express bridge at bus 2, devfn 0, etc. So if we don't force the dummy host controller to bus zero, we'll try to create two devices with the same domain/bus/devfn triplet. Also, add some more log diagnostics to make debugging stuff like this easyer. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index ec5f85b030e..8a7c699bb10 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -392,7 +392,8 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, if (type == NULL) type = ""; - printk(" create device, devfn: %x, type: %s\n", devfn, type); + printk(" create device, devfn: %x, type: %s hostcontroller(%d)\n", + devfn, type, host_controller); dev->bus = bus; dev->sysdata = node; @@ -407,6 +408,9 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->subsystem_vendor = 0x0000; dev->subsystem_device = 0x0000; dev->cfg_size = 256; + dev->class = PCI_CLASS_BRIDGE_HOST << 8; + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + 0x00, PCI_SLOT(devfn), PCI_FUNC(devfn)); } else { dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); dev->device = of_getintprop_default(node, "device-id", 0xffff); @@ -416,13 +420,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, of_getintprop_default(node, "subsystem-id", 0); dev->cfg_size = pci_cfg_space_size(dev); - } - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), - dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); - if (host_controller) { - dev->class = PCI_CLASS_BRIDGE_HOST << 8; - } else { /* We can't actually use the firmware value, we have * to read what is in the register right now. One * reason is that in the case of IDE interfaces the @@ -431,8 +429,12 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, */ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); dev->class = class >> 8; + + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); } - printk(" class: 0x%x\n", dev->class); + printk(" class: 0x%x device name: %s\n", + dev->class, pci_name(dev)); dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; -- cgit v1.2.3 From d78d0891d3dd976a2fb707c6c691d9cd5ed60727 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Mar 2007 22:47:01 -0700 Subject: [SPARC64]: Use SPARSEMEM_STATIC Decrease the SECTION_SIZE_BITS --> MAX_PHYSADDR_BITS range a little bit. The cost of going to SPARSEMEM_STATIC becomes 8K of BSS space, and in return we save a pointer dereferences on every page struct lookup. Even better we hit the main kernel image for the base address which is in a hugepage locked TLB entry. Signed-off-by: David S. Miller --- arch/sparc64/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 51c87fdd998..590a41b864b 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -220,6 +220,7 @@ config ARCH_SPARSEMEM_ENABLE config ARCH_SPARSEMEM_DEFAULT def_bool y + select SPARSEMEM_STATIC config LARGE_ALLOCS def_bool y -- cgit v1.2.3 From 0015d3d68c84eb33e6b380802ad61b23f7eb6523 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 00:06:34 -0700 Subject: [SPARC64]: Simplify read_obp_memory(). Kick out empty entries as soon as we spot them, and use memmove() instead of a silly loop to make the operation more clear. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index f146071a4b2..973c4e122f2 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -122,24 +122,19 @@ static void __init read_obp_memory(const char *property, size = 0UL; base = new_base; } - regs[i].phys_addr = base; - regs[i].reg_size = size; - } - - for (i = 0; i < ents; i++) { - if (regs[i].reg_size == 0UL) { - int j; - - for (j = i; j < ents - 1; j++) { - regs[j].phys_addr = - regs[j+1].phys_addr; - regs[j].reg_size = - regs[j+1].reg_size; - } - - ents--; + if (size == 0UL) { + /* If it is empty, simply get rid of it. + * This simplifies the logic of the other + * functions that process these arrays. + */ + memmove(®s[i], ®s[i + 1], + (ents - i - 1) * sizeof(regs[0])); i--; + ents--; + continue; } + regs[i].phys_addr = base; + regs[i].reg_size = size; } *num_ents = ents; -- cgit v1.2.3 From a0963bdfb91ca97c2b0b6d4ca81ff557fac66901 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 15:09:06 -0700 Subject: [SPARC64]: Kill _start[]/_end[] declarations in mm/init.c We already get those from asm/sections.h Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 973c4e122f2..56be943a6f0 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -155,9 +155,6 @@ unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; #define CTX_BMAP_SLOTS (1UL << (CTX_NR_BITS - 6)) unsigned long mmu_context_bmap[CTX_BMAP_SLOTS]; -/* References to special section boundaries */ -extern char _start[], _end[]; - /* Initial ramdisk setup */ extern unsigned long sparc_ramdisk_image64; extern unsigned int sparc_ramdisk_image; -- cgit v1.2.3 From 4be5c34dc47b5a9e6f91c8f5937a93c464870b8e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 15:44:05 -0700 Subject: [SPARC64]: Privatize sun4u_get_pte() and fix name. __get_phys is only called from init.c as is prom_virt_to_phys(), __get_iospace() is not called at all, and sun4u_get_pte() is largely misnamed. Privatize the implementation and helper functions of sun4u_get_phys() to mm/init.c, and rename to kvaddr_to_paddr(). The only used of this thing is flush_icache_range(), and thus things can be considerably further simplified. For example, we should only see module or PAGE_OFFSET kernel addresses here, so we don't need the OBP firmware range handling at all. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 129 ++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 56be943a6f0..3cacea5da6c 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -392,6 +392,67 @@ out: put_cpu(); } +struct linux_prom_translation { + unsigned long virt; + unsigned long size; + unsigned long data; +}; + +/* Exported for kernel TLB miss handling in ktlb.S */ +struct linux_prom_translation prom_trans[512] __read_mostly; +unsigned int prom_trans_ents __read_mostly; + +/* + * Translate PROM's mapping we capture at boot time into physical address. + * The second parameter is only set from prom_callback() invocations. + */ +static unsigned long prom_virt_to_phys(unsigned long promva) +{ + unsigned long mask; + int i; + + mask = _PAGE_PADDR_4U; + if (tlb_type == hypervisor) + mask = _PAGE_PADDR_4V; + + for (i = 0; i < prom_trans_ents; i++) { + struct linux_prom_translation *p = &prom_trans[i]; + + if (promva >= p->virt && + promva < (p->virt + p->size)) { + unsigned long base = p->data & mask; + + return base + (promva & (8192 - 1)); + } + } + return 0UL; +} + +static unsigned long kvaddr_to_phys(unsigned long addr) +{ + pgd_t *pgdp; + pud_t *pudp; + pmd_t *pmdp; + pte_t *ptep; + unsigned long mask = _PAGE_PADDR_4U; + + if (tlb_type == hypervisor) + mask = _PAGE_PADDR_4V; + + if (addr >= PAGE_OFFSET) + return addr & mask; + + if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS)) + return prom_virt_to_phys(addr); + + pgdp = pgd_offset_k(addr); + pudp = pud_offset(pgdp, addr); + pmdp = pmd_offset(pudp, addr); + ptep = pte_offset_kernel(pmdp, addr); + + return pte_val(*ptep) & mask; +} + void __kprobes flush_icache_range(unsigned long start, unsigned long end) { /* Cheetah and Hypervisor platform cpus have coherent I-cache. */ @@ -399,7 +460,7 @@ void __kprobes flush_icache_range(unsigned long start, unsigned long end) unsigned long kaddr; for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE) - __flush_icache_page(__get_phys(kaddr)); + __flush_icache_page(kvaddr_to_phys(kaddr)); } } @@ -436,16 +497,6 @@ void mmu_info(struct seq_file *m) #endif /* CONFIG_DEBUG_DCFLUSH */ } -struct linux_prom_translation { - unsigned long virt; - unsigned long size; - unsigned long data; -}; - -/* Exported for kernel TLB miss handling in ktlb.S */ -struct linux_prom_translation prom_trans[512] __read_mostly; -unsigned int prom_trans_ents __read_mostly; - /* Exported for SMP bootup purposes. */ unsigned long kern_locked_tte_data; @@ -1875,62 +1926,6 @@ static unsigned long kern_large_tte(unsigned long paddr) return val | paddr; } -/* - * Translate PROM's mapping we capture at boot time into physical address. - * The second parameter is only set from prom_callback() invocations. - */ -unsigned long prom_virt_to_phys(unsigned long promva, int *error) -{ - unsigned long mask; - int i; - - mask = _PAGE_PADDR_4U; - if (tlb_type == hypervisor) - mask = _PAGE_PADDR_4V; - - for (i = 0; i < prom_trans_ents; i++) { - struct linux_prom_translation *p = &prom_trans[i]; - - if (promva >= p->virt && - promva < (p->virt + p->size)) { - unsigned long base = p->data & mask; - - if (error) - *error = 0; - return base + (promva & (8192 - 1)); - } - } - if (error) - *error = 1; - return 0UL; -} - -/* XXX We should kill off this ugly thing at so me point. XXX */ -unsigned long sun4u_get_pte(unsigned long addr) -{ - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep; - unsigned long mask = _PAGE_PADDR_4U; - - if (tlb_type == hypervisor) - mask = _PAGE_PADDR_4V; - - if (addr >= PAGE_OFFSET) - return addr & mask; - - if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS)) - return prom_virt_to_phys(addr, NULL); - - pgdp = pgd_offset_k(addr); - pudp = pud_offset(pgdp, addr); - pmdp = pmd_offset(pudp, addr); - ptep = pte_offset_kernel(pmdp, addr); - - return pte_val(*ptep) & mask; -} - /* If not locked, zap it. */ void __flush_tlb_all(void) { -- cgit v1.2.3 From a94aa2530643f02a4b243f81b5f6354b9b958d7e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 15:50:11 -0700 Subject: [SPARC64]: Kill kvaddr_to_phys() and friends. Just inline it into flush_icache_range() which is the only user. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 91 ++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 63 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 3cacea5da6c..fca253989e5 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -392,75 +392,30 @@ out: put_cpu(); } -struct linux_prom_translation { - unsigned long virt; - unsigned long size; - unsigned long data; -}; - -/* Exported for kernel TLB miss handling in ktlb.S */ -struct linux_prom_translation prom_trans[512] __read_mostly; -unsigned int prom_trans_ents __read_mostly; - -/* - * Translate PROM's mapping we capture at boot time into physical address. - * The second parameter is only set from prom_callback() invocations. - */ -static unsigned long prom_virt_to_phys(unsigned long promva) -{ - unsigned long mask; - int i; - - mask = _PAGE_PADDR_4U; - if (tlb_type == hypervisor) - mask = _PAGE_PADDR_4V; - - for (i = 0; i < prom_trans_ents; i++) { - struct linux_prom_translation *p = &prom_trans[i]; - - if (promva >= p->virt && - promva < (p->virt + p->size)) { - unsigned long base = p->data & mask; - - return base + (promva & (8192 - 1)); - } - } - return 0UL; -} - -static unsigned long kvaddr_to_phys(unsigned long addr) -{ - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep; - unsigned long mask = _PAGE_PADDR_4U; - - if (tlb_type == hypervisor) - mask = _PAGE_PADDR_4V; - - if (addr >= PAGE_OFFSET) - return addr & mask; - - if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS)) - return prom_virt_to_phys(addr); - - pgdp = pgd_offset_k(addr); - pudp = pud_offset(pgdp, addr); - pmdp = pmd_offset(pudp, addr); - ptep = pte_offset_kernel(pmdp, addr); - - return pte_val(*ptep) & mask; -} - void __kprobes flush_icache_range(unsigned long start, unsigned long end) { /* Cheetah and Hypervisor platform cpus have coherent I-cache. */ if (tlb_type == spitfire) { unsigned long kaddr; - for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE) - __flush_icache_page(kvaddr_to_phys(kaddr)); + /* This code only runs on Spitfire cpus so this is + * why we can assume _PAGE_PADDR_4U. + */ + for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE) { + unsigned long paddr, mask = _PAGE_PADDR_4U; + + if (kaddr >= PAGE_OFFSET) + paddr = kaddr & mask; + else { + pgd_t *pgdp = pgd_offset_k(kaddr); + pud_t *pudp = pud_offset(pgdp, kaddr); + pmd_t *pmdp = pmd_offset(pudp, kaddr); + pte_t *ptep = pte_offset_kernel(pmdp, kaddr); + + paddr = pte_val(*ptep) & mask; + } + __flush_icache_page(paddr); + } } } @@ -497,6 +452,16 @@ void mmu_info(struct seq_file *m) #endif /* CONFIG_DEBUG_DCFLUSH */ } +struct linux_prom_translation { + unsigned long virt; + unsigned long size; + unsigned long data; +}; + +/* Exported for kernel TLB miss handling in ktlb.S */ +struct linux_prom_translation prom_trans[512] __read_mostly; +unsigned int prom_trans_ents __read_mostly; + /* Exported for SMP bootup purposes. */ unsigned long kern_locked_tte_data; -- cgit v1.2.3 From 28256ca2e04c72eee1e83524d7f78ce5646030e2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 15:56:07 -0700 Subject: [SPARC64]: Mark show_mem() printk's with KERN_INFO. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index fca253989e5..6fa78c5a30c 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -421,12 +421,12 @@ void __kprobes flush_icache_range(unsigned long start, unsigned long end) void show_mem(void) { - printk("Mem-info:\n"); + printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk("Free swap: %6ldkB\n", + printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); - printk("%ld pages of RAM\n", num_physpages); - printk("%lu free pages\n", nr_free_pages()); + printk(KERN_INFO "%ld pages of RAM\n", num_physpages); + printk(KERN_INFO "%lu free pages\n", nr_free_pages()); } void mmu_info(struct seq_file *m) -- cgit v1.2.3 From 5be4a963675d3270fab7f55e8c4a2e56afd408f6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 16:00:29 -0700 Subject: [SPARC64]: Give move verbose show_mem() output just like i386. We now report everything i386 does except for highmem which doesn't apply. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 6fa78c5a30c..97b5ebc9116 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -421,12 +421,47 @@ void __kprobes flush_icache_range(unsigned long start, unsigned long end) void show_mem(void) { + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; + pg_data_t *pgdat; + printk(KERN_INFO "Mem-info:\n"); show_free_areas(); printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); - printk(KERN_INFO "%ld pages of RAM\n", num_physpages); - printk(KERN_INFO "%lu free pages\n", nr_free_pages()); + for_each_online_pgdat(pgdat) { + unsigned long i, flags; + + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; i++) { + struct page *page = pgdat_page_nr(pgdat, i); + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + pgdat_resize_unlock(pgdat, &flags); + } + + printk(KERN_INFO "%lu pages of RAM\n", total); + printk(KERN_INFO "%lu reserved pages\n", reserved); + printk(KERN_INFO "%lu pages shared\n", shared); + printk(KERN_INFO "%lu pages swap cached\n", cached); + + printk(KERN_INFO "%lu pages dirty\n", + global_page_state(NR_FILE_DIRTY)); + printk(KERN_INFO "%lu pages writeback\n", + global_page_state(NR_WRITEBACK)); + printk(KERN_INFO "%lu pages mapped\n", + global_page_state(NR_FILE_MAPPED)); + printk(KERN_INFO "%lu pages slab\n", + global_page_state(NR_SLAB_RECLAIMABLE) + + global_page_state(NR_SLAB_UNRECLAIMABLE)); + printk(KERN_INFO "%lu pages pagetables\n", + global_page_state(NR_PAGETABLE)); } void mmu_info(struct seq_file *m) -- cgit v1.2.3 From 85f1e1f66011e67e68065f2db4cde499decb9c84 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 17:51:26 -0700 Subject: [SPARC64]: Use DECLARE_BITMAP and BITS_TO_LONGS in mm/init.c Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 97b5ebc9116..83a76a2eb71 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -149,12 +149,6 @@ unsigned long *sparc64_valid_addr_bitmap __read_mostly; unsigned long kern_base __read_mostly; unsigned long kern_size __read_mostly; -/* get_new_mmu_context() uses "cache + 1". */ -DEFINE_SPINLOCK(ctx_alloc_lock); -unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; -#define CTX_BMAP_SLOTS (1UL << (CTX_NR_BITS - 6)) -unsigned long mmu_context_bmap[CTX_BMAP_SLOTS]; - /* Initial ramdisk setup */ extern unsigned long sparc_ramdisk_image64; extern unsigned int sparc_ramdisk_image; @@ -701,6 +695,13 @@ void __flush_dcache_range(unsigned long start, unsigned long end) } #endif /* DCACHE_ALIASING_POSSIBLE */ +/* get_new_mmu_context() uses "cache + 1". */ +DEFINE_SPINLOCK(ctx_alloc_lock); +unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1; +#define MAX_CTX_NR (1UL << CTX_NR_BITS) +#define CTX_BMAP_SLOTS BITS_TO_LONGS(MAX_CTX_NR) +DECLARE_BITMAP(mmu_context_bmap, MAX_CTX_NR); + /* Caller does TLB context flushing on local CPU if necessary. * The caller also ensures that CTX_VALID(mm->context) is false. * -- cgit v1.2.3 From 9753f0d6502acd65761ff15244d26d0e88f0820a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 18:26:00 -0700 Subject: [SPARC64]: Kill sparc_ultra_dump_{i,d}tlb() While useful in odd circumstances to debug something, they are normally totally unused and anyone can fetch this code out of the history if they really need it. And in any event, the person who needs this kind of code is usually me :-) Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 87 -------------------------------------------------- 1 file changed, 87 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 83a76a2eb71..668b7bba90e 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -761,93 +761,6 @@ out: smp_new_mmu_context_version(); } -void sparc_ultra_dump_itlb(void) -{ - int slot; - - if (tlb_type == spitfire) { - printk ("Contents of itlb: "); - for (slot = 0; slot < 14; slot++) printk (" "); - printk ("%2x:%016lx,%016lx\n", - 0, - spitfire_get_itlb_tag(0), spitfire_get_itlb_data(0)); - for (slot = 1; slot < 64; slot+=3) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, - spitfire_get_itlb_tag(slot), spitfire_get_itlb_data(slot), - slot+1, - spitfire_get_itlb_tag(slot+1), spitfire_get_itlb_data(slot+1), - slot+2, - spitfire_get_itlb_tag(slot+2), spitfire_get_itlb_data(slot+2)); - } - } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { - printk ("Contents of itlb0:\n"); - for (slot = 0; slot < 16; slot+=2) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, - cheetah_get_litlb_tag(slot), cheetah_get_litlb_data(slot), - slot+1, - cheetah_get_litlb_tag(slot+1), cheetah_get_litlb_data(slot+1)); - } - printk ("Contents of itlb2:\n"); - for (slot = 0; slot < 128; slot+=2) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, - cheetah_get_itlb_tag(slot), cheetah_get_itlb_data(slot), - slot+1, - cheetah_get_itlb_tag(slot+1), cheetah_get_itlb_data(slot+1)); - } - } -} - -void sparc_ultra_dump_dtlb(void) -{ - int slot; - - if (tlb_type == spitfire) { - printk ("Contents of dtlb: "); - for (slot = 0; slot < 14; slot++) printk (" "); - printk ("%2x:%016lx,%016lx\n", 0, - spitfire_get_dtlb_tag(0), spitfire_get_dtlb_data(0)); - for (slot = 1; slot < 64; slot+=3) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, - spitfire_get_dtlb_tag(slot), spitfire_get_dtlb_data(slot), - slot+1, - spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1), - slot+2, - spitfire_get_dtlb_tag(slot+2), spitfire_get_dtlb_data(slot+2)); - } - } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { - printk ("Contents of dtlb0:\n"); - for (slot = 0; slot < 16; slot+=2) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, - cheetah_get_ldtlb_tag(slot), cheetah_get_ldtlb_data(slot), - slot+1, - cheetah_get_ldtlb_tag(slot+1), cheetah_get_ldtlb_data(slot+1)); - } - printk ("Contents of dtlb2:\n"); - for (slot = 0; slot < 512; slot+=2) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, - cheetah_get_dtlb_tag(slot, 2), cheetah_get_dtlb_data(slot, 2), - slot+1, - cheetah_get_dtlb_tag(slot+1, 2), cheetah_get_dtlb_data(slot+1, 2)); - } - if (tlb_type == cheetah_plus) { - printk ("Contents of dtlb3:\n"); - for (slot = 0; slot < 512; slot+=2) { - printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n", - slot, - cheetah_get_dtlb_tag(slot, 3), cheetah_get_dtlb_data(slot, 3), - slot+1, - cheetah_get_dtlb_tag(slot+1, 3), cheetah_get_dtlb_data(slot+1, 3)); - } - } - } -} - extern unsigned long cmdline_memory_size; /* Find a free area for the bootmem map, avoiding the kernel image -- cgit v1.2.3 From b93f2620231d4641bdbaaa952d3e8890687124bb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 18:29:13 -0700 Subject: [SPARC64]: Add proper header file extern for cmdline_memory_size. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 668b7bba90e..df4e37e0b0f 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -761,8 +761,6 @@ out: smp_new_mmu_context_version(); } -extern unsigned long cmdline_memory_size; - /* Find a free area for the bootmem map, avoiding the kernel image * and the initial ramdisk. */ -- cgit v1.2.3 From 3996465392fd1632b671707d16bbc96a9481cfe2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 19:36:53 -0700 Subject: [SPARC64]: Use bootmem_bootmap_pages() in choose_bootmap_pfn(). Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index df4e37e0b0f..40276189c10 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -770,8 +770,8 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn, unsigned long avoid_start, avoid_end, bootmap_size; int i; - bootmap_size = ((end_pfn - start_pfn) + 7) / 8; - bootmap_size = ALIGN(bootmap_size, sizeof(long)); + bootmap_size = bootmem_bootmap_pages(end_pfn - start_pfn); + bootmap_size <<= PAGE_SHIFT; avoid_start = avoid_end = 0; #ifdef CONFIG_BLK_DEV_INITRD -- cgit v1.2.3 From 0f3e25049e0a54916d0991c1eaa5f8df926c7f92 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 21:44:03 -0700 Subject: [SPARC64]: Make sure pbm->prom_node is setup easly enough in psycho.c It needs to be ready before we invoke pci_determine_mem_io_space(). Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_psycho.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 154c03290d5..3725910c8b2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1107,8 +1107,6 @@ static void psycho_pbm_init(struct pci_controller_info *p, if (prop) pbm->chip_revision = *(int *) prop->value; - pci_determine_mem_io_space(pbm); - pbm->parent = p; pbm->prom_node = dp; pbm->name = dp->full_name; @@ -1117,6 +1115,8 @@ static void psycho_pbm_init(struct pci_controller_info *p, pbm->name, pbm->chip_version, pbm->chip_revision); + pci_determine_mem_io_space(pbm); + prop = of_find_property(dp, "bus-range", NULL); busrange = prop->value; pbm->pci_first_busno = busrange[0]; -- cgit v1.2.3 From f1cfdb55f16596752e8a61a8570a90ee26af183a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Mar 2007 22:52:18 -0700 Subject: [SPARC64]: Document and fix calculation of pages_avail. It should be set to the total number of pages that the system will really have available after things like initmem, the bootmem map, and initrd are freed up. Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 40276189c10..cafadcbcdf3 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -938,6 +938,20 @@ static void __init trim_pavail(unsigned long *cur_size_p, } } +/* About pages_avail, this is the value we will use to calculate + * the zholes_size[] argument given to free_area_init_node(). The + * page allocator uses this to calculate nr_kernel_pages, + * nr_all_pages and zone->present_pages. On NUMA it is used + * to calculate zone->min_unmapped_pages and zone->min_slab_pages. + * + * So this number should really be set to what the page allocator + * actually ends up with. This means: + * 1) It should include bootmem map pages, we'll release those. + * 2) It should not include the kernel image, except for the + * __init sections which we will also release. + * 3) It should include the initrd image, since we'll release + * that too. + */ static unsigned long __init bootmem_init(unsigned long *pages_avail, unsigned long phys_base) { @@ -1024,7 +1038,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, initrd_start, initrd_end); #endif reserve_bootmem(initrd_start, size); - *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; initrd_start += PAGE_OFFSET; initrd_end += PAGE_OFFSET; @@ -1037,6 +1050,11 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, reserve_bootmem(kern_base, kern_size); *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT; + /* Add back in the initmem pages. */ + size = ((unsigned long)(__init_end) & PAGE_MASK) - + PAGE_ALIGN((unsigned long)__init_begin); + *pages_avail += size >> PAGE_SHIFT; + /* Reserve the bootmem map. We do not account for it * in pages_avail because we will release that memory * in free_all_bootmem. @@ -1047,7 +1065,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, (bootmap_pfn << PAGE_SHIFT), size); #endif reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size); - *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; for (i = 0; i < pavail_ents; i++) { unsigned long start_pfn, end_pfn; @@ -1539,6 +1556,10 @@ void __init mem_init(void) #ifdef CONFIG_DEBUG_BOOTMEM prom_printf("mem_init: Calling free_all_bootmem().\n"); #endif + + /* We subtract one to account for the mem_map_zero page + * allocated below. + */ totalram_pages = num_physpages = free_all_bootmem() - 1; /* -- cgit v1.2.3 From a165b4205e0097c7544ec3c59522a3b20ec14eb1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 29 Mar 2007 01:50:16 -0700 Subject: [SPARC64]: Fix PCI rework to adhere to of_get_property() const return. Signed-off-by: David S. Miller --- arch/sparc64/kernel/of_device.c | 4 ++-- arch/sparc64/kernel/pci.c | 2 +- arch/sparc64/kernel/pci_common.c | 6 +++--- arch/sparc64/kernel/pci_sabre.c | 6 +++--- arch/sparc64/kernel/pci_schizo.c | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index f18eec6ad69..9ac9a307999 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -317,7 +317,7 @@ static unsigned int of_bus_default_get_flags(const u32 *addr) static int of_bus_pci_match(struct device_node *np) { if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { - char *model = of_get_property(np, "model", NULL); + const char *model = of_get_property(np, "model", NULL); if (model && !strcmp(model, "SUNW,simba")) return 0; @@ -339,7 +339,7 @@ static int of_bus_pci_match(struct device_node *np) static int of_bus_simba_match(struct device_node *np) { - char *model = of_get_property(np, "model", NULL); + const char *model = of_get_property(np, "model", NULL); if (model && !strcmp(model, "SUNW,simba")) return 1; diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 8a7c699bb10..023af41ad68 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -551,7 +551,7 @@ void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, ranges = of_get_property(node, "ranges", &len); simba = 0; if (ranges == NULL) { - char *model = of_get_property(node, "model", NULL); + const char *model = of_get_property(node, "model", NULL); if (model && !strcmp(model, "SUNW,simba")) { simba = 1; } else { diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 6b5c8e7a3eb..1e6aeedf43c 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -54,7 +54,7 @@ static void pci_register_legacy_regions(struct resource *io_res, static void pci_register_iommu_region(struct pci_pbm_info *pbm) { - u32 *vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL); + const u32 *vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL); if (vdma) { struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); @@ -73,7 +73,7 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) void pci_determine_mem_io_space(struct pci_pbm_info *pbm) { - struct linux_prom_pci_ranges *pbm_ranges; + const struct linux_prom_pci_ranges *pbm_ranges; int i, saw_mem, saw_io; int num_pbm_ranges; @@ -82,7 +82,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) num_pbm_ranges = i / sizeof(*pbm_ranges); for (i = 0; i < num_pbm_ranges; i++) { - struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; + const struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; unsigned long a; u32 parent_phys_hi, parent_phys_lo; int type; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index a2f129d29c2..9a2ce0637c8 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1015,12 +1015,12 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp void sabre_init(struct device_node *dp, char *model_name) { - struct linux_prom64_registers *pr_regs; + const struct linux_prom64_registers *pr_regs; struct pci_controller_info *p; struct pci_iommu *iommu; int tsbsize; - u32 *busrange; - u32 *vdma; + const u32 *busrange; + const u32 *vdma; u32 upa_portid, dma_mask; u64 clear_irq; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 322cdbf50ef..47a5aa94dca 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1490,11 +1490,11 @@ static void schizo_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 portid, int chip_type) { - struct linux_prom64_registers *regs; - unsigned int *busrange; + const struct linux_prom64_registers *regs; + const unsigned int *busrange; struct pci_pbm_info *pbm; const char *chipset_name; - u32 *ino_bitmap; + const u32 *ino_bitmap; int is_pbm_a; switch (chip_type) { -- cgit v1.2.3 From 3dfe10ee7caae9802d84a06fe7724274dea24020 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 29 Mar 2007 11:22:57 -0700 Subject: [SPARC64]: constify some paramaters of OF routines This starts bringing the PowerPC and Sparc64 implemetations back closer together. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- arch/sparc64/kernel/prom.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 13734b50a6e..5e1fcd05160 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -36,12 +36,13 @@ static struct device_node *allnodes; */ static DEFINE_RWLOCK(devtree_lock); -int of_device_is_compatible(struct device_node *device, const char *compat) +int of_device_is_compatible(const struct device_node *device, + const char *compat) { const char* cp; int cplen, l; - cp = (char *) of_get_property(device, "compatible", &cplen); + cp = of_get_property(device, "compatible", &cplen); if (cp == NULL) return 0; while (cplen > 0) { @@ -154,7 +155,8 @@ struct device_node *of_find_compatible_node(struct device_node *from, } EXPORT_SYMBOL(of_find_compatible_node); -struct property *of_find_property(struct device_node *np, const char *name, +struct property *of_find_property(const struct device_node *np, + const char *name, int *lenp) { struct property *pp; @@ -174,7 +176,8 @@ EXPORT_SYMBOL(of_find_property); * Find a property with a given name for a given node * and return the value. */ -const void *of_get_property(struct device_node *np, const char *name, int *lenp) +const void *of_get_property(const struct device_node *np, const char *name, + int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; -- cgit v1.2.3 From 9b3627f389c07c5be9c86ac4d472a0d4fd47feac Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 24 Apr 2007 23:51:18 -0700 Subject: [SPARC64]: Consolidate {sbus,pci}_iommu_arena. Move to asm-sparc64/iommu.h and rename to plain "iommu_arena". Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_iommu.c | 4 ++-- arch/sparc64/kernel/pci_sun4v.c | 6 +++--- arch/sparc64/kernel/sbus.c | 12 +++--------- 3 files changed, 8 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index aefdcc51045..355ed0ba937 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -77,7 +77,7 @@ static inline void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) /* Based largely upon the ppc64 iommu allocator. */ static long pci_arena_alloc(struct pci_iommu *iommu, unsigned long npages) { - struct pci_iommu_arena *arena = &iommu->arena; + struct iommu_arena *arena = &iommu->arena; unsigned long n, i, start, end, limit; int pass; @@ -116,7 +116,7 @@ again: return n; } -static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, unsigned long npages) +static void pci_arena_free(struct iommu_arena *arena, unsigned long base, unsigned long npages) { unsigned long i; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 52bd4563492..0e99808f212 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -110,7 +110,7 @@ static inline long pci_iommu_batch_end(void) return pci_iommu_batch_flush(p); } -static long pci_arena_alloc(struct pci_iommu_arena *arena, unsigned long npages) +static long pci_arena_alloc(struct iommu_arena *arena, unsigned long npages) { unsigned long n, i, start, end, limit; int pass; @@ -149,7 +149,7 @@ again: return n; } -static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, unsigned long npages) +static void pci_arena_free(struct iommu_arena *arena, unsigned long base, unsigned long npages) { unsigned long i; @@ -707,7 +707,7 @@ static void pci_sun4v_scan_bus(struct pci_controller_info *p) static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, struct pci_iommu *iommu) { - struct pci_iommu_arena *arena = &iommu->arena; + struct iommu_arena *arena = &iommu->arena; unsigned long i, cnt = 0; u32 devhandle; diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index d403f3df2dc..279758d56b2 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -26,16 +26,10 @@ #define MAP_BASE ((u32)0xc0000000) -struct sbus_iommu_arena { - unsigned long *map; - unsigned int hint; - unsigned int limit; -}; - struct sbus_iommu { spinlock_t lock; - struct sbus_iommu_arena arena; + struct iommu_arena arena; iopte_t *page_table; unsigned long strbuf_regs; @@ -123,7 +117,7 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long /* Based largely upon the ppc64 iommu allocator. */ static long sbus_arena_alloc(struct sbus_iommu *iommu, unsigned long npages) { - struct sbus_iommu_arena *arena = &iommu->arena; + struct iommu_arena *arena = &iommu->arena; unsigned long n, i, start, end, limit; int pass; @@ -162,7 +156,7 @@ again: return n; } -static void sbus_arena_free(struct sbus_iommu_arena *arena, unsigned long base, unsigned long npages) +static void sbus_arena_free(struct iommu_arena *arena, unsigned long base, unsigned long npages) { unsigned long i; -- cgit v1.2.3 From 3e4d26508af6d03034a97583c895f33bef671d06 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 25 Apr 2007 15:58:22 -0700 Subject: [SPARC64]: Convert SBUS over to generic iommu/strbuf structs. Signed-off-by: David S. Miller --- arch/sparc64/kernel/sbus.c | 229 ++++++++++++++++++++++++++------------------- 1 file changed, 132 insertions(+), 97 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 279758d56b2..3b05428cc90 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -26,17 +26,9 @@ #define MAP_BASE ((u32)0xc0000000) -struct sbus_iommu { - spinlock_t lock; - - struct iommu_arena arena; - - iopte_t *page_table; - unsigned long strbuf_regs; - unsigned long iommu_regs; - unsigned long sbus_control_reg; - - volatile unsigned long strbuf_flushflag; +struct sbus_info { + struct iommu iommu; + struct strbuf strbuf; }; /* Offsets from iommu_regs */ @@ -52,16 +44,17 @@ struct sbus_iommu { #define IOMMU_DRAM_VALID (1UL << 30UL) -static void __iommu_flushall(struct sbus_iommu *iommu) +static void __iommu_flushall(struct iommu *iommu) { - unsigned long tag = iommu->iommu_regs + IOMMU_TAGDIAG; + unsigned long tag; int entry; + tag = iommu->iommu_control + (IOMMU_TAGDIAG - IOMMU_CONTROL); for (entry = 0; entry < 16; entry++) { upa_writeq(0, tag); tag += 8UL; } - upa_readq(iommu->sbus_control_reg); + upa_readq(iommu->write_complete_reg); } /* Offsets from strbuf_regs */ @@ -76,15 +69,14 @@ static void __iommu_flushall(struct sbus_iommu *iommu) #define STRBUF_TAG_VALID 0x02UL -static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages, int direction) +static void sbus_strbuf_flush(struct iommu *iommu, struct strbuf *strbuf, u32 base, unsigned long npages, int direction) { unsigned long n; int limit; n = npages; while (n--) - upa_writeq(base + (n << IO_PAGE_SHIFT), - iommu->strbuf_regs + STRBUF_PFLUSH); + upa_writeq(base + (n << IO_PAGE_SHIFT), strbuf->strbuf_pflush); /* If the device could not have possibly put dirty data into * the streaming cache, no flush-flag synchronization needs @@ -93,15 +85,14 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long if (direction == SBUS_DMA_TODEVICE) return; - iommu->strbuf_flushflag = 0UL; + *(strbuf->strbuf_flushflag) = 0UL; /* Whoopee cushion! */ - upa_writeq(__pa(&iommu->strbuf_flushflag), - iommu->strbuf_regs + STRBUF_FSYNC); - upa_readq(iommu->sbus_control_reg); + upa_writeq(strbuf->strbuf_flushflag_pa, strbuf->strbuf_fsync); + upa_readq(iommu->write_complete_reg); limit = 100000; - while (iommu->strbuf_flushflag == 0UL) { + while (*(strbuf->strbuf_flushflag) == 0UL) { limit--; if (!limit) break; @@ -115,7 +106,7 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long } /* Based largely upon the ppc64 iommu allocator. */ -static long sbus_arena_alloc(struct sbus_iommu *iommu, unsigned long npages) +static long sbus_arena_alloc(struct iommu *iommu, unsigned long npages) { struct iommu_arena *arena = &iommu->arena; unsigned long n, i, start, end, limit; @@ -164,7 +155,7 @@ static void sbus_arena_free(struct iommu_arena *arena, unsigned long base, unsig __clear_bit(i, arena->map); } -static void sbus_iommu_table_init(struct sbus_iommu *iommu, unsigned int tsbsize) +static void sbus_iommu_table_init(struct iommu *iommu, unsigned int tsbsize) { unsigned long tsbbase, order, sz, num_tsb_entries; @@ -172,13 +163,14 @@ static void sbus_iommu_table_init(struct sbus_iommu *iommu, unsigned int tsbsize /* Setup initial software IOMMU state. */ spin_lock_init(&iommu->lock); + iommu->page_table_map_base = MAP_BASE; /* Allocate and initialize the free area map. */ sz = num_tsb_entries / 8; sz = (sz + 7UL) & ~7UL; iommu->arena.map = kzalloc(sz, GFP_KERNEL); if (!iommu->arena.map) { - prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); + prom_printf("SBUS_IOMMU: Error, kmalloc(arena.map) failed.\n"); prom_halt(); } iommu->arena.limit = num_tsb_entries; @@ -194,7 +186,7 @@ static void sbus_iommu_table_init(struct sbus_iommu *iommu, unsigned int tsbsize memset(iommu->page_table, 0, tsbsize); } -static inline iopte_t *alloc_npages(struct sbus_iommu *iommu, unsigned long npages) +static inline iopte_t *alloc_npages(struct iommu *iommu, unsigned long npages) { long entry; @@ -205,14 +197,15 @@ static inline iopte_t *alloc_npages(struct sbus_iommu *iommu, unsigned long npag return iommu->page_table + entry; } -static inline void free_npages(struct sbus_iommu *iommu, dma_addr_t base, unsigned long npages) +static inline void free_npages(struct iommu *iommu, dma_addr_t base, unsigned long npages) { sbus_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages); } void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr) { - struct sbus_iommu *iommu; + struct sbus_info *info; + struct iommu *iommu; iopte_t *iopte; unsigned long flags, order, first_page; void *ret; @@ -228,7 +221,8 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma return NULL; memset((char *)first_page, 0, PAGE_SIZE << order); - iommu = sdev->bus->iommu; + info = sdev->bus->iommu; + iommu = &info->iommu; spin_lock_irqsave(&iommu->lock, flags); iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT); @@ -239,7 +233,7 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma return NULL; } - *dvma_addr = (MAP_BASE + + *dvma_addr = (iommu->page_table_map_base + ((iopte - iommu->page_table) << IO_PAGE_SHIFT)); ret = (void *) first_page; npages = size >> IO_PAGE_SHIFT; @@ -257,18 +251,20 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma) { - struct sbus_iommu *iommu; + struct sbus_info *info; + struct iommu *iommu; iopte_t *iopte; unsigned long flags, order, npages; npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; - iommu = sdev->bus->iommu; + info = sdev->bus->iommu; + iommu = &info->iommu; iopte = iommu->page_table + - ((dvma - MAP_BASE) >> IO_PAGE_SHIFT); + ((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT); spin_lock_irqsave(&iommu->lock, flags); - free_npages(iommu, dvma - MAP_BASE, npages); + free_npages(iommu, dvma - iommu->page_table_map_base, npages); spin_unlock_irqrestore(&iommu->lock, flags); @@ -279,14 +275,16 @@ void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_add dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t sz, int direction) { - struct sbus_iommu *iommu; + struct sbus_info *info; + struct iommu *iommu; iopte_t *base; unsigned long flags, npages, oaddr; unsigned long i, base_paddr; u32 bus_addr, ret; unsigned long iopte_protection; - iommu = sdev->bus->iommu; + info = sdev->bus->iommu; + iommu = &info->iommu; if (unlikely(direction == SBUS_DMA_NONE)) BUG(); @@ -302,7 +300,7 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t sz, int dire if (unlikely(!base)) BUG(); - bus_addr = (MAP_BASE + + bus_addr = (iommu->page_table_map_base + ((base - iommu->page_table) << IO_PAGE_SHIFT)); ret = bus_addr | (oaddr & ~IO_PAGE_MASK); base_paddr = __pa(oaddr & IO_PAGE_MASK); @@ -319,7 +317,9 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t sz, int dire void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct sbus_iommu *iommu = sdev->bus->iommu; + struct sbus_info *info = sdev->bus->iommu; + struct iommu *iommu = &info->iommu; + struct strbuf *strbuf = &info->strbuf; iopte_t *base; unsigned long flags, npages, i; @@ -329,15 +329,15 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, in npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; base = iommu->page_table + - ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT); + ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); bus_addr &= IO_PAGE_MASK; spin_lock_irqsave(&iommu->lock, flags); - sbus_strbuf_flush(iommu, bus_addr, npages, direction); + sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction); for (i = 0; i < npages; i++) iopte_val(base[i]) = 0UL; - free_npages(iommu, bus_addr - MAP_BASE, npages); + free_npages(iommu, bus_addr - iommu->page_table_map_base, npages); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -419,7 +419,8 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) { - struct sbus_iommu *iommu; + struct sbus_info *info; + struct iommu *iommu; unsigned long flags, npages, iopte_protection; iopte_t *base; u32 dma_base; @@ -436,7 +437,8 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, i return 1; } - iommu = sdev->bus->iommu; + info = sdev->bus->iommu; + iommu = &info->iommu; if (unlikely(direction == SBUS_DMA_NONE)) BUG(); @@ -450,7 +452,7 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, i if (unlikely(base == NULL)) BUG(); - dma_base = MAP_BASE + + dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << IO_PAGE_SHIFT); /* Normalize DVMA addresses. */ @@ -479,7 +481,9 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, i void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) { - struct sbus_iommu *iommu; + struct sbus_info *info; + struct iommu *iommu; + struct strbuf *strbuf; iopte_t *base; unsigned long flags, i, npages; u32 bus_addr; @@ -487,7 +491,9 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems if (unlikely(direction == SBUS_DMA_NONE)) BUG(); - iommu = sdev->bus->iommu; + info = sdev->bus->iommu; + iommu = &info->iommu; + strbuf = &info->strbuf; bus_addr = sglist->dma_address & IO_PAGE_MASK; @@ -499,29 +505,33 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems bus_addr) >> IO_PAGE_SHIFT; base = iommu->page_table + - ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT); + ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); spin_lock_irqsave(&iommu->lock, flags); - sbus_strbuf_flush(iommu, bus_addr, npages, direction); + sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction); for (i = 0; i < npages; i++) iopte_val(base[i]) = 0UL; - free_npages(iommu, bus_addr - MAP_BASE, npages); + free_npages(iommu, bus_addr - iommu->page_table_map_base, npages); spin_unlock_irqrestore(&iommu->lock, flags); } void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct sbus_iommu *iommu; + struct sbus_info *info; + struct iommu *iommu; + struct strbuf *strbuf; unsigned long flags, npages; - iommu = sdev->bus->iommu; + info = sdev->bus->iommu; + iommu = &info->iommu; + strbuf = &info->strbuf; npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; bus_addr &= IO_PAGE_MASK; spin_lock_irqsave(&iommu->lock, flags); - sbus_strbuf_flush(iommu, bus_addr, npages, direction); + sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -531,11 +541,15 @@ void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t base, siz void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) { - struct sbus_iommu *iommu; + struct sbus_info *info; + struct iommu *iommu; + struct strbuf *strbuf; unsigned long flags, npages, i; u32 bus_addr; - iommu = sdev->bus->iommu; + info = sdev->bus->iommu; + iommu = &info->iommu; + strbuf = &info->strbuf; bus_addr = sglist[0].dma_address & IO_PAGE_MASK; for (i = 0; i < nelems; i++) { @@ -547,7 +561,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sglist, - bus_addr) >> IO_PAGE_SHIFT; spin_lock_irqsave(&iommu->lock, flags); - sbus_strbuf_flush(iommu, bus_addr, npages, direction); + sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -558,12 +572,13 @@ void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, /* Enable 64-bit DVMA mode for the given device. */ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts) { - struct sbus_iommu *iommu = sdev->bus->iommu; + struct sbus_info *info = sdev->bus->iommu; + struct iommu *iommu = &info->iommu; int slot = sdev->slot; unsigned long cfg_reg; u64 val; - cfg_reg = iommu->sbus_control_reg; + cfg_reg = iommu->write_complete_reg; switch (slot) { case 0: cfg_reg += 0x20UL; @@ -698,8 +713,9 @@ static unsigned long sysio_imap_to_iclr(unsigned long imap) unsigned int sbus_build_irq(void *buscookie, unsigned int ino) { struct sbus_bus *sbus = (struct sbus_bus *)buscookie; - struct sbus_iommu *iommu = sbus->iommu; - unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; + struct sbus_info *info = sbus->iommu; + struct iommu *iommu = &info->iommu; + unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; unsigned long imap, iclr; int sbus_level = 0; @@ -760,8 +776,9 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) static irqreturn_t sysio_ue_handler(int irq, void *dev_id) { struct sbus_bus *sbus = dev_id; - struct sbus_iommu *iommu = sbus->iommu; - unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; + struct sbus_info *info = sbus->iommu; + struct iommu *iommu = &info->iommu; + unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; unsigned long afsr_reg, afar_reg; unsigned long afsr, afar, error_bits; int reported; @@ -832,8 +849,9 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) static irqreturn_t sysio_ce_handler(int irq, void *dev_id) { struct sbus_bus *sbus = dev_id; - struct sbus_iommu *iommu = sbus->iommu; - unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; + struct sbus_info *info = sbus->iommu; + struct iommu *iommu = &info->iommu; + unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; unsigned long afsr_reg, afar_reg; unsigned long afsr, afar, error_bits; int reported; @@ -909,12 +927,13 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) { struct sbus_bus *sbus = dev_id; - struct sbus_iommu *iommu = sbus->iommu; + struct sbus_info *info = sbus->iommu; + struct iommu *iommu = &info->iommu; unsigned long afsr_reg, afar_reg, reg_base; unsigned long afsr, afar, error_bits; int reported; - reg_base = iommu->sbus_control_reg - 0x2000UL; + reg_base = iommu->write_complete_reg - 0x2000UL; afsr_reg = reg_base + SYSIO_SBUS_AFSR; afar_reg = reg_base + SYSIO_SBUS_AFAR; @@ -976,8 +995,9 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) static void __init sysio_register_error_handlers(struct sbus_bus *sbus) { - struct sbus_iommu *iommu = sbus->iommu; - unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; + struct sbus_info *info = sbus->iommu; + struct iommu *iommu = &info->iommu; + unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; unsigned int irq; u64 control; @@ -1011,9 +1031,9 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) SYSIO_ECNTRL_CEEN), reg_base + ECC_CONTROL); - control = upa_readq(iommu->sbus_control_reg); + control = upa_readq(iommu->write_complete_reg); control |= 0x100UL; /* SBUS Error Interrupt Enable */ - upa_writeq(control, iommu->sbus_control_reg); + upa_writeq(control, iommu->write_complete_reg); } /* Boot time initialization. */ @@ -1021,8 +1041,10 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) { const struct linux_prom64_registers *pr; struct device_node *dp; - struct sbus_iommu *iommu; - unsigned long regs; + struct sbus_info *info; + struct iommu *iommu; + struct strbuf *strbuf; + unsigned long regs, reg_base; u64 control; int i; @@ -1037,33 +1059,42 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) } regs = pr->phys_addr; - iommu = kmalloc(sizeof(*iommu) + SMP_CACHE_BYTES, GFP_ATOMIC); - if (iommu == NULL) { - prom_printf("sbus_iommu_init: Fatal error, kmalloc(iommu) failed\n"); + info = kzalloc(sizeof(*info), GFP_ATOMIC); + if (info == NULL) { + prom_printf("sbus_iommu_init: Fatal error, " + "kmalloc(info) failed\n"); prom_halt(); } - /* Align on E$ line boundary. */ - iommu = (struct sbus_iommu *) - (((unsigned long)iommu + (SMP_CACHE_BYTES - 1UL)) & - ~(SMP_CACHE_BYTES - 1UL)); + iommu = &info->iommu; + strbuf = &info->strbuf; - memset(iommu, 0, sizeof(*iommu)); + reg_base = regs + SYSIO_IOMMUREG_BASE; + iommu->iommu_control = reg_base + IOMMU_CONTROL; + iommu->iommu_tsbbase = reg_base + IOMMU_TSBBASE; + iommu->iommu_flush = reg_base + IOMMU_FLUSH; - /* Setup spinlock. */ - spin_lock_init(&iommu->lock); + reg_base = regs + SYSIO_STRBUFREG_BASE; + strbuf->strbuf_control = reg_base + STRBUF_CONTROL; + strbuf->strbuf_pflush = reg_base + STRBUF_PFLUSH; + strbuf->strbuf_fsync = reg_base + STRBUF_FSYNC; + + strbuf->strbuf_enabled = 1; - /* Init register offsets. */ - iommu->iommu_regs = regs + SYSIO_IOMMUREG_BASE; - iommu->strbuf_regs = regs + SYSIO_STRBUFREG_BASE; + strbuf->strbuf_flushflag = (volatile unsigned long *) + ((((unsigned long)&strbuf->__flushflag_buf[0]) + + 63UL) + & ~63UL); + strbuf->strbuf_flushflag_pa = (unsigned long) + __pa(strbuf->strbuf_flushflag); /* The SYSIO SBUS control register is used for dummy reads * in order to ensure write completion. */ - iommu->sbus_control_reg = regs + 0x2000UL; + iommu->write_complete_reg = regs + 0x2000UL; /* Link into SYSIO software state. */ - sbus->iommu = iommu; + sbus->iommu = info; printk("SYSIO: UPA portID %x, at %016lx\n", sbus->portid, regs); @@ -1071,40 +1102,44 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */ sbus_iommu_table_init(iommu, IO_TSB_SIZE); - control = upa_readq(iommu->iommu_regs + IOMMU_CONTROL); + control = upa_readq(iommu->iommu_control); control = ((7UL << 16UL) | (0UL << 2UL) | (1UL << 1UL) | (1UL << 0UL)); - upa_writeq(control, iommu->iommu_regs + IOMMU_CONTROL); + upa_writeq(control, iommu->iommu_control); /* Clean out any cruft in the IOMMU using * diagnostic accesses. */ for (i = 0; i < 16; i++) { - unsigned long dram = iommu->iommu_regs + IOMMU_DRAMDIAG; - unsigned long tag = iommu->iommu_regs + IOMMU_TAGDIAG; + unsigned long dram, tag; + + dram = iommu->iommu_control + (IOMMU_DRAMDIAG - IOMMU_CONTROL); + tag = iommu->iommu_control + (IOMMU_TAGDIAG - IOMMU_CONTROL); dram += (unsigned long)i * 8UL; tag += (unsigned long)i * 8UL; upa_writeq(0, dram); upa_writeq(0, tag); } - upa_readq(iommu->sbus_control_reg); + upa_readq(iommu->write_complete_reg); /* Give the TSB to SYSIO. */ - upa_writeq(__pa(iommu->page_table), iommu->iommu_regs + IOMMU_TSBBASE); + upa_writeq(__pa(iommu->page_table), iommu->iommu_tsbbase); /* Setup streaming buffer, DE=1 SB_EN=1 */ control = (1UL << 1UL) | (1UL << 0UL); - upa_writeq(control, iommu->strbuf_regs + STRBUF_CONTROL); + upa_writeq(control, strbuf->strbuf_control); /* Clear out the tags using diagnostics. */ for (i = 0; i < 16; i++) { unsigned long ptag, ltag; - ptag = iommu->strbuf_regs + STRBUF_PTAGDIAG; - ltag = iommu->strbuf_regs + STRBUF_LTAGDIAG; + ptag = strbuf->strbuf_control + + (STRBUF_PTAGDIAG - STRBUF_CONTROL); + ltag = strbuf->strbuf_control + + (STRBUF_LTAGDIAG - STRBUF_CONTROL); ptag += (unsigned long)i * 8UL; ltag += (unsigned long)i * 8UL; @@ -1113,9 +1148,9 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) } /* Enable DVMA arbitration for all devices/slots. */ - control = upa_readq(iommu->sbus_control_reg); + control = upa_readq(iommu->write_complete_reg); control |= 0x3fUL; - upa_writeq(control, iommu->sbus_control_reg); + upa_writeq(control, iommu->write_complete_reg); /* Now some Xfire specific grot... */ if (this_is_starfire) -- cgit v1.2.3 From ee5ac9ddf2ea13be2418ac7d0ce5a930e78af013 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 26 Apr 2007 00:03:53 -0700 Subject: [SPARC]: device_node name constification fallout A couple of routines need their arguments to be const. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- arch/sparc/kernel/ebus.c | 4 ++-- arch/sparc/kernel/pcic.c | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index 7724e206715..7bb86b9cdaa 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -25,7 +25,7 @@ struct linux_ebus *ebus_chain = NULL; /* We are together with pcic.c under CONFIG_PCI. */ -extern unsigned int pcic_pin_to_irq(unsigned int, char *name); +extern unsigned int pcic_pin_to_irq(unsigned int, const char *name); /* * IRQ Blacklist @@ -69,7 +69,7 @@ static inline unsigned long ebus_alloc(size_t size) /* */ -int __init ebus_blacklist_irq(char *name) +int __init ebus_blacklist_irq(const char *name) { struct ebus_device_irq *dp; diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 1c927c538b8..5ca7e8f42bd 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -37,8 +37,6 @@ #include -unsigned int pcic_pin_to_irq(unsigned int pin, char *name); - /* * I studied different documents and many live PROMs both from 2.30 * family and 3.xx versions. I came to the amazing conclusion: there is @@ -681,7 +679,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) * pcic_pin_to_irq() is exported to ebus.c. */ unsigned int -pcic_pin_to_irq(unsigned int pin, char *name) +pcic_pin_to_irq(unsigned int pin, const char *name) { struct linux_pcic *pcic = &pcic0; unsigned int irq; -- cgit v1.2.3 From 16ce82d846f2e6b652a064f91c5019cfe8682be4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 26 Apr 2007 21:08:21 -0700 Subject: [SPARC64]: Convert PCI over to generic struct iommu/strbuf. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_iommu.c | 53 ++++++++++++++++++++-------------------- arch/sparc64/kernel/pci_psycho.c | 10 ++++---- arch/sparc64/kernel/pci_sabre.c | 11 ++++----- arch/sparc64/kernel/pci_schizo.c | 12 ++++----- arch/sparc64/kernel/pci_sun4v.c | 34 +++++++++++++------------- 5 files changed, 59 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 355ed0ba937..66712772f49 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -1,7 +1,6 @@ -/* $Id: pci_iommu.c,v 1.17 2001/12/17 07:05:09 davem Exp $ - * pci_iommu.c: UltraSparc PCI controller IOM/STC support. +/* pci_iommu.c: UltraSparc PCI controller IOM/STC support. * - * Copyright (C) 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1999, 2000 Jakub Jelinek (jakub@redhat.com) */ @@ -36,7 +35,7 @@ "i" (ASI_PHYS_BYPASS_EC_E)) /* Must be invoked under the IOMMU lock. */ -static void __iommu_flushall(struct pci_iommu *iommu) +static void __iommu_flushall(struct iommu *iommu) { unsigned long tag; int entry; @@ -64,7 +63,7 @@ static void __iommu_flushall(struct pci_iommu *iommu) #define IOPTE_IS_DUMMY(iommu, iopte) \ ((iopte_val(*iopte) & IOPTE_PAGE) == (iommu)->dummy_page_pa) -static inline void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) +static inline void iopte_make_dummy(struct iommu *iommu, iopte_t *iopte) { unsigned long val = iopte_val(*iopte); @@ -75,7 +74,7 @@ static inline void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) } /* Based largely upon the ppc64 iommu allocator. */ -static long pci_arena_alloc(struct pci_iommu *iommu, unsigned long npages) +static long pci_arena_alloc(struct iommu *iommu, unsigned long npages) { struct iommu_arena *arena = &iommu->arena; unsigned long n, i, start, end, limit; @@ -124,7 +123,7 @@ static void pci_arena_free(struct iommu_arena *arena, unsigned long base, unsign __clear_bit(i, arena->map); } -void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask) +void pci_iommu_table_init(struct iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask) { unsigned long i, tsbbase, order, sz, num_tsb_entries; @@ -170,7 +169,7 @@ void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, iopte_make_dummy(iommu, &iommu->page_table[i]); } -static inline iopte_t *alloc_npages(struct pci_iommu *iommu, unsigned long npages) +static inline iopte_t *alloc_npages(struct iommu *iommu, unsigned long npages) { long entry; @@ -181,12 +180,12 @@ static inline iopte_t *alloc_npages(struct pci_iommu *iommu, unsigned long npage return iommu->page_table + entry; } -static inline void free_npages(struct pci_iommu *iommu, dma_addr_t base, unsigned long npages) +static inline void free_npages(struct iommu *iommu, dma_addr_t base, unsigned long npages) { pci_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages); } -static int iommu_alloc_ctx(struct pci_iommu *iommu) +static int iommu_alloc_ctx(struct iommu *iommu) { int lowest = iommu->ctx_lowest_free; int sz = IOMMU_NUM_CTXS - lowest; @@ -205,7 +204,7 @@ static int iommu_alloc_ctx(struct pci_iommu *iommu) return n; } -static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx) +static inline void iommu_free_ctx(struct iommu *iommu, int ctx) { if (likely(ctx)) { __clear_bit(ctx, iommu->ctx_bitmap); @@ -220,7 +219,7 @@ static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx) */ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) { - struct pci_iommu *iommu; + struct iommu *iommu; iopte_t *iopte; unsigned long flags, order, first_page; void *ret; @@ -266,7 +265,7 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr /* Free and unmap a consistent DMA translation. */ static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) { - struct pci_iommu *iommu; + struct iommu *iommu; iopte_t *iopte; unsigned long flags, order, npages; @@ -291,8 +290,8 @@ static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, */ static dma_addr_t pci_4u_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction) { - struct pci_iommu *iommu; - struct pci_strbuf *strbuf; + struct iommu *iommu; + struct strbuf *strbuf; iopte_t *base; unsigned long flags, npages, oaddr; unsigned long i, base_paddr, ctx; @@ -343,7 +342,7 @@ bad_no_ctx: return PCI_DMA_ERROR_CODE; } -static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages, int direction) +static void pci_strbuf_flush(struct strbuf *strbuf, struct iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages, int direction) { int limit; @@ -410,8 +409,8 @@ do_flush_sync: /* Unmap a single streaming mode DMA translation. */ static void pci_4u_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct pci_iommu *iommu; - struct pci_strbuf *strbuf; + struct iommu *iommu; + struct strbuf *strbuf; iopte_t *base; unsigned long flags, npages, ctx, i; @@ -541,8 +540,8 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, */ static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pci_iommu *iommu; - struct pci_strbuf *strbuf; + struct iommu *iommu; + struct strbuf *strbuf; unsigned long flags, ctx, npages, iopte_protection; iopte_t *base; u32 dma_base; @@ -626,8 +625,8 @@ bad_no_ctx: /* Unmap a set of streaming mode DMA translations. */ static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pci_iommu *iommu; - struct pci_strbuf *strbuf; + struct iommu *iommu; + struct strbuf *strbuf; iopte_t *base; unsigned long flags, ctx, i, npages; u32 bus_addr; @@ -684,8 +683,8 @@ static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, in */ static void pci_4u_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) { - struct pci_iommu *iommu; - struct pci_strbuf *strbuf; + struct iommu *iommu; + struct strbuf *strbuf; unsigned long flags, ctx, npages; iommu = pdev->dev.archdata.iommu; @@ -722,8 +721,8 @@ static void pci_4u_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_ */ static void pci_4u_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pci_iommu *iommu; - struct pci_strbuf *strbuf; + struct iommu *iommu; + struct strbuf *strbuf; unsigned long flags, ctx, npages, i; u32 bus_addr; @@ -798,7 +797,7 @@ int pci_dma_supported(struct pci_dev *pdev, u64 device_mask) if (pdev == NULL) { dma_addr_mask = 0xffffffff; } else { - struct pci_iommu *iommu = pdev->dev.archdata.iommu; + struct iommu *iommu = pdev->dev.archdata.iommu; dma_addr_mask = iommu->dma_addr_mask; diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 3725910c8b2..253d40ec224 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -269,7 +269,7 @@ static void __psycho_check_one_stc(struct pci_controller_info *p, struct pci_pbm_info *pbm, int is_pbm_a) { - struct pci_strbuf *strbuf = &pbm->stc; + struct strbuf *strbuf = &pbm->stc; unsigned long regbase = p->pbm_A.controller_regs; unsigned long err_base, tag_base, line_base; u64 control; @@ -418,7 +418,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, unsigned long afar, enum psycho_error_type type) { - struct pci_iommu *iommu = p->pbm_A.iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; @@ -941,7 +941,7 @@ static void psycho_scan_bus(struct pci_controller_info *p) static void psycho_iommu_init(struct pci_controller_info *p) { - struct pci_iommu *iommu = p->pbm_A.iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long i; u64 control; @@ -1131,7 +1131,7 @@ void psycho_init(struct device_node *dp, char *model_name) { struct linux_prom64_registers *pr_regs; struct pci_controller_info *p; - struct pci_iommu *iommu; + struct iommu *iommu; struct property *prop; u32 upa_portid; int is_pbm_a; @@ -1154,7 +1154,7 @@ void psycho_init(struct device_node *dp, char *model_name) prom_printf("PSYCHO: Fatal memory allocation error.\n"); prom_halt(); } - iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); if (!iommu) { prom_printf("PSYCHO: Fatal memory allocation error.\n"); prom_halt(); diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 9a2ce0637c8..397862fbd9e 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1,7 +1,6 @@ -/* $Id: pci_sabre.c,v 1.42 2002/01/23 11:27:32 davem Exp $ - * pci_sabre.c: Sabre specific PCI controller support. +/* pci_sabre.c: Sabre specific PCI controller support. * - * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) + * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) */ @@ -499,7 +498,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, unsigned long afsr, unsigned long afar) { - struct pci_iommu *iommu = p->pbm_A.iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; @@ -948,7 +947,7 @@ static void sabre_iommu_init(struct pci_controller_info *p, int tsbsize, unsigned long dvma_offset, u32 dma_mask) { - struct pci_iommu *iommu = p->pbm_A.iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long i; u64 control; @@ -1017,7 +1016,7 @@ void sabre_init(struct device_node *dp, char *model_name) { const struct linux_prom64_registers *pr_regs; struct pci_controller_info *p; - struct pci_iommu *iommu; + struct iommu *iommu; int tsbsize; const u32 *busrange; const u32 *vdma; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 47a5aa94dca..91a7385e5d3 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -279,7 +279,7 @@ struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) static void __schizo_check_stc_error_pbm(struct pci_pbm_info *pbm, enum schizo_error_type type) { - struct pci_strbuf *strbuf = &pbm->stc; + struct strbuf *strbuf = &pbm->stc; unsigned long regbase = pbm->pbm_regs; unsigned long err_base, tag_base, line_base; u64 control; @@ -387,7 +387,7 @@ static void __schizo_check_stc_error_pbm(struct pci_pbm_info *pbm, static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm, enum schizo_error_type type) { - struct pci_iommu *iommu = pbm->iommu; + struct iommu *iommu = pbm->iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; @@ -1308,7 +1308,7 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm) static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) { - struct pci_iommu *iommu = pbm->iommu; + struct iommu *iommu = pbm->iommu; unsigned long i, tagbase, database; struct property *prop; u32 vdma[2], dma_mask; @@ -1580,7 +1580,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) { struct pci_controller_info *p; - struct pci_iommu *iommu; + struct iommu *iommu; u32 portid; portid = of_getintprop_default(dp, "portid", 0xff); @@ -1605,13 +1605,13 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ if (!p) goto memfail; - iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); if (!iommu) goto memfail; p->pbm_A.iommu = iommu; - iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); if (!iommu) goto memfail; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 0e99808f212..94295c21932 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -29,7 +29,7 @@ #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) -struct pci_iommu_batch { +struct iommu_batch { struct pci_dev *pdev; /* Device mapping is for. */ unsigned long prot; /* IOMMU page protections */ unsigned long entry; /* Index into IOTSB. */ @@ -37,12 +37,12 @@ struct pci_iommu_batch { unsigned long npages; /* Number of pages in list. */ }; -static DEFINE_PER_CPU(struct pci_iommu_batch, pci_iommu_batch); +static DEFINE_PER_CPU(struct iommu_batch, pci_iommu_batch); /* Interrupts must be disabled. */ static inline void pci_iommu_batch_start(struct pci_dev *pdev, unsigned long prot, unsigned long entry) { - struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); + struct iommu_batch *p = &__get_cpu_var(pci_iommu_batch); p->pdev = pdev; p->prot = prot; @@ -51,7 +51,7 @@ static inline void pci_iommu_batch_start(struct pci_dev *pdev, unsigned long pro } /* Interrupts must be disabled. */ -static long pci_iommu_batch_flush(struct pci_iommu_batch *p) +static long pci_iommu_batch_flush(struct iommu_batch *p) { struct pci_pbm_info *pbm = p->pdev->dev.archdata.host_controller; unsigned long devhandle = pbm->devhandle; @@ -89,7 +89,7 @@ static long pci_iommu_batch_flush(struct pci_iommu_batch *p) /* Interrupts must be disabled. */ static inline long pci_iommu_batch_add(u64 phys_page) { - struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); + struct iommu_batch *p = &__get_cpu_var(pci_iommu_batch); BUG_ON(p->npages >= PGLIST_NENTS); @@ -103,7 +103,7 @@ static inline long pci_iommu_batch_add(u64 phys_page) /* Interrupts must be disabled. */ static inline long pci_iommu_batch_end(void) { - struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); + struct iommu_batch *p = &__get_cpu_var(pci_iommu_batch); BUG_ON(p->npages >= PGLIST_NENTS); @@ -159,7 +159,7 @@ static void pci_arena_free(struct iommu_arena *arena, unsigned long base, unsign static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) { - struct pci_iommu *iommu; + struct iommu *iommu; unsigned long flags, order, first_page, npages, n; void *ret; long entry; @@ -225,7 +225,7 @@ arena_alloc_fail: static void pci_4v_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) { struct pci_pbm_info *pbm; - struct pci_iommu *iommu; + struct iommu *iommu; unsigned long flags, order, npages, entry; u32 devhandle; @@ -257,7 +257,7 @@ static void pci_4v_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, static dma_addr_t pci_4v_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction) { - struct pci_iommu *iommu; + struct iommu *iommu; unsigned long flags, npages, oaddr; unsigned long i, base_paddr; u32 bus_addr, ret; @@ -321,7 +321,7 @@ iommu_map_fail: static void pci_4v_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) { struct pci_pbm_info *pbm; - struct pci_iommu *iommu; + struct iommu *iommu; unsigned long flags, npages; long entry; u32 devhandle; @@ -456,7 +456,7 @@ iommu_map_failed: static int pci_4v_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { - struct pci_iommu *iommu; + struct iommu *iommu; unsigned long flags, npages, prot; u32 dma_base; struct scatterlist *sgtmp; @@ -532,7 +532,7 @@ iommu_map_failed: static void pci_4v_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) { struct pci_pbm_info *pbm; - struct pci_iommu *iommu; + struct iommu *iommu; unsigned long flags, i, npages; long entry; u32 devhandle, bus_addr; @@ -705,7 +705,7 @@ static void pci_sun4v_scan_bus(struct pci_controller_info *p) } static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, - struct pci_iommu *iommu) + struct iommu *iommu) { struct iommu_arena *arena = &iommu->arena; unsigned long i, cnt = 0; @@ -734,7 +734,7 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) { - struct pci_iommu *iommu = pbm->iommu; + struct iommu *iommu = pbm->iommu; struct property *prop; unsigned long num_tsb_entries, sz; u32 vdma[2], dma_mask, dma_offset; @@ -1279,7 +1279,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node void sun4v_pci_init(struct device_node *dp, char *model_name) { struct pci_controller_info *p; - struct pci_iommu *iommu; + struct iommu *iommu; struct property *prop; struct linux_prom64_registers *regs; u32 devhandle; @@ -1319,13 +1319,13 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) if (!p) goto fatal_memory_error; - iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); if (!iommu) goto fatal_memory_error; p->pbm_A.iommu = iommu; - iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); if (!iommu) goto fatal_memory_error; -- cgit v1.2.3 From 9c8f8e752431f3f7ed6ea6ea6e491ce12057f572 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Thu, 1 Feb 2007 16:34:10 +0100 Subject: [AVR32] Add basic HMATRIX support This adds register and clock definitions for the High-speed bus Matrix (HMATRIX) as well as a function that can be used to configure special EBI functionality like CompactFlash and NAND flash support. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/at32ap7000.c | 38 ++++++++ arch/avr32/mach-at32ap/hmatrix.h | 182 ++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 arch/avr32/mach-at32ap/hmatrix.h (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 472703f90c2..32c7045141c 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -18,6 +18,7 @@ #include #include "clock.h" +#include "hmatrix.h" #include "pio.h" #include "sm.h" @@ -466,6 +467,42 @@ static struct clk pico_clk = { .users = 1, }; +/* -------------------------------------------------------------------- + * HMATRIX + * -------------------------------------------------------------------- */ + +static struct clk hmatrix_clk = { + .name = "hmatrix_clk", + .parent = &pbb_clk, + .mode = pbb_clk_mode, + .get_rate = pbb_clk_get_rate, + .index = 2, + .users = 1, +}; +#define HMATRIX_BASE ((void __iomem *)0xfff00800) + +#define hmatrix_readl(reg) \ + __raw_readl((HMATRIX_BASE) + HMATRIX_##reg) +#define hmatrix_writel(reg,value) \ + __raw_writel((value), (HMATRIX_BASE) + HMATRIX_##reg) + +/* + * Set bits in the HMATRIX Special Function Register (SFR) used by the + * External Bus Interface (EBI). This can be used to enable special + * features like CompactFlash support, NAND Flash support, etc. on + * certain chipselects. + */ +static inline void set_ebi_sfr_bits(u32 mask) +{ + u32 sfr; + + clk_enable(&hmatrix_clk); + sfr = hmatrix_readl(SFR4); + sfr |= mask; + hmatrix_writel(SFR4, sfr); + clk_disable(&hmatrix_clk); +} + /* -------------------------------------------------------------------- * PIO * -------------------------------------------------------------------- */ @@ -950,6 +987,7 @@ struct clk *at32_clock_list[] = { &pbb_clk, &at32_sm_pclk, &at32_intc0_pclk, + &hmatrix_clk, &ebi_clk, &hramc_clk, &smc0_pclk, diff --git a/arch/avr32/mach-at32ap/hmatrix.h b/arch/avr32/mach-at32ap/hmatrix.h new file mode 100644 index 00000000000..d10bfb60d68 --- /dev/null +++ b/arch/avr32/mach-at32ap/hmatrix.h @@ -0,0 +1,182 @@ +/* + * Register definitions for High-Speed Bus Matrix + */ +#ifndef __HMATRIX_H +#define __HMATRIX_H + +/* HMATRIX register offsets */ +#define HMATRIX_MCFG0 0x0000 +#define HMATRIX_MCFG1 0x0004 +#define HMATRIX_MCFG2 0x0008 +#define HMATRIX_MCFG3 0x000c +#define HMATRIX_MCFG4 0x0010 +#define HMATRIX_MCFG5 0x0014 +#define HMATRIX_MCFG6 0x0018 +#define HMATRIX_MCFG7 0x001c +#define HMATRIX_MCFG8 0x0020 +#define HMATRIX_MCFG9 0x0024 +#define HMATRIX_MCFG10 0x0028 +#define HMATRIX_MCFG11 0x002c +#define HMATRIX_MCFG12 0x0030 +#define HMATRIX_MCFG13 0x0034 +#define HMATRIX_MCFG14 0x0038 +#define HMATRIX_MCFG15 0x003c +#define HMATRIX_SCFG0 0x0040 +#define HMATRIX_SCFG1 0x0044 +#define HMATRIX_SCFG2 0x0048 +#define HMATRIX_SCFG3 0x004c +#define HMATRIX_SCFG4 0x0050 +#define HMATRIX_SCFG5 0x0054 +#define HMATRIX_SCFG6 0x0058 +#define HMATRIX_SCFG7 0x005c +#define HMATRIX_SCFG8 0x0060 +#define HMATRIX_SCFG9 0x0064 +#define HMATRIX_SCFG10 0x0068 +#define HMATRIX_SCFG11 0x006c +#define HMATRIX_SCFG12 0x0070 +#define HMATRIX_SCFG13 0x0074 +#define HMATRIX_SCFG14 0x0078 +#define HMATRIX_SCFG15 0x007c +#define HMATRIX_PRAS0 0x0080 +#define HMATRIX_PRBS0 0x0084 +#define HMATRIX_PRAS1 0x0088 +#define HMATRIX_PRBS1 0x008c +#define HMATRIX_PRAS2 0x0090 +#define HMATRIX_PRBS2 0x0094 +#define HMATRIX_PRAS3 0x0098 +#define HMATRIX_PRBS3 0x009c +#define HMATRIX_PRAS4 0x00a0 +#define HMATRIX_PRBS4 0x00a4 +#define HMATRIX_PRAS5 0x00a8 +#define HMATRIX_PRBS5 0x00ac +#define HMATRIX_PRAS6 0x00b0 +#define HMATRIX_PRBS6 0x00b4 +#define HMATRIX_PRAS7 0x00b8 +#define HMATRIX_PRBS7 0x00bc +#define HMATRIX_PRAS8 0x00c0 +#define HMATRIX_PRBS8 0x00c4 +#define HMATRIX_PRAS9 0x00c8 +#define HMATRIX_PRBS9 0x00cc +#define HMATRIX_PRAS10 0x00d0 +#define HMATRIX_PRBS10 0x00d4 +#define HMATRIX_PRAS11 0x00d8 +#define HMATRIX_PRBS11 0x00dc +#define HMATRIX_PRAS12 0x00e0 +#define HMATRIX_PRBS12 0x00e4 +#define HMATRIX_PRAS13 0x00e8 +#define HMATRIX_PRBS13 0x00ec +#define HMATRIX_PRAS14 0x00f0 +#define HMATRIX_PRBS14 0x00f4 +#define HMATRIX_PRAS15 0x00f8 +#define HMATRIX_PRBS15 0x00fc +#define HMATRIX_MRCR 0x0100 +#define HMATRIX_SFR0 0x0110 +#define HMATRIX_SFR1 0x0114 +#define HMATRIX_SFR2 0x0118 +#define HMATRIX_SFR3 0x011c +#define HMATRIX_SFR4 0x0120 +#define HMATRIX_SFR5 0x0124 +#define HMATRIX_SFR6 0x0128 +#define HMATRIX_SFR7 0x012c +#define HMATRIX_SFR8 0x0130 +#define HMATRIX_SFR9 0x0134 +#define HMATRIX_SFR10 0x0138 +#define HMATRIX_SFR11 0x013c +#define HMATRIX_SFR12 0x0140 +#define HMATRIX_SFR13 0x0144 +#define HMATRIX_SFR14 0x0148 +#define HMATRIX_SFR15 0x014c + +/* Bitfields in MCFGx */ +#define HMATRIX_ULBT_OFFSET 0 +#define HMATRIX_ULBT_SIZE 3 + +/* Bitfields in SCFGx */ +#define HMATRIX_SLOT_CYCLE_OFFSET 0 +#define HMATRIX_SLOT_CYCLE_SIZE 8 +#define HMATRIX_DEFMSTR_TYPE_OFFSET 16 +#define HMATRIX_DEFMSTR_TYPE_SIZE 2 +#define HMATRIX_FIXED_DEFMSTR_OFFSET 18 +#define HMATRIX_FIXED_DEFMSTR_SIZE 4 +#define HMATRIX_ARBT_OFFSET 24 +#define HMATRIX_ARBT_SIZE 2 + +/* Bitfields in PRASx */ +#define HMATRIX_M0PR_OFFSET 0 +#define HMATRIX_M0PR_SIZE 4 +#define HMATRIX_M1PR_OFFSET 4 +#define HMATRIX_M1PR_SIZE 4 +#define HMATRIX_M2PR_OFFSET 8 +#define HMATRIX_M2PR_SIZE 4 +#define HMATRIX_M3PR_OFFSET 12 +#define HMATRIX_M3PR_SIZE 4 +#define HMATRIX_M4PR_OFFSET 16 +#define HMATRIX_M4PR_SIZE 4 +#define HMATRIX_M5PR_OFFSET 20 +#define HMATRIX_M5PR_SIZE 4 +#define HMATRIX_M6PR_OFFSET 24 +#define HMATRIX_M6PR_SIZE 4 +#define HMATRIX_M7PR_OFFSET 28 +#define HMATRIX_M7PR_SIZE 4 + +/* Bitfields in PRBSx */ +#define HMATRIX_M8PR_OFFSET 0 +#define HMATRIX_M8PR_SIZE 4 +#define HMATRIX_M9PR_OFFSET 4 +#define HMATRIX_M9PR_SIZE 4 +#define HMATRIX_M10PR_OFFSET 8 +#define HMATRIX_M10PR_SIZE 4 +#define HMATRIX_M11PR_OFFSET 12 +#define HMATRIX_M11PR_SIZE 4 +#define HMATRIX_M12PR_OFFSET 16 +#define HMATRIX_M12PR_SIZE 4 +#define HMATRIX_M13PR_OFFSET 20 +#define HMATRIX_M13PR_SIZE 4 +#define HMATRIX_M14PR_OFFSET 24 +#define HMATRIX_M14PR_SIZE 4 +#define HMATRIX_M15PR_OFFSET 28 +#define HMATRIX_M15PR_SIZE 4 + +/* Bitfields in SFR4 */ +#define HMATRIX_CS1A_OFFSET 1 +#define HMATRIX_CS1A_SIZE 1 +#define HMATRIX_CS3A_OFFSET 3 +#define HMATRIX_CS3A_SIZE 1 +#define HMATRIX_CS4A_OFFSET 4 +#define HMATRIX_CS4A_SIZE 1 +#define HMATRIX_CS5A_OFFSET 5 +#define HMATRIX_CS5A_SIZE 1 +#define HMATRIX_DBPUC_OFFSET 8 +#define HMATRIX_DBPUC_SIZE 1 + +/* Constants for ULBT */ +#define HMATRIX_ULBT_INFINITE 0 +#define HMATRIX_ULBT_SINGLE 1 +#define HMATRIX_ULBT_FOUR_BEAT 2 +#define HMATRIX_ULBT_EIGHT_BEAT 3 +#define HMATRIX_ULBT_SIXTEEN_BEAT 4 + +/* Constants for DEFMSTR_TYPE */ +#define HMATRIX_DEFMSTR_TYPE_NO_DEFAULT 0 +#define HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT 1 +#define HMATRIX_DEFMSTR_TYPE_FIXED_DEFAULT 2 + +/* Constants for ARBT */ +#define HMATRIX_ARBT_ROUND_ROBIN 0 +#define HMATRIX_ARBT_FIXED_PRIORITY 1 + +/* Bit manipulation macros */ +#define HMATRIX_BIT(name) \ + (1 << HMATRIX_##name##_OFFSET) +#define HMATRIX_BF(name,value) \ + (((value) & ((1 << HMATRIX_##name##_SIZE) - 1)) \ + << HMATRIX_##name##_OFFSET) +#define HMATRIX_BFEXT(name,value) \ + (((value) >> HMATRIX_##name##_OFFSET) \ + & ((1 << HMATRIX_##name##_SIZE) - 1)) +#define HMATRIX_BFINS(name,value,old) \ + (((old) & ~(((1 << HMATRIX_##name##_SIZE) - 1) \ + << HMATRIX_##name##_OFFSET)) \ + | HMATRIX_BF(name,value)) + +#endif /* __HMATRIX_H */ -- cgit v1.2.3 From 068d9f6eb9369a00eb45be91c07653cfef65f4a0 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Wed, 31 Jan 2007 18:01:45 +0100 Subject: [AVR32] Add nwait and tdf parameters to SMC configuration Complete the SMC configuration code by adding nwait and tdf parameter. After this change, we support the same parameters as the hardware. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/hsmc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/hsmc.c b/arch/avr32/mach-at32ap/hsmc.c index 7691721928a..5e22a750632 100644 --- a/arch/avr32/mach-at32ap/hsmc.c +++ b/arch/avr32/mach-at32ap/hsmc.c @@ -75,12 +75,35 @@ int smc_set_configuration(int cs, const struct smc_config *config) return -EINVAL; } + switch (config->nwait_mode) { + case 0: + mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_DISABLED); + break; + case 1: + mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_RESERVED); + break; + case 2: + mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_FROZEN); + break; + case 3: + mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_READY); + break; + default: + return -EINVAL; + } + + if (config->tdf_cycles) { + mode |= HSMC_BF(TDF_CYCLES, config->tdf_cycles); + } + if (config->nrd_controlled) mode |= HSMC_BIT(READ_MODE); if (config->nwe_controlled) mode |= HSMC_BIT(WRITE_MODE); if (config->byte_write) mode |= HSMC_BIT(BAT); + if (config->tdf_mode) + mode |= HSMC_BIT(TDF_MODE); pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n", cs, setup, pulse, cycle, mode); -- cgit v1.2.3 From 228e845fd243bf42033998afab792357444e9e4a Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 7 Mar 2007 15:24:34 +0100 Subject: [AVR32] Add mach-specific Kconfig Include at32ap-specific Kconfig file from top-level Kconfig file. The at32ap Kconfig is currently empty, but it will grow some machine- specific options soon. Signed-off-by: Haavard Skinnemoen --- arch/avr32/Kconfig | 2 ++ arch/avr32/mach-at32ap/Kconfig | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 arch/avr32/mach-at32ap/Kconfig (limited to 'arch') diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index ce4013aee59..257b83648cb 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -116,6 +116,8 @@ config LOADER_U_BOOT bool "U-Boot (or similar) bootloader" endchoice +source "arch/avr32/mach-at32ap/Kconfig" + config LOAD_ADDRESS hex default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y diff --git a/arch/avr32/mach-at32ap/Kconfig b/arch/avr32/mach-at32ap/Kconfig new file mode 100644 index 00000000000..d7497715cc0 --- /dev/null +++ b/arch/avr32/mach-at32ap/Kconfig @@ -0,0 +1,7 @@ +if PLATFORM_AT32AP + +menu "Atmel AVR32 AP options" + +endmenu + +endif -- cgit v1.2.3 From 7760989e5e2900e484e9115e6e690c6ce0b0221c Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Mon, 12 Mar 2007 18:15:16 +0100 Subject: [AVR32] Change system timer from count-compare to Timer/Counter 0 Due to limitation of the count-compare system timer (not able to count when CPU is in sleep), the system timer had to be changed to use a peripheral timer/counter. The old COUNT-COMPARE code is still present in time.c as weak functions. The new timer is added to the architecture directory. This patch sets up TC0 as system timer The new timer has been tested on AT32AP7000/ATSTK1000 at 100 Hz, 250 Hz, 300 Hz and 1000 Hz. For more details about the timer/counter see the datasheet for AT32AP700x available at http://www.atmel.com/dyn/products/product_card.asp?part_id=3903 Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/time.c | 150 +++++++++++++------------ arch/avr32/mach-at32ap/Makefile | 1 + arch/avr32/mach-at32ap/at32ap7000.c | 18 +++ arch/avr32/mach-at32ap/time-tc.c | 217 ++++++++++++++++++++++++++++++++++++ 4 files changed, 313 insertions(+), 73 deletions(-) create mode 100644 arch/avr32/mach-at32ap/time-tc.c (limited to 'arch') diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index c10833f2ee0..7014a3571ec 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Atmel Corporation + * Copyright (C) 2004-2007 Atmel Corporation * * Based on MIPS implementation arch/mips/kernel/time.c * Copyright 2001 MontaVista Software Inc. @@ -20,18 +20,25 @@ #include #include #include +#include #include #include #include #include -static cycle_t read_cycle_count(void) +/* how many counter cycles in a jiffy? */ +static u32 cycles_per_jiffy; + +/* the count value for the next timer interrupt */ +static u32 expirelo; + +cycle_t __weak read_cycle_count(void) { return (cycle_t)sysreg_read(COUNT); } -static struct clocksource clocksource_avr32 = { +struct clocksource __weak clocksource_avr32 = { .name = "avr32", .rating = 350, .read = read_cycle_count, @@ -40,12 +47,20 @@ static struct clocksource clocksource_avr32 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +irqreturn_t __weak timer_interrupt(int irq, void *dev_id); + +struct irqaction timer_irqaction = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED, + .name = "timer", +}; + /* * By default we provide the null RTC ops */ static unsigned long null_rtc_get_time(void) { - return mktime(2004, 1, 1, 0, 0, 0); + return mktime(2007, 1, 1, 0, 0, 0); } static int null_rtc_set_time(unsigned long sec) @@ -56,23 +71,14 @@ static int null_rtc_set_time(unsigned long sec) static unsigned long (*rtc_get_time)(void) = null_rtc_get_time; static int (*rtc_set_time)(unsigned long) = null_rtc_set_time; -/* how many counter cycles in a jiffy? */ -static unsigned long cycles_per_jiffy; - -/* cycle counter value at the previous timer interrupt */ -static unsigned int timerhi, timerlo; - -/* the count value for the next timer interrupt */ -static unsigned int expirelo; - static void avr32_timer_ack(void) { - unsigned int count; + u32 count; /* Ack this timer interrupt and set the next one */ expirelo += cycles_per_jiffy; + /* setting COMPARE to 0 stops the COUNT-COMPARE */ if (expirelo == 0) { - printk(KERN_DEBUG "expirelo == 0\n"); sysreg_write(COMPARE, expirelo + 1); } else { sysreg_write(COMPARE, expirelo); @@ -86,27 +92,56 @@ static void avr32_timer_ack(void) } } -static unsigned int avr32_hpt_read(void) +int __weak avr32_hpt_init(void) { - return sysreg_read(COUNT); + int ret; + unsigned long mult, shift, count_hz; + + count_hz = clk_get_rate(boot_cpu_data.clk); + shift = clocksource_avr32.shift; + mult = clocksource_hz2mult(count_hz, shift); + clocksource_avr32.mult = mult; + + { + u64 tmp; + + tmp = TICK_NSEC; + tmp <<= shift; + tmp += mult / 2; + do_div(tmp, mult); + + cycles_per_jiffy = tmp; + } + + ret = setup_irq(0, &timer_irqaction); + if (ret) { + pr_debug("timer: could not request IRQ 0: %d\n", ret); + return -ENODEV; + } + + printk(KERN_INFO "timer: AT32AP COUNT-COMPARE at irq 0, " + "%lu.%03lu MHz\n", + ((count_hz + 500) / 1000) / 1000, + ((count_hz + 500) / 1000) % 1000); + + return 0; } /* * Taken from MIPS c0_hpt_timer_init(). * - * Why is it so complicated, and what is "count"? My assumption is - * that `count' specifies the "reference cycle", i.e. the cycle since - * reset that should mean "zero". The reason COUNT is written twice is - * probably to make sure we don't get any timer interrupts while we - * are messing with the counter. + * The reason COUNT is written twice is probably to make sure we don't get any + * timer interrupts while we are messing with the counter. */ -static void avr32_hpt_init(unsigned int count) +int __weak avr32_hpt_start(void) { - count = sysreg_read(COUNT) - count; + u32 count = sysreg_read(COUNT); expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; sysreg_write(COUNT, expirelo - cycles_per_jiffy); sysreg_write(COMPARE, expirelo); sysreg_write(COUNT, count); + + return 0; } /* @@ -115,26 +150,18 @@ static void avr32_hpt_init(unsigned int count) * * In UP mode, it is invoked from the (global) timer_interrupt. */ -static void local_timer_interrupt(int irq, void *dev_id) +void local_timer_interrupt(int irq, void *dev_id) { if (current->pid) profile_tick(CPU_PROFILING); update_process_times(user_mode(get_irq_regs())); } -static irqreturn_t -timer_interrupt(int irq, void *dev_id) +irqreturn_t __weak timer_interrupt(int irq, void *dev_id) { - unsigned int count; - /* ack timer interrupt and try to set next interrupt */ - count = avr32_hpt_read(); avr32_timer_ack(); - /* Update timerhi/timerlo for intra-jiffy calibration */ - timerhi += count < timerlo; /* Wrap around */ - timerlo = count; - /* * Call the generic timer interrupt handler */ @@ -153,60 +180,37 @@ timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction timer_irqaction = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED, - .name = "timer", -}; - void __init time_init(void) { - unsigned long mult, shift, count_hz; int ret; + /* + * Make sure we don't get any COMPARE interrupts before we can + * handle them. + */ + sysreg_write(COMPARE, 0); + xtime.tv_sec = rtc_get_time(); xtime.tv_nsec = 0; set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); - printk("Before time_init: count=%08lx, compare=%08lx\n", - (unsigned long)sysreg_read(COUNT), - (unsigned long)sysreg_read(COMPARE)); - - count_hz = clk_get_rate(boot_cpu_data.clk); - shift = clocksource_avr32.shift; - mult = clocksource_hz2mult(count_hz, shift); - clocksource_avr32.mult = mult; - - printk("Cycle counter: mult=%lu, shift=%lu\n", mult, shift); - - { - u64 tmp; - - tmp = TICK_NSEC; - tmp <<= shift; - tmp += mult / 2; - do_div(tmp, mult); - - cycles_per_jiffy = tmp; + ret = avr32_hpt_init(); + if (ret) { + pr_debug("timer: failed setup: %d\n", ret); + return; } - /* This sets up the high precision timer for the first interrupt. */ - avr32_hpt_init(avr32_hpt_read()); - - printk("After time_init: count=%08lx, compare=%08lx\n", - (unsigned long)sysreg_read(COUNT), - (unsigned long)sysreg_read(COMPARE)); - ret = clocksource_register(&clocksource_avr32); if (ret) - printk(KERN_ERR - "timer: could not register clocksource: %d\n", ret); + pr_debug("timer: could not register clocksource: %d\n", ret); - ret = setup_irq(0, &timer_irqaction); - if (ret) - printk("timer: could not request IRQ 0: %d\n", ret); + ret = avr32_hpt_start(); + if (ret) { + pr_debug("timer: failed starting: %d\n", ret); + return; + } } static struct sysdev_class timer_class = { diff --git a/arch/avr32/mach-at32ap/Makefile b/arch/avr32/mach-at32ap/Makefile index b21bea9af8b..f1d395724ac 100644 --- a/arch/avr32/mach-at32ap/Makefile +++ b/arch/avr32/mach-at32ap/Makefile @@ -1,2 +1,3 @@ obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o +obj-$(CONFIG_CPU_AT32AP7000) += time-tc.o diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 32c7045141c..6eeda60b828 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -503,6 +503,21 @@ static inline void set_ebi_sfr_bits(u32 mask) clk_disable(&hmatrix_clk); } +/* -------------------------------------------------------------------- + * System Timer/Counter (TC) + * -------------------------------------------------------------------- */ +static struct resource at32_systc0_resource[] = { + PBMEM(0xfff00c00), + IRQ(22), +}; +struct platform_device at32_systc0_device = { + .name = "systc", + .id = 0, + .resource = at32_systc0_resource, + .num_resources = ARRAY_SIZE(at32_systc0_resource), +}; +DEV_CLK(pclk, at32_systc0, pbb, 3); + /* -------------------------------------------------------------------- * PIO * -------------------------------------------------------------------- */ @@ -551,6 +566,8 @@ void __init at32_add_system_devices(void) platform_device_register(&smc0_device); platform_device_register(&pdc_device); + platform_device_register(&at32_systc0_device); + platform_device_register(&pio0_device); platform_device_register(&pio1_device); platform_device_register(&pio2_device); @@ -1000,6 +1017,7 @@ struct clk *at32_clock_list[] = { &pio2_mck, &pio3_mck, &pio4_mck, + &at32_systc0_pclk, &atmel_usart0_usart, &atmel_usart1_usart, &atmel_usart2_usart, diff --git a/arch/avr32/mach-at32ap/time-tc.c b/arch/avr32/mach-at32ap/time-tc.c new file mode 100644 index 00000000000..7ac0e94d8ed --- /dev/null +++ b/arch/avr32/mach-at32ap/time-tc.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2004-2007 Atmel Corporation + * + * Based on MIPS implementation arch/mips/kernel/time.c + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* how many counter cycles in a jiffy? */ +static u32 cycles_per_jiffy; + +/* the count value for the next timer interrupt */ +static u32 expirelo; + +/* the I/O registers of the TC module */ +static void __iomem *ioregs; + +cycle_t read_cycle_count(void) +{ + return (cycle_t)timer_read(ioregs, 0, CV); +} + +struct clocksource clocksource_avr32 = { + .name = "avr32", + .rating = 342, + .read = read_cycle_count, + .mask = CLOCKSOURCE_MASK(16), + .shift = 16, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void avr32_timer_ack(void) +{ + u16 count = expirelo; + + /* Ack this timer interrupt and set the next one, use a u16 + * variable so it will wrap around correctly */ + count += cycles_per_jiffy; + expirelo = count; + timer_write(ioregs, 0, RC, expirelo); + + /* Check to see if we have missed any timer interrupts */ + count = timer_read(ioregs, 0, CV); + if ((count - expirelo) < 0x7fff) { + expirelo = count + cycles_per_jiffy; + timer_write(ioregs, 0, RC, expirelo); + } +} + +u32 avr32_hpt_read(void) +{ + return timer_read(ioregs, 0, CV); +} + +static int avr32_timer_calc_div_and_set_jiffies(struct clk *pclk) +{ + unsigned int cycles_max = (clocksource_avr32.mask + 1) / 2; + unsigned int divs[] = { 4, 8, 16, 32 }; + int divs_size = sizeof(divs) / sizeof(*divs); + int i = 0; + unsigned long count_hz; + unsigned long shift; + unsigned long mult; + int clock_div = -1; + u64 tmp; + + shift = clocksource_avr32.shift; + + do { + count_hz = clk_get_rate(pclk) / divs[i]; + mult = clocksource_hz2mult(count_hz, shift); + clocksource_avr32.mult = mult; + + tmp = TICK_NSEC; + tmp <<= shift; + tmp += mult / 2; + do_div(tmp, mult); + + cycles_per_jiffy = tmp; + } while (cycles_per_jiffy > cycles_max && ++i < divs_size); + + clock_div = i + 1; + + if (clock_div > divs_size) { + pr_debug("timer: could not calculate clock divider\n"); + return -EFAULT; + } + + /* Set the clock divider */ + timer_write(ioregs, 0, CMR, TIMER_BF(CMR_TCCLKS, clock_div)); + + return 0; +} + +int avr32_hpt_init(unsigned int count) +{ + struct resource *regs; + struct clk *pclk; + int irq = -1; + int ret = 0; + + ret = -ENXIO; + + irq = platform_get_irq(&at32_systc0_device, 0); + if (irq < 0) { + pr_debug("timer: could not get irq\n"); + goto out_error; + } + + pclk = clk_get(&at32_systc0_device.dev, "pclk"); + if (IS_ERR(pclk)) { + pr_debug("timer: could not get clk: %ld\n", PTR_ERR(pclk)); + goto out_error; + } + + regs = platform_get_resource(&at32_systc0_device, IORESOURCE_MEM, 0); + if (!regs) { + pr_debug("timer: could not get resource\n"); + goto out_error_clk; + } + + ioregs = ioremap(regs->start, regs->end - regs->start + 1); + if (!ioregs) { + pr_debug("timer: could not get ioregs\n"); + goto out_error_clk; + } + + ret = avr32_timer_calc_div_and_set_jiffies(pclk); + if (ret) + goto out_error_io; + + ret = setup_irq(irq, &timer_irqaction); + if (ret) { + pr_debug("timer: could not request irq %d: %d\n", + irq, ret); + goto out_error_io; + } + + expirelo = (timer_read(ioregs, 0, CV) / cycles_per_jiffy + 1) + * cycles_per_jiffy; + + /* Enable clock and interrupts on RC compare */ + timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_CLKEN)); + timer_write(ioregs, 0, IER, TIMER_BIT(IER_CPCS)); + /* Set cycles to first interrupt */ + timer_write(ioregs, 0, RC, expirelo); + + printk(KERN_INFO "timer: AT32AP system timer/counter at 0x%p irq %d\n", + ioregs, irq); + + return 0; + +out_error_io: + iounmap(ioregs); +out_error_clk: + clk_put(pclk); +out_error: + return ret; +} + +int avr32_hpt_start(void) +{ + timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_SWTRG)); + return 0; +} + +irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + unsigned int sr = timer_read(ioregs, 0, SR); + + if (sr & TIMER_BIT(SR_CPCS)) { + /* ack timer interrupt and try to set next interrupt */ + avr32_timer_ack(); + + /* + * Call the generic timer interrupt handler + */ + write_seqlock(&xtime_lock); + do_timer(1); + write_sequnlock(&xtime_lock); + + /* + * In UP mode, we call local_timer_interrupt() to do profiling + * and process accounting. + * + * SMP is not supported yet. + */ + local_timer_interrupt(irq, dev_id); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} -- cgit v1.2.3 From 19b7ce8bad718a2850ea19aeb7383f1728596c24 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Mon, 26 Feb 2007 13:50:43 +0100 Subject: [AVR32] Put cpu in sleep 0 when idle. This patch puts the CPU in sleep 0 when doing nothing, idle. This will turn of the CPU clock and thus save power. The CPU is waken again when an interrupt occurs. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/entry-avr32b.S | 42 +++++++++++++++++++++++++++++++++++----- arch/avr32/kernel/process.c | 5 +++-- 2 files changed, 40 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index eeb66792bc3..5f5f7e42f51 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S @@ -630,9 +630,12 @@ irq_level\level: rcall do_IRQ lddsp r4, sp[REG_SR] - andh r4, (MODE_MASK >> 16), COH + bfextu r4, r4, SYSREG_M0_OFFSET, 3 + cp.w r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET + breq 2f + cp.w r4, MODE_USER >> SYSREG_M0_OFFSET #ifdef CONFIG_PREEMPT - brne 2f + brne 3f #else brne 1f #endif @@ -649,9 +652,18 @@ irq_level\level: sub sp, -4 /* ignore r12_orig */ rete +2: get_thread_info r0 + ld.w r1, r0[TI_flags] + bld r1, TIF_CPU_GOING_TO_SLEEP #ifdef CONFIG_PREEMPT -2: - get_thread_info r0 + brcc 3f +#else + brcc 1b +#endif + sub r1, pc, . - cpu_idle_skip_sleep + stdsp sp[REG_PC], r1 +#ifdef CONFIG_PREEMPT +3: get_thread_info r0 ld.w r2, r0[TI_preempt_count] cp.w r2, 0 brne 1b @@ -662,12 +674,32 @@ irq_level\level: bld r4, SYSREG_GM_OFFSET brcs 1b rcall preempt_schedule_irq - rjmp 1b #endif + rjmp 1b .endm .section .irq.text,"ax",@progbits +.global cpu_idle_sleep +cpu_idle_sleep: + mask_interrupts + get_thread_info r8 + ld.w r9, r8[TI_flags] + bld r9, TIF_NEED_RESCHED + brcs cpu_idle_enable_int_and_exit + sbr r9, TIF_CPU_GOING_TO_SLEEP + st.w r8[TI_flags], r9 + unmask_interrupts + sleep 0 +cpu_idle_skip_sleep: + mask_interrupts + ld.w r9, r8[TI_flags] + cbr r9, TIF_CPU_GOING_TO_SLEEP + st.w r8[TI_flags], r9 +cpu_idle_enable_int_and_exit: + unmask_interrupts + retal r12 + .global irq_level0 .global irq_level1 .global irq_level2 diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 0b4325946a4..4f8d2d47474 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -19,6 +19,8 @@ void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); +extern void cpu_idle_sleep(void); + /* * This file handles the architecture-dependent parts of process handling.. */ @@ -27,9 +29,8 @@ void cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { - /* TODO: Enter sleep mode */ while (!need_resched()) - cpu_relax(); + cpu_idle_sleep(); preempt_enable_no_resched(); schedule(); preempt_disable(); -- cgit v1.2.3 From 188ff65d49dadf7b0e9b6718abc3fe98a5098711 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 14 Mar 2007 13:23:44 +0100 Subject: [AVR32] Don't enable clocks with no users Bring the code that sets the initial PM clock masks in line with the comment preceding it by only enabling clocks that have users != 0. Fix SM clock definition and avr32_hpt_init() so that the SM and TC0 clocks keep ticking. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/at32ap7000.c | 14 +++++++++++++- arch/avr32/mach-at32ap/time-tc.c | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 6eeda60b828..56db45b99a0 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -417,7 +417,15 @@ struct platform_device at32_sm_device = { .resource = sm_resource, .num_resources = ARRAY_SIZE(sm_resource), }; -DEV_CLK(pclk, at32_sm, pbb, 0); +static struct clk at32_sm_pclk = { + .name = "pclk", + .dev = &at32_sm_device.dev, + .parent = &pbb_clk, + .mode = pbb_clk_mode, + .get_rate = pbb_clk_get_rate, + .users = 1, + .index = 0, +}; static struct resource intc0_resource[] = { PBMEM(0xfff00400), @@ -443,6 +451,7 @@ static struct clk hramc_clk = { .mode = hsb_clk_mode, .get_rate = hsb_clk_get_rate, .users = 1, + .index = 3, }; static struct resource smc0_resource[] = { @@ -1080,6 +1089,9 @@ void __init at32_clock_init(void) for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) { struct clk *clk = at32_clock_list[i]; + if (clk->users == 0) + continue; + if (clk->mode == &cpu_clk_mode) cpu_mask |= 1 << clk->index; else if (clk->mode == &hsb_clk_mode) diff --git a/arch/avr32/mach-at32ap/time-tc.c b/arch/avr32/mach-at32ap/time-tc.c index 7ac0e94d8ed..e3070bdd4bb 100644 --- a/arch/avr32/mach-at32ap/time-tc.c +++ b/arch/avr32/mach-at32ap/time-tc.c @@ -135,6 +135,7 @@ int avr32_hpt_init(unsigned int count) pr_debug("timer: could not get clk: %ld\n", PTR_ERR(pclk)); goto out_error; } + clk_enable(pclk); regs = platform_get_resource(&at32_systc0_device, IORESOURCE_MEM, 0); if (!regs) { -- cgit v1.2.3 From 3b328c98093702c584692bffabd440800b383d73 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 13 Mar 2007 15:30:38 +0100 Subject: [AVR32] Clean up cpu identification and add features bitmap Clean up the cpu identification code, using definitions from instead of hardcoded constants. Also, add a features bitmap to struct avr32_cpuinfo to allow other code to make decisions based upon what the running cpu is actually capable of. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/cpu.c | 64 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c index 2e72fd2699d..2714cf6452b 100644 --- a/arch/avr32/kernel/cpu.c +++ b/arch/avr32/kernel/cpu.c @@ -209,16 +209,17 @@ static const char *mmu_types[] = { void __init setup_processor(void) { unsigned long config0, config1; + unsigned long features; unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type; unsigned tmp; - config0 = sysreg_read(CONFIG0); /* 0x0000013e; */ - config1 = sysreg_read(CONFIG1); /* 0x01f689a2; */ - cpu_id = config0 >> 24; - cpu_rev = (config0 >> 16) & 0xff; - arch_id = (config0 >> 13) & 0x07; - arch_rev = (config0 >> 10) & 0x07; - mmu_type = (config0 >> 7) & 0x03; + config0 = sysreg_read(CONFIG0); + config1 = sysreg_read(CONFIG1); + cpu_id = SYSREG_BFEXT(PROCESSORID, config0); + cpu_rev = SYSREG_BFEXT(PROCESSORREVISION, config0); + arch_id = SYSREG_BFEXT(AT, config0); + arch_rev = SYSREG_BFEXT(AR, config0); + mmu_type = SYSREG_BFEXT(MMUT, config0); boot_cpu_data.arch_type = arch_id; boot_cpu_data.cpu_type = cpu_id; @@ -226,16 +227,16 @@ void __init setup_processor(void) boot_cpu_data.cpu_revision = cpu_rev; boot_cpu_data.tlb_config = mmu_type; - tmp = (config1 >> 13) & 0x07; + tmp = SYSREG_BFEXT(ILSZ, config1); if (tmp) { - boot_cpu_data.icache.ways = 1 << ((config1 >> 10) & 0x07); - boot_cpu_data.icache.sets = 1 << ((config1 >> 16) & 0x0f); + boot_cpu_data.icache.ways = 1 << SYSREG_BFEXT(IASS, config1); + boot_cpu_data.icache.sets = 1 << SYSREG_BFEXT(ISET, config1); boot_cpu_data.icache.linesz = 1 << (tmp + 1); } - tmp = (config1 >> 3) & 0x07; + tmp = SYSREG_BFEXT(DLSZ, config1); if (tmp) { - boot_cpu_data.dcache.ways = 1 << (config1 & 0x07); - boot_cpu_data.dcache.sets = 1 << ((config1 >> 6) & 0x0f); + boot_cpu_data.dcache.ways = 1 << SYSREG_BFEXT(DASS, config1); + boot_cpu_data.dcache.sets = 1 << SYSREG_BFEXT(DSET, config1); boot_cpu_data.dcache.linesz = 1 << (tmp + 1); } @@ -250,16 +251,39 @@ void __init setup_processor(void) cpu_names[cpu_id], cpu_id, cpu_rev, arch_names[arch_id], arch_rev); printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]); + printk ("CPU: features:"); - if (config0 & (1 << 6)) - printk(" fpu"); - if (config0 & (1 << 5)) - printk(" java"); - if (config0 & (1 << 4)) - printk(" perfctr"); - if (config0 & (1 << 3)) + features = 0; + if (config0 & SYSREG_BIT(CONFIG0_R)) { + features |= AVR32_FEATURE_RMW; + printk(" rmw"); + } + if (config0 & SYSREG_BIT(CONFIG0_D)) { + features |= AVR32_FEATURE_DSP; + printk(" dsp"); + } + if (config0 & SYSREG_BIT(CONFIG0_S)) { + features |= AVR32_FEATURE_SIMD; + printk(" simd"); + } + if (config0 & SYSREG_BIT(CONFIG0_O)) { + features |= AVR32_FEATURE_OCD; printk(" ocd"); + } + if (config0 & SYSREG_BIT(CONFIG0_P)) { + features |= AVR32_FEATURE_PCTR; + printk(" perfctr"); + } + if (config0 & SYSREG_BIT(CONFIG0_J)) { + features |= AVR32_FEATURE_JAVA; + printk(" java"); + } + if (config0 & SYSREG_BIT(CONFIG0_F)) { + features |= AVR32_FEATURE_FPU; + printk(" fpu"); + } printk("\n"); + boot_cpu_data.features = features; } #ifdef CONFIG_PROC_FS -- cgit v1.2.3 From 623b0355d5b1f9c6d05005b649a2f3a7b9fd7816 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 13 Mar 2007 17:59:11 +0100 Subject: [AVR32] Clean up exception handling code * Use generic BUG() handling * Remove some useless debug statements * Use a common function _exception() to send signals or oops when an exception can't be handled. This makes sure init doesn't enter an infinite exception loop as well. Borrowed from powerpc. * Add some basic exception tracing support to the page fault code. * Rework dump_stack(), show_regs() and friends and move everything into process.c * Print information about configuration options and chip type when oopsing Signed-off-by: Haavard Skinnemoen --- arch/avr32/Kconfig | 5 + arch/avr32/kernel/module.c | 11 +- arch/avr32/kernel/process.c | 188 ++++++++++++++++-- arch/avr32/kernel/traps.c | 421 ++++++++++++---------------------------- arch/avr32/kernel/vmlinux.lds.c | 9 +- arch/avr32/mm/fault.c | 116 ++++------- 6 files changed, 357 insertions(+), 393 deletions(-) (limited to 'arch') diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 257b83648cb..7a1eb445c17 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -68,6 +68,11 @@ config GENERIC_CALIBRATE_DELAY bool default y +config GENERIC_BUG + bool + default y + depends on BUG + source "init/Kconfig" menu "System Type and features" diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c index b599eae6457..1167fe9cf6c 100644 --- a/arch/avr32/kernel/module.c +++ b/arch/avr32/kernel/module.c @@ -12,10 +12,11 @@ * published by the Free Software Foundation. */ -#include -#include -#include +#include #include +#include +#include +#include #include void *module_alloc(unsigned long size) @@ -315,10 +316,10 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, vfree(module->arch.syminfo); module->arch.syminfo = NULL; - return 0; + return module_bug_finalize(hdr, sechdrs, module); } void module_arch_cleanup(struct module *module) { - + module_bug_cleanup(module); } diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 4f8d2d47474..4e4181ed1c6 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -115,39 +116,178 @@ void release_thread(struct task_struct *dead_task) /* do nothing */ } +static void dump_mem(const char *str, const char *log_lvl, + unsigned long bottom, unsigned long top) +{ + unsigned long p; + int i; + + printk("%s%s(0x%08lx to 0x%08lx)\n", log_lvl, str, bottom, top); + + for (p = bottom & ~31; p < top; ) { + printk("%s%04lx: ", log_lvl, p & 0xffff); + + for (i = 0; i < 8; i++, p += 4) { + unsigned int val; + + if (p < bottom || p >= top) + printk(" "); + else { + if (__get_user(val, (unsigned int __user *)p)) { + printk("\n"); + goto out; + } + printk("%08x ", val); + } + } + printk("\n"); + } + +out: + return; +} + +static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p) +{ + return (p > (unsigned long)tinfo) + && (p < (unsigned long)tinfo + THREAD_SIZE - 3); +} + +#ifdef CONFIG_FRAME_POINTER +static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp, + struct pt_regs *regs, const char *log_lvl) +{ + unsigned long lr, fp; + struct thread_info *tinfo; + + if (regs) + fp = regs->r7; + else if (tsk == current) + asm("mov %0, r7" : "=r"(fp)); + else + fp = tsk->thread.cpu_context.r7; + + /* + * Walk the stack as long as the frame pointer (a) is within + * the kernel stack of the task, and (b) it doesn't move + * downwards. + */ + tinfo = task_thread_info(tsk); + printk("%sCall trace:\n", log_lvl); + while (valid_stack_ptr(tinfo, fp)) { + unsigned long new_fp; + + lr = *(unsigned long *)fp; +#ifdef CONFIG_KALLSYMS + printk("%s [<%08lx>] ", log_lvl, lr); +#else + printk(" [<%08lx>] ", lr); +#endif + print_symbol("%s\n", lr); + + new_fp = *(unsigned long *)(fp + 4); + if (new_fp <= fp) + break; + fp = new_fp; + } + printk("\n"); +} +#else +static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp, + struct pt_regs *regs, const char *log_lvl) +{ + unsigned long addr; + + printk("%sCall trace:\n", log_lvl); + + while (!kstack_end(sp)) { + addr = *sp++; + if (kernel_text_address(addr)) { +#ifdef CONFIG_KALLSYMS + printk("%s [<%08lx>] ", log_lvl, addr); +#else + printk(" [<%08lx>] ", addr); +#endif + print_symbol("%s\n", addr); + } + } + printk("\n"); +} +#endif + +void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp, + struct pt_regs *regs, const char *log_lvl) +{ + struct thread_info *tinfo; + + if (sp == 0) { + if (tsk) + sp = tsk->thread.cpu_context.ksp; + else + sp = (unsigned long)&tinfo; + } + if (!tsk) + tsk = current; + + tinfo = task_thread_info(tsk); + + if (valid_stack_ptr(tinfo, sp)) { + dump_mem("Stack: ", log_lvl, sp, + THREAD_SIZE + (unsigned long)tinfo); + show_trace_log_lvl(tsk, (unsigned long *)sp, regs, log_lvl); + } +} + +void show_stack(struct task_struct *tsk, unsigned long *stack) +{ + show_stack_log_lvl(tsk, (unsigned long)stack, NULL, ""); +} + +void dump_stack(void) +{ + unsigned long stack; + + show_trace_log_lvl(current, &stack, NULL, ""); +} +EXPORT_SYMBOL(dump_stack); + static const char *cpu_modes[] = { "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1", "Interrupt level 2", "Interrupt level 3", "Exception", "NMI" }; -void show_regs(struct pt_regs *regs) +void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl) { unsigned long sp = regs->sp; unsigned long lr = regs->lr; unsigned long mode = (regs->sr & MODE_MASK) >> MODE_SHIFT; - if (!user_mode(regs)) + if (!user_mode(regs)) { sp = (unsigned long)regs + FRAME_SIZE_FULL; - print_symbol("PC is at %s\n", instruction_pointer(regs)); - print_symbol("LR is at %s\n", lr); - printk("pc : [<%08lx>] lr : [<%08lx>] %s\n" - "sp : %08lx r12: %08lx r11: %08lx\n", - instruction_pointer(regs), - lr, print_tainted(), sp, regs->r12, regs->r11); - printk("r10: %08lx r9 : %08lx r8 : %08lx\n", - regs->r10, regs->r9, regs->r8); - printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", - regs->r7, regs->r6, regs->r5, regs->r4); - printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", - regs->r3, regs->r2, regs->r1, regs->r0); - printk("Flags: %c%c%c%c%c\n", + printk("%s", log_lvl); + print_symbol("PC is at %s\n", instruction_pointer(regs)); + printk("%s", log_lvl); + print_symbol("LR is at %s\n", lr); + } + + printk("%spc : [<%08lx>] lr : [<%08lx>] %s\n" + "%ssp : %08lx r12: %08lx r11: %08lx\n", + log_lvl, instruction_pointer(regs), lr, print_tainted(), + log_lvl, sp, regs->r12, regs->r11); + printk("%sr10: %08lx r9 : %08lx r8 : %08lx\n", + log_lvl, regs->r10, regs->r9, regs->r8); + printk("%sr7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + log_lvl, regs->r7, regs->r6, regs->r5, regs->r4); + printk("%sr3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + log_lvl, regs->r3, regs->r2, regs->r1, regs->r0); + printk("%sFlags: %c%c%c%c%c\n", log_lvl, regs->sr & SR_Q ? 'Q' : 'q', regs->sr & SR_V ? 'V' : 'v', regs->sr & SR_N ? 'N' : 'n', regs->sr & SR_Z ? 'Z' : 'z', regs->sr & SR_C ? 'C' : 'c'); - printk("Mode bits: %c%c%c%c%c%c%c%c%c\n", + printk("%sMode bits: %c%c%c%c%c%c%c%c%c\n", log_lvl, regs->sr & SR_H ? 'H' : 'h', regs->sr & SR_R ? 'R' : 'r', regs->sr & SR_J ? 'J' : 'j', @@ -157,9 +297,21 @@ void show_regs(struct pt_regs *regs) regs->sr & SR_I1M ? '1' : '.', regs->sr & SR_I0M ? '0' : '.', regs->sr & SR_GM ? 'G' : 'g'); - printk("CPU Mode: %s\n", cpu_modes[mode]); + printk("%sCPU Mode: %s\n", log_lvl, cpu_modes[mode]); + printk("%sProcess: %s [%d] (task: %p thread: %p)\n", + log_lvl, current->comm, current->pid, current, + task_thread_info(current)); +} + +void show_regs(struct pt_regs *regs) +{ + unsigned long sp = regs->sp; + + if (!user_mode(regs)) + sp = (unsigned long)regs + FRAME_SIZE_FULL; - show_trace(NULL, (unsigned long *)sp, regs); + show_regs_log_lvl(regs, ""); + show_trace_log_lvl(current, (unsigned long *)sp, regs, ""); } EXPORT_SYMBOL(show_regs); diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c index adc01a12d15..4f0382d8483 100644 --- a/arch/avr32/kernel/traps.c +++ b/arch/avr32/kernel/traps.c @@ -5,158 +5,25 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#undef DEBUG -#include + +#include #include -#include #include +#include #include +#include +#include -#include -#include #include -#include #include -#include - -static void dump_mem(const char *str, unsigned long bottom, unsigned long top) -{ - unsigned long p; - int i; - - printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); - - for (p = bottom & ~31; p < top; ) { - printk("%04lx: ", p & 0xffff); - - for (i = 0; i < 8; i++, p += 4) { - unsigned int val; - - if (p < bottom || p >= top) - printk(" "); - else { - if (__get_user(val, (unsigned int __user *)p)) { - printk("\n"); - goto out; - } - printk("%08x ", val); - } - } - printk("\n"); - } - -out: - return; -} - -static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p) -{ - return (p > (unsigned long)tinfo) - && (p < (unsigned long)tinfo + THREAD_SIZE - 3); -} - -#ifdef CONFIG_FRAME_POINTER -static inline void __show_trace(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs) -{ - unsigned long lr, fp; - struct thread_info *tinfo; - - tinfo = (struct thread_info *) - ((unsigned long)sp & ~(THREAD_SIZE - 1)); - - if (regs) - fp = regs->r7; - else if (tsk == current) - asm("mov %0, r7" : "=r"(fp)); - else - fp = tsk->thread.cpu_context.r7; - - /* - * Walk the stack as long as the frame pointer (a) is within - * the kernel stack of the task, and (b) it doesn't move - * downwards. - */ - while (valid_stack_ptr(tinfo, fp)) { - unsigned long new_fp; - - lr = *(unsigned long *)fp; - printk(" [<%08lx>] ", lr); - print_symbol("%s\n", lr); - - new_fp = *(unsigned long *)(fp + 4); - if (new_fp <= fp) - break; - fp = new_fp; - } - printk("\n"); -} -#else -static inline void __show_trace(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs) -{ - unsigned long addr; - - while (!kstack_end(sp)) { - addr = *sp++; - if (kernel_text_address(addr)) { - printk(" [<%08lx>] ", addr); - print_symbol("%s\n", addr); - } - } -} -#endif - -void show_trace(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs) -{ - if (regs && - (((regs->sr & MODE_MASK) == MODE_EXCEPTION) || - ((regs->sr & MODE_MASK) == MODE_USER))) - return; - - printk ("Call trace:"); -#ifdef CONFIG_KALLSYMS - printk("\n"); -#endif - - __show_trace(tsk, sp, regs); - printk("\n"); -} - -void show_stack(struct task_struct *tsk, unsigned long *sp) -{ - unsigned long stack; - - if (!tsk) - tsk = current; - if (sp == 0) { - if (tsk == current) { - register unsigned long *real_sp __asm__("sp"); - sp = real_sp; - } else { - sp = (unsigned long *)tsk->thread.cpu_context.ksp; - } - } - - stack = (unsigned long)sp; - dump_mem("Stack: ", stack, - THREAD_SIZE + (unsigned long)tsk->thread_info); - show_trace(tsk, sp, NULL); -} - -void dump_stack(void) -{ - show_stack(NULL, NULL); -} -EXPORT_SYMBOL(dump_stack); +#include +#include +#include ATOMIC_NOTIFIER_HEAD(avr32_die_chain); int register_die_notifier(struct notifier_block *nb) { - pr_debug("register_die_notifier: %p\n", nb); - return atomic_notifier_chain_register(&avr32_die_chain, nb); } EXPORT_SYMBOL(register_die_notifier); @@ -169,93 +36,103 @@ EXPORT_SYMBOL(unregister_die_notifier); static DEFINE_SPINLOCK(die_lock); -void __die(const char *str, struct pt_regs *regs, unsigned long err, - const char *file, const char *func, unsigned long line) +void NORET_TYPE die(const char *str, struct pt_regs *regs, long err) { - struct task_struct *tsk = current; static int die_counter; console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); - printk(KERN_ALERT "%s", str); - if (file && func) - printk(" in %s:%s, line %ld", file, func, line); - printk("[#%d]:\n", ++die_counter); - print_modules(); - show_regs(regs); - printk("Process %s (pid: %d, stack limit = 0x%p)\n", - tsk->comm, tsk->pid, tsk->thread_info + 1); - - if (!user_mode(regs) || in_interrupt()) { - dump_mem("Stack: ", regs->sp, - THREAD_SIZE + (unsigned long)tsk->thread_info); + printk(KERN_ALERT "Oops: %s, sig: %ld [#%d]\n" KERN_EMERG, + str, err, ++die_counter); +#ifdef CONFIG_PREEMPT + printk("PREEMPT "); +#endif +#ifdef CONFIG_FRAME_POINTER + printk("FRAME_POINTER "); +#endif + if (current_cpu_data.features & AVR32_FEATURE_OCD) { + unsigned long did = __mfdr(DBGREG_DID); + printk("chip: 0x%03lx:0x%04lx rev %lu\n", + (did >> 1) & 0x7ff, + (did >> 12) & 0x7fff, + (did >> 28) & 0xf); + } else { + printk("cpu: arch %u r%u / core %u r%u\n", + current_cpu_data.arch_type, + current_cpu_data.arch_revision, + current_cpu_data.cpu_type, + current_cpu_data.cpu_revision); } + print_modules(); + show_regs_log_lvl(regs, KERN_EMERG); + show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG); bust_spinlocks(0); spin_unlock_irq(&die_lock); - do_exit(SIGSEGV); + + if (in_interrupt()) + panic("Fatal exception in interrupt"); + + if (panic_on_oops) + panic("Fatal exception"); + + do_exit(err); } -void __die_if_kernel(const char *str, struct pt_regs *regs, unsigned long err, - const char *file, const char *func, unsigned long line) +void _exception(long signr, struct pt_regs *regs, int code, + unsigned long addr) { + siginfo_t info; + if (!user_mode(regs)) - __die(str, regs, err, file, func, line); -} + die("Unhandled exception in kernel mode", regs, signr); + + memset(&info, 0, sizeof(info)); + info.si_signo = signr; + info.si_code = code; + info.si_addr = (void __user *)addr; + force_sig_info(signr, &info, current); -asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) -{ -#ifdef CONFIG_SUBARCH_AVR32B /* - * The exception entry always saves RSR_EX. For NMI, this is - * wrong; it should be RSR_NMI + * Init gets no signals that it doesn't have a handler for. + * That's all very well, but if it has caused a synchronous + * exception and we ignore the resulting signal, it will just + * generate the same exception over and over again and we get + * nowhere. Better to kill it and let the kernel panic. */ - regs->sr = sysreg_read(RSR_NMI); -#endif + if (is_init(current)) { + __sighandler_t handler; + + spin_lock_irq(¤t->sighand->siglock); + handler = current->sighand->action[signr-1].sa.sa_handler; + spin_unlock_irq(¤t->sighand->siglock); + if (handler == SIG_DFL) { + /* init has generated a synchronous exception + and it doesn't have a handler for the signal */ + printk(KERN_CRIT "init has generated signal %ld " + "but has no handler for it\n", signr); + do_exit(signr); + } + } +} - printk("NMI taken!!!!\n"); - die("NMI", regs, ecr); - BUG(); +asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) +{ + printk(KERN_ALERT "Got Non-Maskable Interrupt, dumping regs\n"); + show_regs_log_lvl(regs, KERN_ALERT); + show_stack_log_lvl(current, regs->sp, regs, KERN_ALERT); } asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) { - printk("Unable to handle critical exception %lu at pc = %08lx!\n", - ecr, regs->pc); - die("Oops", regs, ecr); - BUG(); + die("Critical exception", regs, SIGKILL); } asmlinkage void do_address_exception(unsigned long ecr, struct pt_regs *regs) { - siginfo_t info; - - die_if_kernel("Oops: Address exception in kernel mode", regs, ecr); - -#ifdef DEBUG - if (ecr == ECR_ADDR_ALIGN_X) - pr_debug("Instruction Address Exception at pc = %08lx\n", - regs->pc); - else if (ecr == ECR_ADDR_ALIGN_R) - pr_debug("Data Address Exception (Read) at pc = %08lx\n", - regs->pc); - else if (ecr == ECR_ADDR_ALIGN_W) - pr_debug("Data Address Exception (Write) at pc = %08lx\n", - regs->pc); - else - BUG(); - - show_regs(regs); -#endif - - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRALN; - info.si_addr = (void __user *)regs->pc; - - force_sig_info(SIGBUS, &info, current); + _exception(SIGBUS, regs, BUS_ADRALN, regs->pc); } /* This way of handling undefined instructions is stolen from ARM */ @@ -280,7 +157,8 @@ static int do_cop_absent(u32 insn) { int cop_nr; u32 cpucr; - if ( (insn & 0xfdf00000) == 0xf1900000 ) + + if ((insn & 0xfdf00000) == 0xf1900000) /* LDC0 */ cop_nr = 0; else @@ -292,136 +170,91 @@ static int do_cop_absent(u32 insn) sysreg_write(CPUCR, cpucr); cpucr = sysreg_read(CPUCR); - if ( !(cpucr & (1 << (24 + cop_nr))) ){ - printk("Coprocessor #%i not found!\n", cop_nr); - return -1; - } + if (!(cpucr & (1 << (24 + cop_nr)))) + return -ENODEV; return 0; } -#ifdef CONFIG_BUG -#ifdef CONFIG_DEBUG_BUGVERBOSE -static inline void do_bug_verbose(struct pt_regs *regs, u32 insn) -{ - char *file; - u16 line; - char c; - - if (__get_user(line, (u16 __user *)(regs->pc + 2))) - return; - if (__get_user(file, (char * __user *)(regs->pc + 4)) - || (unsigned long)file < PAGE_OFFSET - || __get_user(c, file)) - file = ""; - - printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line); -} -#else -static inline void do_bug_verbose(struct pt_regs *regs, u32 insn) +int is_valid_bugaddr(unsigned long pc) { + unsigned short opcode; + + if (pc < PAGE_OFFSET) + return 0; + if (probe_kernel_address((u16 *)pc, opcode)) + return 0; + return opcode == AVR32_BUG_OPCODE; } -#endif -#endif asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs) { u32 insn; struct undef_hook *hook; - siginfo_t info; void __user *pc; + long code; - if (!user_mode(regs)) - goto kernel_trap; + if (!user_mode(regs) && (ecr == ECR_ILLEGAL_OPCODE)) { + enum bug_trap_type type; + + type = report_bug(regs->pc); + switch (type) { + case BUG_TRAP_TYPE_NONE: + break; + case BUG_TRAP_TYPE_WARN: + regs->pc += 2; + return; + case BUG_TRAP_TYPE_BUG: + die("Kernel BUG", regs, SIGKILL); + } + } local_irq_enable(); - pc = (void __user *)instruction_pointer(regs); - if (__get_user(insn, (u32 __user *)pc)) - goto invalid_area; + if (user_mode(regs)) { + pc = (void __user *)instruction_pointer(regs); + if (get_user(insn, (u32 __user *)pc)) + goto invalid_area; - if (ecr == ECR_COPROC_ABSENT) { - if (do_cop_absent(insn) == 0) + if (ecr == ECR_COPROC_ABSENT && !do_cop_absent(insn)) return; - } - spin_lock_irq(&undef_lock); - list_for_each_entry(hook, &undef_hook, node) { - if ((insn & hook->insn_mask) == hook->insn_val) { - if (hook->fn(regs, insn) == 0) { - spin_unlock_irq(&undef_lock); - return; + spin_lock_irq(&undef_lock); + list_for_each_entry(hook, &undef_hook, node) { + if ((insn & hook->insn_mask) == hook->insn_val) { + if (hook->fn(regs, insn) == 0) { + spin_unlock_irq(&undef_lock); + return; + } } } + spin_unlock_irq(&undef_lock); } - spin_unlock_irq(&undef_lock); - -invalid_area: -#ifdef DEBUG - printk("Illegal instruction at pc = %08lx\n", regs->pc); - if (regs->pc < TASK_SIZE) { - unsigned long ptbr, pgd, pte, *p; - - ptbr = sysreg_read(PTBR); - p = (unsigned long *)ptbr; - pgd = p[regs->pc >> 22]; - p = (unsigned long *)((pgd & 0x1ffff000) | 0x80000000); - pte = p[(regs->pc >> 12) & 0x3ff]; - printk("page table: 0x%08lx -> 0x%08lx -> 0x%08lx\n", ptbr, pgd, pte); - } -#endif - - info.si_signo = SIGILL; - info.si_errno = 0; - info.si_addr = (void __user *)regs->pc; switch (ecr) { - case ECR_ILLEGAL_OPCODE: - case ECR_UNIMPL_INSTRUCTION: - info.si_code = ILL_ILLOPC; - break; case ECR_PRIVILEGE_VIOLATION: - info.si_code = ILL_PRVOPC; + code = ILL_PRVOPC; break; case ECR_COPROC_ABSENT: - info.si_code = ILL_COPROC; + code = ILL_COPROC; break; default: - BUG(); + code = ILL_ILLOPC; + break; } - force_sig_info(SIGILL, &info, current); + _exception(SIGILL, regs, code, regs->pc); return; -kernel_trap: -#ifdef CONFIG_BUG - if (__kernel_text_address(instruction_pointer(regs))) { - insn = *(u16 *)instruction_pointer(regs); - if (insn == AVR32_BUG_OPCODE) { - do_bug_verbose(regs, insn); - die("Kernel BUG", regs, 0); - return; - } - } -#endif - - die("Oops: Illegal instruction in kernel code", regs, ecr); +invalid_area: + _exception(SIGSEGV, regs, SEGV_MAPERR, regs->pc); } asmlinkage void do_fpe(unsigned long ecr, struct pt_regs *regs) { - siginfo_t info; - - printk("Floating-point exception at pc = %08lx\n", regs->pc); - - /* We have no FPU... */ - info.si_signo = SIGILL; - info.si_errno = 0; - info.si_addr = (void __user *)regs->pc; - info.si_code = ILL_COPROC; - - force_sig_info(SIGILL, &info, current); + /* We have no FPU yet */ + _exception(SIGILL, regs, ILL_COPROC, regs->pc); } diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c index ef13b7c7893..7ad20cfb48a 100644 --- a/arch/avr32/kernel/vmlinux.lds.c +++ b/arch/avr32/kernel/vmlinux.lds.c @@ -26,6 +26,12 @@ SECTIONS _sinittext = .; *(.text.reset) *(.init.text) + /* + * .exit.text is discarded at runtime, not + * link time, to deal with references from + * __bug_table + */ + *(.exit.text) _einittext = .; . = ALIGN(4); __tagtable_begin = .; @@ -86,6 +92,8 @@ SECTIONS __stop___ex_table = .; } + BUG_TABLE + RODATA . = ALIGN(8192); @@ -126,7 +134,6 @@ SECTIONS * thrown away, as cleanup code is never called unless it's a module. */ /DISCARD/ : { - *(.exit.text) *(.exit.data) *(.exitcall.exit) } diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index 678557260a3..146ebdbdc30 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -16,26 +16,8 @@ #include #include #include -#include #include - -#ifdef DEBUG -static void dump_code(unsigned long pc) -{ - char *p = (char *)pc; - char val; - int i; - - - printk(KERN_DEBUG "Code:"); - for (i = 0; i < 16; i++) { - if (__get_user(val, p + i)) - break; - printk(" %02x", val); - } - printk("\n"); -} -#endif +#include #ifdef CONFIG_KPROBES ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); @@ -68,17 +50,19 @@ static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, } #endif +int exception_trace = 1; + /* * This routine handles page faults. It determines the address and the * problem, and then passes it off to one of the appropriate routines. * * ecr is the Exception Cause Register. Possible values are: - * 5: Page not found (instruction access) * 6: Protection fault (instruction access) - * 12: Page not found (read access) - * 13: Page not found (write access) - * 14: Protection fault (read access) - * 15: Protection fault (write access) + * 15: Protection fault (read access) + * 16: Protection fault (write access) + * 20: Page not found (instruction access) + * 24: Page not found (read access) + * 28: Page not found (write access) */ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) { @@ -88,7 +72,9 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) const struct exception_table_entry *fixup; unsigned long address; unsigned long page; - int writeaccess = 0; + int writeaccess; + long signr; + int code; if (notify_page_fault(DIE_PAGE_FAULT, regs, ecr, SIGSEGV) == NOTIFY_STOP) @@ -99,6 +85,9 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) tsk = current; mm = tsk->mm; + signr = SIGSEGV; + code = SEGV_MAPERR; + /* * If we're in an interrupt or have no user context, we must * not take the fault... @@ -125,7 +114,9 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) * can handle it... */ good_area: - //pr_debug("good area: vm_flags = 0x%lx\n", vma->vm_flags); + code = SEGV_ACCERR; + writeaccess = 0; + switch (ecr) { case ECR_PROTECTION_X: case ECR_TLB_MISS_X: @@ -176,46 +167,24 @@ survive: * map. Fix it, but check if it's kernel or user first... */ bad_area: - pr_debug("Bad area [%s:%u]: addr %08lx, ecr %lu\n", - tsk->comm, tsk->pid, address, ecr); - up_read(&mm->mmap_sem); if (user_mode(regs)) { - /* Hmm...we have to pass address and ecr somehow... */ - /* tsk->thread.address = address; - tsk->thread.error_code = ecr; */ -#ifdef DEBUG - show_regs(regs); - dump_code(regs->pc); - - page = sysreg_read(PTBR); - printk("ptbr = %08lx", page); - if (page) { - page = ((unsigned long *)page)[address >> 22]; - printk(" pgd = %08lx", page); - if (page & _PAGE_PRESENT) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT]; - printk(" pte = %08lx\n", page); - } - } -#endif - pr_debug("Sending SIGSEGV to PID %d...\n", - tsk->pid); - force_sig(SIGSEGV, tsk); + if (exception_trace) + printk("%s%s[%d]: segfault at %08lx pc %08lx " + "sp %08lx ecr %lu\n", + is_init(tsk) ? KERN_EMERG : KERN_INFO, + tsk->comm, tsk->pid, address, regs->pc, + regs->sp, ecr); + _exception(SIGSEGV, regs, code, address); return; } no_context: - pr_debug("No context\n"); - /* Are we prepared to handle this kernel fault? */ fixup = search_exception_tables(regs->pc); if (fixup) { regs->pc = fixup->fixup; - pr_debug("Found fixup at %08lx\n", fixup->fixup); return; } @@ -230,7 +199,6 @@ no_context: printk(KERN_ALERT "Unable to handle kernel paging request"); printk(" at virtual address %08lx\n", address); - printk(KERN_ALERT "pc = %08lx\n", regs->pc); page = sysreg_read(PTBR); printk(KERN_ALERT "ptbr = %08lx", page); @@ -241,20 +209,20 @@ no_context: page &= PAGE_MASK; address &= 0x003ff000; page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT]; - printk(" pte = %08lx\n", page); + printk(" pte = %08lx", page); } } - die("\nOops", regs, ecr); - do_exit(SIGKILL); + printk("\n"); + die("Kernel access of bad area", regs, signr); + return; /* * We ran out of memory, or some other thing happened to us * that made us unable to handle the page fault gracefully. */ out_of_memory: - printk("Out of memory\n"); up_read(&mm->mmap_sem); - if (current->pid == 1) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; @@ -267,21 +235,20 @@ out_of_memory: do_sigbus: up_read(&mm->mmap_sem); - /* - * Send a sigbus, regardless of whether we were in kernel or - * user mode. - */ - /* address, error_code, trap_no, ... */ -#ifdef DEBUG - show_regs(regs); - dump_code(regs->pc); -#endif - pr_debug("Sending SIGBUS to PID %d...\n", tsk->pid); - force_sig(SIGBUS, tsk); - /* Kernel mode? Handle exceptions or die */ + signr = SIGBUS; + code = BUS_ADRERR; if (!user_mode(regs)) goto no_context; + + if (exception_trace) + printk("%s%s[%d]: bus error at %08lx pc %08lx " + "sp %08lx ecr %lu\n", + is_init(tsk) ? KERN_EMERG : KERN_INFO, + tsk->comm, tsk->pid, address, regs->pc, + regs->sp, ecr); + + _exception(SIGBUS, regs, BUS_ADRERR, address); } asmlinkage void do_bus_error(unsigned long addr, int write_access, @@ -292,8 +259,7 @@ asmlinkage void do_bus_error(unsigned long addr, int write_access, addr, write_access ? "write" : "read"); printk(KERN_INFO "DTLB dump:\n"); dump_dtlb(); - die("Bus Error", regs, write_access); - do_exit(SIGKILL); + die("Bus Error", regs, SIGKILL); } /* -- cgit v1.2.3 From 92b728c147adb8c690b520304f4c9ee3eee43c21 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 13 Mar 2007 10:06:37 +0100 Subject: [AVR32] Fix NMI handler Fix a problem with the NMI handler entry code related to the NMI handler sharing some code with the exception handlers. This is not a good idea because the RSR and RAR registers are not the same, and the NMI handler runs with interrupts masked the whole time so there's no need to check for pending work. Open-code the low-level NMI handling logic instead so that the pt_regs layout is actually correct when the higher-level handler is called. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/entry-avr32b.S | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 5f5f7e42f51..484e08310f1 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S @@ -340,12 +340,34 @@ do_bus_error_read: do_nmi_ll: sub sp, 4 stmts --sp, r0-lr - /* FIXME: Make sure RAR_NMI and RSR_NMI are pushed instead of *_EX */ - rcall save_full_context_ex + mfsr r9, SYSREG_RSR_NMI + mfsr r8, SYSREG_RAR_NMI + bfextu r0, r9, MODE_SHIFT, 3 + brne 2f + +1: pushm r8, r9 /* PC and SR */ mfsr r12, SYSREG_ECR mov r11, sp rcall do_nmi - rjmp bad_return + popm r8-r9 + mtsr SYSREG_RAR_NMI, r8 + tst r0, r0 + mtsr SYSREG_RSR_NMI, r9 + brne 3f + + ldmts sp++, r0-lr + sub sp, -4 /* skip r12_orig */ + rete + +2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR) + stdsp sp[4], r10 /* replace saved SP */ + rjmp 1b + +3: popm lr + sub sp, -4 /* skip sp */ + popm r0-r12 + sub sp, -4 /* skip r12_orig */ + rete handle_address_fault: sub sp, 4 -- cgit v1.2.3 From e3e7d8d4ea37b8372ee417452d03171c5dc55125 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 12 Feb 2007 16:28:56 +0100 Subject: [AVR32] Make I/O access macros work with external devices Fix the I/O access macros so that they work with externally connected devices accessed in little-endian mode over any bus width: * Use a set of macros to define I/O port- and memory operations borrowed from MIPS. * Allow subarchitecture to specify address- and data-mangling * Implement at32ap-specific port mangling (with build-time configurable bus width. Only one bus width at a time supported for now.) * Rewrite iowriteN and friends to use write[bwl] and friends (not the __raw counterparts.) This has been tested using pata_pcmcia to access a CompactFlash card connected to the EBI (16-bit bus width.) Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/Kconfig | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/Kconfig b/arch/avr32/mach-at32ap/Kconfig index d7497715cc0..eb307838457 100644 --- a/arch/avr32/mach-at32ap/Kconfig +++ b/arch/avr32/mach-at32ap/Kconfig @@ -2,6 +2,30 @@ if PLATFORM_AT32AP menu "Atmel AVR32 AP options" +choice + prompt "AT32AP7000 static memory bus width" + depends on CPU_AT32AP7000 + default AP7000_16_BIT_SMC + help + Define the width of the AP7000 external static memory interface. + This is used to determine how to mangle the address and/or data + when doing little-endian port access. + + The current code can only support a single external memory bus + width for all chip selects, excluding the flash (which is using + raw access and is thus not affected by any of this.) + +config AP7000_32_BIT_SMC + bool "32 bit" + +config AP7000_16_BIT_SMC + bool "16 bit" + +config AP7000_8_BIT_SMC + bool "8 bit" + +endchoice + endmenu -endif +endif # PLATFORM_AT32AP -- cgit v1.2.3 From 5539f59ac40473730806580f212c4eac6e769f01 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 21 Mar 2007 15:39:18 +0100 Subject: [AVR32] Move setup_bootmem() from mm/init.c to kernel/setup.c Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/setup.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++ arch/avr32/mm/init.c | 238 ---------------------------------------------- 2 files changed, 238 insertions(+), 238 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index a1a7c3c3f52..53a1ff0cb05 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -8,12 +8,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -260,6 +262,242 @@ static void __init parse_tags(struct tag *t) t->hdr.tag); } +static void __init print_memory_map(const char *what, + struct tag_mem_range *mem) +{ + printk ("%s:\n", what); + for (; mem; mem = mem->next) { + printk (" %08lx - %08lx\n", + (unsigned long)mem->addr, + (unsigned long)(mem->addr + mem->size)); + } +} + +#define MAX_LOWMEM HIGHMEM_START +#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM) + +/* + * Sort a list of memory regions in-place by ascending address. + * + * We're using bubble sort because we only have singly linked lists + * with few elements. + */ +static void __init sort_mem_list(struct tag_mem_range **pmem) +{ + int done; + struct tag_mem_range **a, **b; + + if (!*pmem) + return; + + do { + done = 1; + a = pmem, b = &(*pmem)->next; + while (*b) { + if ((*a)->addr > (*b)->addr) { + struct tag_mem_range *tmp; + tmp = (*b)->next; + (*b)->next = *a; + *a = *b; + *b = tmp; + done = 0; + } + a = &(*a)->next; + b = &(*a)->next; + } + } while (!done); +} + +/* + * Find a free memory region large enough for storing the + * bootmem bitmap. + */ +static unsigned long __init +find_bootmap_pfn(const struct tag_mem_range *mem) +{ + unsigned long bootmap_pages, bootmap_len; + unsigned long node_pages = PFN_UP(mem->size); + unsigned long bootmap_addr = mem->addr; + struct tag_mem_range *reserved = mem_reserved; + struct tag_mem_range *ramdisk = mem_ramdisk; + unsigned long kern_start = __pa(_stext); + unsigned long kern_end = __pa(_end); + + bootmap_pages = bootmem_bootmap_pages(node_pages); + bootmap_len = bootmap_pages << PAGE_SHIFT; + + /* + * Find a large enough region without reserved pages for + * storing the bootmem bitmap. We can take advantage of the + * fact that all lists have been sorted. + * + * We have to check explicitly reserved regions as well as the + * kernel image and any RAMDISK images... + * + * Oh, and we have to make sure we don't overwrite the taglist + * since we're going to use it until the bootmem allocator is + * fully up and running. + */ + while (1) { + if ((bootmap_addr < kern_end) && + ((bootmap_addr + bootmap_len) > kern_start)) + bootmap_addr = kern_end; + + while (reserved && + (bootmap_addr >= (reserved->addr + reserved->size))) + reserved = reserved->next; + + if (reserved && + ((bootmap_addr + bootmap_len) >= reserved->addr)) { + bootmap_addr = reserved->addr + reserved->size; + continue; + } + + while (ramdisk && + (bootmap_addr >= (ramdisk->addr + ramdisk->size))) + ramdisk = ramdisk->next; + + if (!ramdisk || + ((bootmap_addr + bootmap_len) < ramdisk->addr)) + break; + + bootmap_addr = ramdisk->addr + ramdisk->size; + } + + if ((PFN_UP(bootmap_addr) + bootmap_len) >= (mem->addr + mem->size)) + return ~0UL; + + return PFN_UP(bootmap_addr); +} + +static void __init setup_bootmem(void) +{ + unsigned bootmap_size; + unsigned long first_pfn, bootmap_pfn, pages; + unsigned long max_pfn, max_low_pfn; + unsigned long kern_start = __pa(_stext); + unsigned long kern_end = __pa(_end); + unsigned node = 0; + struct tag_mem_range *bank, *res; + + sort_mem_list(&mem_phys); + sort_mem_list(&mem_reserved); + + print_memory_map("Physical memory", mem_phys); + print_memory_map("Reserved memory", mem_reserved); + + nodes_clear(node_online_map); + + if (mem_ramdisk) { +#ifdef CONFIG_BLK_DEV_INITRD + initrd_start = (unsigned long)__va(mem_ramdisk->addr); + initrd_end = initrd_start + mem_ramdisk->size; + + print_memory_map("RAMDISK images", mem_ramdisk); + if (mem_ramdisk->next) + printk(KERN_WARNING + "Warning: Only the first RAMDISK image " + "will be used\n"); + sort_mem_list(&mem_ramdisk); +#else + printk(KERN_WARNING "RAM disk image present, but " + "no initrd support in kernel!\n"); +#endif + } + + if (mem_phys->next) + printk(KERN_WARNING "Only using first memory bank\n"); + + for (bank = mem_phys; bank; bank = NULL) { + first_pfn = PFN_UP(bank->addr); + max_low_pfn = max_pfn = PFN_DOWN(bank->addr + bank->size); + bootmap_pfn = find_bootmap_pfn(bank); + if (bootmap_pfn > max_pfn) + panic("No space for bootmem bitmap!\n"); + + if (max_low_pfn > MAX_LOWMEM_PFN) { + max_low_pfn = MAX_LOWMEM_PFN; +#ifndef CONFIG_HIGHMEM + /* + * Lowmem is memory that can be addressed + * directly through P1/P2 + */ + printk(KERN_WARNING + "Node %u: Only %ld MiB of memory will be used.\n", + node, MAX_LOWMEM >> 20); + printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); +#else +#error HIGHMEM is not supported by AVR32 yet +#endif + } + + /* Initialize the boot-time allocator with low memory only. */ + bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn, + first_pfn, max_low_pfn); + + printk("Node %u: bdata = %p, bdata->node_bootmem_map = %p\n", + node, NODE_DATA(node)->bdata, + NODE_DATA(node)->bdata->node_bootmem_map); + + /* + * Register fully available RAM pages with the bootmem + * allocator. + */ + pages = max_low_pfn - first_pfn; + free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn), + PFN_PHYS(pages)); + + /* + * Reserve space for the kernel image (if present in + * this node)... + */ + if ((kern_start >= PFN_PHYS(first_pfn)) && + (kern_start < PFN_PHYS(max_pfn))) { + printk("Node %u: Kernel image %08lx - %08lx\n", + node, kern_start, kern_end); + reserve_bootmem_node(NODE_DATA(node), kern_start, + kern_end - kern_start); + } + + /* ...the bootmem bitmap... */ + reserve_bootmem_node(NODE_DATA(node), + PFN_PHYS(bootmap_pfn), + bootmap_size); + + /* ...any RAMDISK images... */ + for (res = mem_ramdisk; res; res = res->next) { + if (res->addr > PFN_PHYS(max_pfn)) + break; + + if (res->addr >= PFN_PHYS(first_pfn)) { + printk("Node %u: RAMDISK %08lx - %08lx\n", + node, + (unsigned long)res->addr, + (unsigned long)(res->addr + res->size)); + reserve_bootmem_node(NODE_DATA(node), + res->addr, res->size); + } + } + + /* ...and any other reserved regions. */ + for (res = mem_reserved; res; res = res->next) { + if (res->addr > PFN_PHYS(max_pfn)) + break; + + if (res->addr >= PFN_PHYS(first_pfn)) { + printk("Node %u: Reserved %08lx - %08lx\n", + node, + (unsigned long)res->addr, + (unsigned long)(res->addr + res->size)); + reserve_bootmem_node(NODE_DATA(node), + res->addr, res->size); + } + } + + node_set_online(node); + } +} + void __init setup_arch (char **cmdline_p) { struct clk *cpu_clk; diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c index 70da6894acc..82cf70854b9 100644 --- a/arch/avr32/mm/init.c +++ b/arch/avr32/mm/init.c @@ -10,11 +10,9 @@ #include #include #include -#include #include #include #include -#include #include #include @@ -78,242 +76,6 @@ void show_mem(void) printk ("%d pages swap cached\n", cached); } -static void __init print_memory_map(const char *what, - struct tag_mem_range *mem) -{ - printk ("%s:\n", what); - for (; mem; mem = mem->next) { - printk (" %08lx - %08lx\n", - (unsigned long)mem->addr, - (unsigned long)(mem->addr + mem->size)); - } -} - -#define MAX_LOWMEM HIGHMEM_START -#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM) - -/* - * Sort a list of memory regions in-place by ascending address. - * - * We're using bubble sort because we only have singly linked lists - * with few elements. - */ -static void __init sort_mem_list(struct tag_mem_range **pmem) -{ - int done; - struct tag_mem_range **a, **b; - - if (!*pmem) - return; - - do { - done = 1; - a = pmem, b = &(*pmem)->next; - while (*b) { - if ((*a)->addr > (*b)->addr) { - struct tag_mem_range *tmp; - tmp = (*b)->next; - (*b)->next = *a; - *a = *b; - *b = tmp; - done = 0; - } - a = &(*a)->next; - b = &(*a)->next; - } - } while (!done); -} - -/* - * Find a free memory region large enough for storing the - * bootmem bitmap. - */ -static unsigned long __init -find_bootmap_pfn(const struct tag_mem_range *mem) -{ - unsigned long bootmap_pages, bootmap_len; - unsigned long node_pages = PFN_UP(mem->size); - unsigned long bootmap_addr = mem->addr; - struct tag_mem_range *reserved = mem_reserved; - struct tag_mem_range *ramdisk = mem_ramdisk; - unsigned long kern_start = virt_to_phys(_stext); - unsigned long kern_end = virt_to_phys(_end); - - bootmap_pages = bootmem_bootmap_pages(node_pages); - bootmap_len = bootmap_pages << PAGE_SHIFT; - - /* - * Find a large enough region without reserved pages for - * storing the bootmem bitmap. We can take advantage of the - * fact that all lists have been sorted. - * - * We have to check explicitly reserved regions as well as the - * kernel image and any RAMDISK images... - * - * Oh, and we have to make sure we don't overwrite the taglist - * since we're going to use it until the bootmem allocator is - * fully up and running. - */ - while (1) { - if ((bootmap_addr < kern_end) && - ((bootmap_addr + bootmap_len) > kern_start)) - bootmap_addr = kern_end; - - while (reserved && - (bootmap_addr >= (reserved->addr + reserved->size))) - reserved = reserved->next; - - if (reserved && - ((bootmap_addr + bootmap_len) >= reserved->addr)) { - bootmap_addr = reserved->addr + reserved->size; - continue; - } - - while (ramdisk && - (bootmap_addr >= (ramdisk->addr + ramdisk->size))) - ramdisk = ramdisk->next; - - if (!ramdisk || - ((bootmap_addr + bootmap_len) < ramdisk->addr)) - break; - - bootmap_addr = ramdisk->addr + ramdisk->size; - } - - if ((PFN_UP(bootmap_addr) + bootmap_len) >= (mem->addr + mem->size)) - return ~0UL; - - return PFN_UP(bootmap_addr); -} - -void __init setup_bootmem(void) -{ - unsigned bootmap_size; - unsigned long first_pfn, bootmap_pfn, pages; - unsigned long max_pfn, max_low_pfn; - unsigned long kern_start = virt_to_phys(_stext); - unsigned long kern_end = virt_to_phys(_end); - unsigned node = 0; - struct tag_mem_range *bank, *res; - - sort_mem_list(&mem_phys); - sort_mem_list(&mem_reserved); - - print_memory_map("Physical memory", mem_phys); - print_memory_map("Reserved memory", mem_reserved); - - nodes_clear(node_online_map); - - if (mem_ramdisk) { -#ifdef CONFIG_BLK_DEV_INITRD - initrd_start = (unsigned long)__va(mem_ramdisk->addr); - initrd_end = initrd_start + mem_ramdisk->size; - - print_memory_map("RAMDISK images", mem_ramdisk); - if (mem_ramdisk->next) - printk(KERN_WARNING - "Warning: Only the first RAMDISK image " - "will be used\n"); - sort_mem_list(&mem_ramdisk); -#else - printk(KERN_WARNING "RAM disk image present, but " - "no initrd support in kernel!\n"); -#endif - } - - if (mem_phys->next) - printk(KERN_WARNING "Only using first memory bank\n"); - - for (bank = mem_phys; bank; bank = NULL) { - first_pfn = PFN_UP(bank->addr); - max_low_pfn = max_pfn = PFN_DOWN(bank->addr + bank->size); - bootmap_pfn = find_bootmap_pfn(bank); - if (bootmap_pfn > max_pfn) - panic("No space for bootmem bitmap!\n"); - - if (max_low_pfn > MAX_LOWMEM_PFN) { - max_low_pfn = MAX_LOWMEM_PFN; -#ifndef CONFIG_HIGHMEM - /* - * Lowmem is memory that can be addressed - * directly through P1/P2 - */ - printk(KERN_WARNING - "Node %u: Only %ld MiB of memory will be used.\n", - node, MAX_LOWMEM >> 20); - printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); -#else -#error HIGHMEM is not supported by AVR32 yet -#endif - } - - /* Initialize the boot-time allocator with low memory only. */ - bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn, - first_pfn, max_low_pfn); - - printk("Node %u: bdata = %p, bdata->node_bootmem_map = %p\n", - node, NODE_DATA(node)->bdata, - NODE_DATA(node)->bdata->node_bootmem_map); - - /* - * Register fully available RAM pages with the bootmem - * allocator. - */ - pages = max_low_pfn - first_pfn; - free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn), - PFN_PHYS(pages)); - - /* - * Reserve space for the kernel image (if present in - * this node)... - */ - if ((kern_start >= PFN_PHYS(first_pfn)) && - (kern_start < PFN_PHYS(max_pfn))) { - printk("Node %u: Kernel image %08lx - %08lx\n", - node, kern_start, kern_end); - reserve_bootmem_node(NODE_DATA(node), kern_start, - kern_end - kern_start); - } - - /* ...the bootmem bitmap... */ - reserve_bootmem_node(NODE_DATA(node), - PFN_PHYS(bootmap_pfn), - bootmap_size); - - /* ...any RAMDISK images... */ - for (res = mem_ramdisk; res; res = res->next) { - if (res->addr > PFN_PHYS(max_pfn)) - break; - - if (res->addr >= PFN_PHYS(first_pfn)) { - printk("Node %u: RAMDISK %08lx - %08lx\n", - node, - (unsigned long)res->addr, - (unsigned long)(res->addr + res->size)); - reserve_bootmem_node(NODE_DATA(node), - res->addr, res->size); - } - } - - /* ...and any other reserved regions. */ - for (res = mem_reserved; res; res = res->next) { - if (res->addr > PFN_PHYS(max_pfn)) - break; - - if (res->addr >= PFN_PHYS(first_pfn)) { - printk("Node %u: Reserved %08lx - %08lx\n", - node, - (unsigned long)res->addr, - (unsigned long)(res->addr + res->size)); - reserve_bootmem_node(NODE_DATA(node), - res->addr, res->size); - } - } - - node_set_online(node); - } -} - /* * paging_init() sets up the page tables * -- cgit v1.2.3 From d8011768e6bdd0d9de5cc7bdbd3077b4b4fab8c7 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 21 Mar 2007 16:02:57 +0100 Subject: [AVR32] Simplify early handling of memory regions Use struct resource to specify both physical memory regions and reserved regions and push everything into the same framework, including kernel code/data and initrd memory. This allows us to get rid of many special cases in the bootmem initialization and will also make it easier to implement more robust handling of framebuffer memory later. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/setup.c | 495 ++++++++++++++++++++++------------------------ 1 file changed, 232 insertions(+), 263 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index 53a1ff0cb05..d0a35a1b6a6 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -31,13 +31,6 @@ extern int root_mountflags; -/* - * Bootloader-provided information about physical memory - */ -struct tag_mem_range *mem_phys; -struct tag_mem_range *mem_reserved; -struct tag_mem_range *mem_ramdisk; - /* * Initialize loops_per_jiffy as 5000000 (500MIPS). * Better make it too large than too small... @@ -50,32 +43,153 @@ EXPORT_SYMBOL(boot_cpu_data); static char __initdata command_line[COMMAND_LINE_SIZE]; /* - * Should be more than enough, but if you have a _really_ complex - * setup, you might need to increase the size of this... + * Standard memory resources */ -static struct tag_mem_range __initdata mem_range_cache[32]; -static unsigned mem_range_next_free; +static struct resource __initdata kernel_data = { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM, +}; +static struct resource __initdata kernel_code = { + .name = "Kernel code", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM, + .sibling = &kernel_data, +}; /* - * Standard memory resources + * Available system RAM and reserved regions as singly linked + * lists. These lists are traversed using the sibling pointer in + * struct resource and are kept sorted at all times. */ -static struct resource mem_res[] = { - { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM - }, - { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM, - }, -}; +static struct resource *__initdata system_ram; +static struct resource *__initdata reserved = &kernel_code; + +/* + * We need to allocate these before the bootmem allocator is up and + * running, so we need this "cache". 32 entries are probably enough + * for all but the most insanely complex systems. + */ +static struct resource __initdata res_cache[32]; +static unsigned int __initdata res_cache_next_free; + +static void __init resource_init(void) +{ + struct resource *mem, *res; + struct resource *new; + + kernel_code.start = __pa(init_mm.start_code); + + for (mem = system_ram; mem; mem = mem->sibling) { + new = alloc_bootmem_low(sizeof(struct resource)); + memcpy(new, mem, sizeof(struct resource)); + + new->sibling = NULL; + if (request_resource(&iomem_resource, new)) + printk(KERN_WARNING "Bad RAM resource %08x-%08x\n", + mem->start, mem->end); + } + + for (res = reserved; res; res = res->sibling) { + new = alloc_bootmem_low(sizeof(struct resource)); + memcpy(new, res, sizeof(struct resource)); + + new->sibling = NULL; + if (insert_resource(&iomem_resource, new)) + printk(KERN_WARNING + "Bad reserved resource %s (%08x-%08x)\n", + res->name, res->start, res->end); + } +} + +static void __init +add_physical_memory(resource_size_t start, resource_size_t end) +{ + struct resource *new, *next, **pprev; + + for (pprev = &system_ram, next = system_ram; next; + pprev = &next->sibling, next = next->sibling) { + if (end < next->start) + break; + if (start <= next->end) { + printk(KERN_WARNING + "Warning: Physical memory map is broken\n"); + printk(KERN_WARNING + "Warning: %08x-%08x overlaps %08x-%08x\n", + start, end, next->start, next->end); + return; + } + } + + if (res_cache_next_free >= ARRAY_SIZE(res_cache)) { + printk(KERN_WARNING + "Warning: Failed to add physical memory %08x-%08x\n", + start, end); + return; + } + + new = &res_cache[res_cache_next_free++]; + new->start = start; + new->end = end; + new->name = "System RAM"; + new->flags = IORESOURCE_MEM; + + *pprev = new; +} + +static int __init +add_reserved_region(resource_size_t start, resource_size_t end, + const char *name) +{ + struct resource *new, *next, **pprev; -#define kernel_code mem_res[0] -#define kernel_data mem_res[1] + if (end < start) + return -EINVAL; + + if (res_cache_next_free >= ARRAY_SIZE(res_cache)) + return -ENOMEM; + + for (pprev = &reserved, next = reserved; next; + pprev = &next->sibling, next = next->sibling) { + if (end < next->start) + break; + if (start <= next->end) + return -EBUSY; + } + + new = &res_cache[res_cache_next_free++]; + new->start = start; + new->end = end; + new->name = name; + new->flags = IORESOURCE_MEM; + + *pprev = new; + + return 0; +} + +static unsigned long __init +find_free_region(const struct resource *mem, resource_size_t size, + resource_size_t align) +{ + struct resource *res; + unsigned long target; + + target = ALIGN(mem->start, align); + for (res = reserved; res; res = res->sibling) { + if ((target + size) <= res->start) + break; + if (target <= res->end) + target = ALIGN(res->end + 1, align); + } + + if ((target + size) > (mem->end + 1)) + return mem->end + 1; + + return target; +} /* * Early framebuffer allocation. Works as follows: @@ -112,42 +226,6 @@ static int __init early_parse_fbmem(char *p) } early_param("fbmem", early_parse_fbmem); -static inline void __init resource_init(void) -{ - struct tag_mem_range *region; - - kernel_code.start = __pa(init_mm.start_code); - kernel_code.end = __pa(init_mm.end_code - 1); - kernel_data.start = __pa(init_mm.end_code); - kernel_data.end = __pa(init_mm.brk - 1); - - for (region = mem_phys; region; region = region->next) { - struct resource *res; - unsigned long phys_start, phys_end; - - if (region->size == 0) - continue; - - phys_start = region->addr; - phys_end = phys_start + region->size - 1; - - res = alloc_bootmem_low(sizeof(*res)); - res->name = "System RAM"; - res->start = phys_start; - res->end = phys_end; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - - request_resource (&iomem_resource, res); - - if (kernel_code.start >= res->start && - kernel_code.end <= res->end) - request_resource (res, &kernel_code); - if (kernel_data.start >= res->start && - kernel_data.end <= res->end) - request_resource (res, &kernel_data); - } -} - static int __init parse_tag_core(struct tag *tag) { if (tag->hdr.size > 2) { @@ -159,11 +237,9 @@ static int __init parse_tag_core(struct tag *tag) } __tagtable(ATAG_CORE, parse_tag_core); -static int __init parse_tag_mem_range(struct tag *tag, - struct tag_mem_range **root) +static int __init parse_tag_mem(struct tag *tag) { - struct tag_mem_range *cur, **pprev; - struct tag_mem_range *new; + unsigned long start, end; /* * Ignore zero-sized entries. If we're running standalone, the @@ -173,34 +249,53 @@ static int __init parse_tag_mem_range(struct tag *tag, if (tag->u.mem_range.size == 0) return 0; - /* - * Copy the data so the bootmem init code doesn't need to care - * about it. - */ - if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache)) - panic("Physical memory map too complex!\n"); + start = tag->u.mem_range.addr; + end = tag->u.mem_range.addr + tag->u.mem_range.size - 1; - new = &mem_range_cache[mem_range_next_free++]; - *new = tag->u.mem_range; + add_physical_memory(start, end); + return 0; +} +__tagtable(ATAG_MEM, parse_tag_mem); - pprev = root; - cur = *root; - while (cur) { - pprev = &cur->next; - cur = cur->next; +static int __init parse_tag_rdimg(struct tag *tag) +{ +#ifdef CONFIG_INITRD + struct tag_mem_range *mem = &tag->u.mem_range; + int ret; + + if (initrd_start) { + printk(KERN_WARNING + "Warning: Only the first initrd image will be used\n"); + return 0; } - *pprev = new; - new->next = NULL; + ret = add_reserved_region(mem->start, mem->start + mem->size - 1, + "initrd"); + if (ret) { + printk(KERN_WARNING + "Warning: Failed to reserve initrd memory\n"); + return ret; + } + + initrd_start = (unsigned long)__va(mem->addr); + initrd_end = initrd_start + mem->size; +#else + printk(KERN_WARNING "RAM disk image present, but " + "no initrd support in kernel, ignoring\n"); +#endif return 0; } +__tagtable(ATAG_RDIMG, parse_tag_rdimg); -static int __init parse_tag_mem(struct tag *tag) +static int __init parse_tag_rsvd_mem(struct tag *tag) { - return parse_tag_mem_range(tag, &mem_phys); + struct tag_mem_range *mem = &tag->u.mem_range; + + return add_reserved_region(mem->addr, mem->addr + mem->size - 1, + "Reserved"); } -__tagtable(ATAG_MEM, parse_tag_mem); +__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); static int __init parse_tag_cmdline(struct tag *tag) { @@ -209,12 +304,6 @@ static int __init parse_tag_cmdline(struct tag *tag) } __tagtable(ATAG_CMDLINE, parse_tag_cmdline); -static int __init parse_tag_rdimg(struct tag *tag) -{ - return parse_tag_mem_range(tag, &mem_ramdisk); -} -__tagtable(ATAG_RDIMG, parse_tag_rdimg); - static int __init parse_tag_clock(struct tag *tag) { /* @@ -225,12 +314,6 @@ static int __init parse_tag_clock(struct tag *tag) } __tagtable(ATAG_CLOCK, parse_tag_clock); -static int __init parse_tag_rsvd_mem(struct tag *tag) -{ - return parse_tag_mem_range(tag, &mem_reserved); -} -__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); - /* * Scan the tag table for this tag, and call its parse function. The * tag table is built by the linker from all the __tagtable @@ -262,66 +345,16 @@ static void __init parse_tags(struct tag *t) t->hdr.tag); } -static void __init print_memory_map(const char *what, - struct tag_mem_range *mem) -{ - printk ("%s:\n", what); - for (; mem; mem = mem->next) { - printk (" %08lx - %08lx\n", - (unsigned long)mem->addr, - (unsigned long)(mem->addr + mem->size)); - } -} - -#define MAX_LOWMEM HIGHMEM_START -#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM) - -/* - * Sort a list of memory regions in-place by ascending address. - * - * We're using bubble sort because we only have singly linked lists - * with few elements. - */ -static void __init sort_mem_list(struct tag_mem_range **pmem) -{ - int done; - struct tag_mem_range **a, **b; - - if (!*pmem) - return; - - do { - done = 1; - a = pmem, b = &(*pmem)->next; - while (*b) { - if ((*a)->addr > (*b)->addr) { - struct tag_mem_range *tmp; - tmp = (*b)->next; - (*b)->next = *a; - *a = *b; - *b = tmp; - done = 0; - } - a = &(*a)->next; - b = &(*a)->next; - } - } while (!done); -} - /* * Find a free memory region large enough for storing the * bootmem bitmap. */ static unsigned long __init -find_bootmap_pfn(const struct tag_mem_range *mem) +find_bootmap_pfn(const struct resource *mem) { unsigned long bootmap_pages, bootmap_len; - unsigned long node_pages = PFN_UP(mem->size); - unsigned long bootmap_addr = mem->addr; - struct tag_mem_range *reserved = mem_reserved; - struct tag_mem_range *ramdisk = mem_ramdisk; - unsigned long kern_start = __pa(_stext); - unsigned long kern_end = __pa(_end); + unsigned long node_pages = PFN_UP(mem->end - mem->start + 1); + unsigned long bootmap_start; bootmap_pages = bootmem_bootmap_pages(node_pages); bootmap_len = bootmap_pages << PAGE_SHIFT; @@ -331,87 +364,43 @@ find_bootmap_pfn(const struct tag_mem_range *mem) * storing the bootmem bitmap. We can take advantage of the * fact that all lists have been sorted. * - * We have to check explicitly reserved regions as well as the - * kernel image and any RAMDISK images... - * - * Oh, and we have to make sure we don't overwrite the taglist - * since we're going to use it until the bootmem allocator is - * fully up and running. + * We have to check that we don't collide with any reserved + * regions, which includes the kernel image and any RAMDISK + * images. */ - while (1) { - if ((bootmap_addr < kern_end) && - ((bootmap_addr + bootmap_len) > kern_start)) - bootmap_addr = kern_end; - - while (reserved && - (bootmap_addr >= (reserved->addr + reserved->size))) - reserved = reserved->next; - - if (reserved && - ((bootmap_addr + bootmap_len) >= reserved->addr)) { - bootmap_addr = reserved->addr + reserved->size; - continue; - } - - while (ramdisk && - (bootmap_addr >= (ramdisk->addr + ramdisk->size))) - ramdisk = ramdisk->next; - - if (!ramdisk || - ((bootmap_addr + bootmap_len) < ramdisk->addr)) - break; - - bootmap_addr = ramdisk->addr + ramdisk->size; - } - - if ((PFN_UP(bootmap_addr) + bootmap_len) >= (mem->addr + mem->size)) - return ~0UL; + bootmap_start = find_free_region(mem, bootmap_len, PAGE_SIZE); - return PFN_UP(bootmap_addr); + return bootmap_start >> PAGE_SHIFT; } +#define MAX_LOWMEM HIGHMEM_START +#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM) + static void __init setup_bootmem(void) { unsigned bootmap_size; unsigned long first_pfn, bootmap_pfn, pages; unsigned long max_pfn, max_low_pfn; - unsigned long kern_start = __pa(_stext); - unsigned long kern_end = __pa(_end); unsigned node = 0; - struct tag_mem_range *bank, *res; + struct resource *res; - sort_mem_list(&mem_phys); - sort_mem_list(&mem_reserved); - - print_memory_map("Physical memory", mem_phys); - print_memory_map("Reserved memory", mem_reserved); + printk(KERN_INFO "Physical memory:\n"); + for (res = system_ram; res; res = res->sibling) + printk(" %08x-%08x\n", res->start, res->end); + printk(KERN_INFO "Reserved memory:\n"); + for (res = reserved; res; res = res->sibling) + printk(" %08x-%08x: %s\n", + res->start, res->end, res->name); nodes_clear(node_online_map); - if (mem_ramdisk) { -#ifdef CONFIG_BLK_DEV_INITRD - initrd_start = (unsigned long)__va(mem_ramdisk->addr); - initrd_end = initrd_start + mem_ramdisk->size; - - print_memory_map("RAMDISK images", mem_ramdisk); - if (mem_ramdisk->next) - printk(KERN_WARNING - "Warning: Only the first RAMDISK image " - "will be used\n"); - sort_mem_list(&mem_ramdisk); -#else - printk(KERN_WARNING "RAM disk image present, but " - "no initrd support in kernel!\n"); -#endif - } - - if (mem_phys->next) + if (system_ram->sibling) printk(KERN_WARNING "Only using first memory bank\n"); - for (bank = mem_phys; bank; bank = NULL) { - first_pfn = PFN_UP(bank->addr); - max_low_pfn = max_pfn = PFN_DOWN(bank->addr + bank->size); - bootmap_pfn = find_bootmap_pfn(bank); + for (res = system_ram; res; res = NULL) { + first_pfn = PFN_UP(res->start); + max_low_pfn = max_pfn = PFN_DOWN(res->end + 1); + bootmap_pfn = find_bootmap_pfn(res); if (bootmap_pfn > max_pfn) panic("No space for bootmem bitmap!\n"); @@ -435,10 +424,6 @@ static void __init setup_bootmem(void) bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn, first_pfn, max_low_pfn); - printk("Node %u: bdata = %p, bdata->node_bootmem_map = %p\n", - node, NODE_DATA(node)->bdata, - NODE_DATA(node)->bdata->node_bootmem_map); - /* * Register fully available RAM pages with the bootmem * allocator. @@ -447,51 +432,26 @@ static void __init setup_bootmem(void) free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn), PFN_PHYS(pages)); - /* - * Reserve space for the kernel image (if present in - * this node)... - */ - if ((kern_start >= PFN_PHYS(first_pfn)) && - (kern_start < PFN_PHYS(max_pfn))) { - printk("Node %u: Kernel image %08lx - %08lx\n", - node, kern_start, kern_end); - reserve_bootmem_node(NODE_DATA(node), kern_start, - kern_end - kern_start); - } - - /* ...the bootmem bitmap... */ + /* Reserve space for the bootmem bitmap... */ reserve_bootmem_node(NODE_DATA(node), PFN_PHYS(bootmap_pfn), bootmap_size); - /* ...any RAMDISK images... */ - for (res = mem_ramdisk; res; res = res->next) { - if (res->addr > PFN_PHYS(max_pfn)) - break; - - if (res->addr >= PFN_PHYS(first_pfn)) { - printk("Node %u: RAMDISK %08lx - %08lx\n", - node, - (unsigned long)res->addr, - (unsigned long)(res->addr + res->size)); - reserve_bootmem_node(NODE_DATA(node), - res->addr, res->size); - } - } - /* ...and any other reserved regions. */ - for (res = mem_reserved; res; res = res->next) { - if (res->addr > PFN_PHYS(max_pfn)) + for (res = reserved; res; res = res->sibling) { + if (res->start > PFN_PHYS(max_pfn)) break; - if (res->addr >= PFN_PHYS(first_pfn)) { - printk("Node %u: Reserved %08lx - %08lx\n", - node, - (unsigned long)res->addr, - (unsigned long)(res->addr + res->size)); - reserve_bootmem_node(NODE_DATA(node), - res->addr, res->size); - } + /* + * resource_init will complain about partial + * overlaps, so we'll just ignore such + * resources for now. + */ + if (res->start >= PFN_PHYS(first_pfn) + && res->end < PFN_PHYS(max_pfn)) + reserve_bootmem_node( + NODE_DATA(node), res->start, + res->end - res->start + 1); } node_set_online(node); @@ -502,6 +462,20 @@ void __init setup_arch (char **cmdline_p) { struct clk *cpu_clk; + init_mm.start_code = (unsigned long)_text; + init_mm.end_code = (unsigned long)_etext; + init_mm.end_data = (unsigned long)_edata; + init_mm.brk = (unsigned long)_end; + + /* + * Include .init section to make allocations easier. It will + * be removed before the resource is actually requested. + */ + kernel_code.start = __pa(__init_begin); + kernel_code.end = __pa(init_mm.end_code - 1); + kernel_data.start = __pa(init_mm.end_code); + kernel_data.end = __pa(init_mm.brk - 1); + parse_tags(bootloader_tags); setup_processor(); @@ -527,11 +501,6 @@ void __init setup_arch (char **cmdline_p) ((cpu_hz + 500) / 1000) % 1000); } - init_mm.start_code = (unsigned long) &_text; - init_mm.end_code = (unsigned long) &_etext; - init_mm.end_data = (unsigned long) &_edata; - init_mm.brk = (unsigned long) &_end; - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; parse_early_param(); -- cgit v1.2.3 From f9692b9501c339ec90647d8cd6ee5c106f072f9f Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 21 Mar 2007 16:16:50 +0100 Subject: [AVR32] Reserve framebuffer memory in early_parse_fbmem() With the current strategy of using the bootmem allocator to allocate or reserve framebuffer memory, there's a slight chance that the requested area has been taken by the boot allocator bitmap before we get around to reserving it. By inserting the framebuffer region as a reserved region as early as possible, we improve our chances for success and we make the region visible as a reserved region in dmesg and /proc/iomem without any extra work. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/setup.c | 68 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index d0a35a1b6a6..1682e2d61cf 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -191,21 +191,45 @@ find_free_region(const struct resource *mem, resource_size_t size, return target; } +static int __init +alloc_reserved_region(resource_size_t *start, resource_size_t size, + resource_size_t align, const char *name) +{ + struct resource *mem; + resource_size_t target; + int ret; + + for (mem = system_ram; mem; mem = mem->sibling) { + target = find_free_region(mem, size, align); + if (target <= mem->end) { + ret = add_reserved_region(target, target + size - 1, + name); + if (!ret) + *start = target; + return ret; + } + } + + return -ENOMEM; +} + /* * Early framebuffer allocation. Works as follows: * - If fbmem_size is zero, nothing will be allocated or reserved. * - If fbmem_start is zero when setup_bootmem() is called, - * fbmem_size bytes will be allocated from the bootmem allocator. + * a block of fbmem_size bytes will be reserved before bootmem + * initialization. It will be aligned to the largest page size + * that fbmem_size is a multiple of. * - If fbmem_start is nonzero, an area of size fbmem_size will be - * reserved at the physical address fbmem_start if necessary. If - * the area isn't in a memory region known to the kernel, it will - * be left alone. + * reserved at the physical address fbmem_start if possible. If + * it collides with other reserved memory, a different block of + * same size will be allocated, just as if fbmem_start was zero. * * Board-specific code may use these variables to set up platform data * for the framebuffer driver if fbmem_size is nonzero. */ -static unsigned long __initdata fbmem_start; -static unsigned long __initdata fbmem_size; +static resource_size_t __initdata fbmem_start; +static resource_size_t __initdata fbmem_size; /* * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for @@ -219,9 +243,39 @@ static unsigned long __initdata fbmem_size; */ static int __init early_parse_fbmem(char *p) { + int ret; + unsigned long align; + fbmem_size = memparse(p, &p); - if (*p == '@') + if (*p == '@') { fbmem_start = memparse(p, &p); + ret = add_reserved_region(fbmem_start, + fbmem_start + fbmem_size - 1, + "Framebuffer"); + if (ret) { + printk(KERN_WARNING + "Failed to reserve framebuffer memory\n"); + fbmem_start = 0; + } + } + + if (!fbmem_start) { + if ((fbmem_size & 0x000fffffUL) == 0) + align = 0x100000; /* 1 MiB */ + else if ((fbmem_size & 0x0000ffffUL) == 0) + align = 0x10000; /* 64 KiB */ + else + align = 0x1000; /* 4 KiB */ + + ret = alloc_reserved_region(&fbmem_start, fbmem_size, + align, "Framebuffer"); + if (ret) { + printk(KERN_WARNING + "Failed to allocate framebuffer memory\n"); + fbmem_size = 0; + } + } + return 0; } early_param("fbmem", early_parse_fbmem); -- cgit v1.2.3 From d80e2bb12606906fd0b5b5592f519852de8b0113 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 21 Mar 2007 16:23:41 +0100 Subject: [AVR32] Get rid of board_setup_fbmem() Since the core setup code takes care of both allocation and reservation of framebuffer memory, there's no need for this board- specific hook anymore. Replace it with two global variables, fbmem_start and fbmem_size, which can be used directly. Signed-off-by: Haavard Skinnemoen --- arch/avr32/boards/atstk1000/atstk1002.c | 4 +++- arch/avr32/boards/atstk1000/setup.c | 30 ------------------------------ arch/avr32/kernel/setup.c | 7 ++----- 3 files changed, 5 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 5974768a59e..abe6ca203fa 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -33,7 +33,7 @@ struct eth_addr { static struct eth_addr __initdata hw_addr[2]; static struct eth_platform_data __initdata eth_data[2]; -extern struct lcdc_platform_data atstk1000_fb0_data; +static struct lcdc_platform_data atstk1000_fb0_data; static struct spi_board_info spi0_board_info[] __initdata = { { @@ -148,6 +148,8 @@ static int __init atstk1002_init(void) set_hw_addr(at32_add_device_eth(0, ð_data[0])); at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); + atstk1000_fb0_data.fbmem_start = fbmem_start; + atstk1000_fb0_data.fbmem_size = fbmem_size; at32_add_device_lcdc(0, &atstk1000_fb0_data); return 0; diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c index 272c011802a..2bc4b88d7ed 100644 --- a/arch/avr32/boards/atstk1000/setup.c +++ b/arch/avr32/boards/atstk1000/setup.c @@ -18,33 +18,3 @@ /* Initialized by bootloader-specific startup code. */ struct tag *bootloader_tags __initdata; - -struct lcdc_platform_data __initdata atstk1000_fb0_data; - -void __init board_setup_fbmem(unsigned long fbmem_start, - unsigned long fbmem_size) -{ - if (!fbmem_size) - return; - - if (!fbmem_start) { - void *fbmem; - - fbmem = alloc_bootmem_low_pages(fbmem_size); - fbmem_start = __pa(fbmem); - } else { - pg_data_t *pgdat; - - for_each_online_pgdat(pgdat) { - if (fbmem_start >= pgdat->bdata->node_boot_start - && fbmem_start <= pgdat->bdata->node_low_pfn) - reserve_bootmem_node(pgdat, fbmem_start, - fbmem_size); - } - } - - printk("%luKiB framebuffer memory at address 0x%08lx\n", - fbmem_size >> 10, fbmem_start); - atstk1000_fb0_data.fbmem_start = fbmem_start; - atstk1000_fb0_data.fbmem_size = fbmem_size; -} diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index 1682e2d61cf..b279d66acf5 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -228,8 +228,8 @@ alloc_reserved_region(resource_size_t *start, resource_size_t size, * Board-specific code may use these variables to set up platform data * for the framebuffer driver if fbmem_size is nonzero. */ -static resource_size_t __initdata fbmem_start; -static resource_size_t __initdata fbmem_size; +resource_size_t __initdata fbmem_start; +resource_size_t __initdata fbmem_size; /* * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for @@ -561,13 +561,10 @@ void __init setup_arch (char **cmdline_p) setup_bootmem(); - board_setup_fbmem(fbmem_start, fbmem_size); - #ifdef CONFIG_VT conswitchp = &dummy_con; #endif paging_init(); - resource_init(); } -- cgit v1.2.3 From 9ca20a8366462c553c27216161c735937f9de108 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Thu, 12 Apr 2007 17:26:57 +0200 Subject: [AVR32] Board code for ATNGW100 Add board code and defconfig for the ATNGW100 Network Gateway kit. For more information about this board, see http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4102 Signed-off-by: Haavard Skinnemoen --- arch/avr32/Kconfig | 3 + arch/avr32/Makefile | 1 + arch/avr32/boards/atngw100/Makefile | 1 + arch/avr32/boards/atngw100/flash.c | 95 +++ arch/avr32/boards/atngw100/setup.c | 124 ++++ arch/avr32/configs/atngw100_defconfig | 1085 +++++++++++++++++++++++++++++++++ 6 files changed, 1309 insertions(+) create mode 100644 arch/avr32/boards/atngw100/Makefile create mode 100644 arch/avr32/boards/atngw100/flash.c create mode 100644 arch/avr32/boards/atngw100/setup.c create mode 100644 arch/avr32/configs/atngw100_defconfig (limited to 'arch') diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 7a1eb445c17..50fee549e1c 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -111,6 +111,9 @@ choice config BOARD_ATSTK1000 bool "ATSTK1000 evaluation board" select BOARD_ATSTK1002 if CPU_AT32AP7000 + +config BOARD_ATNGW100 + bool "ATNGW100 Network Gateway" endchoice choice diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile index 7b842e98efe..6115fc1f0cf 100644 --- a/arch/avr32/Makefile +++ b/arch/avr32/Makefile @@ -27,6 +27,7 @@ head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o head-y += arch/avr32/kernel/head.o core-$(CONFIG_PLATFORM_AT32AP) += arch/avr32/mach-at32ap/ core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/ +core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/ core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/ core-y += arch/avr32/kernel/ core-y += arch/avr32/mm/ diff --git a/arch/avr32/boards/atngw100/Makefile b/arch/avr32/boards/atngw100/Makefile new file mode 100644 index 00000000000..c740aa11675 --- /dev/null +++ b/arch/avr32/boards/atngw100/Makefile @@ -0,0 +1 @@ +obj-y += setup.o flash.o diff --git a/arch/avr32/boards/atngw100/flash.c b/arch/avr32/boards/atngw100/flash.c new file mode 100644 index 00000000000..f9b32a8eab9 --- /dev/null +++ b/arch/avr32/boards/atngw100/flash.c @@ -0,0 +1,95 @@ +/* + * ATNGW100 board-specific flash initialization + * + * Copyright (C) 2005-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include + +static struct smc_config flash_config __initdata = { + .ncs_read_setup = 0, + .nrd_setup = 40, + .ncs_write_setup = 0, + .nwe_setup = 10, + + .ncs_read_pulse = 80, + .nrd_pulse = 40, + .ncs_write_pulse = 65, + .nwe_pulse = 55, + + .read_cycle = 120, + .write_cycle = 120, + + .bus_width = 2, + .nrd_controlled = 1, + .nwe_controlled = 1, + .byte_write = 1, +}; + +static struct mtd_partition flash_parts[] = { + { + .name = "u-boot", + .offset = 0x00000000, + .size = 0x00020000, /* 128 KiB */ + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "root", + .offset = 0x00020000, + .size = 0x007d0000, + }, + { + .name = "env", + .offset = 0x007f0000, + .size = 0x00010000, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct physmap_flash_data flash_data = { + .width = 2, + .nr_parts = ARRAY_SIZE(flash_parts), + .parts = flash_parts, +}; + +static struct resource flash_resource = { + .start = 0x00000000, + .end = 0x007fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = 0, + .resource = &flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &flash_data, + }, +}; + +/* This needs to be called after the SMC has been initialized */ +static int __init atngw100_flash_init(void) +{ + int ret; + + ret = smc_set_configuration(0, &flash_config); + if (ret < 0) { + printk(KERN_ERR "atngw100: failed to set NOR flash timing\n"); + return ret; + } + + platform_device_register(&flash_device); + + return 0; +} +device_initcall(atngw100_flash_init); diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c new file mode 100644 index 00000000000..9bc37d4f668 --- /dev/null +++ b/arch/avr32/boards/atngw100/setup.c @@ -0,0 +1,124 @@ +/* + * Board-specific setup code for the ATNGW100 Network Gateway + * + * Copyright (C) 2005-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +/* Initialized by bootloader-specific startup code. */ +struct tag *bootloader_tags __initdata; + +struct eth_addr { + u8 addr[6]; +}; +static struct eth_addr __initdata hw_addr[2]; +static struct eth_platform_data __initdata eth_data[2]; + +static struct spi_board_info spi0_board_info[] __initdata = { + { + .modalias = "mtd_dataflash", + .max_speed_hz = 10000000, + .chip_select = 0, + }, +}; + +/* + * The next two functions should go away as the boot loader is + * supposed to initialize the macb address registers with a valid + * ethernet address. But we need to keep it around for a while until + * we can be reasonably sure the boot loader does this. + * + * The phy_id is ignored as the driver will probe for it. + */ +static int __init parse_tag_ethernet(struct tag *tag) +{ + int i; + + i = tag->u.ethernet.mac_index; + if (i < ARRAY_SIZE(hw_addr)) + memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, + sizeof(hw_addr[i].addr)); + + return 0; +} +__tagtable(ATAG_ETHERNET, parse_tag_ethernet); + +static void __init set_hw_addr(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + const u8 *addr; + void __iomem *regs; + struct clk *pclk; + + if (!res) + return; + if (pdev->id >= ARRAY_SIZE(hw_addr)) + return; + + addr = hw_addr[pdev->id].addr; + if (!is_valid_ether_addr(addr)) + return; + + /* + * Since this is board-specific code, we'll cheat and use the + * physical address directly as we happen to know that it's + * the same as the virtual address. + */ + regs = (void __iomem __force *)res->start; + pclk = clk_get(&pdev->dev, "pclk"); + if (!pclk) + return; + + clk_enable(pclk); + __raw_writel((addr[3] << 24) | (addr[2] << 16) + | (addr[1] << 8) | addr[0], regs + 0x98); + __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); + clk_disable(pclk); + clk_put(pclk); +} + +struct platform_device *at32_usart_map[1]; +unsigned int at32_nr_usarts = 1; + +void __init setup_board(void) +{ + at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */ + at32_setup_serial_console(0); +} + +static int __init atngw100_init(void) +{ + /* + * ATNGW100 uses 16-bit SDRAM interface, so we don't need to + * reserve any pins for it. + */ + + at32_add_system_devices(); + + at32_add_device_usart(0); + + set_hw_addr(at32_add_device_eth(0, ð_data[0])); + set_hw_addr(at32_add_device_eth(1, ð_data[1])); + + at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); + + return 0; +} +postcore_initcall(atngw100_init); diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig new file mode 100644 index 00000000000..c254ffcfa45 --- /dev/null +++ b/arch/avr32/configs/atngw100_defconfig @@ -0,0 +1,1085 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc6 +# Thu Apr 12 16:35:07 2007 +# +CONFIG_AVR32=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_TIME=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=1 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# System Type and features +# +CONFIG_SUBARCH_AVR32B=y +CONFIG_MMU=y +CONFIG_PERFORMANCE_COUNTERS=y +CONFIG_PLATFORM_AT32AP=y +CONFIG_CPU_AT32AP7000=y +# CONFIG_BOARD_ATSTK1000 is not set +CONFIG_BOARD_ATNGW100=y +CONFIG_LOADER_U_BOOT=y + +# +# Atmel AVR32 AP options +# +# CONFIG_AP7000_32_BIT_SMC is not set +CONFIG_AP7000_16_BIT_SMC=y +# CONFIG_AP7000_8_BIT_SMC is not set +CONFIG_LOAD_ADDRESS=0x10000000 +CONFIG_ENTRY_ADDRESS=0x90000000 +CONFIG_PHYS_OFFSET=0x10000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set +# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set +# CONFIG_NEED_NODE_MEMMAP_SIZE is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +# CONFIG_ARCH_SPARSEMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +# CONFIG_OWNERSHIP_TRACE is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_CMDLINE="" + +# +# Bus options +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_SUPPORT=y +# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +CONFIG_NF_CT_PROTO_GRE=m +# CONFIG_NF_CT_PROTO_SCTP is not set +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x80000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACB=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=850 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +CONFIG_CONFIGFS_FS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_KPROBES is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y -- cgit v1.2.3 From c0c3e81608fc300027f2131e351e67ab118cf24c Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 14 Mar 2007 13:59:13 +0100 Subject: [AVR32] Optimize the TLB miss handler Reorder some instructions and change the register usage to reduce the number of pipeline stalls. Also use the bfextu and bfins instructions for bitfield manipulations instead of shifting and masking. This makes gzipping a 80MB file approximately 2% faster. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/entry-avr32b.S | 54 ++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 484e08310f1..42657f1703b 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S @@ -100,55 +100,49 @@ dtlb_miss_write: .global tlb_miss_common tlb_miss_common: - mfsr r0, SYSREG_PTBR - mfsr r1, SYSREG_TLBEAR + mfsr r0, SYSREG_TLBEAR + mfsr r1, SYSREG_PTBR /* Is it the vmalloc space? */ - bld r1, 31 + bld r0, 31 brcs handle_vmalloc_miss /* First level lookup */ pgtbl_lookup: - lsr r2, r1, PGDIR_SHIFT - ld.w r0, r0[r2 << 2] - bld r0, _PAGE_BIT_PRESENT + lsr r2, r0, PGDIR_SHIFT + ld.w r3, r1[r2 << 2] + bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT + bld r3, _PAGE_BIT_PRESENT brcc page_table_not_present - /* TODO: Check access rights on page table if necessary */ - /* Translate to virtual address in P1. */ - andl r0, 0xf000 - sbr r0, 31 + andl r3, 0xf000 + sbr r3, 31 /* Second level lookup */ - lsl r1, (32 - PGDIR_SHIFT) - lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT - add r2, r0, r1 << 2 - ld.w r1, r2[0] - bld r1, _PAGE_BIT_PRESENT + ld.w r2, r3[r1 << 2] + mfsr r0, SYSREG_TLBARLO + bld r2, _PAGE_BIT_PRESENT brcc page_not_present /* Mark the page as accessed */ - sbr r1, _PAGE_BIT_ACCESSED - st.w r2[0], r1 + sbr r2, _PAGE_BIT_ACCESSED + st.w r3[r1 << 2], r2 /* Drop software flags */ - andl r1, _PAGE_FLAGS_HARDWARE_MASK & 0xffff - mtsr SYSREG_TLBELO, r1 + andl r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff + mtsr SYSREG_TLBELO, r2 /* Figure out which entry we want to replace */ - mfsr r0, SYSREG_TLBARLO + mfsr r1, SYSREG_MMUCR clz r2, r0 brcc 1f - mov r1, -1 /* All entries have been accessed, */ - mtsr SYSREG_TLBARLO, r1 /* so reset TLBAR */ - mov r2, 0 /* and start at 0 */ -1: mfsr r1, SYSREG_MMUCR - lsl r2, 14 - andl r1, 0x3fff, COH - or r1, r2 - mtsr SYSREG_MMUCR, r1 + mov r3, -1 /* All entries have been accessed, */ + mov r2, 0 /* so start at 0 */ + mtsr SYSREG_TLBARLO, r3 /* and reset TLBAR */ +1: bfins r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE + mtsr SYSREG_MMUCR, r1 tlbw tlbmiss_restore @@ -156,8 +150,8 @@ pgtbl_lookup: handle_vmalloc_miss: /* Simply do the lookup in init's page table */ - mov r0, lo(swapper_pg_dir) - orh r0, hi(swapper_pg_dir) + mov r1, lo(swapper_pg_dir) + orh r1, hi(swapper_pg_dir) rjmp pgtbl_lookup -- cgit v1.2.3 From 0277b378c3779e3c8a413afb7d4ee00fa24a5a26 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 26 Apr 2007 08:53:38 -0400 Subject: AVR32: Remove useless config option "GENERIC_BUST_SPINLOCK". Remove the clearly useless config option GENERIC_BUST_SPINLOCK, which is not used anywhere in the tree. Signed-off-by: Robert P. J. Day Signed-off-by: Haavard Skinnemoen --- arch/avr32/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 50fee549e1c..3ec76586877 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -57,9 +57,6 @@ config ARCH_HAS_ILOG2_U64 bool default n -config GENERIC_BUST_SPINLOCK - bool - config GENERIC_HWEIGHT bool default y -- cgit v1.2.3 From 29c380f5f06d0c5a320b9bb6f8987065e7b81c91 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 27 Apr 2007 16:01:04 +0200 Subject: [S390] memory detection: stop at first memory hole. If both sclp and diag memory detection don't work stop at the first memory hole. Otherwise the code might loop forever... Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/early.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 5e47936573f..50538e54561 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -253,11 +253,10 @@ static noinline __init void find_memory_chunks(unsigned long memsize) break; #endif /* - * Finish memory detection at the first hole, unless - * - we reached the hsa -> skip it. - * - we know there must be more. + * Finish memory detection at the first hole + * if storage size is unknown. */ - if (cc == -1UL && !memsize && old_addr != ADDR2G) + if (cc == -1UL && !memsize) break; if (memsize && addr >= memsize) break; -- cgit v1.2.3 From 6fc321fd7dd91f0592f37503219196835314fbb7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 27 Apr 2007 16:01:25 +0200 Subject: [S390] cio/ipl: Clean interface between cio and ipl code. Clean interface between cio and ipl code, so Peter stops complaining. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/ipl.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index f731185bf2b..a83cf1fdd8f 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -47,7 +47,7 @@ enum ipl_type { * Must be in data section since the bss section * is not cleared when these are accessed. */ -u16 ipl_devno __attribute__((__section__(".data"))) = 0; +static u16 ipl_devno __attribute__((__section__(".data"))) = 0; u32 ipl_flags __attribute__((__section__(".data"))) = 0; static char *ipl_type_str(enum ipl_type type) @@ -1038,6 +1038,27 @@ static int __init s390_ipl_init(void) __initcall(s390_ipl_init); +void __init ipl_save_parameters(void) +{ + struct cio_iplinfo iplinfo; + unsigned int *ipl_ptr; + void *src, *dst; + + if (cio_get_iplinfo(&iplinfo)) + return; + + ipl_devno = iplinfo.devno; + ipl_flags |= IPL_DEVNO_VALID; + if (!iplinfo.is_qdio) + return; + ipl_flags |= IPL_PARMBLOCK_VALID; + ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; + src = (void *)(unsigned long)*ipl_ptr; + dst = (void *)IPL_PARMBLOCK_ORIGIN; + memmove(dst, src, PAGE_SIZE); + *ipl_ptr = IPL_PARMBLOCK_ORIGIN; +} + static LIST_HEAD(rcall); static DEFINE_MUTEX(rcall_mutex); -- cgit v1.2.3 From 03ff9a235a0602724fc54916469b6e0939c62c9b Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2007 16:01:40 +0200 Subject: [S390] System call cleanup. Remove system call glue for sys_clone, sys_fork, sys_vfork, sys_execve, sys_sigreturn, sys_rt_sigreturn and sys_sigaltstack. Call do_execve from kernel_execve directly, move pt_regs to the right place and branch to sysc_return to start the user space program. This removes the last in-kernel system call. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 60 ++++++++++++----------- arch/s390/kernel/compat_signal.c | 14 +++--- arch/s390/kernel/entry.S | 87 +++++++++++++--------------------- arch/s390/kernel/entry64.S | 100 +++++++++++---------------------------- arch/s390/kernel/process.c | 82 +++++++++++++++++++------------- arch/s390/kernel/signal.c | 10 ++-- arch/s390/kernel/sys_s390.c | 20 -------- arch/s390/kernel/syscalls.S | 14 +++--- 8 files changed, 162 insertions(+), 225 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 664c669b185..5236fdb17fc 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -495,29 +495,34 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) * sys32_execve() executes a new program after the asm stub has set * things up for us. This should basically do what I want it to. */ -asmlinkage long -sys32_execve(struct pt_regs regs) +asmlinkage long sys32_execve(void) { - int error; - char * filename; + struct pt_regs *regs = task_pt_regs(current); + char *filename; + unsigned long result; + int rc; - filename = getname(compat_ptr(regs.orig_gpr2)); - error = PTR_ERR(filename); - if (IS_ERR(filename)) + filename = getname(compat_ptr(regs->orig_gpr2)); + if (IS_ERR(filename)) { + result = PTR_ERR(filename); goto out; - error = compat_do_execve(filename, compat_ptr(regs.gprs[3]), - compat_ptr(regs.gprs[4]), ®s); - if (error == 0) - { - task_lock(current); - current->ptrace &= ~PT_DTRACE; - task_unlock(current); - current->thread.fp_regs.fpc=0; - asm volatile("sfpc %0,0" : : "d" (0)); } + rc = compat_do_execve(filename, compat_ptr(regs->gprs[3]), + compat_ptr(regs->gprs[4]), regs); + if (rc) { + result = rc; + goto out_putname; + } + task_lock(current); + current->ptrace &= ~PT_DTRACE; + task_unlock(current); + current->thread.fp_regs.fpc=0; + asm volatile("sfpc %0,0" : : "d" (0)); + result = regs->gprs[2]; +out_putname: putname(filename); out: - return error; + return result; } @@ -918,19 +923,20 @@ asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count) return sys_write(fd, buf, count); } -asmlinkage long sys32_clone(struct pt_regs regs) +asmlinkage long sys32_clone(void) { - unsigned long clone_flags; - unsigned long newsp; + struct pt_regs *regs = task_pt_regs(current); + unsigned long clone_flags; + unsigned long newsp; int __user *parent_tidptr, *child_tidptr; - clone_flags = regs.gprs[3] & 0xffffffffUL; - newsp = regs.orig_gpr2 & 0x7fffffffUL; - parent_tidptr = compat_ptr(regs.gprs[4]); - child_tidptr = compat_ptr(regs.gprs[5]); - if (!newsp) - newsp = regs.gprs[15]; - return do_fork(clone_flags, newsp, ®s, 0, + clone_flags = regs->gprs[3] & 0xffffffffUL; + newsp = regs->orig_gpr2 & 0x7fffffffUL; + parent_tidptr = compat_ptr(regs->gprs[4]); + child_tidptr = compat_ptr(regs->gprs[5]); + if (!newsp) + newsp = regs->gprs[15]; + return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); } diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 887a9881d0d..80a54a0149a 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -255,9 +255,9 @@ sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, } asmlinkage long -sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss, - struct pt_regs *regs) +sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss) { + struct pt_regs *regs = task_pt_regs(current); stack_t kss, koss; unsigned long ss_sp; int ret, err = 0; @@ -344,8 +344,9 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) return 0; } -asmlinkage long sys32_sigreturn(struct pt_regs *regs) +asmlinkage long sys32_sigreturn(void) { + struct pt_regs *regs = task_pt_regs(current); sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; sigset_t set; @@ -370,8 +371,9 @@ badframe: return 0; } -asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) +asmlinkage long sys32_rt_sigreturn(void) { + struct pt_regs *regs = task_pt_regs(current); rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; sigset_t set; stack_t st; @@ -407,8 +409,8 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) return regs->gprs[2]; badframe: - force_sig(SIGSEGV, current); - return 0; + force_sig(SIGSEGV, current); + return 0; } /* diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index dddc3de3040..c8a2212014e 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -249,8 +249,6 @@ sysc_do_restart: bnz BASED(sysc_tracesys) basr %r14,%r8 # call sys_xxxx st %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! sysc_return: tm SP_PSW+1(%r15),0x01 # returning to user ? @@ -381,50 +379,37 @@ ret_from_fork: b BASED(sysc_return) # -# clone, fork, vfork, exec and sigreturn need glue, -# because they all expect pt_regs as parameter, -# but are called with different parameter. -# return-address is set up above +# kernel_execve function needs to deal with pt_regs that is not +# at the usual place # -sys_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lclone) - br %r1 # branch to sys_clone - -sys_fork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lfork) - br %r1 # branch to sys_fork - -sys_vfork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lvfork) - br %r1 # branch to sys_vfork - -sys_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lexecve) - lr %r12,%r14 # save return address - basr %r14,%r1 # call sys_execve - ltr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 - # in system_call/sysc_tracesys - -sys_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lsigreturn) - br %r1 # branch to sys_sigreturn - -sys_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lrt_sigreturn) - br %r1 # branch to sys_sigreturn - -sys_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lsigaltstack) - br %r1 # branch to sys_sigreturn + .globl kernel_execve +kernel_execve: + stm %r12,%r15,48(%r15) + lr %r14,%r15 + l %r13,__LC_SVC_NEW_PSW+4 + s %r15,BASED(.Lc_spsize) + st %r14,__SF_BACKCHAIN(%r15) + la %r12,SP_PTREGS(%r15) + xc 0(__PT_SIZE,%r12),0(%r12) + l %r1,BASED(.Ldo_execve) + lr %r5,%r12 + basr %r14,%r1 + ltr %r2,%r2 + be BASED(0f) + a %r15,BASED(.Lc_spsize) + lm %r12,%r15,48(%r15) + br %r14 + # execve succeeded. +0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts + l %r15,__LC_KERNEL_STACK # load ksp + s %r15,BASED(.Lc_spsize) # make room for registers & psw + l %r9,__LC_THREAD_INFO + mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs + xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + l %r1,BASED(.Lexecve_tail) + basr %r14,%r1 + b BASED(sysc_return) /* * Program check handler routine @@ -1031,19 +1016,11 @@ cleanup_io_leave_insn: .Ldo_extint: .long do_extint .Ldo_signal: .long do_signal .Lhandle_per: .long do_single_step +.Ldo_execve: .long do_execve +.Lexecve_tail: .long execve_tail .Ljump_table: .long pgm_check_table .Lschedule: .long schedule -.Lclone: .long sys_clone -.Lexecve: .long sys_execve -.Lfork: .long sys_fork -.Lrt_sigreturn: .long sys_rt_sigreturn -.Lrt_sigsuspend: - .long sys_rt_sigsuspend -.Lsigreturn: .long sys_sigreturn -.Lsigsuspend: .long sys_sigsuspend -.Lsigaltstack: .long sys_sigaltstack .Ltrace: .long syscall_trace -.Lvfork: .long sys_vfork .Lschedtail: .long schedule_tail .Lsysc_table: .long sys_call_table #ifdef CONFIG_TRACE_IRQFLAGS diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 0f758c329a5..93745fd8f55 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -244,8 +244,6 @@ sysc_noemu: jnz sysc_tracesys basr %r14,%r8 # call sys_xxxx stg %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! sysc_return: tm SP_PSW+1(%r15),0x01 # returning to user ? @@ -371,77 +369,35 @@ ret_from_fork: j sysc_return # -# clone, fork, vfork, exec and sigreturn need glue, -# because they all expect pt_regs as parameter, -# but are called with different parameter. -# return-address is set up above +# kernel_execve function needs to deal with pt_regs that is not +# at the usual place # -sys_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_clone # branch to sys_clone - -#ifdef CONFIG_COMPAT -sys32_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys32_clone # branch to sys32_clone -#endif - -sys_fork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_fork # branch to sys_fork - -sys_vfork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_vfork # branch to sys_vfork - -sys_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - lgr %r12,%r14 # save return address - brasl %r14,sys_execve # call sys_execve - ltgr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 6(%r12) # SKIP STG 2,SP_R2(15) in - # system_call/sysc_tracesys -#ifdef CONFIG_COMPAT -sys32_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - lgr %r12,%r14 # save return address - brasl %r14,sys32_execve # call sys32_execve - ltgr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 6(%r12) # SKIP STG 2,SP_R2(15) in - # system_call/sysc_tracesys -#endif - -sys_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_sigreturn # branch to sys_sigreturn - -#ifdef CONFIG_COMPAT -sys32_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_sigreturn # branch to sys32_sigreturn -#endif - -sys_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_rt_sigreturn # branch to sys_sigreturn - -#ifdef CONFIG_COMPAT -sys32_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_rt_sigreturn # branch to sys32_sigreturn -#endif - -sys_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_sigaltstack # branch to sys_sigreturn - -#ifdef CONFIG_COMPAT -sys32_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_sigaltstack_wrapper # branch to sys_sigreturn -#endif + .globl kernel_execve +kernel_execve: + stmg %r12,%r15,96(%r15) + lgr %r14,%r15 + aghi %r15,-SP_SIZE + stg %r14,__SF_BACKCHAIN(%r15) + la %r12,SP_PTREGS(%r15) + xc 0(__PT_SIZE,%r12),0(%r12) + lgr %r5,%r12 + brasl %r14,do_execve + ltgfr %r2,%r2 + je 0f + aghi %r15,SP_SIZE + lmg %r12,%r15,96(%r15) + br %r14 + # execve succeeded. +0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts + lg %r15,__LC_KERNEL_STACK # load ksp + aghi %r15,-SP_SIZE # make room for registers & psw + lg %r13,__LC_SVC_NEW_PSW+8 + lg %r9,__LC_THREAD_INFO + mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + brasl %r14,execve_tail + j sysc_return /* * Program check handler routine diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 5acfac654f9..11d9b019762 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -280,24 +280,26 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, return 0; } -asmlinkage long sys_fork(struct pt_regs regs) +asmlinkage long sys_fork(void) { - return do_fork(SIGCHLD, regs.gprs[15], ®s, 0, NULL, NULL); + struct pt_regs *regs = task_pt_regs(current); + return do_fork(SIGCHLD, regs->gprs[15], regs, 0, NULL, NULL); } -asmlinkage long sys_clone(struct pt_regs regs) +asmlinkage long sys_clone(void) { - unsigned long clone_flags; - unsigned long newsp; + struct pt_regs *regs = task_pt_regs(current); + unsigned long clone_flags; + unsigned long newsp; int __user *parent_tidptr, *child_tidptr; - clone_flags = regs.gprs[3]; - newsp = regs.orig_gpr2; - parent_tidptr = (int __user *) regs.gprs[4]; - child_tidptr = (int __user *) regs.gprs[5]; - if (!newsp) - newsp = regs.gprs[15]; - return do_fork(clone_flags, newsp, ®s, 0, + clone_flags = regs->gprs[3]; + newsp = regs->orig_gpr2; + parent_tidptr = (int __user *) regs->gprs[4]; + child_tidptr = (int __user *) regs->gprs[5]; + if (!newsp) + newsp = regs->gprs[15]; + return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); } @@ -311,40 +313,52 @@ asmlinkage long sys_clone(struct pt_regs regs) * do not have enough call-clobbered registers to hold all * the information you need. */ -asmlinkage long sys_vfork(struct pt_regs regs) +asmlinkage long sys_vfork(void) { + struct pt_regs *regs = task_pt_regs(current); return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, - regs.gprs[15], ®s, 0, NULL, NULL); + regs->gprs[15], regs, 0, NULL, NULL); +} + +asmlinkage void execve_tail(void) +{ + task_lock(current); + current->ptrace &= ~PT_DTRACE; + task_unlock(current); + current->thread.fp_regs.fpc = 0; + if (MACHINE_HAS_IEEE) + asm volatile("sfpc %0,%0" : : "d" (0)); } /* * sys_execve() executes a new program. */ -asmlinkage long sys_execve(struct pt_regs regs) +asmlinkage long sys_execve(void) { - int error; - char * filename; - - filename = getname((char __user *) regs.orig_gpr2); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, (char __user * __user *) regs.gprs[3], - (char __user * __user *) regs.gprs[4], ®s); - if (error == 0) { - task_lock(current); - current->ptrace &= ~PT_DTRACE; - task_unlock(current); - current->thread.fp_regs.fpc = 0; - if (MACHINE_HAS_IEEE) - asm volatile("sfpc %0,%0" : : "d" (0)); + struct pt_regs *regs = task_pt_regs(current); + char *filename; + unsigned long result; + int rc; + + filename = getname((char __user *) regs->orig_gpr2); + if (IS_ERR(filename)) { + result = PTR_ERR(filename); + goto out; } - putname(filename); + rc = do_execve(filename, (char __user * __user *) regs->gprs[3], + (char __user * __user *) regs->gprs[4], regs); + if (rc) { + result = rc; + goto out_putname; + } + execve_tail(); + result = regs->gprs[2]; +out_putname: + putname(filename); out: - return error; + return result; } - /* * fill in the FPU structure for a core dump. */ diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 554f9cf7499..3c41907799a 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -102,9 +102,9 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, } asmlinkage long -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, - struct pt_regs *regs) +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) { + struct pt_regs *regs = task_pt_regs(current); return do_sigaltstack(uss, uoss, regs->gprs[15]); } @@ -163,8 +163,9 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) return 0; } -asmlinkage long sys_sigreturn(struct pt_regs *regs) +asmlinkage long sys_sigreturn(void) { + struct pt_regs *regs = task_pt_regs(current); sigframe __user *frame = (sigframe __user *)regs->gprs[15]; sigset_t set; @@ -189,8 +190,9 @@ badframe: return 0; } -asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) +asmlinkage long sys_rt_sigreturn(void) { + struct pt_regs *regs = task_pt_regs(current); rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15]; sigset_t set; diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index 584ed95f338..3a77c22cda7 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -266,23 +266,3 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args) return -EFAULT; return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register const char *__arg1 asm("2") = filename; - register char *const*__arg2 asm("3") = argv; - register char *const*__arg3 asm("4") = envp; - register long __svcres asm("2"); - asm volatile( - "svc %b1" - : "=d" (__svcres) - : "i" (__NR_execve), - "0" (__arg1), - "d" (__arg2), - "d" (__arg3) : "memory"); - return __svcres; -} diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index c774f1069e1..cd8d321cd0c 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -10,7 +10,7 @@ NI_SYSCALL /* 0 */ SYSCALL(sys_exit,sys_exit,sys32_exit_wrapper) -SYSCALL(sys_fork_glue,sys_fork_glue,sys_fork_glue) +SYSCALL(sys_fork,sys_fork,sys_fork) SYSCALL(sys_read,sys_read,sys32_read_wrapper) SYSCALL(sys_write,sys_write,sys32_write_wrapper) SYSCALL(sys_open,sys_open,sys32_open_wrapper) /* 5 */ @@ -19,7 +19,7 @@ SYSCALL(sys_restart_syscall,sys_restart_syscall,sys_restart_syscall) SYSCALL(sys_creat,sys_creat,sys32_creat_wrapper) SYSCALL(sys_link,sys_link,sys32_link_wrapper) SYSCALL(sys_unlink,sys_unlink,sys32_unlink_wrapper) /* 10 */ -SYSCALL(sys_execve_glue,sys_execve_glue,sys32_execve_glue) +SYSCALL(sys_execve,sys_execve,sys32_execve) SYSCALL(sys_chdir,sys_chdir,sys32_chdir_wrapper) SYSCALL(sys_time,sys_ni_syscall,sys32_time_wrapper) /* old time syscall */ SYSCALL(sys_mknod,sys_mknod,sys32_mknod_wrapper) @@ -127,8 +127,8 @@ SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper) /* 115 */ SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper) SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper) SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper) -SYSCALL(sys_sigreturn_glue,sys_sigreturn_glue,sys32_sigreturn_glue) -SYSCALL(sys_clone_glue,sys_clone_glue,sys32_clone_glue) /* 120 */ +SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) +SYSCALL(sys_clone,sys_clone,sys32_clone) /* 120 */ SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper) SYSCALL(sys_newuname,s390x_newuname,sys32_newuname_wrapper) NI_SYSCALL /* modify_ldt for i386 */ @@ -181,7 +181,7 @@ SYSCALL(sys_nfsservctl,sys_nfsservctl,compat_sys_nfsservctl_wrapper) SYSCALL(sys_setresgid16,sys_ni_syscall,sys32_setresgid16_wrapper) /* 170 old setresgid16 syscall */ SYSCALL(sys_getresgid16,sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */ SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper) -SYSCALL(sys_rt_sigreturn_glue,sys_rt_sigreturn_glue,sys32_rt_sigreturn_glue) +SYSCALL(sys_rt_sigreturn,sys_rt_sigreturn,sys32_rt_sigreturn) SYSCALL(sys_rt_sigaction,sys_rt_sigaction,sys32_rt_sigaction_wrapper) SYSCALL(sys_rt_sigprocmask,sys_rt_sigprocmask,sys32_rt_sigprocmask_wrapper) /* 175 */ SYSCALL(sys_rt_sigpending,sys_rt_sigpending,sys32_rt_sigpending_wrapper) @@ -194,11 +194,11 @@ SYSCALL(sys_chown16,sys_ni_syscall,sys32_chown16_wrapper) /* old chown16 syscall SYSCALL(sys_getcwd,sys_getcwd,sys32_getcwd_wrapper) SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper) SYSCALL(sys_capset,sys_capset,sys32_capset_wrapper) /* 185 */ -SYSCALL(sys_sigaltstack_glue,sys_sigaltstack_glue,sys32_sigaltstack_glue) +SYSCALL(sys_sigaltstack,sys_sigaltstack,sys32_sigaltstack) SYSCALL(sys_sendfile,sys_sendfile64,sys32_sendfile_wrapper) NI_SYSCALL /* streams1 */ NI_SYSCALL /* streams2 */ -SYSCALL(sys_vfork_glue,sys_vfork_glue,sys_vfork_glue) /* 190 */ +SYSCALL(sys_vfork,sys_vfork,sys_vfork) /* 190 */ SYSCALL(sys_getrlimit,sys_getrlimit,compat_sys_getrlimit_wrapper) SYSCALL(sys_mmap2,sys_mmap2,sys32_mmap2_wrapper) SYSCALL(sys_truncate64,sys_ni_syscall,sys32_truncate64_wrapper) -- cgit v1.2.3 From bb11e3bdbac08f773a89f3ca287024a956ee8a12 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2007 16:01:41 +0200 Subject: [S390] Improved oops output. This patch adds two improvements to the oops output. First it adds an additional line after the PSW which decodes the different fields of it. Second a disassembler is added that decodes the instructions surrounding the faulting PSW. The output of a test oops now looks like this: kernel BUG at init/main.c:419 illegal operation: 0001 [#1] CPU: 0 Not tainted Process swapper (pid: 0, task: 0000000000464968, ksp: 00000000004be000) Krnl PSW : 0700000180000000 00000000000120b6 (rest_init+0x36/0x38) R:0 T:1 IO:1 EX:1 Key:0 M:0 W:0 P:0 AS:0 CC:0 PM:0 EA:3 Krnl GPRS: 0000000000000003 00000000004ba017 0000000000000022 0000000000000001 000000000003a5f6 0000000000000000 00000000004be6a8 0000000000000000 0000000000000000 00000000004b8200 0000000000003a50 0000000000008000 0000000000516368 000000000033d008 00000000000120b2 00000000004bdee0 Krnl Code: 00000000000120a6: e3e0f0980024 stg %r14,152(%r15) 00000000000120ac: c0e500014296 brasl %r14,3a5d8 00000000000120b2: a7f40001 brc 15,120b4 >00000000000120b6: 0707 bcr 0,%r7 00000000000120b8: eb7ff0500024 stmg %r7,%r15,80(%r15) 00000000000120be: c0d000195825 larl %r13,33d108 00000000000120c4: a7f13f00 tmll %r15,16128 00000000000120c8: a7840001 brc 8,120ca Call Trace: ([<00000000000120b2>] rest_init+0x32/0x38) [<00000000004be614>] start_kernel+0x37c/0x410 [<0000000000012020>] _ehead+0x20/0x80 Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/dis.c | 1278 +++++++++++++++++++++++++++++++++++++++++++++ arch/s390/kernel/traps.c | 55 +- 3 files changed, 1296 insertions(+), 39 deletions(-) create mode 100644 arch/s390/kernel/dis.c (limited to 'arch') diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 5492d25d7d6..3195d375bd5 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390_ext.o debug.o irq.o ipl.o + semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c new file mode 100644 index 00000000000..dabaf98943d --- /dev/null +++ b/arch/s390/kernel/dis.c @@ -0,0 +1,1278 @@ +/* + * arch/s390/kernel/dis.c + * + * Disassemble s390 instructions. + * + * Copyright IBM Corp. 2007 + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_64BIT +#define ONELONG "%08lx: " +#else /* CONFIG_64BIT */ +#define ONELONG "%016lx: " +#endif /* CONFIG_64BIT */ + +#define OPERAND_GPR 0x1 /* Operand printed as %rx */ +#define OPERAND_FPR 0x2 /* Operand printed as %fx */ +#define OPERAND_AR 0x4 /* Operand printed as %ax */ +#define OPERAND_CR 0x8 /* Operand printed as %cx */ +#define OPERAND_DISP 0x10 /* Operand printed as displacement */ +#define OPERAND_BASE 0x20 /* Operand printed as base register */ +#define OPERAND_INDEX 0x40 /* Operand printed as index register */ +#define OPERAND_PCREL 0x80 /* Operand printed as pc-relative symbol */ +#define OPERAND_SIGNED 0x100 /* Operand printed as signed value */ +#define OPERAND_LENGTH 0x200 /* Operand printed as length (+1) */ + +enum { + UNUSED, /* Indicates the end of the operand list */ + R_8, /* GPR starting at position 8 */ + R_12, /* GPR starting at position 12 */ + R_16, /* GPR starting at position 16 */ + R_20, /* GPR starting at position 20 */ + R_24, /* GPR starting at position 24 */ + R_28, /* GPR starting at position 28 */ + R_32, /* GPR starting at position 32 */ + F_8, /* FPR starting at position 8 */ + F_12, /* FPR starting at position 12 */ + F_16, /* FPR starting at position 16 */ + F_20, /* FPR starting at position 16 */ + F_24, /* FPR starting at position 24 */ + F_28, /* FPR starting at position 28 */ + F_32, /* FPR starting at position 32 */ + A_8, /* Access reg. starting at position 8 */ + A_12, /* Access reg. starting at position 12 */ + A_24, /* Access reg. starting at position 24 */ + A_28, /* Access reg. starting at position 28 */ + C_8, /* Control reg. starting at position 8 */ + C_12, /* Control reg. starting at position 12 */ + B_16, /* Base register starting at position 16 */ + B_32, /* Base register starting at position 32 */ + X_12, /* Index register starting at position 12 */ + D_20, /* Displacement starting at position 20 */ + D_36, /* Displacement starting at position 36 */ + D20_20, /* 20 bit displacement starting at 20 */ + L4_8, /* 4 bit length starting at position 8 */ + L4_12, /* 4 bit length starting at position 12 */ + L8_8, /* 8 bit length starting at position 8 */ + U4_8, /* 4 bit unsigned value starting at 8 */ + U4_12, /* 4 bit unsigned value starting at 12 */ + U4_16, /* 4 bit unsigned value starting at 16 */ + U4_20, /* 4 bit unsigned value starting at 20 */ + U8_8, /* 8 bit unsigned value starting at 8 */ + U8_16, /* 8 bit unsigned value starting at 16 */ + I16_16, /* 16 bit signed value starting at 16 */ + U16_16, /* 16 bit unsigned value starting at 16 */ + J16_16, /* PC relative jump offset at 16 */ + J32_16, /* PC relative long offset at 16 */ + I32_16, /* 32 bit signed value starting at 16 */ + U32_16, /* 32 bit unsigned value starting at 16 */ + M_16, /* 4 bit optional mask starting at 16 */ + RO_28, /* optional GPR starting at position 28 */ +}; + +/* + * Enumeration of the different instruction formats. + * For details consult the principles of operation. + */ +enum { + INSTR_INVALID, + INSTR_E, INSTR_RIE_RRP, INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, + INSTR_RIL_UP, INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP, + INSTR_RRE_00, INSTR_RRE_0R, INSTR_RRE_AA, INSTR_RRE_AR, INSTR_RRE_F0, + INSTR_RRE_FF, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF, INSTR_RRE_RR, + INSTR_RRE_RR_OPT, INSTR_RRF_F0FF, INSTR_RRF_FUFF, INSTR_RRF_M0RR, + INSTR_RRF_R0RR, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, + INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR, + INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD, INSTR_RSI_RRP, + INSTR_RSL_R0RD, INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, + INSTR_RSY_RURD, INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, + INSTR_RS_RRRD, INSTR_RS_RURD, INSTR_RXE_FRRD, INSTR_RXE_RRRD, + INSTR_RXF_FRRDF, INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RX_FRRD, + INSTR_RX_RRRD, INSTR_RX_URRD, INSTR_SIY_URD, INSTR_SI_URD, + INSTR_SSE_RDRD, INSTR_SSF_RRDRD, INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, + INSTR_SS_LLRDRD, INSTR_SS_RRRDRD, INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3, + INSTR_S_00, INSTR_S_RD, +}; + +struct operand { + int bits; /* The number of bits in the operand. */ + int shift; /* The number of bits to shift. */ + int flags; /* One bit syntax flags. */ +}; + +struct insn { + const char name[5]; + unsigned char opfrag; + unsigned char format; +}; + +static const struct operand operands[] = +{ + [UNUSED] = { 0, 0, 0 }, + [R_8] = { 4, 8, OPERAND_GPR }, + [R_12] = { 4, 12, OPERAND_GPR }, + [R_16] = { 4, 16, OPERAND_GPR }, + [R_20] = { 4, 20, OPERAND_GPR }, + [R_24] = { 4, 24, OPERAND_GPR }, + [R_28] = { 4, 28, OPERAND_GPR }, + [R_32] = { 4, 32, OPERAND_GPR }, + [F_8] = { 4, 8, OPERAND_FPR }, + [F_12] = { 4, 12, OPERAND_FPR }, + [F_16] = { 4, 16, OPERAND_FPR }, + [F_20] = { 4, 16, OPERAND_FPR }, + [F_24] = { 4, 24, OPERAND_FPR }, + [F_28] = { 4, 28, OPERAND_FPR }, + [F_32] = { 4, 32, OPERAND_FPR }, + [A_8] = { 4, 8, OPERAND_AR }, + [A_12] = { 4, 12, OPERAND_AR }, + [A_24] = { 4, 24, OPERAND_AR }, + [A_28] = { 4, 28, OPERAND_AR }, + [C_8] = { 4, 8, OPERAND_CR }, + [C_12] = { 4, 12, OPERAND_CR }, + [B_16] = { 4, 16, OPERAND_BASE | OPERAND_GPR }, + [B_32] = { 4, 32, OPERAND_BASE | OPERAND_GPR }, + [X_12] = { 4, 12, OPERAND_INDEX | OPERAND_GPR }, + [D_20] = { 12, 20, OPERAND_DISP }, + [D_36] = { 12, 36, OPERAND_DISP }, + [D20_20] = { 20, 20, OPERAND_DISP | OPERAND_SIGNED }, + [L4_8] = { 4, 8, OPERAND_LENGTH }, + [L4_12] = { 4, 12, OPERAND_LENGTH }, + [L8_8] = { 8, 8, OPERAND_LENGTH }, + [U4_8] = { 4, 8, 0 }, + [U4_12] = { 4, 12, 0 }, + [U4_16] = { 4, 16, 0 }, + [U4_20] = { 4, 20, 0 }, + [U8_8] = { 8, 8, 0 }, + [U8_16] = { 8, 16, 0 }, + [I16_16] = { 16, 16, OPERAND_SIGNED }, + [U16_16] = { 16, 16, 0 }, + [J16_16] = { 16, 16, OPERAND_PCREL }, + [J32_16] = { 32, 16, OPERAND_PCREL }, + [I32_16] = { 32, 16, OPERAND_SIGNED }, + [U32_16] = { 32, 16, 0 }, + [M_16] = { 4, 16, 0 }, + [RO_28] = { 4, 28, OPERAND_GPR } +}; + +static const unsigned char formats[][7] = { + [INSTR_E] = { 0xff, 0,0,0,0,0,0 }, /* e.g. pr */ + [INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, /* e.g. brxhg */ + [INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 }, /* e.g. brasl */ + [INSTR_RIL_UP] = { 0x0f, U4_8,J32_16,0,0,0,0 }, /* e.g. brcl */ + [INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 }, /* e.g. afi */ + [INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 }, /* e.g. alfi */ + [INSTR_RI_RI] = { 0x0f, R_8,I16_16,0,0,0,0 }, /* e.g. ahi */ + [INSTR_RI_RP] = { 0x0f, R_8,J16_16,0,0,0,0 }, /* e.g. brct */ + [INSTR_RI_RU] = { 0x0f, R_8,U16_16,0,0,0,0 }, /* e.g. tml */ + [INSTR_RI_UP] = { 0x0f, U4_8,J16_16,0,0,0,0 }, /* e.g. brc */ + [INSTR_RRE_00] = { 0xff, 0,0,0,0,0,0 }, /* e.g. palb */ + [INSTR_RRE_0R] = { 0xff, R_28,0,0,0,0,0 }, /* e.g. tb */ + [INSTR_RRE_AA] = { 0xff, A_24,A_28,0,0,0,0 }, /* e.g. cpya */ + [INSTR_RRE_AR] = { 0xff, A_24,R_28,0,0,0,0 }, /* e.g. sar */ + [INSTR_RRE_F0] = { 0xff, F_24,0,0,0,0,0 }, /* e.g. sqer */ + [INSTR_RRE_FF] = { 0xff, F_24,F_28,0,0,0,0 }, /* e.g. debr */ + [INSTR_RRE_R0] = { 0xff, R_24,0,0,0,0,0 }, /* e.g. ipm */ + [INSTR_RRE_RA] = { 0xff, R_24,A_28,0,0,0,0 }, /* e.g. ear */ + [INSTR_RRE_RF] = { 0xff, R_24,F_28,0,0,0,0 }, /* e.g. cefbr */ + [INSTR_RRE_RR] = { 0xff, R_24,R_28,0,0,0,0 }, /* e.g. lura */ + [INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 }, /* efpc, sfpc */ + [INSTR_RRF_F0FF] = { 0xff, F_16,F_24,F_28,0,0,0 }, /* e.g. madbr */ + [INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },/* e.g. didbr */ + [INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },/* e.g. .insn */ + [INSTR_RRF_R0RR] = { 0xff, R_24,R_28,R_16,0,0,0 }, /* e.g. idte */ + [INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 }, /* e.g. fixr */ + [INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 }, /* e.g. cfebr */ + [INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 }, /* e.g. sske */ + [INSTR_RR_FF] = { 0xff, F_8,F_12,0,0,0,0 }, /* e.g. adr */ + [INSTR_RR_R0] = { 0xff, R_8, 0,0,0,0,0 }, /* e.g. spm */ + [INSTR_RR_RR] = { 0xff, R_8,R_12,0,0,0,0 }, /* e.g. lr */ + [INSTR_RR_U0] = { 0xff, U8_8, 0,0,0,0,0 }, /* e.g. svc */ + [INSTR_RR_UR] = { 0xff, U4_8,R_12,0,0,0,0 }, /* e.g. bcr */ + [INSTR_RSE_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 }, /* e.g. lmh */ + [INSTR_RSE_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, /* e.g. lmh */ + [INSTR_RSE_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icmh */ + [INSTR_RSL_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, /* e.g. tp */ + [INSTR_RSI_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, /* e.g. brxh */ + [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },/* e.g. stmy */ + [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, + /* e.g. icmh */ + [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 },/* e.g. lamy */ + [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },/* e.g. lamy */ + [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, /* e.g. lam */ + [INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, /* e.g. lctl */ + [INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, /* e.g. sll */ + [INSTR_RS_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 }, /* e.g. cs */ + [INSTR_RS_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icm */ + [INSTR_RXE_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 }, /* e.g. axbr */ + [INSTR_RXE_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 }, /* e.g. lg */ + [INSTR_RXF_FRRDF] = { 0xff, F_32,F_8,D_20,X_12,B_16,0 }, + /* e.g. madb */ + [INSTR_RXY_RRRD] = { 0xff, R_8,D20_20,X_12,B_16,0,0 },/* e.g. ly */ + [INSTR_RXY_FRRD] = { 0xff, F_8,D20_20,X_12,B_16,0,0 },/* e.g. ley */ + [INSTR_RX_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 }, /* e.g. ae */ + [INSTR_RX_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 }, /* e.g. l */ + [INSTR_RX_URRD] = { 0x00, U4_8,D_20,X_12,B_16,0,0 }, /* e.g. bc */ + [INSTR_SI_URD] = { 0x00, D_20,B_16,U8_8,0,0,0 }, /* e.g. cli */ + [INSTR_SIY_URD] = { 0xff, D20_20,B_16,U8_8,0,0,0 }, /* e.g. tmy */ + [INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 }, /* e.g. mvsdk */ + [INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 }, + /* e.g. mvc */ + [INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 }, + /* e.g. srp */ + [INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 }, + /* e.g. pack */ + [INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 }, + /* e.g. mvck */ + [INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 }, + /* e.g. plo */ + [INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 }, + /* e.g. lmd */ + [INSTR_S_00] = { 0xff, 0,0,0,0,0,0 }, /* e.g. hsch */ + [INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 }, /* e.g. lpsw */ + [INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 }, + /* e.g. mvcos */ +}; + +static struct insn opcode[] = { +#ifdef CONFIG_64BIT + { "lmd", 0xef, INSTR_SS_RRRDRD3 }, +#endif + { "spm", 0x04, INSTR_RR_R0 }, + { "balr", 0x05, INSTR_RR_RR }, + { "bctr", 0x06, INSTR_RR_RR }, + { "bcr", 0x07, INSTR_RR_UR }, + { "svc", 0x0a, INSTR_RR_U0 }, + { "bsm", 0x0b, INSTR_RR_RR }, + { "bassm", 0x0c, INSTR_RR_RR }, + { "basr", 0x0d, INSTR_RR_RR }, + { "mvcl", 0x0e, INSTR_RR_RR }, + { "clcl", 0x0f, INSTR_RR_RR }, + { "lpr", 0x10, INSTR_RR_RR }, + { "lnr", 0x11, INSTR_RR_RR }, + { "ltr", 0x12, INSTR_RR_RR }, + { "lcr", 0x13, INSTR_RR_RR }, + { "nr", 0x14, INSTR_RR_RR }, + { "clr", 0x15, INSTR_RR_RR }, + { "or", 0x16, INSTR_RR_RR }, + { "xr", 0x17, INSTR_RR_RR }, + { "lr", 0x18, INSTR_RR_RR }, + { "cr", 0x19, INSTR_RR_RR }, + { "ar", 0x1a, INSTR_RR_RR }, + { "sr", 0x1b, INSTR_RR_RR }, + { "mr", 0x1c, INSTR_RR_RR }, + { "dr", 0x1d, INSTR_RR_RR }, + { "alr", 0x1e, INSTR_RR_RR }, + { "slr", 0x1f, INSTR_RR_RR }, + { "lpdr", 0x20, INSTR_RR_FF }, + { "lndr", 0x21, INSTR_RR_FF }, + { "ltdr", 0x22, INSTR_RR_FF }, + { "lcdr", 0x23, INSTR_RR_FF }, + { "hdr", 0x24, INSTR_RR_FF }, + { "ldxr", 0x25, INSTR_RR_FF }, + { "lrdr", 0x25, INSTR_RR_FF }, + { "mxr", 0x26, INSTR_RR_FF }, + { "mxdr", 0x27, INSTR_RR_FF }, + { "ldr", 0x28, INSTR_RR_FF }, + { "cdr", 0x29, INSTR_RR_FF }, + { "adr", 0x2a, INSTR_RR_FF }, + { "sdr", 0x2b, INSTR_RR_FF }, + { "mdr", 0x2c, INSTR_RR_FF }, + { "ddr", 0x2d, INSTR_RR_FF }, + { "awr", 0x2e, INSTR_RR_FF }, + { "swr", 0x2f, INSTR_RR_FF }, + { "lper", 0x30, INSTR_RR_FF }, + { "lner", 0x31, INSTR_RR_FF }, + { "lter", 0x32, INSTR_RR_FF }, + { "lcer", 0x33, INSTR_RR_FF }, + { "her", 0x34, INSTR_RR_FF }, + { "ledr", 0x35, INSTR_RR_FF }, + { "lrer", 0x35, INSTR_RR_FF }, + { "axr", 0x36, INSTR_RR_FF }, + { "sxr", 0x37, INSTR_RR_FF }, + { "ler", 0x38, INSTR_RR_FF }, + { "cer", 0x39, INSTR_RR_FF }, + { "aer", 0x3a, INSTR_RR_FF }, + { "ser", 0x3b, INSTR_RR_FF }, + { "mder", 0x3c, INSTR_RR_FF }, + { "mer", 0x3c, INSTR_RR_FF }, + { "der", 0x3d, INSTR_RR_FF }, + { "aur", 0x3e, INSTR_RR_FF }, + { "sur", 0x3f, INSTR_RR_FF }, + { "sth", 0x40, INSTR_RX_RRRD }, + { "la", 0x41, INSTR_RX_RRRD }, + { "stc", 0x42, INSTR_RX_RRRD }, + { "ic", 0x43, INSTR_RX_RRRD }, + { "ex", 0x44, INSTR_RX_RRRD }, + { "bal", 0x45, INSTR_RX_RRRD }, + { "bct", 0x46, INSTR_RX_RRRD }, + { "bc", 0x47, INSTR_RX_URRD }, + { "lh", 0x48, INSTR_RX_RRRD }, + { "ch", 0x49, INSTR_RX_RRRD }, + { "ah", 0x4a, INSTR_RX_RRRD }, + { "sh", 0x4b, INSTR_RX_RRRD }, + { "mh", 0x4c, INSTR_RX_RRRD }, + { "bas", 0x4d, INSTR_RX_RRRD }, + { "cvd", 0x4e, INSTR_RX_RRRD }, + { "cvb", 0x4f, INSTR_RX_RRRD }, + { "st", 0x50, INSTR_RX_RRRD }, + { "lae", 0x51, INSTR_RX_RRRD }, + { "n", 0x54, INSTR_RX_RRRD }, + { "cl", 0x55, INSTR_RX_RRRD }, + { "o", 0x56, INSTR_RX_RRRD }, + { "x", 0x57, INSTR_RX_RRRD }, + { "l", 0x58, INSTR_RX_RRRD }, + { "c", 0x59, INSTR_RX_RRRD }, + { "a", 0x5a, INSTR_RX_RRRD }, + { "s", 0x5b, INSTR_RX_RRRD }, + { "m", 0x5c, INSTR_RX_RRRD }, + { "d", 0x5d, INSTR_RX_RRRD }, + { "al", 0x5e, INSTR_RX_RRRD }, + { "sl", 0x5f, INSTR_RX_RRRD }, + { "std", 0x60, INSTR_RX_FRRD }, + { "mxd", 0x67, INSTR_RX_FRRD }, + { "ld", 0x68, INSTR_RX_FRRD }, + { "cd", 0x69, INSTR_RX_FRRD }, + { "ad", 0x6a, INSTR_RX_FRRD }, + { "sd", 0x6b, INSTR_RX_FRRD }, + { "md", 0x6c, INSTR_RX_FRRD }, + { "dd", 0x6d, INSTR_RX_FRRD }, + { "aw", 0x6e, INSTR_RX_FRRD }, + { "sw", 0x6f, INSTR_RX_FRRD }, + { "ste", 0x70, INSTR_RX_FRRD }, + { "ms", 0x71, INSTR_RX_RRRD }, + { "le", 0x78, INSTR_RX_FRRD }, + { "ce", 0x79, INSTR_RX_FRRD }, + { "ae", 0x7a, INSTR_RX_FRRD }, + { "se", 0x7b, INSTR_RX_FRRD }, + { "mde", 0x7c, INSTR_RX_FRRD }, + { "me", 0x7c, INSTR_RX_FRRD }, + { "de", 0x7d, INSTR_RX_FRRD }, + { "au", 0x7e, INSTR_RX_FRRD }, + { "su", 0x7f, INSTR_RX_FRRD }, + { "ssm", 0x80, INSTR_S_RD }, + { "lpsw", 0x82, INSTR_S_RD }, + { "diag", 0x83, INSTR_RS_RRRD }, + { "brxh", 0x84, INSTR_RSI_RRP }, + { "brxle", 0x85, INSTR_RSI_RRP }, + { "bxh", 0x86, INSTR_RS_RRRD }, + { "bxle", 0x87, INSTR_RS_RRRD }, + { "srl", 0x88, INSTR_RS_R0RD }, + { "sll", 0x89, INSTR_RS_R0RD }, + { "sra", 0x8a, INSTR_RS_R0RD }, + { "sla", 0x8b, INSTR_RS_R0RD }, + { "srdl", 0x8c, INSTR_RS_R0RD }, + { "sldl", 0x8d, INSTR_RS_R0RD }, + { "srda", 0x8e, INSTR_RS_R0RD }, + { "slda", 0x8f, INSTR_RS_R0RD }, + { "stm", 0x90, INSTR_RS_RRRD }, + { "tm", 0x91, INSTR_SI_URD }, + { "mvi", 0x92, INSTR_SI_URD }, + { "ts", 0x93, INSTR_S_RD }, + { "ni", 0x94, INSTR_SI_URD }, + { "cli", 0x95, INSTR_SI_URD }, + { "oi", 0x96, INSTR_SI_URD }, + { "xi", 0x97, INSTR_SI_URD }, + { "lm", 0x98, INSTR_RS_RRRD }, + { "trace", 0x99, INSTR_RS_RRRD }, + { "lam", 0x9a, INSTR_RS_AARD }, + { "stam", 0x9b, INSTR_RS_AARD }, + { "mvcle", 0xa8, INSTR_RS_RRRD }, + { "clcle", 0xa9, INSTR_RS_RRRD }, + { "stnsm", 0xac, INSTR_SI_URD }, + { "stosm", 0xad, INSTR_SI_URD }, + { "sigp", 0xae, INSTR_RS_RRRD }, + { "mc", 0xaf, INSTR_SI_URD }, + { "lra", 0xb1, INSTR_RX_RRRD }, + { "stctl", 0xb6, INSTR_RS_CCRD }, + { "lctl", 0xb7, INSTR_RS_CCRD }, + { "cs", 0xba, INSTR_RS_RRRD }, + { "cds", 0xbb, INSTR_RS_RRRD }, + { "clm", 0xbd, INSTR_RS_RURD }, + { "stcm", 0xbe, INSTR_RS_RURD }, + { "icm", 0xbf, INSTR_RS_RURD }, + { "mvn", 0xd1, INSTR_SS_L0RDRD }, + { "mvc", 0xd2, INSTR_SS_L0RDRD }, + { "mvz", 0xd3, INSTR_SS_L0RDRD }, + { "nc", 0xd4, INSTR_SS_L0RDRD }, + { "clc", 0xd5, INSTR_SS_L0RDRD }, + { "oc", 0xd6, INSTR_SS_L0RDRD }, + { "xc", 0xd7, INSTR_SS_L0RDRD }, + { "mvck", 0xd9, INSTR_SS_RRRDRD }, + { "mvcp", 0xda, INSTR_SS_RRRDRD }, + { "mvcs", 0xdb, INSTR_SS_RRRDRD }, + { "tr", 0xdc, INSTR_SS_L0RDRD }, + { "trt", 0xdd, INSTR_SS_L0RDRD }, + { "ed", 0xde, INSTR_SS_L0RDRD }, + { "edmk", 0xdf, INSTR_SS_L0RDRD }, + { "pku", 0xe1, INSTR_SS_L0RDRD }, + { "unpku", 0xe2, INSTR_SS_L0RDRD }, + { "mvcin", 0xe8, INSTR_SS_L0RDRD }, + { "pka", 0xe9, INSTR_SS_L0RDRD }, + { "unpka", 0xea, INSTR_SS_L0RDRD }, + { "plo", 0xee, INSTR_SS_RRRDRD2 }, + { "srp", 0xf0, INSTR_SS_LIRDRD }, + { "mvo", 0xf1, INSTR_SS_LLRDRD }, + { "pack", 0xf2, INSTR_SS_LLRDRD }, + { "unpk", 0xf3, INSTR_SS_LLRDRD }, + { "zap", 0xf8, INSTR_SS_LLRDRD }, + { "cp", 0xf9, INSTR_SS_LLRDRD }, + { "ap", 0xfa, INSTR_SS_LLRDRD }, + { "sp", 0xfb, INSTR_SS_LLRDRD }, + { "mp", 0xfc, INSTR_SS_LLRDRD }, + { "dp", 0xfd, INSTR_SS_LLRDRD }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_01[] = { +#ifdef CONFIG_64BIT + { "sam64", 0x0e, INSTR_E }, +#endif + { "pr", 0x01, INSTR_E }, + { "upt", 0x02, INSTR_E }, + { "sckpf", 0x07, INSTR_E }, + { "tam", 0x0b, INSTR_E }, + { "sam24", 0x0c, INSTR_E }, + { "sam31", 0x0d, INSTR_E }, + { "trap2", 0xff, INSTR_E }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_a5[] = { +#ifdef CONFIG_64BIT + { "iihh", 0x00, INSTR_RI_RU }, + { "iihl", 0x01, INSTR_RI_RU }, + { "iilh", 0x02, INSTR_RI_RU }, + { "iill", 0x03, INSTR_RI_RU }, + { "nihh", 0x04, INSTR_RI_RU }, + { "nihl", 0x05, INSTR_RI_RU }, + { "nilh", 0x06, INSTR_RI_RU }, + { "nill", 0x07, INSTR_RI_RU }, + { "oihh", 0x08, INSTR_RI_RU }, + { "oihl", 0x09, INSTR_RI_RU }, + { "oilh", 0x0a, INSTR_RI_RU }, + { "oill", 0x0b, INSTR_RI_RU }, + { "llihh", 0x0c, INSTR_RI_RU }, + { "llihl", 0x0d, INSTR_RI_RU }, + { "llilh", 0x0e, INSTR_RI_RU }, + { "llill", 0x0f, INSTR_RI_RU }, +#endif + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_a7[] = { +#ifdef CONFIG_64BIT + { "tmhh", 0x02, INSTR_RI_RU }, + { "tmhl", 0x03, INSTR_RI_RU }, + { "brctg", 0x07, INSTR_RI_RP }, + { "lghi", 0x09, INSTR_RI_RI }, + { "aghi", 0x0b, INSTR_RI_RI }, + { "mghi", 0x0d, INSTR_RI_RI }, + { "cghi", 0x0f, INSTR_RI_RI }, +#endif + { "tmlh", 0x00, INSTR_RI_RU }, + { "tmll", 0x01, INSTR_RI_RU }, + { "brc", 0x04, INSTR_RI_UP }, + { "bras", 0x05, INSTR_RI_RP }, + { "brct", 0x06, INSTR_RI_RP }, + { "lhi", 0x08, INSTR_RI_RI }, + { "ahi", 0x0a, INSTR_RI_RI }, + { "mhi", 0x0c, INSTR_RI_RI }, + { "chi", 0x0e, INSTR_RI_RI }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_b2[] = { +#ifdef CONFIG_64BIT + { "sske", 0x2b, INSTR_RRF_M0RR }, + { "stckf", 0x7c, INSTR_S_RD }, + { "cu21", 0xa6, INSTR_RRF_M0RR }, + { "cuutf", 0xa6, INSTR_RRF_M0RR }, + { "cu12", 0xa7, INSTR_RRF_M0RR }, + { "cutfu", 0xa7, INSTR_RRF_M0RR }, + { "stfle", 0xb0, INSTR_S_RD }, + { "lpswe", 0xb2, INSTR_S_RD }, +#endif + { "stidp", 0x02, INSTR_S_RD }, + { "sck", 0x04, INSTR_S_RD }, + { "stck", 0x05, INSTR_S_RD }, + { "sckc", 0x06, INSTR_S_RD }, + { "stckc", 0x07, INSTR_S_RD }, + { "spt", 0x08, INSTR_S_RD }, + { "stpt", 0x09, INSTR_S_RD }, + { "spka", 0x0a, INSTR_S_RD }, + { "ipk", 0x0b, INSTR_S_00 }, + { "ptlb", 0x0d, INSTR_S_00 }, + { "spx", 0x10, INSTR_S_RD }, + { "stpx", 0x11, INSTR_S_RD }, + { "stap", 0x12, INSTR_S_RD }, + { "sie", 0x14, INSTR_S_RD }, + { "pc", 0x18, INSTR_S_RD }, + { "sac", 0x19, INSTR_S_RD }, + { "cfc", 0x1a, INSTR_S_RD }, + { "ipte", 0x21, INSTR_RRE_RR }, + { "ipm", 0x22, INSTR_RRE_R0 }, + { "ivsk", 0x23, INSTR_RRE_RR }, + { "iac", 0x24, INSTR_RRE_R0 }, + { "ssar", 0x25, INSTR_RRE_R0 }, + { "epar", 0x26, INSTR_RRE_R0 }, + { "esar", 0x27, INSTR_RRE_R0 }, + { "pt", 0x28, INSTR_RRE_RR }, + { "iske", 0x29, INSTR_RRE_RR }, + { "rrbe", 0x2a, INSTR_RRE_RR }, + { "sske", 0x2b, INSTR_RRE_RR }, + { "tb", 0x2c, INSTR_RRE_0R }, + { "dxr", 0x2d, INSTR_RRE_F0 }, + { "pgin", 0x2e, INSTR_RRE_RR }, + { "pgout", 0x2f, INSTR_RRE_RR }, + { "csch", 0x30, INSTR_S_00 }, + { "hsch", 0x31, INSTR_S_00 }, + { "msch", 0x32, INSTR_S_RD }, + { "ssch", 0x33, INSTR_S_RD }, + { "stsch", 0x34, INSTR_S_RD }, + { "tsch", 0x35, INSTR_S_RD }, + { "tpi", 0x36, INSTR_S_RD }, + { "sal", 0x37, INSTR_S_00 }, + { "rsch", 0x38, INSTR_S_00 }, + { "stcrw", 0x39, INSTR_S_RD }, + { "stcps", 0x3a, INSTR_S_RD }, + { "rchp", 0x3b, INSTR_S_00 }, + { "schm", 0x3c, INSTR_S_00 }, + { "bakr", 0x40, INSTR_RRE_RR }, + { "cksm", 0x41, INSTR_RRE_RR }, + { "sqdr", 0x44, INSTR_RRE_F0 }, + { "sqer", 0x45, INSTR_RRE_F0 }, + { "stura", 0x46, INSTR_RRE_RR }, + { "msta", 0x47, INSTR_RRE_R0 }, + { "palb", 0x48, INSTR_RRE_00 }, + { "ereg", 0x49, INSTR_RRE_RR }, + { "esta", 0x4a, INSTR_RRE_RR }, + { "lura", 0x4b, INSTR_RRE_RR }, + { "tar", 0x4c, INSTR_RRE_AR }, + { "cpya", INSTR_RRE_AA }, + { "sar", 0x4e, INSTR_RRE_AR }, + { "ear", 0x4f, INSTR_RRE_RA }, + { "csp", 0x50, INSTR_RRE_RR }, + { "msr", 0x52, INSTR_RRE_RR }, + { "mvpg", 0x54, INSTR_RRE_RR }, + { "mvst", 0x55, INSTR_RRE_RR }, + { "cuse", 0x57, INSTR_RRE_RR }, + { "bsg", 0x58, INSTR_RRE_RR }, + { "bsa", 0x5a, INSTR_RRE_RR }, + { "clst", 0x5d, INSTR_RRE_RR }, + { "srst", 0x5e, INSTR_RRE_RR }, + { "cmpsc", 0x63, INSTR_RRE_RR }, + { "cmpsc", 0x63, INSTR_RRE_RR }, + { "siga", 0x74, INSTR_S_RD }, + { "xsch", 0x76, INSTR_S_00 }, + { "rp", 0x77, INSTR_S_RD }, + { "stcke", 0x78, INSTR_S_RD }, + { "sacf", 0x79, INSTR_S_RD }, + { "stsi", 0x7d, INSTR_S_RD }, + { "srnm", 0x99, INSTR_S_RD }, + { "stfpc", 0x9c, INSTR_S_RD }, + { "lfpc", 0x9d, INSTR_S_RD }, + { "tre", 0xa5, INSTR_RRE_RR }, + { "cuutf", 0xa6, INSTR_RRE_RR }, + { "cutfu", 0xa7, INSTR_RRE_RR }, + { "stfl", 0xb1, INSTR_S_RD }, + { "trap4", 0xff, INSTR_S_RD }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_b3[] = { +#ifdef CONFIG_64BIT + { "maylr", 0x38, INSTR_RRF_F0FF }, + { "mylr", 0x39, INSTR_RRF_F0FF }, + { "mayr", 0x3a, INSTR_RRF_F0FF }, + { "myr", 0x3b, INSTR_RRF_F0FF }, + { "mayhr", 0x3c, INSTR_RRF_F0FF }, + { "myhr", 0x3d, INSTR_RRF_F0FF }, + { "cegbr", 0xa4, INSTR_RRE_RR }, + { "cdgbr", 0xa5, INSTR_RRE_RR }, + { "cxgbr", 0xa6, INSTR_RRE_RR }, + { "cgebr", 0xa8, INSTR_RRF_U0RF }, + { "cgdbr", 0xa9, INSTR_RRF_U0RF }, + { "cgxbr", 0xaa, INSTR_RRF_U0RF }, + { "cfer", 0xb8, INSTR_RRF_U0RF }, + { "cfdr", 0xb9, INSTR_RRF_U0RF }, + { "cfxr", 0xba, INSTR_RRF_U0RF }, + { "cegr", 0xc4, INSTR_RRE_RR }, + { "cdgr", 0xc5, INSTR_RRE_RR }, + { "cxgr", 0xc6, INSTR_RRE_RR }, + { "cger", 0xc8, INSTR_RRF_U0RF }, + { "cgdr", 0xc9, INSTR_RRF_U0RF }, + { "cgxr", 0xca, INSTR_RRF_U0RF }, +#endif + { "lpebr", 0x00, INSTR_RRE_FF }, + { "lnebr", 0x01, INSTR_RRE_FF }, + { "ltebr", 0x02, INSTR_RRE_FF }, + { "lcebr", 0x03, INSTR_RRE_FF }, + { "ldebr", 0x04, INSTR_RRE_FF }, + { "lxdbr", 0x05, INSTR_RRE_FF }, + { "lxebr", 0x06, INSTR_RRE_FF }, + { "mxdbr", 0x07, INSTR_RRE_FF }, + { "kebr", 0x08, INSTR_RRE_FF }, + { "cebr", 0x09, INSTR_RRE_FF }, + { "aebr", 0x0a, INSTR_RRE_FF }, + { "sebr", 0x0b, INSTR_RRE_FF }, + { "mdebr", 0x0c, INSTR_RRE_FF }, + { "debr", 0x0d, INSTR_RRE_FF }, + { "maebr", 0x0e, INSTR_RRF_F0FF }, + { "msebr", 0x0f, INSTR_RRF_F0FF }, + { "lpdbr", 0x10, INSTR_RRE_FF }, + { "lndbr", 0x11, INSTR_RRE_FF }, + { "ltdbr", 0x12, INSTR_RRE_FF }, + { "lcdbr", 0x13, INSTR_RRE_FF }, + { "sqebr", 0x14, INSTR_RRE_FF }, + { "sqdbr", 0x15, INSTR_RRE_FF }, + { "sqxbr", 0x16, INSTR_RRE_FF }, + { "meebr", 0x17, INSTR_RRE_FF }, + { "kdbr", 0x18, INSTR_RRE_FF }, + { "cdbr", 0x19, INSTR_RRE_FF }, + { "adbr", 0x1a, INSTR_RRE_FF }, + { "sdbr", 0x1b, INSTR_RRE_FF }, + { "mdbr", 0x1c, INSTR_RRE_FF }, + { "ddbr", 0x1d, INSTR_RRE_FF }, + { "madbr", 0x1e, INSTR_RRF_F0FF }, + { "msdbr", 0x1f, INSTR_RRF_F0FF }, + { "lder", 0x24, INSTR_RRE_FF }, + { "lxdr", 0x25, INSTR_RRE_FF }, + { "lxer", 0x26, INSTR_RRE_FF }, + { "maer", 0x2e, INSTR_RRF_F0FF }, + { "mser", 0x2f, INSTR_RRF_F0FF }, + { "sqxr", 0x36, INSTR_RRE_FF }, + { "meer", 0x37, INSTR_RRE_FF }, + { "madr", 0x3e, INSTR_RRF_F0FF }, + { "msdr", 0x3f, INSTR_RRF_F0FF }, + { "lpxbr", 0x40, INSTR_RRE_FF }, + { "lnxbr", 0x41, INSTR_RRE_FF }, + { "ltxbr", 0x42, INSTR_RRE_FF }, + { "lcxbr", 0x43, INSTR_RRE_FF }, + { "ledbr", 0x44, INSTR_RRE_FF }, + { "ldxbr", 0x45, INSTR_RRE_FF }, + { "lexbr", 0x46, INSTR_RRE_FF }, + { "fixbr", 0x47, INSTR_RRF_U0FF }, + { "kxbr", 0x48, INSTR_RRE_FF }, + { "cxbr", 0x49, INSTR_RRE_FF }, + { "axbr", 0x4a, INSTR_RRE_FF }, + { "sxbr", 0x4b, INSTR_RRE_FF }, + { "mxbr", 0x4c, INSTR_RRE_FF }, + { "dxbr", 0x4d, INSTR_RRE_FF }, + { "tbedr", 0x50, INSTR_RRF_U0FF }, + { "tbdr", 0x51, INSTR_RRF_U0FF }, + { "diebr", 0x53, INSTR_RRF_FUFF }, + { "fiebr", 0x57, INSTR_RRF_U0FF }, + { "thder", 0x58, INSTR_RRE_RR }, + { "thdr", 0x59, INSTR_RRE_RR }, + { "didbr", 0x5b, INSTR_RRF_FUFF }, + { "fidbr", 0x5f, INSTR_RRF_U0FF }, + { "lpxr", 0x60, INSTR_RRE_FF }, + { "lnxr", 0x61, INSTR_RRE_FF }, + { "ltxr", 0x62, INSTR_RRE_FF }, + { "lcxr", 0x63, INSTR_RRE_FF }, + { "lxr", 0x65, INSTR_RRE_RR }, + { "lexr", 0x66, INSTR_RRE_FF }, + { "fixr", 0x67, INSTR_RRF_U0FF }, + { "cxr", 0x69, INSTR_RRE_FF }, + { "lzer", 0x74, INSTR_RRE_R0 }, + { "lzdr", 0x75, INSTR_RRE_R0 }, + { "lzxr", 0x76, INSTR_RRE_R0 }, + { "fier", 0x77, INSTR_RRF_U0FF }, + { "fidr", 0x7f, INSTR_RRF_U0FF }, + { "sfpc", 0x84, INSTR_RRE_RR_OPT }, + { "efpc", 0x8c, INSTR_RRE_RR_OPT }, + { "cefbr", 0x94, INSTR_RRE_RF }, + { "cdfbr", 0x95, INSTR_RRE_RF }, + { "cxfbr", 0x96, INSTR_RRE_RF }, + { "cfebr", 0x98, INSTR_RRF_U0RF }, + { "cfdbr", 0x99, INSTR_RRF_U0RF }, + { "cfxbr", 0x9a, INSTR_RRF_U0RF }, + { "cefr", 0xb4, INSTR_RRE_RF }, + { "cdfr", 0xb5, INSTR_RRE_RF }, + { "cxfr", 0xb6, INSTR_RRE_RF }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_b9[] = { +#ifdef CONFIG_64BIT + { "lpgr", 0x00, INSTR_RRE_RR }, + { "lngr", 0x01, INSTR_RRE_RR }, + { "ltgr", 0x02, INSTR_RRE_RR }, + { "lcgr", 0x03, INSTR_RRE_RR }, + { "lgr", 0x04, INSTR_RRE_RR }, + { "lurag", 0x05, INSTR_RRE_RR }, + { "lgbr", 0x06, INSTR_RRE_RR }, + { "lghr", 0x07, INSTR_RRE_RR }, + { "agr", 0x08, INSTR_RRE_RR }, + { "sgr", 0x09, INSTR_RRE_RR }, + { "algr", 0x0a, INSTR_RRE_RR }, + { "slgr", 0x0b, INSTR_RRE_RR }, + { "msgr", 0x0c, INSTR_RRE_RR }, + { "dsgr", 0x0d, INSTR_RRE_RR }, + { "eregg", 0x0e, INSTR_RRE_RR }, + { "lrvgr", 0x0f, INSTR_RRE_RR }, + { "lpgfr", 0x10, INSTR_RRE_RR }, + { "lngfr", 0x11, INSTR_RRE_RR }, + { "ltgfr", 0x12, INSTR_RRE_RR }, + { "lcgfr", 0x13, INSTR_RRE_RR }, + { "lgfr", 0x14, INSTR_RRE_RR }, + { "llgfr", 0x16, INSTR_RRE_RR }, + { "llgtr", 0x17, INSTR_RRE_RR }, + { "agfr", 0x18, INSTR_RRE_RR }, + { "sgfr", 0x19, INSTR_RRE_RR }, + { "algfr", 0x1a, INSTR_RRE_RR }, + { "slgfr", 0x1b, INSTR_RRE_RR }, + { "msgfr", 0x1c, INSTR_RRE_RR }, + { "dsgfr", 0x1d, INSTR_RRE_RR }, + { "cgr", 0x20, INSTR_RRE_RR }, + { "clgr", 0x21, INSTR_RRE_RR }, + { "sturg", 0x25, INSTR_RRE_RR }, + { "lbr", 0x26, INSTR_RRE_RR }, + { "lhr", 0x27, INSTR_RRE_RR }, + { "cgfr", 0x30, INSTR_RRE_RR }, + { "clgfr", 0x31, INSTR_RRE_RR }, + { "bctgr", 0x46, INSTR_RRE_RR }, + { "ngr", 0x80, INSTR_RRE_RR }, + { "ogr", 0x81, INSTR_RRE_RR }, + { "xgr", 0x82, INSTR_RRE_RR }, + { "flogr", 0x83, INSTR_RRE_RR }, + { "llgcr", 0x84, INSTR_RRE_RR }, + { "llghr", 0x85, INSTR_RRE_RR }, + { "mlgr", 0x86, INSTR_RRE_RR }, + { "dlgr", 0x87, INSTR_RRE_RR }, + { "alcgr", 0x88, INSTR_RRE_RR }, + { "slbgr", 0x89, INSTR_RRE_RR }, + { "cspg", 0x8a, INSTR_RRE_RR }, + { "idte", 0x8e, INSTR_RRF_R0RR }, + { "llcr", 0x94, INSTR_RRE_RR }, + { "llhr", 0x95, INSTR_RRE_RR }, + { "esea", 0x9d, INSTR_RRE_R0 }, + { "lptea", 0xaa, INSTR_RRF_RURR }, + { "cu14", 0xb0, INSTR_RRF_M0RR }, + { "cu24", 0xb1, INSTR_RRF_M0RR }, + { "cu41", 0xb2, INSTR_RRF_M0RR }, + { "cu42", 0xb3, INSTR_RRF_M0RR }, +#endif + { "kmac", 0x1e, INSTR_RRE_RR }, + { "lrvr", 0x1f, INSTR_RRE_RR }, + { "km", 0x2e, INSTR_RRE_RR }, + { "kmc", 0x2f, INSTR_RRE_RR }, + { "kimd", 0x3e, INSTR_RRE_RR }, + { "klmd", 0x3f, INSTR_RRE_RR }, + { "epsw", 0x8d, INSTR_RRE_RR }, + { "trtt", 0x90, INSTR_RRE_RR }, + { "trtt", 0x90, INSTR_RRF_M0RR }, + { "trto", 0x91, INSTR_RRE_RR }, + { "trto", 0x91, INSTR_RRF_M0RR }, + { "trot", 0x92, INSTR_RRE_RR }, + { "trot", 0x92, INSTR_RRF_M0RR }, + { "troo", 0x93, INSTR_RRE_RR }, + { "troo", 0x93, INSTR_RRF_M0RR }, + { "mlr", 0x96, INSTR_RRE_RR }, + { "dlr", 0x97, INSTR_RRE_RR }, + { "alcr", 0x98, INSTR_RRE_RR }, + { "slbr", 0x99, INSTR_RRE_RR }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_c0[] = { +#ifdef CONFIG_64BIT + { "lgfi", 0x01, INSTR_RIL_RI }, + { "xihf", 0x06, INSTR_RIL_RU }, + { "xilf", 0x07, INSTR_RIL_RU }, + { "iihf", 0x08, INSTR_RIL_RU }, + { "iilf", 0x09, INSTR_RIL_RU }, + { "nihf", 0x0a, INSTR_RIL_RU }, + { "nilf", 0x0b, INSTR_RIL_RU }, + { "oihf", 0x0c, INSTR_RIL_RU }, + { "oilf", 0x0d, INSTR_RIL_RU }, + { "llihf", 0x0e, INSTR_RIL_RU }, + { "llilf", 0x0f, INSTR_RIL_RU }, +#endif + { "larl", 0x00, INSTR_RIL_RP }, + { "brcl", 0x04, INSTR_RIL_UP }, + { "brasl", 0x05, INSTR_RIL_RP }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_c2[] = { +#ifdef CONFIG_64BIT + { "slgfi", 0x04, INSTR_RIL_RU }, + { "slfi", 0x05, INSTR_RIL_RU }, + { "agfi", 0x08, INSTR_RIL_RI }, + { "afi", 0x09, INSTR_RIL_RI }, + { "algfi", 0x0a, INSTR_RIL_RU }, + { "alfi", 0x0b, INSTR_RIL_RU }, + { "cgfi", 0x0c, INSTR_RIL_RI }, + { "cfi", 0x0d, INSTR_RIL_RI }, + { "clgfi", 0x0e, INSTR_RIL_RU }, + { "clfi", 0x0f, INSTR_RIL_RU }, +#endif + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_c8[] = { +#ifdef CONFIG_64BIT + { "mvcos", 0x00, INSTR_SSF_RRDRD }, +#endif + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_e3[] = { +#ifdef CONFIG_64BIT + { "ltg", 0x02, INSTR_RXY_RRRD }, + { "lrag", 0x03, INSTR_RXY_RRRD }, + { "lg", 0x04, INSTR_RXY_RRRD }, + { "cvby", 0x06, INSTR_RXY_RRRD }, + { "ag", 0x08, INSTR_RXY_RRRD }, + { "sg", 0x09, INSTR_RXY_RRRD }, + { "alg", 0x0a, INSTR_RXY_RRRD }, + { "slg", 0x0b, INSTR_RXY_RRRD }, + { "msg", 0x0c, INSTR_RXY_RRRD }, + { "dsg", 0x0d, INSTR_RXY_RRRD }, + { "cvbg", 0x0e, INSTR_RXY_RRRD }, + { "lrvg", 0x0f, INSTR_RXY_RRRD }, + { "lt", 0x12, INSTR_RXY_RRRD }, + { "lray", 0x13, INSTR_RXY_RRRD }, + { "lgf", 0x14, INSTR_RXY_RRRD }, + { "lgh", 0x15, INSTR_RXY_RRRD }, + { "llgf", 0x16, INSTR_RXY_RRRD }, + { "llgt", 0x17, INSTR_RXY_RRRD }, + { "agf", 0x18, INSTR_RXY_RRRD }, + { "sgf", 0x19, INSTR_RXY_RRRD }, + { "algf", 0x1a, INSTR_RXY_RRRD }, + { "slgf", 0x1b, INSTR_RXY_RRRD }, + { "msgf", 0x1c, INSTR_RXY_RRRD }, + { "dsgf", 0x1d, INSTR_RXY_RRRD }, + { "cg", 0x20, INSTR_RXY_RRRD }, + { "clg", 0x21, INSTR_RXY_RRRD }, + { "stg", 0x24, INSTR_RXY_RRRD }, + { "cvdy", 0x26, INSTR_RXY_RRRD }, + { "cvdg", 0x2e, INSTR_RXY_RRRD }, + { "strvg", 0x2f, INSTR_RXY_RRRD }, + { "cgf", 0x30, INSTR_RXY_RRRD }, + { "clgf", 0x31, INSTR_RXY_RRRD }, + { "strvh", 0x3f, INSTR_RXY_RRRD }, + { "bctg", 0x46, INSTR_RXY_RRRD }, + { "sty", 0x50, INSTR_RXY_RRRD }, + { "msy", 0x51, INSTR_RXY_RRRD }, + { "ny", 0x54, INSTR_RXY_RRRD }, + { "cly", 0x55, INSTR_RXY_RRRD }, + { "oy", 0x56, INSTR_RXY_RRRD }, + { "xy", 0x57, INSTR_RXY_RRRD }, + { "ly", 0x58, INSTR_RXY_RRRD }, + { "cy", 0x59, INSTR_RXY_RRRD }, + { "ay", 0x5a, INSTR_RXY_RRRD }, + { "sy", 0x5b, INSTR_RXY_RRRD }, + { "aly", 0x5e, INSTR_RXY_RRRD }, + { "sly", 0x5f, INSTR_RXY_RRRD }, + { "sthy", 0x70, INSTR_RXY_RRRD }, + { "lay", 0x71, INSTR_RXY_RRRD }, + { "stcy", 0x72, INSTR_RXY_RRRD }, + { "icy", 0x73, INSTR_RXY_RRRD }, + { "lb", 0x76, INSTR_RXY_RRRD }, + { "lgb", 0x77, INSTR_RXY_RRRD }, + { "lhy", 0x78, INSTR_RXY_RRRD }, + { "chy", 0x79, INSTR_RXY_RRRD }, + { "ahy", 0x7a, INSTR_RXY_RRRD }, + { "shy", 0x7b, INSTR_RXY_RRRD }, + { "ng", 0x80, INSTR_RXY_RRRD }, + { "og", 0x81, INSTR_RXY_RRRD }, + { "xg", 0x82, INSTR_RXY_RRRD }, + { "mlg", 0x86, INSTR_RXY_RRRD }, + { "dlg", 0x87, INSTR_RXY_RRRD }, + { "alcg", 0x88, INSTR_RXY_RRRD }, + { "slbg", 0x89, INSTR_RXY_RRRD }, + { "stpq", 0x8e, INSTR_RXY_RRRD }, + { "lpq", 0x8f, INSTR_RXY_RRRD }, + { "llgc", 0x90, INSTR_RXY_RRRD }, + { "llgh", 0x91, INSTR_RXY_RRRD }, + { "llc", 0x94, INSTR_RXY_RRRD }, + { "llh", 0x95, INSTR_RXY_RRRD }, +#endif + { "lrv", 0x1e, INSTR_RXY_RRRD }, + { "lrvh", 0x1f, INSTR_RXY_RRRD }, + { "strv", 0x3e, INSTR_RXY_RRRD }, + { "ml", 0x96, INSTR_RXY_RRRD }, + { "dl", 0x97, INSTR_RXY_RRRD }, + { "alc", 0x98, INSTR_RXY_RRRD }, + { "slb", 0x99, INSTR_RXY_RRRD }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_e5[] = { +#ifdef CONFIG_64BIT + { "strag", 0x02, INSTR_SSE_RDRD }, +#endif + { "lasp", 0x00, INSTR_SSE_RDRD }, + { "tprot", 0x01, INSTR_SSE_RDRD }, + { "mvcsk", 0x0e, INSTR_SSE_RDRD }, + { "mvcdk", 0x0f, INSTR_SSE_RDRD }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_eb[] = { +#ifdef CONFIG_64BIT + { "lmg", 0x04, INSTR_RSY_RRRD }, + { "srag", 0x0a, INSTR_RSY_RRRD }, + { "slag", 0x0b, INSTR_RSY_RRRD }, + { "srlg", 0x0c, INSTR_RSY_RRRD }, + { "sllg", 0x0d, INSTR_RSY_RRRD }, + { "tracg", 0x0f, INSTR_RSY_RRRD }, + { "csy", 0x14, INSTR_RSY_RRRD }, + { "rllg", 0x1c, INSTR_RSY_RRRD }, + { "clmh", 0x20, INSTR_RSY_RURD }, + { "clmy", 0x21, INSTR_RSY_RURD }, + { "stmg", 0x24, INSTR_RSY_RRRD }, + { "stctg", 0x25, INSTR_RSY_CCRD }, + { "stmh", 0x26, INSTR_RSY_RRRD }, + { "stcmh", 0x2c, INSTR_RSY_RURD }, + { "stcmy", 0x2d, INSTR_RSY_RURD }, + { "lctlg", 0x2f, INSTR_RSY_CCRD }, + { "csg", 0x30, INSTR_RSY_RRRD }, + { "cdsy", 0x31, INSTR_RSY_RRRD }, + { "cdsg", 0x3e, INSTR_RSY_RRRD }, + { "bxhg", 0x44, INSTR_RSY_RRRD }, + { "bxleg", 0x45, INSTR_RSY_RRRD }, + { "tmy", 0x51, INSTR_SIY_URD }, + { "mviy", 0x52, INSTR_SIY_URD }, + { "niy", 0x54, INSTR_SIY_URD }, + { "cliy", 0x55, INSTR_SIY_URD }, + { "oiy", 0x56, INSTR_SIY_URD }, + { "xiy", 0x57, INSTR_SIY_URD }, + { "icmh", 0x80, INSTR_RSE_RURD }, + { "icmh", 0x80, INSTR_RSY_RURD }, + { "icmy", 0x81, INSTR_RSY_RURD }, + { "clclu", 0x8f, INSTR_RSY_RRRD }, + { "stmy", 0x90, INSTR_RSY_RRRD }, + { "lmh", 0x96, INSTR_RSY_RRRD }, + { "lmy", 0x98, INSTR_RSY_RRRD }, + { "lamy", 0x9a, INSTR_RSY_AARD }, + { "stamy", 0x9b, INSTR_RSY_AARD }, +#endif + { "rll", 0x1d, INSTR_RSY_RRRD }, + { "mvclu", 0x8e, INSTR_RSY_RRRD }, + { "tp", 0xc0, INSTR_RSL_R0RD }, + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_ec[] = { +#ifdef CONFIG_64BIT + { "brxhg", 0x44, INSTR_RIE_RRP }, + { "brxlg", 0x45, INSTR_RIE_RRP }, +#endif + { "", 0, INSTR_INVALID } +}; + +static struct insn opcode_ed[] = { +#ifdef CONFIG_64BIT + { "mayl", 0x38, INSTR_RXF_FRRDF }, + { "myl", 0x39, INSTR_RXF_FRRDF }, + { "may", 0x3a, INSTR_RXF_FRRDF }, + { "my", 0x3b, INSTR_RXF_FRRDF }, + { "mayh", 0x3c, INSTR_RXF_FRRDF }, + { "myh", 0x3d, INSTR_RXF_FRRDF }, + { "ley", 0x64, INSTR_RXY_FRRD }, + { "ldy", 0x65, INSTR_RXY_FRRD }, + { "stey", 0x66, INSTR_RXY_FRRD }, + { "stdy", 0x67, INSTR_RXY_FRRD }, +#endif + { "ldeb", 0x04, INSTR_RXE_FRRD }, + { "lxdb", 0x05, INSTR_RXE_FRRD }, + { "lxeb", 0x06, INSTR_RXE_FRRD }, + { "mxdb", 0x07, INSTR_RXE_FRRD }, + { "keb", 0x08, INSTR_RXE_FRRD }, + { "ceb", 0x09, INSTR_RXE_FRRD }, + { "aeb", 0x0a, INSTR_RXE_FRRD }, + { "seb", 0x0b, INSTR_RXE_FRRD }, + { "mdeb", 0x0c, INSTR_RXE_FRRD }, + { "deb", 0x0d, INSTR_RXE_FRRD }, + { "maeb", 0x0e, INSTR_RXF_FRRDF }, + { "mseb", 0x0f, INSTR_RXF_FRRDF }, + { "tceb", 0x10, INSTR_RXE_FRRD }, + { "tcdb", 0x11, INSTR_RXE_FRRD }, + { "tcxb", 0x12, INSTR_RXE_FRRD }, + { "sqeb", 0x14, INSTR_RXE_FRRD }, + { "sqdb", 0x15, INSTR_RXE_FRRD }, + { "meeb", 0x17, INSTR_RXE_FRRD }, + { "kdb", 0x18, INSTR_RXE_FRRD }, + { "cdb", 0x19, INSTR_RXE_FRRD }, + { "adb", 0x1a, INSTR_RXE_FRRD }, + { "sdb", 0x1b, INSTR_RXE_FRRD }, + { "mdb", 0x1c, INSTR_RXE_FRRD }, + { "ddb", 0x1d, INSTR_RXE_FRRD }, + { "madb", 0x1e, INSTR_RXF_FRRDF }, + { "msdb", 0x1f, INSTR_RXF_FRRDF }, + { "lde", 0x24, INSTR_RXE_FRRD }, + { "lxd", 0x25, INSTR_RXE_FRRD }, + { "lxe", 0x26, INSTR_RXE_FRRD }, + { "mae", 0x2e, INSTR_RXF_FRRDF }, + { "mse", 0x2f, INSTR_RXF_FRRDF }, + { "sqe", 0x34, INSTR_RXE_FRRD }, + { "mee", 0x37, INSTR_RXE_FRRD }, + { "mad", 0x3e, INSTR_RXF_FRRDF }, + { "msd", 0x3f, INSTR_RXF_FRRDF }, + { "", 0, INSTR_INVALID } +}; + +/* Extracts an operand value from an instruction. */ +static unsigned int extract_operand(unsigned char *code, + const struct operand *operand) +{ + unsigned int val; + int bits; + + /* Extract fragments of the operand byte for byte. */ + code += operand->shift / 8; + bits = (operand->shift & 7) + operand->bits; + val = 0; + do { + val <<= 8; + val |= (unsigned int) *code++; + bits -= 8; + } while (bits > 0); + val >>= -bits; + val &= ((1U << (operand->bits - 1)) << 1) - 1; + + /* Check for special long displacement case. */ + if (operand->bits == 20 && operand->shift == 20) + val = (val & 0xff) << 12 | (val & 0xfff00) >> 8; + + /* Sign extend value if the operand is signed or pc relative. */ + if ((operand->flags & (OPERAND_SIGNED | OPERAND_PCREL)) && + (val & (1U << (operand->bits - 1)))) + val |= (-1U << (operand->bits - 1)) << 1; + + /* Double value if the operand is pc relative. */ + if (operand->flags & OPERAND_PCREL) + val <<= 1; + + /* Length x in an instructions has real length x + 1. */ + if (operand->flags & OPERAND_LENGTH) + val++; + return val; +} + +static inline int insn_length(unsigned char code) +{ + return ((((int) code + 64) >> 7) + 1) << 1; +} + +static struct insn *find_insn(unsigned char *code) +{ + unsigned char opfrag = code[1]; + unsigned char opmask; + struct insn *table; + + switch (code[0]) { + case 0x01: + table = opcode_01; + break; + case 0xa5: + table = opcode_a5; + break; + case 0xa7: + table = opcode_a7; + break; + case 0xb2: + table = opcode_b2; + break; + case 0xb3: + table = opcode_b3; + break; + case 0xb9: + table = opcode_b9; + break; + case 0xc0: + table = opcode_c0; + break; + case 0xc2: + table = opcode_c2; + break; + case 0xc8: + table = opcode_c8; + break; + case 0xe3: + table = opcode_e3; + opfrag = code[5]; + break; + case 0xe5: + table = opcode_e5; + break; + case 0xeb: + table = opcode_eb; + opfrag = code[5]; + break; + case 0xec: + table = opcode_ec; + opfrag = code[5]; + break; + case 0xed: + table = opcode_ed; + opfrag = code[5]; + break; + default: + table = opcode; + opfrag = code[0]; + break; + } + while (table->format != INSTR_INVALID) { + opmask = formats[table->format][0]; + if (table->opfrag == (opfrag & opmask)) + return table; + table++; + } + return NULL; +} + +static int print_insn(char *buffer, unsigned char *code, unsigned long addr) +{ + struct insn *insn; + const unsigned char *ops; + const struct operand *operand; + unsigned int value; + char separator; + char *ptr; + + ptr = buffer; + insn = find_insn(code); + if (insn) { + ptr += sprintf(ptr, "%.5s\t", insn->name); + /* Extract the operands. */ + separator = 0; + for (ops = formats[insn->format] + 1; *ops != 0; ops++) { + operand = operands + *ops; + value = extract_operand(code, operand); + if ((operand->flags & OPERAND_INDEX) && value == 0) + continue; + if ((operand->flags & OPERAND_BASE) && + value == 0 && separator == '(') { + separator = ','; + continue; + } + if (separator) + ptr += sprintf(ptr, "%c", separator); + if (operand->flags & OPERAND_GPR) + ptr += sprintf(ptr, "%%r%i", value); + else if (operand->flags & OPERAND_FPR) + ptr += sprintf(ptr, "%%f%i", value); + else if (operand->flags & OPERAND_AR) + ptr += sprintf(ptr, "%%a%i", value); + else if (operand->flags & OPERAND_CR) + ptr += sprintf(ptr, "%%c%i", value); + else if (operand->flags & OPERAND_PCREL) + ptr += sprintf(ptr, "%lx", value + addr); + else if (operand->flags & OPERAND_SIGNED) + ptr += sprintf(ptr, "%i", value); + else + ptr += sprintf(ptr, "%u", value); + if (operand->flags & OPERAND_DISP) + separator = '('; + else if (operand->flags & OPERAND_BASE) { + ptr += sprintf(ptr, ")"); + separator = ','; + } else + separator = ','; + } + } else + ptr += sprintf(ptr, "unknown"); + return (int) (ptr - buffer); +} + +void show_code(struct pt_regs *regs) +{ + char *mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; + unsigned char code[64]; + char buffer[64], *ptr; + mm_segment_t old_fs; + unsigned long addr; + int start, end, opsize, hops, i; + + /* Get a snapshot of the 64 bytes surrounding the fault address. */ + old_fs = get_fs(); + set_fs((regs->psw.mask & PSW_MASK_PSTATE) ? USER_DS : KERNEL_DS); + for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { + addr = regs->psw.addr - 34 + start; + if (__copy_from_user(code + start - 2, + (char __user *) addr, 2)) + break; + } + for (end = 32; end < 64; end += 2) { + addr = regs->psw.addr + end - 32; + if (__copy_from_user(code + end, + (char __user *) addr, 2)) + break; + } + set_fs(old_fs); + /* Code snapshot useable ? */ + if ((regs->psw.addr & 1) || start >= end) { + printk("%s Code: Bad PSW.\n", mode); + return; + } + /* Find a starting point for the disassembly. */ + while (start < 32) { + hops = 0; + for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) { + if (!find_insn(code + start + i)) + break; + i += insn_length(code[start + i]); + } + if (start + i == 32) + /* Looks good, sequence ends at PSW. */ + break; + start += 2; + } + /* Decode the instructions. */ + ptr = buffer; + ptr += sprintf(ptr, "%s Code:", mode); + hops = 0; + while (start < end && hops < 8) { + *ptr++ = (start == 32) ? '>' : ' '; + addr = regs->psw.addr + start - 32; + ptr += sprintf(ptr, ONELONG, addr); + opsize = insn_length(code[start]); + if (start + opsize >= end) + break; + for (i = 0; i < opsize; i++) + ptr += sprintf(ptr, "%02x", code[start + i]); + *ptr++ = '\t'; + if (i < 6) + *ptr++ = '\t'; + ptr += print_insn(ptr, code + start, addr); + start += opsize; + printk(buffer); + ptr = buffer; + ptr += sprintf(ptr, "\n "); + hops++; + } + printk("\n"); +} diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index f0e5a320e2e..a6540940190 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -188,18 +188,31 @@ void dump_stack(void) EXPORT_SYMBOL(dump_stack); +static inline int mask_bits(struct pt_regs *regs, unsigned long bits) +{ + return (regs->psw.mask & bits) / ((~bits + 1) & bits); +} + void show_registers(struct pt_regs *regs) { - mm_segment_t old_fs; char *mode; - int i; mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; printk("%s PSW : %p %p", mode, (void *) regs->psw.mask, (void *) regs->psw.addr); print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); - printk("%s GPRS: " FOURLONG, mode, + printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " + "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), + mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), + mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), + mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), + mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), + mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); +#ifdef CONFIG_64BIT + printk(" EA:%x", mask_bits(regs, PSW_BASE_BITS)); +#endif + printk("\n%s GPRS: " FOURLONG, mode, regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); printk(" " FOURLONG, regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); @@ -208,41 +221,7 @@ void show_registers(struct pt_regs *regs) printk(" " FOURLONG, regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); -#if 0 - /* FIXME: this isn't needed any more but it changes the ksymoops - * input. To remove or not to remove ... */ - save_access_regs(regs->acrs); - printk("%s ACRS: %08x %08x %08x %08x\n", mode, - regs->acrs[0], regs->acrs[1], regs->acrs[2], regs->acrs[3]); - printk(" %08x %08x %08x %08x\n", - regs->acrs[4], regs->acrs[5], regs->acrs[6], regs->acrs[7]); - printk(" %08x %08x %08x %08x\n", - regs->acrs[8], regs->acrs[9], regs->acrs[10], regs->acrs[11]); - printk(" %08x %08x %08x %08x\n", - regs->acrs[12], regs->acrs[13], regs->acrs[14], regs->acrs[15]); -#endif - - /* - * Print the first 20 byte of the instruction stream at the - * time of the fault. - */ - old_fs = get_fs(); - if (regs->psw.mask & PSW_MASK_PSTATE) - set_fs(USER_DS); - else - set_fs(KERNEL_DS); - printk("%s Code: ", mode); - for (i = 0; i < 20; i++) { - unsigned char c; - if (__get_user(c, (char __user *)(regs->psw.addr + i))) { - printk(" Bad PSW."); - break; - } - printk("%02x ", c); - } - set_fs(old_fs); - - printk("\n"); + show_code(regs); } /* This is called from fs/proc/array.c */ -- cgit v1.2.3 From c0007f1a65762eaf55633d403b380130ec60adad Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 27 Apr 2007 16:01:42 +0200 Subject: [S390] Use generic bug. Generic bug implementation for s390. Will increase the value of the console output on BUG() statements since registers r0-r5,r14 will not be clobbered by a printk() call that was previously done before the illegal instruction of BUG() was hit. Also implements an architecture specific WARN_ON(). Output of that could be increased but requires common code change. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 5 +++++ arch/s390/defconfig | 2 ++ arch/s390/kernel/module.c | 4 +++- arch/s390/kernel/traps.c | 17 ++++++++++++++--- arch/s390/kernel/vmlinux.lds.S | 10 +++++++++- 5 files changed, 33 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 0f293aa7b0f..0f9517bc8e7 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -41,6 +41,11 @@ config GENERIC_HWEIGHT config GENERIC_TIME def_bool y +config GENERIC_BUG + bool + depends on BUG + default y + config NO_IOMEM def_bool y diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 741d2bbb2b3..80046d9e2a3 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -12,6 +12,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_BUG=y CONFIG_NO_IOMEM=y CONFIG_S390=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -705,6 +706,7 @@ CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 39d1dd75252..59b4e796680 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -31,6 +31,7 @@ #include #include #include +#include #if 0 #define DEBUGP printk @@ -398,9 +399,10 @@ int module_finalize(const Elf_Ehdr *hdr, struct module *me) { vfree(me->arch.syminfo); - return 0; + return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { + module_bug_cleanup(mod); } diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index a6540940190..49dec830373 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -30,7 +30,7 @@ #include #include #include - +#include #include #include #include @@ -297,6 +297,11 @@ report_user_fault(long interruption_code, struct pt_regs *regs) #endif } +int is_valid_bugaddr(unsigned long addr) +{ + return 1; +} + static void __kprobes inline do_trap(long interruption_code, int signr, char *str, struct pt_regs *regs, siginfo_t *info) @@ -323,8 +328,14 @@ static void __kprobes inline do_trap(long interruption_code, int signr, fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); if (fixup) regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE; - else - die(str, regs, interruption_code); + else { + enum bug_trap_type btt; + + btt = report_bug(regs->psw.addr & PSW_ADDR_INSN); + if (btt == BUG_TRAP_TYPE_WARN) + return; + die(str, regs, interruption_code); + } } } diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index c30716ae130..418f6426a94 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -45,6 +45,8 @@ SECTIONS __ex_table : { *(__ex_table) } __stop___ex_table = .; + BUG_TABLE + .data : { /* Data */ *(.data) CONSTRUCTORS @@ -77,6 +79,12 @@ SECTIONS *(.init.text) _einittext = .; } + /* + * .exit.text is discarded at runtime, not link time, + * to deal with references from __bug_table + */ + .exit.text : { *(.exit.text) } + .init.data : { *(.init.data) } . = ALIGN(256); __setup_start = .; @@ -116,7 +124,7 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.exit.text) *(.exit.data) *(.exitcall.exit) + *(.exit.data) *(.exitcall.exit) } /* Stabs debugging sections. */ -- cgit v1.2.3 From 10c1031f706bbe0690d84cdbccad15b11c6dc661 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2007 16:01:43 +0200 Subject: [S390] Minor fault path optimization. The minor fault path has grown a lot in terms of cycles. In particular the kprobes hook is very costly. Optimize the path to save a couple of cycles. If kprobes is enabled more than 300 cycles can be avoided if kprobes_running() is false. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/mm/fault.c | 259 ++++++++++++++++++++++++++++----------------------- 1 file changed, 141 insertions(+), 118 deletions(-) (limited to 'arch') diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 7462aebd3eb..8bc35183db5 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -63,21 +63,25 @@ int unregister_page_fault_notifier(struct notifier_block *nb) return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); } -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) +static int __kprobes __notify_page_fault(struct pt_regs *regs, long err) { - struct die_args args = { - .regs = regs, - .str = str, - .err = err, - .trapnr = trap, - .signr = sig - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); + struct die_args args = { .str = "page fault", + .trapnr = 14, + .signr = SIGSEGV }; + args.regs = regs; + args.err = err; + return atomic_notifier_call_chain(¬ify_page_fault_chain, + DIE_PAGE_FAULT, &args); +} + +static inline int notify_page_fault(struct pt_regs *regs, long err) +{ + if (unlikely(kprobe_running())) + return __notify_page_fault(regs, err); + return NOTIFY_DONE; } #else -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) +static inline int notify_page_fault(struct pt_regs *regs, long err) { return NOTIFY_DONE; } @@ -170,6 +174,89 @@ static void do_sigsegv(struct pt_regs *regs, unsigned long error_code, force_sig_info(SIGSEGV, &si, current); } +static void do_no_context(struct pt_regs *regs, unsigned long error_code, + unsigned long address) +{ + const struct exception_table_entry *fixup; + + /* Are we prepared to handle this kernel fault? */ + fixup = search_exception_tables(regs->psw.addr & __FIXUP_MASK); + if (fixup) { + regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE; + return; + } + + /* + * Oops. The kernel tried to access some bad page. We'll have to + * terminate things with extreme prejudice. + */ + if (check_space(current) == 0) + printk(KERN_ALERT "Unable to handle kernel pointer dereference" + " at virtual kernel address %p\n", (void *)address); + else + printk(KERN_ALERT "Unable to handle kernel paging request" + " at virtual user address %p\n", (void *)address); + + die("Oops", regs, error_code); + do_exit(SIGKILL); +} + +static void do_low_address(struct pt_regs *regs, unsigned long error_code) +{ + /* Low-address protection hit in kernel mode means + NULL pointer write access in kernel mode. */ + if (regs->psw.mask & PSW_MASK_PSTATE) { + /* Low-address protection hit in user mode 'cannot happen'. */ + die ("Low-address protection", regs, error_code); + do_exit(SIGKILL); + } + + do_no_context(regs, error_code, 0); +} + +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code, + unsigned long address) +{ + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->mm; + + up_read(&mm->mmap_sem); + if (is_init(tsk)) { + yield(); + down_read(&mm->mmap_sem); + return 1; + } + printk("VM: killing process %s\n", tsk->comm); + if (regs->psw.mask & PSW_MASK_PSTATE) + do_exit(SIGKILL); + do_no_context(regs, error_code, address); + return 0; +} + +static void do_sigbus(struct pt_regs *regs, unsigned long error_code, + unsigned long address) +{ + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->mm; + + up_read(&mm->mmap_sem); + /* + * Send a sigbus, regardless of whether we were in kernel + * or user mode. + */ + tsk->thread.prot_addr = address; + tsk->thread.trap_no = error_code; + force_sig(SIGBUS, tsk); + + /* Kernel mode? Handle exceptions or die */ + if (!(regs->psw.mask & PSW_MASK_PSTATE)) + do_no_context(regs, error_code, address); +} + #ifdef CONFIG_S390_EXEC_PROTECT extern long sys_sigreturn(struct pt_regs *regs); extern long sys_rt_sigreturn(struct pt_regs *regs); @@ -253,49 +340,23 @@ out_fault: * 3b Region third trans. -> Not present (nullification) */ static inline void -do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) +do_exception(struct pt_regs *regs, unsigned long error_code, int write) { - struct task_struct *tsk; - struct mm_struct *mm; - struct vm_area_struct * vma; - unsigned long address; - const struct exception_table_entry *fixup; - int si_code; + struct task_struct *tsk; + struct mm_struct *mm; + struct vm_area_struct *vma; + unsigned long address; int space; + int si_code; - tsk = current; - mm = tsk->mm; - - if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, - SIGSEGV) == NOTIFY_STOP) + if (notify_page_fault(regs, error_code) == NOTIFY_STOP) return; - /* - * Check for low-address protection. This needs to be treated - * as a special case because the translation exception code - * field is not guaranteed to contain valid data in this case. - */ - if (is_protection && !(S390_lowcore.trans_exc_code & 4)) { - - /* Low-address protection hit in kernel mode means - NULL pointer write access in kernel mode. */ - if (!(regs->psw.mask & PSW_MASK_PSTATE)) { - address = 0; - space = 0; - goto no_context; - } - - /* Low-address protection hit in user mode 'cannot happen'. */ - die ("Low-address protection", regs, error_code); - do_exit(SIGKILL); - } + tsk = current; + mm = tsk->mm; - /* - * get the failing address - * more specific the segment and page table portion of - * the address - */ - address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK; + /* get the failing address and the affected space */ + address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK; space = check_space(tsk); /* @@ -313,7 +374,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) */ local_irq_enable(); - down_read(&mm->mmap_sem); + down_read(&mm->mmap_sem); si_code = SEGV_MAPERR; vma = find_vma(mm, address); @@ -330,19 +391,19 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) return; #endif - if (vma->vm_start <= address) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - if (expand_stack(vma, address)) - goto bad_area; + if (vma->vm_start <= address) + goto good_area; + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto bad_area; + if (expand_stack(vma, address)) + goto bad_area; /* * Ok, we have a good vm_area for this memory access, so * we can handle it.. */ good_area: si_code = SEGV_ACCERR; - if (!is_protection) { + if (!write) { /* page not present, check vm flags */ if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) goto bad_area; @@ -357,7 +418,7 @@ survive: * make sure we exit gracefully rather than endlessly redo * the fault. */ - switch (handle_mm_fault(mm, vma, address, is_protection)) { + switch (handle_mm_fault(mm, vma, address, write)) { case VM_FAULT_MINOR: tsk->min_flt++; break; @@ -365,9 +426,12 @@ survive: tsk->maj_flt++; break; case VM_FAULT_SIGBUS: - goto do_sigbus; + do_sigbus(regs, error_code, address); + return; case VM_FAULT_OOM: - goto out_of_memory; + if (do_out_of_memory(regs, error_code, address)) + goto survive; + return; default: BUG(); } @@ -385,75 +449,34 @@ survive: * Fix it, but check if it's kernel or user first.. */ bad_area: - up_read(&mm->mmap_sem); + up_read(&mm->mmap_sem); - /* User mode accesses just cause a SIGSEGV */ - if (regs->psw.mask & PSW_MASK_PSTATE) { - tsk->thread.prot_addr = address; - tsk->thread.trap_no = error_code; + /* User mode accesses just cause a SIGSEGV */ + if (regs->psw.mask & PSW_MASK_PSTATE) { + tsk->thread.prot_addr = address; + tsk->thread.trap_no = error_code; do_sigsegv(regs, error_code, si_code, address); - return; + return; } no_context: - /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(regs->psw.addr & __FIXUP_MASK); - if (fixup) { - regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE; - return; - } - -/* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ - if (space == 0) - printk(KERN_ALERT "Unable to handle kernel pointer dereference" - " at virtual kernel address %p\n", (void *)address); - else - printk(KERN_ALERT "Unable to handle kernel paging request" - " at virtual user address %p\n", (void *)address); - - die("Oops", regs, error_code); - do_exit(SIGKILL); - - -/* - * We ran out of memory, or some other thing happened to us that made - * us unable to handle the page fault gracefully. -*/ -out_of_memory: - up_read(&mm->mmap_sem); - if (is_init(tsk)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk("VM: killing process %s\n", tsk->comm); - if (regs->psw.mask & PSW_MASK_PSTATE) - do_exit(SIGKILL); - goto no_context; - -do_sigbus: - up_read(&mm->mmap_sem); - - /* - * Send a sigbus, regardless of whether we were in kernel - * or user mode. - */ - tsk->thread.prot_addr = address; - tsk->thread.trap_no = error_code; - force_sig(SIGBUS, tsk); - - /* Kernel mode? Handle exceptions or die */ - if (!(regs->psw.mask & PSW_MASK_PSTATE)) - goto no_context; + do_no_context(regs, error_code, address); } void __kprobes do_protection_exception(struct pt_regs *regs, unsigned long error_code) { + /* Protection exception is supressing, decrement psw address. */ regs->psw.addr -= (error_code >> 16); + /* + * Check for low-address protection. This needs to be treated + * as a special case because the translation exception code + * field is not guaranteed to contain valid data in this case. + */ + if (unlikely(!(S390_lowcore.trans_exc_code & 4))) { + do_low_address(regs, error_code); + return; + } do_exception(regs, 4, 1); } -- cgit v1.2.3 From be5ec363e958982454ac9b3138b0e78c032e758d Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2007 16:01:44 +0200 Subject: [S390] No execute support cleanup. Simplify the signal_return function that checks for the two special system calls sigreturn and rt_sigreturn. No need to do a page table walk, a call to copy_from_user while disabled page faults will work as well. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/mm/fault.c | 72 +++++++++++++++------------------------------------- 1 file changed, 21 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 8bc35183db5..2b76a879a7b 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -26,9 +26,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -263,68 +263,38 @@ extern long sys_rt_sigreturn(struct pt_regs *regs); extern long sys32_sigreturn(struct pt_regs *regs); extern long sys32_rt_sigreturn(struct pt_regs *regs); -static inline void do_sigreturn(struct mm_struct *mm, struct pt_regs *regs, - int rt) +static int signal_return(struct mm_struct *mm, struct pt_regs *regs, + unsigned long address, unsigned long error_code) { + u16 instruction; + int rc, compat; + + pagefault_disable(); + rc = __get_user(instruction, (u16 __user *) regs->psw.addr); + pagefault_enable(); + if (rc) + return -EFAULT; + up_read(&mm->mmap_sem); clear_tsk_thread_flag(current, TIF_SINGLE_STEP); #ifdef CONFIG_COMPAT - if (test_tsk_thread_flag(current, TIF_31BIT)) { - if (rt) - sys32_rt_sigreturn(regs); - else - sys32_sigreturn(regs); - return; - } -#endif /* CONFIG_COMPAT */ - if (rt) - sys_rt_sigreturn(regs); + compat = test_tsk_thread_flag(current, TIF_31BIT); + if (compat && instruction == 0x0a77) + sys32_sigreturn(regs); + else if (compat && instruction == 0x0aad) + sys32_rt_sigreturn(regs); else +#endif + if (instruction == 0x0a77) sys_sigreturn(regs); - return; -} - -static int signal_return(struct mm_struct *mm, struct pt_regs *regs, - unsigned long address, unsigned long error_code) -{ - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - u16 *instruction; - unsigned long pfn, uaddr = regs->psw.addr; - - spin_lock(&mm->page_table_lock); - pgd = pgd_offset(mm, uaddr); - if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) - goto out_fault; - pmd = pmd_offset(pgd, uaddr); - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) - goto out_fault; - pte = pte_offset_map(pmd_offset(pgd_offset(mm, uaddr), uaddr), uaddr); - if (!pte || !pte_present(*pte)) - goto out_fault; - pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) - goto out_fault; - spin_unlock(&mm->page_table_lock); - - instruction = (u16 *) ((pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE-1))); - if (*instruction == 0x0a77) - do_sigreturn(mm, regs, 0); - else if (*instruction == 0x0aad) - do_sigreturn(mm, regs, 1); + else if (instruction == 0x0aad) + sys_rt_sigreturn(regs); else { - printk("- XXX - do_exception: task = %s, primary, NO EXEC " - "-> SIGSEGV\n", current->comm); - up_read(&mm->mmap_sem); current->thread.prot_addr = address; current->thread.trap_no = error_code; do_sigsegv(regs, error_code, SEGV_MAPERR, address); } return 0; -out_fault: - spin_unlock(&mm->page_table_lock); - return -EFAULT; } #endif /* CONFIG_S390_EXEC_PROTECT */ -- cgit v1.2.3 From be7962856d299a0f231ac36f89f4a89cbecfe0ff Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2007 16:01:46 +0200 Subject: [S390] Improved kernel stack overflow checking. Recent cvs versions of gcc have support for an improved stack overflow checking that calculates the size of the guard size for each function. If the compiler accepts -mstack-size without -mstack-guard then the new stack check is available. We always want to use the new stack checker. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/s390/Makefile b/arch/s390/Makefile index b1e55849646..ece5adc0560 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -67,8 +67,10 @@ endif ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y) cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE) +ifneq ($(call cc-option-yn,-mstack-size=8192),y) cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD) endif +endif ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y) cflags-$(CONFIG_WARN_STACK) += -mwarn-dynamicstack -- cgit v1.2.3 From 411ed3225733dbd83b4cbaaa992ef80d6ec1534e Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 27 Apr 2007 16:01:49 +0200 Subject: [S390] zfcpdump support. s390 machines provide hardware support for creating Linux dumps on SCSI disks. For creating a dump a special purpose dump Linux is used. The first 32 MB of memory are saved by the hardware before the dump Linux is booted. Via an SCLP interface, the saved memory can be accessed from Linux. This patch exports memory and registers of the crashed Linux to userspace via a debugfs file. For more information refer to Documentation/s390/zfcpdump.txt, which is included in this patch. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 8 ++ arch/s390/Makefile | 3 + arch/s390/defconfig | 1 + arch/s390/kernel/head64.S | 72 +++++++++++++- arch/s390/kernel/ipl.c | 232 ++++++++++++++++++++++++++++++---------------- arch/s390/kernel/setup.c | 38 +++++++- arch/s390/kernel/smp.c | 62 +++++++++++++ 7 files changed, 330 insertions(+), 86 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 0f9517bc8e7..e6ec418093e 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -519,6 +519,14 @@ config KEXEC current kernel, and to start another kernel. It is like a reboot but is independent of hardware/microcode support. +config ZFCPDUMP + tristate "zfcpdump support" + select SMP + default n + help + Select this option if you want to build an zfcpdump enabled kernel. + Refer to "Documentation/s390/zfcpdump.txt" for more details on this. + endmenu source "net/Kconfig" diff --git a/arch/s390/Makefile b/arch/s390/Makefile index ece5adc0560..68441e0e74b 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -105,6 +105,9 @@ install: vmlinux image: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +zfcpdump: + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 80046d9e2a3..0e4da8a7d82 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -167,6 +167,7 @@ CONFIG_NO_IDLE_HZ=y CONFIG_NO_IDLE_HZ_INIT=y CONFIG_S390_HYPFS_FS=y CONFIG_KEXEC=y +# CONFIG_ZFCPDUMP is not set # # Networking diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 37010709fe6..a87b1976d40 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -39,7 +39,69 @@ startup_continue: basr %r13,0 # get base .LPG1: sll %r13,1 # remove high order bit srl %r13,1 - lhi %r1,1 # mode 1 = esame + +#ifdef CONFIG_ZFCPDUMP + + # check if we have been ipled using zfcp dump: + + tm 0xb9,0x01 # test if subchannel is enabled + jno .nodump # subchannel disabled + l %r1,0xb8 + la %r5,.Lipl_schib-.LPG1(%r13) + stsch 0(%r5) # get schib of subchannel + jne .nodump # schib not available + tm 5(%r5),0x01 # devno valid? + jno .nodump + tm 4(%r5),0x80 # qdio capable device? + jno .nodump + l %r2,20(%r0) # address of ipl parameter block + lhi %r3,0 + ic %r3,0x148(%r2) # get opt field + chi %r3,0x20 # load with dump? + jne .nodump + + # store all prefix registers in case of load with dump: + + la %r7,0 # base register for 0 page + la %r8,0 # first cpu + l %r11,.Lpref_arr_ptr-.LPG1(%r13) # address of prefix array + ahi %r11,4 # skip boot cpu + lr %r12,%r11 + ahi %r12,(CONFIG_NR_CPUS*4) # end of prefix array + stap .Lcurrent_cpu+2-.LPG1(%r13) # store current cpu addr +1: + cl %r8,.Lcurrent_cpu-.LPG1(%r13) # is ipl cpu ? + je 4f # if yes get next cpu +2: + lr %r9,%r7 + sigp %r9,%r8,0x9 # stop & store status of cpu + brc 8,3f # accepted + brc 4,4f # status stored: next cpu + brc 2,2b # busy: try again + brc 1,4f # not op: next cpu +3: + mvc 0(4,%r11),264(%r7) # copy prefix register to prefix array + ahi %r11,4 # next element in prefix array + clr %r11,%r12 + je 5f # no more space in prefix array +4: + ahi %r8,1 # next cpu (r8 += 1) + cl %r8,.Llast_cpu-.LPG1(%r13) # is last possible cpu ? + jl 1b # jump if not last cpu +5: + lhi %r1,2 # mode 2 = esame (dump) + j 6f + .align 4 +.Lipl_schib: + .rept 13 + .long 0 + .endr +.nodump: + lhi %r1,1 # mode 1 = esame (normal ipl) +6: +#else + lhi %r1,1 # mode 1 = esame (normal ipl) +#endif /* CONFIG_ZFCPDUMP */ mvi __LC_AR_MODE_ID,1 # set esame flag slr %r0,%r0 # set cpuid to zero sigp %r1,%r0,0x12 # switch to esame mode @@ -149,6 +211,14 @@ startup_continue: .L4malign:.quad 0xffffffffffc00000 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 .Lnop: .long 0x07000700 +#ifdef CONFIG_ZFCPDUMP +.Lcurrent_cpu: + .long 0x0 +.Llast_cpu: + .long 0x0000ffff +.Lpref_arr_ptr: + .long zfcpdump_prefix_array +#endif /* CONFIG_ZFCPDUMP */ .Lparmaddr: .quad PARMAREA .align 64 diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index a83cf1fdd8f..06833ac2b11 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -29,36 +29,21 @@ #define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm) #define SCCB_FLAG (s390_readinfo_sccb.flags) -enum ipl_type { - IPL_TYPE_NONE = 1, - IPL_TYPE_UNKNOWN = 2, - IPL_TYPE_CCW = 4, - IPL_TYPE_FCP = 8, - IPL_TYPE_NSS = 16, -}; - -#define IPL_NONE_STR "none" -#define IPL_UNKNOWN_STR "unknown" -#define IPL_CCW_STR "ccw" -#define IPL_FCP_STR "fcp" -#define IPL_NSS_STR "nss" - -/* - * Must be in data section since the bss section - * is not cleared when these are accessed. - */ -static u16 ipl_devno __attribute__((__section__(".data"))) = 0; -u32 ipl_flags __attribute__((__section__(".data"))) = 0; +#define IPL_UNKNOWN_STR "unknown" +#define IPL_CCW_STR "ccw" +#define IPL_FCP_STR "fcp" +#define IPL_FCP_DUMP_STR "fcp_dump" +#define IPL_NSS_STR "nss" static char *ipl_type_str(enum ipl_type type) { switch (type) { - case IPL_TYPE_NONE: - return IPL_NONE_STR; case IPL_TYPE_CCW: return IPL_CCW_STR; case IPL_TYPE_FCP: return IPL_FCP_STR; + case IPL_TYPE_FCP_DUMP: + return IPL_FCP_DUMP_STR; case IPL_TYPE_NSS: return IPL_NSS_STR; case IPL_TYPE_UNKNOWN: @@ -67,15 +52,55 @@ static char *ipl_type_str(enum ipl_type type) } } +enum dump_type { + DUMP_TYPE_NONE = 1, + DUMP_TYPE_CCW = 2, + DUMP_TYPE_FCP = 4, +}; + +#define DUMP_NONE_STR "none" +#define DUMP_CCW_STR "ccw" +#define DUMP_FCP_STR "fcp" + +static char *dump_type_str(enum dump_type type) +{ + switch (type) { + case DUMP_TYPE_NONE: + return DUMP_NONE_STR; + case DUMP_TYPE_CCW: + return DUMP_CCW_STR; + case DUMP_TYPE_FCP: + return DUMP_FCP_STR; + default: + return NULL; + } +} + +/* + * Must be in data section since the bss section + * is not cleared when these are accessed. + */ +static u16 ipl_devno __attribute__((__section__(".data"))) = 0; +u32 ipl_flags __attribute__((__section__(".data"))) = 0; + enum ipl_method { - IPL_METHOD_NONE, - IPL_METHOD_CCW_CIO, - IPL_METHOD_CCW_DIAG, - IPL_METHOD_CCW_VM, - IPL_METHOD_FCP_RO_DIAG, - IPL_METHOD_FCP_RW_DIAG, - IPL_METHOD_FCP_RO_VM, - IPL_METHOD_NSS, + REIPL_METHOD_CCW_CIO, + REIPL_METHOD_CCW_DIAG, + REIPL_METHOD_CCW_VM, + REIPL_METHOD_FCP_RO_DIAG, + REIPL_METHOD_FCP_RW_DIAG, + REIPL_METHOD_FCP_RO_VM, + REIPL_METHOD_FCP_DUMP, + REIPL_METHOD_NSS, + REIPL_METHOD_DEFAULT, +}; + +enum dump_method { + DUMP_METHOD_NONE, + DUMP_METHOD_CCW_CIO, + DUMP_METHOD_CCW_DIAG, + DUMP_METHOD_CCW_VM, + DUMP_METHOD_FCP_DIAG, }; enum shutdown_action { @@ -107,15 +132,15 @@ static int diag308_set_works = 0; static int reipl_capabilities = IPL_TYPE_UNKNOWN; static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN; -static enum ipl_method reipl_method = IPL_METHOD_NONE; +static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT; static struct ipl_parameter_block *reipl_block_fcp; static struct ipl_parameter_block *reipl_block_ccw; static char reipl_nss_name[NSS_NAME_SIZE + 1]; -static int dump_capabilities = IPL_TYPE_NONE; -static enum ipl_type dump_type = IPL_TYPE_NONE; -static enum ipl_method dump_method = IPL_METHOD_NONE; +static int dump_capabilities = DUMP_TYPE_NONE; +static enum dump_type dump_type = DUMP_TYPE_NONE; +static enum dump_method dump_method = DUMP_METHOD_NONE; static struct ipl_parameter_block *dump_block_fcp; static struct ipl_parameter_block *dump_block_ccw; @@ -134,6 +159,7 @@ int diag308(unsigned long subcode, void *addr) : "d" (subcode) : "cc", "memory"); return _rc; } +EXPORT_SYMBOL_GPL(diag308); /* SYSFS */ @@ -197,7 +223,7 @@ static void make_attrs_ro(struct attribute **attrs) * ipl section */ -static enum ipl_type ipl_get_type(void) +static __init enum ipl_type get_ipl_type(void) { struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; @@ -211,12 +237,44 @@ static enum ipl_type ipl_get_type(void) return IPL_TYPE_UNKNOWN; if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP) return IPL_TYPE_UNKNOWN; + if (ipl->ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP) + return IPL_TYPE_FCP_DUMP; return IPL_TYPE_FCP; } +void __init setup_ipl_info(void) +{ + ipl_info.type = get_ipl_type(); + switch (ipl_info.type) { + case IPL_TYPE_CCW: + ipl_info.data.ccw.dev_id.devno = ipl_devno; + ipl_info.data.ccw.dev_id.ssid = 0; + break; + case IPL_TYPE_FCP: + case IPL_TYPE_FCP_DUMP: + ipl_info.data.fcp.dev_id.devno = + IPL_PARMBLOCK_START->ipl_info.fcp.devno; + ipl_info.data.fcp.dev_id.ssid = 0; + ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn; + ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun; + break; + case IPL_TYPE_NSS: + strncpy(ipl_info.data.nss.name, kernel_nss_name, + sizeof(ipl_info.data.nss.name)); + break; + case IPL_TYPE_UNKNOWN: + default: + /* We have no info to copy */ + break; + } +} + +struct ipl_info ipl_info; +EXPORT_SYMBOL_GPL(ipl_info); + static ssize_t ipl_type_show(struct subsystem *subsys, char *page) { - return sprintf(page, "%s\n", ipl_type_str(ipl_get_type())); + return sprintf(page, "%s\n", ipl_type_str(ipl_info.type)); } static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); @@ -225,10 +283,11 @@ static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page) { struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; - switch (ipl_get_type()) { + switch (ipl_info.type) { case IPL_TYPE_CCW: return sprintf(page, "0.0.%04x\n", ipl_devno); case IPL_TYPE_FCP: + case IPL_TYPE_FCP_DUMP: return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno); default: return 0; @@ -485,23 +544,29 @@ static int reipl_set_type(enum ipl_type type) switch(type) { case IPL_TYPE_CCW: if (MACHINE_IS_VM) - reipl_method = IPL_METHOD_CCW_VM; + reipl_method = REIPL_METHOD_CCW_VM; else - reipl_method = IPL_METHOD_CCW_CIO; + reipl_method = REIPL_METHOD_CCW_CIO; break; case IPL_TYPE_FCP: if (diag308_set_works) - reipl_method = IPL_METHOD_FCP_RW_DIAG; + reipl_method = REIPL_METHOD_FCP_RW_DIAG; else if (MACHINE_IS_VM) - reipl_method = IPL_METHOD_FCP_RO_VM; + reipl_method = REIPL_METHOD_FCP_RO_VM; else - reipl_method = IPL_METHOD_FCP_RO_DIAG; + reipl_method = REIPL_METHOD_FCP_RO_DIAG; + break; + case IPL_TYPE_FCP_DUMP: + reipl_method = REIPL_METHOD_FCP_DUMP; break; case IPL_TYPE_NSS: - reipl_method = IPL_METHOD_NSS; + reipl_method = REIPL_METHOD_NSS; + break; + case IPL_TYPE_UNKNOWN: + reipl_method = REIPL_METHOD_DEFAULT; break; default: - reipl_method = IPL_METHOD_NONE; + BUG(); } reipl_type = type; return 0; @@ -579,22 +644,22 @@ static struct attribute_group dump_ccw_attr_group = { /* dump type */ -static int dump_set_type(enum ipl_type type) +static int dump_set_type(enum dump_type type) { if (!(dump_capabilities & type)) return -EINVAL; switch(type) { - case IPL_TYPE_CCW: + case DUMP_TYPE_CCW: if (MACHINE_IS_VM) - dump_method = IPL_METHOD_CCW_VM; + dump_method = DUMP_METHOD_CCW_VM; else - dump_method = IPL_METHOD_CCW_CIO; + dump_method = DUMP_METHOD_CCW_CIO; break; - case IPL_TYPE_FCP: - dump_method = IPL_METHOD_FCP_RW_DIAG; + case DUMP_TYPE_FCP: + dump_method = DUMP_METHOD_FCP_DIAG; break; default: - dump_method = IPL_METHOD_NONE; + dump_method = DUMP_METHOD_NONE; } dump_type = type; return 0; @@ -602,7 +667,7 @@ static int dump_set_type(enum ipl_type type) static ssize_t dump_type_show(struct subsystem *subsys, char *page) { - return sprintf(page, "%s\n", ipl_type_str(dump_type)); + return sprintf(page, "%s\n", dump_type_str(dump_type)); } static ssize_t dump_type_store(struct subsystem *subsys, const char *buf, @@ -610,12 +675,12 @@ static ssize_t dump_type_store(struct subsystem *subsys, const char *buf, { int rc = -EINVAL; - if (strncmp(buf, IPL_NONE_STR, strlen(IPL_NONE_STR)) == 0) - rc = dump_set_type(IPL_TYPE_NONE); - else if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0) - rc = dump_set_type(IPL_TYPE_CCW); - else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) - rc = dump_set_type(IPL_TYPE_FCP); + if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0) + rc = dump_set_type(DUMP_TYPE_NONE); + else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0) + rc = dump_set_type(DUMP_TYPE_CCW); + else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) + rc = dump_set_type(DUMP_TYPE_FCP); return (rc != 0) ? rc : len; } @@ -664,14 +729,14 @@ void do_reipl(void) char loadparm[LOADPARM_LEN + 1]; switch (reipl_method) { - case IPL_METHOD_CCW_CIO: + case REIPL_METHOD_CCW_CIO: devid.devno = reipl_block_ccw->ipl_info.ccw.devno; - if (ipl_get_type() == IPL_TYPE_CCW && devid.devno == ipl_devno) + if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno) diag308(DIAG308_IPL, NULL); devid.ssid = 0; reipl_ccw_dev(&devid); break; - case IPL_METHOD_CCW_VM: + case REIPL_METHOD_CCW_VM: reipl_get_ascii_loadparm(loadparm); if (strlen(loadparm) == 0) sprintf(buf, "IPL %X", @@ -681,30 +746,32 @@ void do_reipl(void) reipl_block_ccw->ipl_info.ccw.devno, loadparm); __cpcmd(buf, NULL, 0, NULL); break; - case IPL_METHOD_CCW_DIAG: + case REIPL_METHOD_CCW_DIAG: diag308(DIAG308_SET, reipl_block_ccw); diag308(DIAG308_IPL, NULL); break; - case IPL_METHOD_FCP_RW_DIAG: + case REIPL_METHOD_FCP_RW_DIAG: diag308(DIAG308_SET, reipl_block_fcp); diag308(DIAG308_IPL, NULL); break; - case IPL_METHOD_FCP_RO_DIAG: + case REIPL_METHOD_FCP_RO_DIAG: diag308(DIAG308_IPL, NULL); break; - case IPL_METHOD_FCP_RO_VM: + case REIPL_METHOD_FCP_RO_VM: __cpcmd("IPL", NULL, 0, NULL); break; - case IPL_METHOD_NSS: + case REIPL_METHOD_NSS: sprintf(buf, "IPL %s", reipl_nss_name); __cpcmd(buf, NULL, 0, NULL); break; - case IPL_METHOD_NONE: - default: + case REIPL_METHOD_DEFAULT: if (MACHINE_IS_VM) __cpcmd("IPL", NULL, 0, NULL); diag308(DIAG308_IPL, NULL); break; + case REIPL_METHOD_FCP_DUMP: + default: + break; } signal_processor(smp_processor_id(), sigp_stop_and_store_status); } @@ -715,28 +782,28 @@ static void do_dump(void) static char buf[100]; switch (dump_method) { - case IPL_METHOD_CCW_CIO: + case DUMP_METHOD_CCW_CIO: smp_send_stop(); devid.devno = dump_block_ccw->ipl_info.ccw.devno; devid.ssid = 0; reipl_ccw_dev(&devid); break; - case IPL_METHOD_CCW_VM: + case DUMP_METHOD_CCW_VM: smp_send_stop(); sprintf(buf, "STORE STATUS"); __cpcmd(buf, NULL, 0, NULL); sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); __cpcmd(buf, NULL, 0, NULL); break; - case IPL_METHOD_CCW_DIAG: + case DUMP_METHOD_CCW_DIAG: diag308(DIAG308_SET, dump_block_ccw); diag308(DIAG308_DUMP, NULL); break; - case IPL_METHOD_FCP_RW_DIAG: + case DUMP_METHOD_FCP_DIAG: diag308(DIAG308_SET, dump_block_fcp); diag308(DIAG308_DUMP, NULL); break; - case IPL_METHOD_NONE: + case DUMP_METHOD_NONE: default: return; } @@ -777,12 +844,13 @@ static int __init ipl_init(void) rc = firmware_register(&ipl_subsys); if (rc) return rc; - switch (ipl_get_type()) { + switch (ipl_info.type) { case IPL_TYPE_CCW: rc = sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group); break; case IPL_TYPE_FCP: + case IPL_TYPE_FCP_DUMP: rc = ipl_register_fcp_files(); break; case IPL_TYPE_NSS: @@ -852,7 +920,7 @@ static int __init reipl_ccw_init(void) /* FIXME: check for diag308_set_works when enabling diag ccw reipl */ if (!MACHINE_IS_VM) sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; - if (ipl_get_type() == IPL_TYPE_CCW) + if (ipl_info.type == IPL_TYPE_CCW) reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; reipl_capabilities |= IPL_TYPE_CCW; return 0; @@ -862,9 +930,9 @@ static int __init reipl_fcp_init(void) { int rc; - if ((!diag308_set_works) && (ipl_get_type() != IPL_TYPE_FCP)) + if ((!diag308_set_works) && (ipl_info.type != IPL_TYPE_FCP)) return 0; - if ((!diag308_set_works) && (ipl_get_type() == IPL_TYPE_FCP)) + if ((!diag308_set_works) && (ipl_info.type == IPL_TYPE_FCP)) make_attrs_ro(reipl_fcp_attrs); reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); @@ -875,7 +943,7 @@ static int __init reipl_fcp_init(void) free_page((unsigned long)reipl_block_fcp); return rc; } - if (ipl_get_type() == IPL_TYPE_FCP) { + if (ipl_info.type == IPL_TYPE_FCP) { memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); } else { reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; @@ -909,7 +977,7 @@ static int __init reipl_init(void) rc = reipl_nss_init(); if (rc) return rc; - rc = reipl_set_type(ipl_get_type()); + rc = reipl_set_type(ipl_info.type); if (rc) return rc; return 0; @@ -931,7 +999,7 @@ static int __init dump_ccw_init(void) dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; - dump_capabilities |= IPL_TYPE_CCW; + dump_capabilities |= DUMP_TYPE_CCW; return 0; } @@ -956,7 +1024,7 @@ static int __init dump_fcp_init(void) dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP; - dump_capabilities |= IPL_TYPE_FCP; + dump_capabilities |= DUMP_TYPE_FCP; return 0; } @@ -995,7 +1063,7 @@ static int __init dump_init(void) rc = dump_fcp_init(); if (rc) return rc; - dump_set_type(IPL_TYPE_NONE); + dump_set_type(DUMP_TYPE_NONE); return 0; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 863c8d08c02..3dfd0985861 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -285,6 +285,26 @@ static void __init conmode_default(void) } } +#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) +static void __init setup_zfcpdump(unsigned int console_devno) +{ + static char str[64]; + + if (ipl_info.type != IPL_TYPE_FCP_DUMP) + return; + if (console_devno != -1) + sprintf(str, "cio_ignore=all,!0.0.%04x,!0.0.%04x", + ipl_info.data.fcp.dev_id.devno, console_devno); + else + sprintf(str, "cio_ignore=all,!0.0.%04x", + ipl_info.data.fcp.dev_id.devno); + strcat(COMMAND_LINE, str); + console_loglevel = 2; +} +#else +static inline void setup_zfcpdump(unsigned int console_devno) {} +#endif /* CONFIG_ZFCPDUMP */ + #ifdef CONFIG_SMP void (*_machine_restart)(char *command) = machine_restart_smp; void (*_machine_halt)(void) = machine_halt_smp; @@ -586,13 +606,20 @@ setup_resources(void) } } +unsigned long real_memory_size; +EXPORT_SYMBOL_GPL(real_memory_size); + static void __init setup_memory_end(void) { - unsigned long real_size, memory_size; + unsigned long memory_size; unsigned long max_mem, max_phys; int i; - memory_size = real_size = 0; +#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) + if (ipl_info.type == IPL_TYPE_FCP_DUMP) + memory_end = ZFCPDUMP_HSA_SIZE; +#endif + memory_size = 0; max_phys = VMALLOC_END_INIT - VMALLOC_MIN_SIZE; memory_end &= PAGE_MASK; @@ -601,7 +628,8 @@ static void __init setup_memory_end(void) for (i = 0; i < MEMORY_CHUNKS; i++) { struct mem_chunk *chunk = &memory_chunk[i]; - real_size = max(real_size, chunk->addr + chunk->size); + real_memory_size = max(real_memory_size, + chunk->addr + chunk->size); if (chunk->addr >= max_mem) { memset(chunk, 0, sizeof(*chunk)); continue; @@ -765,6 +793,7 @@ setup_arch(char **cmdline_p) parse_early_param(); + setup_ipl_info(); setup_memory_end(); setup_addressing_mode(); setup_memory(); @@ -782,6 +811,9 @@ setup_arch(char **cmdline_p) /* Setup default console */ conmode_default(); + + /* Setup zfcpdump support */ + setup_zfcpdump(console_devno); } void print_cpu_info(struct cpuinfo_S390 *cpuinfo) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 97764f710bb..7c0143fdf71 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include extern volatile int __cpu_logical_map[]; @@ -395,6 +397,65 @@ void smp_ctl_clear_bit(int cr, int bit) on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); } +#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) + +/* + * zfcpdump_prefix_array holds prefix registers for the following scenario: + * 64 bit zfcpdump kernel and 31 bit kernel which is to be dumped. We have to + * save its prefix registers, since they get lost, when switching from 31 bit + * to 64 bit. + */ +unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ + __attribute__((__section__(".data"))); + +static void __init smp_get_save_areas(void) +{ + unsigned int cpu, cpu_num, rc; + __u16 boot_cpu_addr; + + if (ipl_info.type != IPL_TYPE_FCP_DUMP) + return; + boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; + cpu_num = 1; + for (cpu = 0; cpu <= 65535; cpu++) { + if ((u16) cpu == boot_cpu_addr) + continue; + __cpu_logical_map[1] = (__u16) cpu; + if (signal_processor(1, sigp_sense) == sigp_not_operational) + continue; + if (cpu_num >= NR_CPUS) { + printk("WARNING: Registers for cpu %i are not " + "saved, since dump kernel was compiled with" + "NR_CPUS=%i!\n", cpu_num, NR_CPUS); + continue; + } + zfcpdump_save_areas[cpu_num] = + alloc_bootmem(sizeof(union save_area)); + while (1) { + rc = signal_processor(1, sigp_stop_and_store_status); + if (rc != sigp_busy) + break; + cpu_relax(); + } + memcpy(zfcpdump_save_areas[cpu_num], + (void *)(unsigned long) store_prefix() + + SAVE_AREA_BASE, SAVE_AREA_SIZE); +#ifdef __s390x__ + /* copy original prefix register */ + zfcpdump_save_areas[cpu_num]->s390x.pref_reg = + zfcpdump_prefix_array[cpu_num]; +#endif + cpu_num++; + } +} + +union save_area *zfcpdump_save_areas[NR_CPUS + 1]; +EXPORT_SYMBOL_GPL(zfcpdump_save_areas); + +#else +#define smp_get_save_areas() do { } while (0) +#endif + /* * Lets check how many CPUs we have. */ @@ -589,6 +650,7 @@ void __init smp_setup_cpu_possible_map(void) { unsigned int phy_cpus, pos_cpus, cpu; + smp_get_save_areas(); phy_cpus = smp_count_cpus(); pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); -- cgit v1.2.3 From 131a395c18af43d824841642038e5cc0d48f0bd2 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Fri, 27 Apr 2007 16:01:54 +0200 Subject: [S390] crypto: cleanup. Cleanup code and remove obsolete documentation. Signed-off-by: Jan Glauber Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/crypto/sha1_s390.c | 129 +++++++++++++++++++++-------------------- arch/s390/crypto/sha256_s390.c | 38 +++++------- 2 files changed, 81 insertions(+), 86 deletions(-) (limited to 'arch') diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c index 969639f3197..af4460ec381 100644 --- a/arch/s390/crypto/sha1_s390.c +++ b/arch/s390/crypto/sha1_s390.c @@ -25,99 +25,100 @@ */ #include #include -#include #include -#include -#include + #include "crypt_s390.h" #define SHA1_DIGEST_SIZE 20 #define SHA1_BLOCK_SIZE 64 -struct crypt_s390_sha1_ctx { - u64 count; +struct s390_sha1_ctx { + u64 count; /* message length */ u32 state[5]; - u32 buf_len; - u8 buffer[2 * SHA1_BLOCK_SIZE]; + u8 buf[2 * SHA1_BLOCK_SIZE]; }; static void sha1_init(struct crypto_tfm *tfm) { - struct crypt_s390_sha1_ctx *ctx = crypto_tfm_ctx(tfm); - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - - ctx->count = 0; - ctx->buf_len = 0; + struct s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm); + + sctx->state[0] = 0x67452301; + sctx->state[1] = 0xEFCDAB89; + sctx->state[2] = 0x98BADCFE; + sctx->state[3] = 0x10325476; + sctx->state[4] = 0xC3D2E1F0; + sctx->count = 0; } static void sha1_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) { - struct crypt_s390_sha1_ctx *sctx; - long imd_len; - - sctx = crypto_tfm_ctx(tfm); - sctx->count += len * 8; /* message bit length */ - - /* anything in buffer yet? -> must be completed */ - if (sctx->buf_len && (sctx->buf_len + len) >= SHA1_BLOCK_SIZE) { - /* complete full block and hash */ - memcpy(sctx->buffer + sctx->buf_len, data, - SHA1_BLOCK_SIZE - sctx->buf_len); - crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, - SHA1_BLOCK_SIZE); - data += SHA1_BLOCK_SIZE - sctx->buf_len; - len -= SHA1_BLOCK_SIZE - sctx->buf_len; - sctx->buf_len = 0; + struct s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm); + unsigned int index; + int ret; + + /* how much is already in the buffer? */ + index = sctx->count & 0x3f; + + sctx->count += len; + + if (index + len < SHA1_BLOCK_SIZE) + goto store; + + /* process one stored block */ + if (index) { + memcpy(sctx->buf + index, data, SHA1_BLOCK_SIZE - index); + ret = crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buf, + SHA1_BLOCK_SIZE); + BUG_ON(ret != SHA1_BLOCK_SIZE); + data += SHA1_BLOCK_SIZE - index; + len -= SHA1_BLOCK_SIZE - index; } - /* rest of data contains full blocks? */ - imd_len = len & ~0x3ful; - if (imd_len) { - crypt_s390_kimd(KIMD_SHA_1, sctx->state, data, imd_len); - data += imd_len; - len -= imd_len; + /* process as many blocks as possible */ + if (len >= SHA1_BLOCK_SIZE) { + ret = crypt_s390_kimd(KIMD_SHA_1, sctx->state, data, + len & ~(SHA1_BLOCK_SIZE - 1)); + BUG_ON(ret != (len & ~(SHA1_BLOCK_SIZE - 1))); + data += ret; + len -= ret; } - /* anything left? store in buffer */ - if (len) { - memcpy(sctx->buffer + sctx->buf_len , data, len); - sctx->buf_len += len; - } -} +store: + /* anything left? */ + if (len) + memcpy(sctx->buf + index , data, len); +} -static void pad_message(struct crypt_s390_sha1_ctx* sctx) +/* Add padding and return the message digest. */ +static void sha1_final(struct crypto_tfm *tfm, u8 *out) { - int index; + struct s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm); + u64 bits; + unsigned int index, end; + int ret; + + /* must perform manual padding */ + index = sctx->count & 0x3f; + end = (index < 56) ? SHA1_BLOCK_SIZE : (2 * SHA1_BLOCK_SIZE); - index = sctx->buf_len; - sctx->buf_len = (sctx->buf_len < 56) ? - SHA1_BLOCK_SIZE:2 * SHA1_BLOCK_SIZE; /* start pad with 1 */ - sctx->buffer[index] = 0x80; + sctx->buf[index] = 0x80; + /* pad with zeros */ index++; - memset(sctx->buffer + index, 0x00, sctx->buf_len - index); - /* append length */ - memcpy(sctx->buffer + sctx->buf_len - 8, &sctx->count, - sizeof sctx->count); -} + memset(sctx->buf + index, 0x00, end - index - 8); -/* Add padding and return the message digest. */ -static void sha1_final(struct crypto_tfm *tfm, u8 *out) -{ - struct crypt_s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm); + /* append message length */ + bits = sctx->count * 8; + memcpy(sctx->buf + end - 8, &bits, sizeof(bits)); + + ret = crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buf, end); + BUG_ON(ret != end); - /* must perform manual padding */ - pad_message(sctx); - crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len); /* copy digest to out */ memcpy(out, sctx->state, SHA1_DIGEST_SIZE); + /* wipe context */ memset(sctx, 0, sizeof *sctx); } @@ -128,7 +129,7 @@ static struct crypto_alg alg = { .cra_priority = CRYPT_S390_PRIORITY, .cra_flags = CRYPTO_ALG_TYPE_DIGEST, .cra_blocksize = SHA1_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx), + .cra_ctxsize = sizeof(struct s390_sha1_ctx), .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(alg.cra_list), .cra_u = { .digest = { diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index 78436c696d3..2ced3330bce 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c @@ -26,7 +26,7 @@ #define SHA256_BLOCK_SIZE 64 struct s390_sha256_ctx { - u64 count; + u64 count; /* message length */ u32 state[8]; u8 buf[2 * SHA256_BLOCK_SIZE]; }; @@ -54,10 +54,9 @@ static void sha256_update(struct crypto_tfm *tfm, const u8 *data, int ret; /* how much is already in the buffer? */ - index = sctx->count / 8 & 0x3f; + index = sctx->count & 0x3f; - /* update message bit length */ - sctx->count += len * 8; + sctx->count += len; if ((index + len) < SHA256_BLOCK_SIZE) goto store; @@ -87,12 +86,17 @@ store: memcpy(sctx->buf + index , data, len); } -static void pad_message(struct s390_sha256_ctx* sctx) +/* Add padding and return the message digest */ +static void sha256_final(struct crypto_tfm *tfm, u8 *out) { - int index, end; + struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); + u64 bits; + unsigned int index, end; + int ret; - index = sctx->count / 8 & 0x3f; - end = index < 56 ? SHA256_BLOCK_SIZE : 2 * SHA256_BLOCK_SIZE; + /* must perform manual padding */ + index = sctx->count & 0x3f; + end = (index < 56) ? SHA256_BLOCK_SIZE : (2 * SHA256_BLOCK_SIZE); /* start pad with 1 */ sctx->buf[index] = 0x80; @@ -102,21 +106,11 @@ static void pad_message(struct s390_sha256_ctx* sctx) memset(sctx->buf + index, 0x00, end - index - 8); /* append message length */ - memcpy(sctx->buf + end - 8, &sctx->count, sizeof sctx->count); - - sctx->count = end * 8; -} - -/* Add padding and return the message digest */ -static void sha256_final(struct crypto_tfm *tfm, u8 *out) -{ - struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); - - /* must perform manual padding */ - pad_message(sctx); + bits = sctx->count * 8; + memcpy(sctx->buf + end - 8, &bits, sizeof(bits)); - crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf, - sctx->count / 8); + ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf, end); + BUG_ON(ret != end); /* copy digest to out */ memcpy(out, sctx->state, SHA256_DIGEST_SIZE); -- cgit v1.2.3 From db77aa5f3d01fe6a6cc629dbd37936b1fdd129ba Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Fri, 27 Apr 2007 16:01:55 +0200 Subject: [S390] vtime: cleanup per_cpu usage. Replace per_cpu(... , smp_processor_id()) with __get_cpu_var() Signed-off-by: Jan Glauber Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/vtime.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 9d5b02801b4..1e1a6ee2cac 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -128,7 +128,7 @@ static inline void set_vtimer(__u64 expires) S390_lowcore.last_update_timer = expires; /* store expire time for this CPU timer */ - per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires; + __get_cpu_var(virt_cpu_timer).to_expire = expires; } #else static inline void set_vtimer(__u64 expires) @@ -137,7 +137,7 @@ static inline void set_vtimer(__u64 expires) asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer)); /* store expire time for this CPU timer */ - per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires; + __get_cpu_var(virt_cpu_timer).to_expire = expires; } #endif @@ -145,7 +145,7 @@ static void start_cpu_timer(void) { struct vtimer_queue *vt_list; - vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); + vt_list = &__get_cpu_var(virt_cpu_timer); /* CPU timer interrupt is pending, don't reprogramm it */ if (vt_list->idle & 1LL<<63) @@ -159,7 +159,7 @@ static void stop_cpu_timer(void) { struct vtimer_queue *vt_list; - vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); + vt_list = &__get_cpu_var(virt_cpu_timer); /* nothing to do */ if (list_empty(&vt_list->list)) { @@ -219,7 +219,7 @@ static void do_callbacks(struct list_head *cb_list) if (list_empty(cb_list)) return; - vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); + vt_list = &__get_cpu_var(virt_cpu_timer); list_for_each_entry_safe(event, tmp, cb_list, entry) { fn = event->function; @@ -244,7 +244,6 @@ static void do_callbacks(struct list_head *cb_list) */ static void do_cpu_timer_interrupt(__u16 error_code) { - int cpu; __u64 next, delta; struct vtimer_queue *vt_list; struct vtimer_list *event, *tmp; @@ -253,8 +252,7 @@ static void do_cpu_timer_interrupt(__u16 error_code) struct list_head cb_list; INIT_LIST_HEAD(&cb_list); - cpu = smp_processor_id(); - vt_list = &per_cpu(virt_cpu_timer, cpu); + vt_list = &__get_cpu_var(virt_cpu_timer); /* walk timer list, fire all expired events */ spin_lock(&vt_list->lock); @@ -534,7 +532,7 @@ void init_cpu_vtimer(void) /* enable cpu timer interrupts */ __ctl_set_bit(0,10); - vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); + vt_list = &__get_cpu_var(virt_cpu_timer); INIT_LIST_HEAD(&vt_list->list); spin_lock_init(&vt_list->lock); vt_list->to_expire = 0; -- cgit v1.2.3 From 2fc2d1e9ffcde78af7ab63ed640d9a4901797de2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 27 Apr 2007 16:01:56 +0200 Subject: [S390] Processor degradation notification. Generate uevents for all cpus if cpu capability changes. This can happen e.g. because the cpus are overheating. The cpu capability can be read via /sys/devices/system/cpu/cpuN/capability. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/smp.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 7c0143fdf71..2c5de92958d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -821,19 +821,57 @@ int setup_profiling_timer(unsigned int multiplier) static DEFINE_PER_CPU(struct cpu, cpu_devices); +static ssize_t show_capability(struct sys_device *dev, char *buf) +{ + unsigned int capability; + int rc; + + rc = get_cpu_capability(&capability); + if (rc) + return rc; + return sprintf(buf, "%u\n", capability); +} +static SYSDEV_ATTR(capability, 0444, show_capability, NULL); + +static int __cpuinit smp_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned int)(long)hcpu; + struct cpu *c = &per_cpu(cpu_devices, cpu); + struct sys_device *s = &c->sysdev; + + switch (action) { + case CPU_ONLINE: + if (sysdev_create_file(s, &attr_capability)) + return NOTIFY_BAD; + break; + case CPU_DEAD: + sysdev_remove_file(s, &attr_capability); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata smp_cpu_nb = { + .notifier_call = smp_cpu_notify, +}; + static int __init topology_init(void) { int cpu; - int ret; + + register_cpu_notifier(&smp_cpu_nb); for_each_possible_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); + struct sys_device *s = &c->sysdev; c->hotpluggable = 1; - ret = register_cpu(c, cpu); - if (ret) - printk(KERN_WARNING "topology_init: register_cpu %d " - "failed (%d)\n", cpu, ret); + register_cpu(c, cpu); + if (!cpu_online(cpu)) + continue; + s = &c->sysdev; + sysdev_create_file(s, &attr_capability); } return 0; } -- cgit v1.2.3 From ecdcc0234b27472b561378ac59e2beeea06ec6ff Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2007 16:01:58 +0200 Subject: [S390] Switch etr from tasklet to workqueue. The clock synchronization of the ETR code requires an smp_call_function to synchronize all cpus. Calling smp_call_function from a tasklet is illegal. Replace the tasklet with a job on the global workqueue. ETR work is rare and can be postponed to a be done by a kernel thread. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/time.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index e1ad464b6f2..711dae8da7a 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -280,7 +280,6 @@ static void clock_comparator_interrupt(__u16 code) } static void etr_reset(void); -static void etr_init(void); static void etr_ext_handler(__u16); /* @@ -355,7 +354,6 @@ void __init time_init(void) #ifdef CONFIG_VIRT_TIMER vtime_init(); #endif - etr_init(); } /* @@ -426,11 +424,11 @@ static struct etr_aib etr_port1; static int etr_port1_uptodate; static unsigned long etr_events; static struct timer_list etr_timer; -static struct tasklet_struct etr_tasklet; static DEFINE_PER_CPU(atomic_t, etr_sync_word); static void etr_timeout(unsigned long dummy); -static void etr_tasklet_fn(unsigned long dummy); +static void etr_work_fn(struct work_struct *work); +static DECLARE_WORK(etr_work, etr_work_fn); /* * The etr get_clock function. It will write the current clock value @@ -507,29 +505,31 @@ static void etr_reset(void) } } -static void etr_init(void) +static int __init etr_init(void) { struct etr_aib aib; if (test_bit(ETR_FLAG_ENOSYS, &etr_flags)) - return; + return 0; /* Check if this machine has the steai instruction. */ if (etr_steai(&aib, ETR_STEAI_STEPPING_PORT) == 0) set_bit(ETR_FLAG_STEAI, &etr_flags); setup_timer(&etr_timer, etr_timeout, 0UL); - tasklet_init(&etr_tasklet, etr_tasklet_fn, 0); if (!etr_port0_online && !etr_port1_online) set_bit(ETR_FLAG_EACCES, &etr_flags); if (etr_port0_online) { set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } if (etr_port1_online) { set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } + return 0; } +arch_initcall(etr_init); + /* * Two sorts of ETR machine checks. The architecture reads: * "When a machine-check niterruption occurs and if a switch-to-local or @@ -549,7 +549,7 @@ void etr_switch_to_local(void) return; etr_disable_sync_clock(NULL); set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } /* @@ -564,7 +564,7 @@ void etr_sync_check(void) return; etr_disable_sync_clock(NULL); set_bit(ETR_EVENT_SYNC_CHECK, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } /* @@ -591,13 +591,13 @@ static void etr_ext_handler(__u16 code) * Both ports are not up-to-date now. */ set_bit(ETR_EVENT_PORT_ALERT, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } static void etr_timeout(unsigned long dummy) { set_bit(ETR_EVENT_UPDATE, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } /* @@ -927,7 +927,7 @@ static struct etr_eacr etr_handle_update(struct etr_aib *aib, if (!eacr.e0 && !eacr.e1) return eacr; - /* Update port0 or port1 with aib stored in etr_tasklet_fn. */ + /* Update port0 or port1 with aib stored in etr_work_fn. */ if (aib->esw.q == 0) { /* Information for port 0 stored. */ if (eacr.p0 && !etr_port0_uptodate) { @@ -1007,7 +1007,7 @@ static void etr_update_eacr(struct etr_eacr eacr) * particular this is the only function that calls etr_update_eacr(), * it "controls" the etr control register. */ -static void etr_tasklet_fn(unsigned long dummy) +static void etr_work_fn(struct work_struct *work) { unsigned long long now; struct etr_eacr eacr; @@ -1220,13 +1220,13 @@ static ssize_t etr_online_store(struct sys_device *dev, return count; /* Nothing to do. */ etr_port0_online = value; set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } else { if (etr_port1_online == value) return count; /* Nothing to do. */ etr_port1_online = value; set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events); - tasklet_hi_schedule(&etr_tasklet); + schedule_work(&etr_work); } return count; } -- cgit v1.2.3 From 9ff6f4577e69801a43c0d58606a80040aecbc4bc Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 27 Apr 2007 16:01:59 +0200 Subject: [S390] Remove debugging junk. arch/s390/appldata/appldata_base.c has some confusing debugging code left over to allow compiling it as a module. In practice, it cannot be configured as module and there is no need to keep that code. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/appldata/appldata_base.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'arch') diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 0c3cf4b16ae..ee89b33145d 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -668,45 +668,7 @@ EXPORT_SYMBOL_GPL(appldata_register_ops); EXPORT_SYMBOL_GPL(appldata_unregister_ops); EXPORT_SYMBOL_GPL(appldata_diag); -#ifdef MODULE -/* - * Kernel symbols needed by appldata_mem and appldata_os modules. - * However, if this file is compiled as a module (for testing only), these - * symbols are not exported. In this case, we define them locally and export - * those. - */ -void si_swapinfo(struct sysinfo *val) -{ - val->freeswap = -1ul; - val->totalswap = -1ul; -} - -unsigned long avenrun[3] = {-1 - FIXED_1/200, -1 - FIXED_1/200, - -1 - FIXED_1/200}; -int nr_threads = -1; - -void get_full_page_state(struct page_state *ps) -{ - memset(ps, -1, sizeof(struct page_state)); -} - -unsigned long nr_running(void) -{ - return -1; -} - -unsigned long nr_iowait(void) -{ - return -1; -} - -/*unsigned long nr_context_switches(void) -{ - return -1; -}*/ -#endif /* MODULE */ EXPORT_SYMBOL_GPL(si_swapinfo); EXPORT_SYMBOL_GPL(nr_threads); EXPORT_SYMBOL_GPL(nr_running); EXPORT_SYMBOL_GPL(nr_iowait); -//EXPORT_SYMBOL_GPL(nr_context_switches); -- cgit v1.2.3 From 39ce010d38bf6703b49f59eb73bef030b1d659f2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 27 Apr 2007 16:02:00 +0200 Subject: [S390] Clean up smp code in preparation for some larger changes. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/smp.c | 261 +++++++++++++++++++------------------------------ 1 file changed, 100 insertions(+), 161 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 2c5de92958d..3754e2031b3 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1,12 +1,12 @@ /* * arch/s390/kernel/smp.c * - * Copyright (C) IBM Corp. 1999,2006 + * Copyright IBM Corp. 1999,2007 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), - * Martin Schwidefsky (schwidefsky@de.ibm.com) - * Heiko Carstens (heiko.carstens@de.ibm.com) + * Martin Schwidefsky (schwidefsky@de.ibm.com) + * Heiko Carstens (heiko.carstens@de.ibm.com) * - * based on other smp stuff by + * based on other smp stuff by * (c) 1995 Alan Cox, CymruNET Ltd * (c) 1998 Ingo Molnar * @@ -43,16 +43,17 @@ #include #include -extern volatile int __cpu_logical_map[]; - /* * An array with a pointer the lowcore of every CPU. */ - struct _lowcore *lowcore_ptr[NR_CPUS]; +EXPORT_SYMBOL(lowcore_ptr); cpumask_t cpu_online_map = CPU_MASK_NONE; +EXPORT_SYMBOL(cpu_online_map); + cpumask_t cpu_possible_map = CPU_MASK_NONE; +EXPORT_SYMBOL(cpu_possible_map); static struct task_struct *current_set[NR_CPUS]; @@ -72,7 +73,7 @@ struct call_data_struct { int wait; }; -static struct call_data_struct * call_data; +static struct call_data_struct *call_data; /* * 'Call function' interrupt callback @@ -152,8 +153,8 @@ out: * * Run a function on all other CPUs. * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler. You may call it from a bottom half. + * You must not call this function with disabled interrupts, from a + * hardware interrupt handler or from a bottom half. */ int smp_call_function(void (*func) (void *info), void *info, int nonatomic, int wait) @@ -179,11 +180,11 @@ EXPORT_SYMBOL(smp_call_function); * * Run a function on one processor. * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler. You may call it from a bottom half. + * You must not call this function with disabled interrupts, from a + * hardware interrupt handler or from a bottom half. */ int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic, - int wait, int cpu) + int wait, int cpu) { cpumask_t map = CPU_MASK_NONE; @@ -197,9 +198,9 @@ EXPORT_SYMBOL(smp_call_function_on); static void do_send_stop(void) { - int cpu, rc; + int cpu, rc; - /* stop all processors */ + /* stop all processors */ for_each_online_cpu(cpu) { if (cpu == smp_processor_id()) continue; @@ -211,9 +212,9 @@ static void do_send_stop(void) static void do_store_status(void) { - int cpu, rc; + int cpu, rc; - /* store status of all processors in their lowcores (real 0) */ + /* store status of all processors in their lowcores (real 0) */ for_each_online_cpu(cpu) { if (cpu == smp_processor_id()) continue; @@ -221,8 +222,8 @@ static void do_store_status(void) rc = signal_processor_p( (__u32)(unsigned long) lowcore_ptr[cpu], cpu, sigp_store_status_at_address); - } while(rc == sigp_busy); - } + } while (rc == sigp_busy); + } } static void do_wait_for_stop(void) @@ -233,7 +234,7 @@ static void do_wait_for_stop(void) for_each_online_cpu(cpu) { if (cpu == smp_processor_id()) continue; - while(!smp_cpu_not_running(cpu)) + while (!smp_cpu_not_running(cpu)) cpu_relax(); } } @@ -247,7 +248,7 @@ void smp_send_stop(void) /* Disable all interrupts/machine checks */ __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK); - /* write magic number to zero page (absolute 0) */ + /* write magic number to zero page (absolute 0) */ lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC; /* stop other processors. */ @@ -263,8 +264,7 @@ void smp_send_stop(void) /* * Reboot, halt and power_off routines for SMP. */ - -void machine_restart_smp(char * __unused) +void machine_restart_smp(char *__unused) { smp_send_stop(); do_reipl(); @@ -295,17 +295,17 @@ void machine_power_off_smp(void) static void do_ext_call_interrupt(__u16 code) { - unsigned long bits; + unsigned long bits; - /* - * handle bit signal external calls - * - * For the ec_schedule signal we have to do nothing. All the work - * is done automatically when we return from the interrupt. - */ + /* + * handle bit signal external calls + * + * For the ec_schedule signal we have to do nothing. All the work + * is done automatically when we return from the interrupt. + */ bits = xchg(&S390_lowcore.ext_call_fast, 0); - if (test_bit(ec_call_function, &bits)) + if (test_bit(ec_call_function, &bits)) do_call_function(); } @@ -315,11 +315,11 @@ static void do_ext_call_interrupt(__u16 code) */ static void smp_ext_bitcall(int cpu, ec_bit_sig sig) { - /* - * Set signaling bit in lowcore of target cpu and kick it - */ + /* + * Set signaling bit in lowcore of target cpu and kick it + */ set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); - while(signal_processor(cpu, sigp_emergency_signal) == sigp_busy) + while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) udelay(10); } @@ -334,7 +334,7 @@ void smp_ptlb_callback(void *info) void smp_ptlb_all(void) { - on_each_cpu(smp_ptlb_callback, NULL, 0, 1); + on_each_cpu(smp_ptlb_callback, NULL, 0, 1); } EXPORT_SYMBOL(smp_ptlb_all); #endif /* ! CONFIG_64BIT */ @@ -346,7 +346,7 @@ EXPORT_SYMBOL(smp_ptlb_all); */ void smp_send_reschedule(int cpu) { - smp_ext_bitcall(cpu, ec_schedule); + smp_ext_bitcall(cpu, ec_schedule); } /* @@ -360,11 +360,12 @@ struct ec_creg_mask_parms { /* * callback for setting/clearing control bits */ -static void smp_ctl_bit_callback(void *info) { +static void smp_ctl_bit_callback(void *info) +{ struct ec_creg_mask_parms *pp = info; unsigned long cregs[16]; int i; - + __ctl_store(cregs, 0, 15); for (i = 0; i <= 15; i++) cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i]; @@ -383,6 +384,7 @@ void smp_ctl_set_bit(int cr, int bit) parms.orvals[cr] = 1 << bit; on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); } +EXPORT_SYMBOL(smp_ctl_set_bit); /* * Clear a bit in a control register of all cpus @@ -396,6 +398,7 @@ void smp_ctl_clear_bit(int cr, int bit) parms.andvals[cr] = ~(1L << bit); on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); } +EXPORT_SYMBOL(smp_ctl_clear_bit); #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) @@ -460,8 +463,7 @@ EXPORT_SYMBOL_GPL(zfcpdump_save_areas); * Lets check how many CPUs we have. */ -static unsigned int -__init smp_count_cpus(void) +static unsigned int __init smp_count_cpus(void) { unsigned int cpu, num_cpus; __u16 boot_cpu_addr; @@ -477,31 +479,30 @@ __init smp_count_cpus(void) if ((__u16) cpu == boot_cpu_addr) continue; __cpu_logical_map[1] = (__u16) cpu; - if (signal_processor(1, sigp_sense) == - sigp_not_operational) + if (signal_processor(1, sigp_sense) == sigp_not_operational) continue; num_cpus++; } - printk("Detected %d CPU's\n",(int) num_cpus); + printk("Detected %d CPU's\n", (int) num_cpus); printk("Boot cpu address %2X\n", boot_cpu_addr); return num_cpus; } /* - * Activate a secondary processor. + * Activate a secondary processor. */ int __devinit start_secondary(void *cpuvoid) { - /* Setup the cpu */ - cpu_init(); + /* Setup the cpu */ + cpu_init(); preempt_disable(); /* Enable TOD clock interrupts on the secondary cpu. */ - init_cpu_timer(); + init_cpu_timer(); #ifdef CONFIG_VIRT_TIMER /* Enable cpu timer interrupts on the secondary cpu. */ - init_cpu_vtimer(); + init_cpu_vtimer(); #endif /* Enable pfault pseudo page faults on this cpu. */ pfault_init(); @@ -510,11 +511,11 @@ int __devinit start_secondary(void *cpuvoid) cpu_set(smp_processor_id(), cpu_online_map); /* Switch on interrupts */ local_irq_enable(); - /* Print info about this processor */ - print_cpu_info(&S390_lowcore.cpu_data); - /* cpu_idle will call schedule for us */ - cpu_idle(); - return 0; + /* Print info about this processor */ + print_cpu_info(&S390_lowcore.cpu_data); + /* cpu_idle will call schedule for us */ + cpu_idle(); + return 0; } static void __init smp_create_idle(unsigned int cpu) @@ -531,56 +532,13 @@ static void __init smp_create_idle(unsigned int cpu) current_set[cpu] = p; } -/* Reserving and releasing of CPUs */ - -static DEFINE_SPINLOCK(smp_reserve_lock); -static int smp_cpu_reserved[NR_CPUS]; - -int -smp_get_cpu(cpumask_t cpu_mask) -{ - unsigned long flags; - int cpu; - - spin_lock_irqsave(&smp_reserve_lock, flags); - /* Try to find an already reserved cpu. */ - for_each_cpu_mask(cpu, cpu_mask) { - if (smp_cpu_reserved[cpu] != 0) { - smp_cpu_reserved[cpu]++; - /* Found one. */ - goto out; - } - } - /* Reserve a new cpu from cpu_mask. */ - for_each_cpu_mask(cpu, cpu_mask) { - if (cpu_online(cpu)) { - smp_cpu_reserved[cpu]++; - goto out; - } - } - cpu = -ENODEV; -out: - spin_unlock_irqrestore(&smp_reserve_lock, flags); - return cpu; -} - -void -smp_put_cpu(int cpu) -{ - unsigned long flags; - - spin_lock_irqsave(&smp_reserve_lock, flags); - smp_cpu_reserved[cpu]--; - spin_unlock_irqrestore(&smp_reserve_lock, flags); -} - -static int -cpu_stopped(int cpu) +static int cpu_stopped(int cpu) { __u32 status; /* Check for stopped state */ - if (signal_processor_ps(&status, 0, cpu, sigp_sense) == sigp_status_stored) { + if (signal_processor_ps(&status, 0, cpu, sigp_sense) == + sigp_status_stored) { if (status & 0x40) return 1; } @@ -589,14 +547,13 @@ cpu_stopped(int cpu) /* Upping and downing of CPUs */ -int -__cpu_up(unsigned int cpu) +int __cpu_up(unsigned int cpu) { struct task_struct *idle; - struct _lowcore *cpu_lowcore; + struct _lowcore *cpu_lowcore; struct stack_frame *sf; - sigp_ccode ccode; - int curr_cpu; + sigp_ccode ccode; + int curr_cpu; for (curr_cpu = 0; curr_cpu <= 65535; curr_cpu++) { __cpu_logical_map[cpu] = (__u16) curr_cpu; @@ -609,7 +566,7 @@ __cpu_up(unsigned int cpu) ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), cpu, sigp_set_prefix); - if (ccode){ + if (ccode) { printk("sigp_set_prefix failed for cpu %d " "with condition code %d\n", (int) cpu, (int) ccode); @@ -617,9 +574,9 @@ __cpu_up(unsigned int cpu) } idle = current_set[cpu]; - cpu_lowcore = lowcore_ptr[cpu]; + cpu_lowcore = lowcore_ptr[cpu]; cpu_lowcore->kernel_stack = (unsigned long) - task_stack_page(idle) + (THREAD_SIZE); + task_stack_page(idle) + THREAD_SIZE; sf = (struct stack_frame *) (cpu_lowcore->kernel_stack - sizeof(struct pt_regs) - sizeof(struct stack_frame)); @@ -631,11 +588,11 @@ __cpu_up(unsigned int cpu) " stam 0,15,0(%0)" : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; - cpu_lowcore->current_task = (unsigned long) idle; - cpu_lowcore->cpu_data.cpu_nr = cpu; + cpu_lowcore->current_task = (unsigned long) idle; + cpu_lowcore->cpu_data.cpu_nr = cpu; eieio(); - while (signal_processor(cpu,sigp_restart) == sigp_busy) + while (signal_processor(cpu, sigp_restart) == sigp_busy) udelay(10); while (!cpu_online(cpu)) @@ -682,18 +639,11 @@ static int __init setup_possible_cpus(char *s) } early_param("possible_cpus", setup_possible_cpus); -int -__cpu_disable(void) +int __cpu_disable(void) { - unsigned long flags; struct ec_creg_mask_parms cr_parms; int cpu = smp_processor_id(); - spin_lock_irqsave(&smp_reserve_lock, flags); - if (smp_cpu_reserved[cpu] != 0) { - spin_unlock_irqrestore(&smp_reserve_lock, flags); - return -EBUSY; - } cpu_clear(cpu, cpu_online_map); /* Disable pfault pseudo page faults on this cpu. */ @@ -704,24 +654,23 @@ __cpu_disable(void) /* disable all external interrupts */ cr_parms.orvals[0] = 0; - cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 | - 1<<11 | 1<<10 | 1<< 6 | 1<< 4); + cr_parms.andvals[0] = ~(1 << 15 | 1 << 14 | 1 << 13 | 1 << 12 | + 1 << 11 | 1 << 10 | 1 << 6 | 1 << 4); /* disable all I/O interrupts */ cr_parms.orvals[6] = 0; - cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 | - 1<<27 | 1<<26 | 1<<25 | 1<<24); + cr_parms.andvals[6] = ~(1 << 31 | 1 << 30 | 1 << 29 | 1 << 28 | + 1 << 27 | 1 << 26 | 1 << 25 | 1 << 24); /* disable most machine checks */ cr_parms.orvals[14] = 0; - cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24); + cr_parms.andvals[14] = ~(1 << 28 | 1 << 27 | 1 << 26 | + 1 << 25 | 1 << 24); smp_ctl_bit_callback(&cr_parms); - spin_unlock_irqrestore(&smp_reserve_lock, flags); return 0; } -void -__cpu_die(unsigned int cpu) +void __cpu_die(unsigned int cpu) { /* Wait until target cpu is down */ while (!smp_cpu_not_running(cpu)) @@ -729,13 +678,12 @@ __cpu_die(unsigned int cpu) printk("Processor %d spun down\n", cpu); } -void -cpu_die(void) +void cpu_die(void) { idle_task_exit(); signal_processor(smp_processor_id(), sigp_stop); BUG(); - for(;;); + for (;;); } #endif /* CONFIG_HOTPLUG_CPU */ @@ -748,36 +696,36 @@ void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned long stack; unsigned int cpu; - int i; - - /* request the 0x1201 emergency signal external interrupt */ - if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) - panic("Couldn't request external interrupt 0x1201"); - memset(lowcore_ptr,0,sizeof(lowcore_ptr)); - /* - * Initialize prefix pages and stacks for all possible cpus - */ + int i; + + /* request the 0x1201 emergency signal external interrupt */ + if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) + panic("Couldn't request external interrupt 0x1201"); + memset(lowcore_ptr, 0, sizeof(lowcore_ptr)); + /* + * Initialize prefix pages and stacks for all possible cpus + */ print_cpu_info(&S390_lowcore.cpu_data); - for_each_possible_cpu(i) { + for_each_possible_cpu(i) { lowcore_ptr[i] = (struct _lowcore *) - __get_free_pages(GFP_KERNEL|GFP_DMA, - sizeof(void*) == 8 ? 1 : 0); - stack = __get_free_pages(GFP_KERNEL,ASYNC_ORDER); - if (lowcore_ptr[i] == NULL || stack == 0ULL) + __get_free_pages(GFP_KERNEL | GFP_DMA, + sizeof(void*) == 8 ? 1 : 0); + stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); + if (!lowcore_ptr[i] || !stack) panic("smp_boot_cpus failed to allocate memory\n"); *(lowcore_ptr[i]) = S390_lowcore; - lowcore_ptr[i]->async_stack = stack + (ASYNC_SIZE); - stack = __get_free_pages(GFP_KERNEL,0); - if (stack == 0ULL) + lowcore_ptr[i]->async_stack = stack + ASYNC_SIZE; + stack = __get_free_pages(GFP_KERNEL, 0); + if (!stack) panic("smp_boot_cpus failed to allocate memory\n"); - lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE); + lowcore_ptr[i]->panic_stack = stack + PAGE_SIZE; #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) { lowcore_ptr[i]->extended_save_area_addr = - (__u32) __get_free_pages(GFP_KERNEL,0); - if (lowcore_ptr[i]->extended_save_area_addr == 0) + (__u32) __get_free_pages(GFP_KERNEL, 0); + if (!lowcore_ptr[i]->extended_save_area_addr) panic("smp_boot_cpus failed to " "allocate memory\n"); } @@ -816,7 +764,7 @@ void smp_cpus_done(unsigned int max_cpus) */ int setup_profiling_timer(unsigned int multiplier) { - return 0; + return 0; } static DEFINE_PER_CPU(struct cpu, cpu_devices); @@ -853,7 +801,7 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self, } static struct notifier_block __cpuinitdata smp_cpu_nb = { - .notifier_call = smp_cpu_notify, + .notifier_call = smp_cpu_notify, }; static int __init topology_init(void) @@ -875,13 +823,4 @@ static int __init topology_init(void) } return 0; } - subsys_initcall(topology_init); - -EXPORT_SYMBOL(cpu_online_map); -EXPORT_SYMBOL(cpu_possible_map); -EXPORT_SYMBOL(lowcore_ptr); -EXPORT_SYMBOL(smp_ctl_set_bit); -EXPORT_SYMBOL(smp_ctl_clear_bit); -EXPORT_SYMBOL(smp_get_cpu); -EXPORT_SYMBOL(smp_put_cpu); -- cgit v1.2.3 From 7f5a7716dc0b380fd3c85ca5a5841969555feaa7 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 25 Apr 2007 15:08:57 +0100 Subject: [MIPS] Fix AP/SP to work in the reality of modern kernels. Signed-off-by: Ralf Baechle --- arch/mips/kernel/kspd.c | 5 +---- arch/mips/kernel/rtlx.c | 7 ++++--- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 29eadd404fa..c6580018c94 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -17,6 +17,7 @@ */ #include #include +#include #include #include #include @@ -198,7 +199,6 @@ void sp_work_handle_request(void) int cmd; char *vcwd; - mm_segment_t old_fs; int size; ret.retval = -1; @@ -241,8 +241,6 @@ void sp_work_handle_request(void) if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, (int)&tz, 0,0)) == 0) ret.retval = tv.tv_sec; - - ret.errno = errno; break; case MTSP_SYSCALL_EXIT: @@ -279,7 +277,6 @@ void sp_work_handle_request(void) if (cmd >= 0) { ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1, generic.arg2, generic.arg3); - ret.errno = errno; } else printk(KERN_WARNING "KSPD: Unknown SP syscall number %d\n", sc.cmd); diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index e6e3047151a..bfc8ca168f8 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -289,7 +289,7 @@ unsigned int rtlx_write_poll(int index) return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); } -ssize_t rtlx_read(int index, void __user *buff, size_t count, int user) +ssize_t rtlx_read(int index, void __user *buff, size_t count) { size_t lx_write, fl = 0L; struct rtlx_channel *lx; @@ -331,9 +331,10 @@ out: return count; } -ssize_t rtlx_write(int index, const void __user *buffer, size_t count, int user) +ssize_t rtlx_write(int index, const void __user *buffer, size_t count) { struct rtlx_channel *rt; + unsigned long failed; size_t rt_read; size_t fl; @@ -363,7 +364,7 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count, int user) } out: - count -= cailed; + count -= failed; smp_wmb(); rt->rt_write = (rt->rt_write + count) % rt->buffer_size; -- cgit v1.2.3 From cc50b67dcd84c6215232c0e1c95e24786e555782 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 6 Mar 2007 21:34:44 +0900 Subject: [MIPS] Cobalt: clean up include files Signed-off-by: Yoichi Yuasa --- arch/mips/cobalt/console.c | 8 +++----- arch/mips/cobalt/irq.c | 2 +- arch/mips/cobalt/reset.c | 11 ++++------- arch/mips/cobalt/setup.c | 4 +--- 4 files changed, 9 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c index ca56b415b8a..0485d51f721 100644 --- a/arch/mips/cobalt/console.c +++ b/arch/mips/cobalt/console.c @@ -1,13 +1,11 @@ /* * (C) P. Horton 2006 */ - -#include -#include -#include #include + #include -#include + +#include void prom_putchar(char c) { diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c index fe93b846923..950ad1e8be4 100644 --- a/arch/mips/cobalt/irq.c +++ b/arch/mips/cobalt/irq.c @@ -17,7 +17,7 @@ #include #include -#include +#include /* * We have two types of interrupts that we handle, ones that come in through diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c index 753dfccae6f..43cca21fdbc 100644 --- a/arch/mips/cobalt/reset.c +++ b/arch/mips/cobalt/reset.c @@ -8,15 +8,12 @@ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) */ -#include -#include -#include +#include + #include -#include #include -#include -#include -#include + +#include void cobalt_machine_halt(void) { diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index 88d34f11385..db0d83cf1d4 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -19,12 +19,10 @@ #include #include #include -#include -#include #include #include -#include +#include extern void cobalt_machine_restart(char *command); extern void cobalt_machine_halt(void); -- cgit v1.2.3 From 2a9effc67804102d6d5182eb0116520588ae2256 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 5 Mar 2007 19:10:03 +0900 Subject: [MIPS] Cobalt: Split PCI codes from setup.c It's removed #ifdef CONFIG_PCI/#endif from cobalt setup.c . Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/cobalt/Makefile | 1 + arch/mips/cobalt/pci.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ arch/mips/cobalt/setup.c | 28 ---------------------------- 3 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 arch/mips/cobalt/pci.c (limited to 'arch') diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index b36dd8f538f..de017c11f9b 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile @@ -4,5 +4,6 @@ obj-y := irq.o reset.o setup.o +obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_EARLY_PRINTK) += console.o obj-$(CONFIG_MTD_PHYSMAP) += mtd.o diff --git a/arch/mips/cobalt/pci.c b/arch/mips/cobalt/pci.c new file mode 100644 index 00000000000..d0160063954 --- /dev/null +++ b/arch/mips/cobalt/pci.c @@ -0,0 +1,47 @@ +/* + * Register PCI controller. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997, 2004, 05 by Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) + * + */ +#include +#include + +#include + +extern struct pci_ops gt64111_pci_ops; + +static struct resource cobalt_mem_resource = { + .start = GT_DEF_PCI0_MEM0_BASE, + .end = GT_DEF_PCI0_MEM0_BASE + GT_DEF_PCI0_MEM0_SIZE - 1, + .name = "PCI memory", + .flags = IORESOURCE_MEM, +}; + +static struct resource cobalt_io_resource = { + .start = 0x1000, + .end = GT_DEF_PCI0_IO_SIZE - 1, + .name = "PCI I/O", + .flags = IORESOURCE_IO, +}; + +static struct pci_controller cobalt_pci_controller = { + .pci_ops = >64111_pci_ops, + .mem_resource = &cobalt_mem_resource, + .io_resource = &cobalt_io_resource, + .io_offset = 0 - GT_DEF_PCI0_IO_BASE, +}; + +static int __init cobalt_pci_init(void) +{ + register_pci_controller(&cobalt_pci_controller); + + return 0; +} + +arch_initcall(cobalt_pci_init); diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index db0d83cf1d4..d0dd81790f7 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -61,22 +61,6 @@ void __init plat_timer_setup(struct irqaction *irq) GT_WRITE(GT_INTRMASK_OFS, GT_INTR_T0EXP_MSK | GT_READ(GT_INTRMASK_OFS)); } -extern struct pci_ops gt64111_pci_ops; - -static struct resource cobalt_mem_resource = { - .start = GT_DEF_PCI0_MEM0_BASE, - .end = GT_DEF_PCI0_MEM0_BASE + GT_DEF_PCI0_MEM0_SIZE - 1, - .name = "PCI memory", - .flags = IORESOURCE_MEM -}; - -static struct resource cobalt_io_resource = { - .start = 0x1000, - .end = 0xffff, - .name = "PCI I/O", - .flags = IORESOURCE_IO -}; - /* * Cobalt doesn't have PS/2 keyboard/mouse interfaces, * keyboard conntroller is never used. @@ -109,14 +93,6 @@ static struct resource cobalt_reserved_resources[] = { }, }; -static struct pci_controller cobalt_pci_controller = { - .pci_ops = >64111_pci_ops, - .mem_resource = &cobalt_mem_resource, - .mem_offset = 0, - .io_resource = &cobalt_io_resource, - .io_offset = 0 - GT_DEF_PCI0_IO_BASE, -}; - void __init plat_mem_setup(void) { static struct uart_port uart; @@ -144,10 +120,6 @@ void __init plat_mem_setup(void) printk("Cobalt board ID: %d\n", cobalt_board_id); -#ifdef CONFIG_PCI - register_pci_controller(&cobalt_pci_controller); -#endif - if (cobalt_board_id > COBALT_BRD_ID_RAQ1) { #ifdef CONFIG_SERIAL_8250 uart.line = 0; -- cgit v1.2.3 From 252161eccd1a44f32a506d0fedb424d4ff84e4dc Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 14 Mar 2007 21:51:26 +0900 Subject: [MIPS] merge GT64111 PCI routines and GT64120 PCI_0 routines This patch has merged GT64111 PCI routines and GT64120 PCI_0 routines. GT64111 PCI is almost the same as GT64120's PCI_0. This patch don't change GT64120 PCI routines. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 19 ++--- arch/mips/cobalt/pci.c | 4 +- arch/mips/gt64120/wrppmc/pci.c | 4 +- arch/mips/mips-boards/generic/pci.c | 4 +- arch/mips/pci/Makefile | 3 +- arch/mips/pci/ops-gt64111.c | 100 ------------------------ arch/mips/pci/ops-gt64120.c | 152 ------------------------------------ arch/mips/pci/ops-gt64xxx_pci0.c | 152 ++++++++++++++++++++++++++++++++++++ arch/mips/pci/pci-lasat.c | 4 +- arch/mips/pci/pci-ocelot.c | 2 +- 10 files changed, 170 insertions(+), 274 deletions(-) delete mode 100644 arch/mips/pci/ops-gt64111.c delete mode 100644 arch/mips/pci/ops-gt64120.c create mode 100644 arch/mips/pci/ops-gt64xxx_pci0.c (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c78b14380b3..2fd82e54818 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -165,7 +165,7 @@ config MIPS_COBALT select HW_HAS_PCI select I8259 select IRQ_CPU - select MIPS_GT64111 + select PCI_GT64XXX_PCI0 select SYS_HAS_CPU_NEVADA select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL @@ -207,7 +207,7 @@ config MIPS_EV64120 depends on EXPERIMENTAL select DMA_NONCOHERENT select HW_HAS_PCI - select MIPS_GT64120 + select PCI_GT64XXX_PCI0 select SYS_HAS_CPU_R5000 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL @@ -245,7 +245,7 @@ config LASAT select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI - select MIPS_GT64120 + select PCI_GT64XXX_PCI0 select MIPS_NILE4 select R5000_CPU_SCACHE select SYS_HAS_CPU_R5000 @@ -263,7 +263,7 @@ config MIPS_ATLAS select HW_HAS_PCI select MIPS_BOARDS_GEN select MIPS_BONITO64 - select MIPS_GT64120 + select PCI_GT64XXX_PCI0 select MIPS_MSC select RM7000_CPU_SCACHE select SWAP_IO_SPACE @@ -296,7 +296,7 @@ config MIPS_MALTA select MIPS_BOARDS_GEN select MIPS_BONITO64 select MIPS_CPU_SCACHE - select MIPS_GT64120 + select PCI_GT64XXX_PCI0 select MIPS_MSC select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 @@ -340,7 +340,7 @@ config WR_PPMC select BOOT_ELF32 select DMA_NONCOHERENT select HW_HAS_PCI - select MIPS_GT64120 + select PCI_GT64XXX_PCI0 select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 @@ -398,7 +398,7 @@ config MOMENCO_OCELOT select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K - select MIPS_GT64120 + select PCI_GT64XXX_PCI0 select RM7000_CPU_SCACHE select SWAP_IO_SPACE select SYS_HAS_CPU_RM7000 @@ -999,10 +999,7 @@ config DDB5XXX_COMMON config MIPS_BOARDS_GEN bool -config MIPS_GT64111 - bool - -config MIPS_GT64120 +config PCI_GT64XXX_PCI0 bool config MIPS_TX3927 diff --git a/arch/mips/cobalt/pci.c b/arch/mips/cobalt/pci.c index d0160063954..d91027f43de 100644 --- a/arch/mips/cobalt/pci.c +++ b/arch/mips/cobalt/pci.c @@ -14,7 +14,7 @@ #include -extern struct pci_ops gt64111_pci_ops; +extern struct pci_ops gt64xxx_pci0_ops; static struct resource cobalt_mem_resource = { .start = GT_DEF_PCI0_MEM0_BASE, @@ -31,7 +31,7 @@ static struct resource cobalt_io_resource = { }; static struct pci_controller cobalt_pci_controller = { - .pci_ops = >64111_pci_ops, + .pci_ops = >64xxx_pci0_ops, .mem_resource = &cobalt_mem_resource, .io_resource = &cobalt_io_resource, .io_offset = 0 - GT_DEF_PCI0_IO_BASE, diff --git a/arch/mips/gt64120/wrppmc/pci.c b/arch/mips/gt64120/wrppmc/pci.c index 2fbe93467f7..0d5289bc180 100644 --- a/arch/mips/gt64120/wrppmc/pci.c +++ b/arch/mips/gt64120/wrppmc/pci.c @@ -13,7 +13,7 @@ #include #include -extern struct pci_ops gt64120_pci_ops; +extern struct pci_ops gt64xxx_pci0_ops; static struct resource pci0_io_resource = { .name = "pci_0 io", @@ -30,7 +30,7 @@ static struct resource pci0_mem_resource = { }; static struct pci_controller hose_0 = { - .pci_ops = >64120_pci_ops, + .pci_ops = >64xxx_pci0_ops, .io_resource = &pci0_io_resource, .mem_resource = &pci0_mem_resource, }; diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c index 3192a14698c..f98d60f7865 100644 --- a/arch/mips/mips-boards/generic/pci.c +++ b/arch/mips/mips-boards/generic/pci.c @@ -65,7 +65,7 @@ static struct resource msc_io_resource = { }; extern struct pci_ops bonito64_pci_ops; -extern struct pci_ops gt64120_pci_ops; +extern struct pci_ops gt64xxx_pci0_ops; extern struct pci_ops msc_pci_ops; static struct pci_controller bonito64_controller = { @@ -76,7 +76,7 @@ static struct pci_controller bonito64_controller = { }; static struct pci_controller gt64120_controller = { - .pci_ops = >64120_pci_ops, + .pci_ops = >64xxx_pci0_ops, .io_resource = >64120_io_resource, .mem_resource = >64120_mem_resource, }; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index bf85995ca04..df487c063b1 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -8,8 +8,7 @@ obj-y += pci.o pci-dac.o # PCI bus host bridge specific code # obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o -obj-$(CONFIG_MIPS_GT64111) += ops-gt64111.o -obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o +obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c deleted file mode 100644 index ecd3991bd0e..00000000000 --- a/arch/mips/pci/ops-gt64111.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995, 1996, 1997, 2002 by Ralf Baechle - * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) - */ -#include -#include -#include -#include - -#include -#include -#include - -#include - -/* - * Device 31 on the GT64111 is used to generate PCI special - * cycles, so we shouldn't expected to find a device there ... - */ -static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn) -{ - if (bus->number == 0 && PCI_SLOT(devfn) < 31) - return 0; - - return -1; -} - -static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - if (pci_range_ck(bus, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - switch (size) { - case 4: - PCI_CFG_SET(devfn, where); - *val = GT_READ(GT_PCI0_CFGDATA_OFS); - return PCIBIOS_SUCCESSFUL; - - case 2: - PCI_CFG_SET(devfn, (where & ~0x3)); - *val = GT_READ(GT_PCI0_CFGDATA_OFS) - >> ((where & 3) * 8); - return PCIBIOS_SUCCESSFUL; - - case 1: - PCI_CFG_SET(devfn, (where & ~0x3)); - *val = GT_READ(GT_PCI0_CFGDATA_OFS) - >> ((where & 3) * 8); - return PCIBIOS_SUCCESSFUL; - } - - return PCIBIOS_BAD_REGISTER_NUMBER; -} - -static int gt64111_pci_write_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 tmp; - - if (pci_range_ck(bus, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - switch (size) { - case 4: - PCI_CFG_SET(devfn, where); - GT_WRITE(GT_PCI0_CFGDATA_OFS, val); - - return PCIBIOS_SUCCESSFUL; - - case 2: - PCI_CFG_SET(devfn, (where & ~0x3)); - tmp = GT_READ(GT_PCI0_CFGDATA_OFS); - tmp &= ~(0xffff << ((where & 0x3) * 8)); - tmp |= (val << ((where & 0x3) * 8)); - GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); - - return PCIBIOS_SUCCESSFUL; - - case 1: - PCI_CFG_SET(devfn, (where & ~0x3)); - tmp = GT_READ(GT_PCI0_CFGDATA_OFS); - tmp &= ~(0xff << ((where & 0x3) * 8)); - tmp |= (val << ((where & 0x3) * 8)); - GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); - - return PCIBIOS_SUCCESSFUL; - } - - return PCIBIOS_BAD_REGISTER_NUMBER; -} - -struct pci_ops gt64111_pci_ops = { - .read = gt64111_pci_read_config, - .write = gt64111_pci_write_config, -}; diff --git a/arch/mips/pci/ops-gt64120.c b/arch/mips/pci/ops-gt64120.c deleted file mode 100644 index 6335844d607..00000000000 --- a/arch/mips/pci/ops-gt64120.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - */ -#include -#include -#include - -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -/* - * PCI configuration cycle AD bus definition - */ -/* Type 0 */ -#define PCI_CFG_TYPE0_REG_SHF 0 -#define PCI_CFG_TYPE0_FUNC_SHF 8 - -/* Type 1 */ -#define PCI_CFG_TYPE1_REG_SHF 0 -#define PCI_CFG_TYPE1_FUNC_SHF 8 -#define PCI_CFG_TYPE1_DEV_SHF 11 -#define PCI_CFG_TYPE1_BUS_SHF 16 - -static int gt64120_pcibios_config_access(unsigned char access_type, - struct pci_bus *bus, unsigned int devfn, int where, u32 * data) -{ - unsigned char busnum = bus->number; - u32 intr; - - if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0))) - return -1; /* Because of a bug in the galileo (for slot 31). */ - - /* Clear cause register bits */ - GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - /* Setup address */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) | - (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | - ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | - GT_PCI0_CFGADDR_CONFIGEN_BIT); - - if (access_type == PCI_ACCESS_WRITE) { - if (busnum == 0 && PCI_SLOT(devfn) == 0) { - /* - * The Galileo system controller is acting - * differently than other devices. - */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } else - __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } else { - if (busnum == 0 && PCI_SLOT(devfn) == 0) { - /* - * The Galileo system controller is acting - * differently than other devices. - */ - *data = GT_READ(GT_PCI0_CFGDATA_OFS); - } else - *data = __GT_READ(GT_PCI0_CFGDATA_OFS); - } - - /* Check for master or target abort */ - intr = GT_READ(GT_INTRCAUSE_OFS); - - if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) { - /* Error occurred */ - - /* Clear bits */ - GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - return -1; - } - - return 0; -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int gt64120_pcibios_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - u32 data = 0; - - if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, - &data)) - return PCIBIOS_DEVICE_NOT_FOUND; - - if (size == 1) - *val = (data >> ((where & 3) << 3)) & 0xff; - else if (size == 2) - *val = (data >> ((where & 3) << 3)) & 0xffff; - else - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - -static int gt64120_pcibios_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 data = 0; - - if (size == 4) - data = val; - else { - if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, - where, &data)) - return PCIBIOS_DEVICE_NOT_FOUND; - - if (size == 1) - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - else if (size == 2) - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - } - - if (gt64120_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, - &data)) - return PCIBIOS_DEVICE_NOT_FOUND; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops gt64120_pci_ops = { - .read = gt64120_pcibios_read, - .write = gt64120_pcibios_write -}; diff --git a/arch/mips/pci/ops-gt64xxx_pci0.c b/arch/mips/pci/ops-gt64xxx_pci0.c new file mode 100644 index 00000000000..3d896c5f413 --- /dev/null +++ b/arch/mips/pci/ops-gt64xxx_pci0.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include + +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +static int gt64xxx_pci0_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, unsigned int devfn, int where, u32 * data) +{ + unsigned char busnum = bus->number; + u32 intr; + + if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0))) + return -1; /* Because of a bug in the galileo (for slot 31). */ + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + if (access_type == PCI_ACCESS_WRITE) { + if (busnum == 0 && PCI_SLOT(devfn) == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else + __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else { + if (busnum == 0 && PCI_SLOT(devfn) == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + *data = GT_READ(GT_PCI0_CFGDATA_OFS); + } else + *data = __GT_READ(GT_PCI0_CFGDATA_OFS); + } + + /* Check for master or target abort */ + intr = GT_READ(GT_INTRCAUSE_OFS); + + if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) { + /* Error occurred */ + + /* Clear bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + return -1; + } + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int gt64xxx_pci0_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64xxx_pci0_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + if (size == 4) + data = val; + else { + if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus, + devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + } + + if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, + where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops gt64xxx_pci0_ops = { + .read = gt64xxx_pci0_pcibios_read, + .write = gt64xxx_pci0_pcibios_write +}; diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c index 88fb191ad2e..985784a3e6f 100644 --- a/arch/mips/pci/pci-lasat.c +++ b/arch/mips/pci/pci-lasat.c @@ -12,7 +12,7 @@ #include extern struct pci_ops nile4_pci_ops; -extern struct pci_ops gt64120_pci_ops; +extern struct pci_ops gt64xxx_pci0_ops; static struct resource lasat_pci_mem_resource = { .name = "LASAT PCI MEM", .start = 0x18000000, @@ -38,7 +38,7 @@ static int __init lasat_pci_setup(void) switch (mips_machtype) { case MACH_LASAT_100: - lasat_pci_controller.pci_ops = >64120_pci_ops; + lasat_pci_controller.pci_ops = >64xxx_pci0_ops; break; case MACH_LASAT_200: lasat_pci_controller.pci_ops = &nile4_pci_ops; diff --git a/arch/mips/pci/pci-ocelot.c b/arch/mips/pci/pci-ocelot.c index 2b9495dce6b..7f94f26d35a 100644 --- a/arch/mips/pci/pci-ocelot.c +++ b/arch/mips/pci/pci-ocelot.c @@ -81,7 +81,7 @@ static struct resource ocelot_io_resource = { }; static struct pci_controller ocelot_pci_controller = { - .pci_ops = gt64120_pci_ops; + .pci_ops = gt64xxx_pci0_ops; .mem_resource = &ocelot_mem_resource; .io_resource = &ocelot_io_resource; }; -- cgit v1.2.3 From 2127435e57a15f1fea8d6969e264eeb05b28ba4b Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 15 Mar 2007 00:58:28 +0900 Subject: [MIPS] JMR3927 cleanup * Kill dead codes * Rearrange irq chip handlers * Minimize defconfig Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/configs/jmr3927_defconfig | 254 ++++++++------------------- arch/mips/jmr3927/common/prom.c | 12 +- arch/mips/jmr3927/common/puts.c | 122 +------------ arch/mips/jmr3927/rbhma3100/Makefile | 1 - arch/mips/jmr3927/rbhma3100/init.c | 16 +- arch/mips/jmr3927/rbhma3100/irq.c | 312 ++++------------------------------ arch/mips/jmr3927/rbhma3100/kgdb_io.c | 54 +----- arch/mips/jmr3927/rbhma3100/setup.c | 157 +++-------------- arch/mips/pci/fixup-jmr3927.c | 11 +- arch/mips/pci/ops-tx3927.c | 232 ------------------------- 11 files changed, 141 insertions(+), 1031 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2fd82e54818..acceae0e831 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -779,6 +779,7 @@ config TOSHIBA_JMR3927 select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN select TOSHIBA_BOARDS + select GENERIC_HARDIRQS_NO__DO_IRQ config TOSHIBA_RBTX4927 bool "Toshiba TBTX49[23]7 board" diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 21a094752da..068e48ec709 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:34 2007 +# Linux kernel version: 2.6.21-rc3 +# Thu Mar 15 00:40:40 2007 # CONFIG_MIPS=y @@ -70,7 +70,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y CONFIG_CPU_BIG_ENDIAN=y @@ -138,12 +138,12 @@ CONFIG_ZONE_DMA_FLAG=1 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set +CONFIG_HZ_250=y # CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y +# CONFIG_HZ_1000 is not set # CONFIG_HZ_1024 is not set CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 +CONFIG_HZ=250 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -175,14 +175,15 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y @@ -217,11 +218,11 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" # # Bus options (PCI, PCMCIA, EISA, ISA, TC) @@ -233,12 +234,10 @@ CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # -# CONFIG_PCCARD is not set # # PCI Hotplug Support # -# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -250,10 +249,7 @@ CONFIG_TRAD_SIGNALS=y # # Power management options # -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_PM is not set # # Networking @@ -267,12 +263,7 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y +# CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -290,19 +281,18 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -343,13 +333,7 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -CONFIG_IEEE80211=y -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=y -CONFIG_IEEE80211_CRYPT_CCMP=y -CONFIG_IEEE80211_SOFTMAC=y -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -360,14 +344,12 @@ CONFIG_WIRELESS_EXT=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y +# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -396,16 +378,13 @@ CONFIG_PROC_EVENTS=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CDROM_PKTCDVD=y -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # # Misc devices # -CONFIG_SGI_IOC4=y +# CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # @@ -416,7 +395,7 @@ CONFIG_SGI_IOC4=y # # SCSI device support # -CONFIG_RAID_ATTRS=y +# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set @@ -462,26 +441,13 @@ CONFIG_NETDEVICES=y # # PHY device support # -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set +CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set @@ -493,7 +459,27 @@ CONFIG_NET_ETHERNET=y # # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +CONFIG_TC35815=y +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set # # Ethernet (1000 Mbit) @@ -509,20 +495,21 @@ CONFIG_NET_ETHERNET=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set -CONFIG_QLA3XXX=y +# CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set # # Ethernet (10000 Mbit) # # CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=y +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=y +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -566,10 +553,7 @@ CONFIG_INPUT=y # # Userland interfaces # -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set @@ -587,21 +571,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # Hardware I/O ports # -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_LIBPS2 is not set -CONFIG_SERIO_RAW=y +# CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set # # Character devices # -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VT is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -609,7 +585,7 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_DIGIEPCA is not set # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set -CONFIG_MOXA_SMARTIO_NEW=y +# CONFIG_MOXA_SMARTIO_NEW is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set # CONFIG_SYNCLINK_GT is not set @@ -629,11 +605,12 @@ CONFIG_MOXA_SMARTIO_NEW=y # Non-8250 serial port support # CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_TXX9=y CONFIG_HAS_TXX9_SERIAL=y CONFIG_SERIAL_TXX9_NR_UARTS=6 -# CONFIG_SERIAL_TXX9_CONSOLE is not set -# CONFIG_SERIAL_TXX9_STDSERIAL is not set +CONFIG_SERIAL_TXX9_CONSOLE=y +CONFIG_SERIAL_TXX9_STDSERIAL=y # CONFIG_SERIAL_JSM is not set # CONFIG_UNIX98_PTYS is not set CONFIG_LEGACY_PTYS=y @@ -684,6 +661,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # @@ -697,51 +679,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set -CONFIG_FB=y -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_SMIVGX is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set # # Sound @@ -864,7 +803,7 @@ CONFIG_INOTIFY_USER=y CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=y +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -889,14 +828,13 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set @@ -944,10 +882,7 @@ CONFIG_MSDOS_PARTITION=y # # Distributed Lock Manager # -CONFIG_DLM=y -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set +# CONFIG_DLM is not set # # Profiling support @@ -972,65 +907,22 @@ CONFIG_CMDLINE="" # # Security options # -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # # Cryptographic options # -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_WP512=y -CONFIG_CRYPTO_TGR192=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=y -CONFIG_CRYPTO_BLOWFISH=y -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y -CONFIG_CRYPTO_SERPENT=y -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_CAST5=y -CONFIG_CRYPTO_CAST6=y -CONFIG_CRYPTO_TEA=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_KHAZAD=y -CONFIG_CRYPTO_ANUBIS=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CAMELLIA=y - -# -# Hardware crypto devices -# +# CONFIG_CRYPTO is not set # # Library routines # CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set -CONFIG_CRC16=y +# CONFIG_CRC16 is not set CONFIG_CRC32=y -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y +# CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y diff --git a/arch/mips/jmr3927/common/prom.c b/arch/mips/jmr3927/common/prom.c index aa481b774c4..5398813e50e 100644 --- a/arch/mips/jmr3927/common/prom.c +++ b/arch/mips/jmr3927/common/prom.c @@ -41,16 +41,6 @@ #include -extern int prom_argc; -extern char **prom_argv, **prom_envp; - -typedef struct -{ - char *name; -/* char *val; */ -}t_env_var; - - char * __init prom_getcmdline(void) { return &(arcs_cmdline[0]); @@ -60,6 +50,8 @@ void __init prom_init_cmdline(void) { char *cp; int actr; + int prom_argc = fw_arg0; + char **prom_argv = (char **) fw_arg1; actr = 1; /* Always ignore argv[0] */ diff --git a/arch/mips/jmr3927/common/puts.c b/arch/mips/jmr3927/common/puts.c index 1c1cad9cd07..c611ab49788 100644 --- a/arch/mips/jmr3927/common/puts.c +++ b/arch/mips/jmr3927/common/puts.c @@ -32,137 +32,29 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include #include -#include #define TIMEOUT 0xffffff -#define SLOW_DOWN - -static const char digits[16] = "0123456789abcdef"; - -#ifdef SLOW_DOWN -#define slow_down() { int k; for (k=0; k<10000; k++); } -#else -#define slow_down() -#endif void -putch(const unsigned char c) +prom_putchar(char c) { int i = 0; do { - slow_down(); i++; - if (i>TIMEOUT) { + if (i>TIMEOUT) break; - } } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); tx3927_sioptr(1)->tfifo = c; return; } -unsigned char getch(void) -{ - int i = 0; - int dicr; - char c; - - /* diable RX int. */ - dicr = tx3927_sioptr(1)->dicr; - tx3927_sioptr(1)->dicr = 0; - - do { - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (tx3927_sioptr(1)->disr & TXx927_SIDISR_UVALID) - ; - c = tx3927_sioptr(1)->rfifo; - - /* clear RX int. status */ - tx3927_sioptr(1)->disr &= ~TXx927_SIDISR_RDIS; - /* enable RX int. */ - tx3927_sioptr(1)->dicr = dicr; - - return c; -} -void -do_jmr3927_led_set(char n) -{ - /* and with current leds */ - jmr3927_led_and_set(n); -} - void -puts(unsigned char *cp) +puts(const char *cp) { - int i = 0; - - while (*cp) { - do { - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); - tx3927_sioptr(1)->tfifo = *cp++; - } - putch('\r'); - putch('\n'); -} - -void -fputs(unsigned char *cp) -{ - int i = 0; - - while (*cp) { - do { - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); - tx3927_sioptr(1)->tfifo = *cp++; - } -} - - -void -put64(uint64_t ul) -{ - int cnt; - unsigned ch; - - cnt = 16; /* 16 nibbles in a 64 bit long */ - putch('0'); - putch('x'); - do { - cnt--; - ch = (unsigned char)(ul >> cnt * 4) & 0x0F; - putch(digits[ch]); - } while (cnt > 0); -} - -void -put32(unsigned u) -{ - int cnt; - unsigned ch; - - cnt = 8; /* 8 nibbles in a 32 bit long */ - putch('0'); - putch('x'); - do { - cnt--; - ch = (unsigned char)(u >> cnt * 4) & 0x0F; - putch(digits[ch]); - } while (cnt > 0); + while (*cp) + prom_putchar(*cp++); + prom_putchar('\r'); + prom_putchar('\n'); } diff --git a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/jmr3927/rbhma3100/Makefile index 18fe9a898cb..8d00ba460ce 100644 --- a/arch/mips/jmr3927/rbhma3100/Makefile +++ b/arch/mips/jmr3927/rbhma3100/Makefile @@ -3,5 +3,4 @@ # obj-y += init.o irq.o setup.o -obj-$(CONFIG_RUNTIME_DEBUG) += debug.o obj-$(CONFIG_KGDB) += kgdb_io.o diff --git a/arch/mips/jmr3927/rbhma3100/init.c b/arch/mips/jmr3927/rbhma3100/init.c index a55cb4572de..9169fab1773 100644 --- a/arch/mips/jmr3927/rbhma3100/init.c +++ b/arch/mips/jmr3927/rbhma3100/init.c @@ -28,20 +28,10 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include -#include -#include - -#include #include -#include #include -int prom_argc; -char **prom_argv, **prom_envp; extern void __init prom_init_cmdline(void); -extern char *prom_getenv(char *envname); -unsigned long mips_nofpu = 0; const char *get_system_type(void) { @@ -52,7 +42,7 @@ const char *get_system_type(void) ; } -extern void puts(unsigned char *cp); +extern void puts(const char *cp); void __init prom_init(void) { @@ -61,10 +51,6 @@ void __init prom_init(void) if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) puts("Warning: TX3927 TLB off\n"); #endif - prom_argc = fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; - mips_machgroup = MACH_GROUP_TOSHIBA; #ifdef CONFIG_TOSHIBA_JMR3927 diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 7d2c203cb40..1187b44a3dd 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c @@ -30,53 +30,21 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include - -#include -#include -#include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include -#include #include -#include -#include #include #if JMR3927_IRQ_END > NR_IRQS #error JMR3927_IRQ_END > NR_IRQS #endif -struct tb_irq_space* tb_irq_spaces; - -static int jmr3927_irq_base = -1; - -#ifdef CONFIG_PCI -static int jmr3927_gen_iack(void) -{ - /* generate ACK cycle */ -#ifdef __BIG_ENDIAN - return (tx3927_pcicptr->iiadp >> 24) & 0xff; -#else - return tx3927_pcicptr->iiadp & 0xff; -#endif -} -#endif - #define irc_dlevel 0 #define irc_elevel 1 @@ -87,89 +55,24 @@ static unsigned char irc_level[TX3927_NUM_IR] = { 6, 6, 6 /* TMR */ }; -static void jmr3927_irq_disable(unsigned int irq_nr); -static void jmr3927_irq_enable(unsigned int irq_nr); - -static void jmr3927_irq_ack(unsigned int irq) -{ - if (irq == JMR3927_IRQ_IRC_TMR0) - jmr3927_tmrptr->tisr = 0; /* ack interrupt */ - - jmr3927_irq_disable(irq); -} - -static void jmr3927_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - jmr3927_irq_enable(irq); -} - -static void jmr3927_irq_disable(unsigned int irq_nr) -{ - struct tb_irq_space* sp; - - for (sp = tb_irq_spaces; sp; sp = sp->next) { - if (sp->start_irqno <= irq_nr && - irq_nr < sp->start_irqno + sp->nr_irqs) { - if (sp->mask_func) - sp->mask_func(irq_nr - sp->start_irqno, - sp->space_id); - break; - } - } -} - -static void jmr3927_irq_enable(unsigned int irq_nr) -{ - struct tb_irq_space* sp; - - for (sp = tb_irq_spaces; sp; sp = sp->next) { - if (sp->start_irqno <= irq_nr && - irq_nr < sp->start_irqno + sp->nr_irqs) { - if (sp->unmask_func) - sp->unmask_func(irq_nr - sp->start_irqno, - sp->space_id); - break; - } - } -} - /* * CP0_STATUS is a thread's resource (saved/restored on context switch). - * So disable_irq/enable_irq MUST handle IOC/ISAC/IRC registers. + * So disable_irq/enable_irq MUST handle IOC/IRC registers. */ -static void mask_irq_isac(int irq_nr, int space_id) -{ - /* 0: mask */ - unsigned char imask = - jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR); - unsigned int bit = 1 << irq_nr; - jmr3927_isac_reg_out(imask & ~bit, JMR3927_ISAC_INTM_ADDR); - /* flush write buffer */ - (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); -} -static void unmask_irq_isac(int irq_nr, int space_id) -{ - /* 0: mask */ - unsigned char imask = jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR); - unsigned int bit = 1 << irq_nr; - jmr3927_isac_reg_out(imask | bit, JMR3927_ISAC_INTM_ADDR); - /* flush write buffer */ - (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); -} - -static void mask_irq_ioc(int irq_nr, int space_id) +static void mask_irq_ioc(unsigned int irq) { /* 0: mask */ + unsigned int irq_nr = irq - JMR3927_IRQ_IOC; unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); /* flush write buffer */ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } -static void unmask_irq_ioc(int irq_nr, int space_id) +static void unmask_irq_ioc(unsigned int irq) { /* 0: mask */ + unsigned int irq_nr = irq - JMR3927_IRQ_IOC; unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); @@ -177,8 +80,9 @@ static void unmask_irq_ioc(int irq_nr, int space_id) (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } -static void mask_irq_irc(int irq_nr, int space_id) +static void mask_irq_irc(unsigned int irq) { + unsigned int irq_nr = irq - JMR3927_IRQ_IRC; volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2]; if (irq_nr & 1) *ilrp = (*ilrp & 0x00ff) | (irc_dlevel << 8); @@ -191,8 +95,9 @@ static void mask_irq_irc(int irq_nr, int space_id) (void)tx3927_ircptr->ssr; } -static void unmask_irq_irc(int irq_nr, int space_id) +static void unmask_irq_irc(unsigned int irq) { + unsigned int irq_nr = irq - JMR3927_IRQ_IRC; volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2]; if (irq_nr & 1) *ilrp = (*ilrp & 0x00ff) | (irc_level[irq_nr] << 8); @@ -203,98 +108,14 @@ static void unmask_irq_irc(int irq_nr, int space_id) tx3927_ircptr->imr = irc_elevel; } -struct tb_irq_space jmr3927_isac_irqspace = { - .next = NULL, - .start_irqno = JMR3927_IRQ_ISAC, - nr_irqs : JMR3927_NR_IRQ_ISAC, - .mask_func = mask_irq_isac, - .unmask_func = unmask_irq_isac, - .name = "ISAC", - .space_id = 0, - can_share : 0 -}; -struct tb_irq_space jmr3927_ioc_irqspace = { - .next = NULL, - .start_irqno = JMR3927_IRQ_IOC, - nr_irqs : JMR3927_NR_IRQ_IOC, - .mask_func = mask_irq_ioc, - .unmask_func = unmask_irq_ioc, - .name = "IOC", - .space_id = 0, - can_share : 1 -}; - -struct tb_irq_space jmr3927_irc_irqspace = { - .next = NULL, - .start_irqno = JMR3927_IRQ_IRC, - .nr_irqs = JMR3927_NR_IRQ_IRC, - .mask_func = mask_irq_irc, - .unmask_func = unmask_irq_irc, - .name = "on-chip", - .space_id = 0, - .can_share = 0 -}; - - -#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND -static int tx_branch_likely_bug_count = 0; -static int have_tx_branch_likely_bug = 0; - -static void tx_branch_likely_bug_fixup(void) -{ - struct pt_regs *regs = get_irq_regs(); - - /* TX39/49-BUG: Under this condition, the insn in delay slot - of the branch likely insn is executed (not nullified) even - the branch condition is false. */ - if (!have_tx_branch_likely_bug) - return; - if ((regs->cp0_epc & 0xfff) == 0xffc && - KSEGX(regs->cp0_epc) != KSEG0 && - KSEGX(regs->cp0_epc) != KSEG1) { - unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4); - /* beql,bnel,blezl,bgtzl */ - /* bltzl,bgezl,blezall,bgezall */ - /* bczfl, bcztl */ - if ((insn & 0xf0000000) == 0x50000000 || - (insn & 0xfc0e0000) == 0x04020000 || - (insn & 0xf3fe0000) == 0x41020000) { - regs->cp0_epc -= 4; - tx_branch_likely_bug_count++; - printk(KERN_INFO - "fix branch-likery bug in %s (insn %08x)\n", - current->comm, insn); - } - } -} -#endif - -static void jmr3927_spurious(void) -{ - struct pt_regs * regs = get_irq_regs(); - -#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND - tx_branch_likely_bug_fixup(); -#endif - printk(KERN_WARNING "spurious interrupt (cause 0x%lx, pc 0x%lx, ra 0x%lx).\n", - regs->cp0_cause, regs->cp0_epc, regs->regs[31]); -} - asmlinkage void plat_irq_dispatch(void) { - struct pt_regs * regs = get_irq_regs(); + unsigned long cp0_cause = read_c0_cause(); int irq; -#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND - tx_branch_likely_bug_fixup(); -#endif - if ((regs->cp0_cause & CAUSEF_IP7) == 0) { -#if 0 - jmr3927_spurious(); -#endif + if ((cp0_cause & CAUSEF_IP7) == 0) return; - } - irq = (regs->cp0_cause >> CAUSEB_IP2) & 0x0f; + irq = (cp0_cause >> CAUSEB_IP2) & 0x0f; do_IRQ(irq + JMR3927_IRQ_IRC); } @@ -317,35 +138,6 @@ static struct irqaction ioc_action = { jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL, }; -static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id) -{ - unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR); - int i; - - for (i = 0; i < JMR3927_NR_IRQ_ISAC; i++) { - if (istat & (1 << i)) { - irq = JMR3927_IRQ_ISAC + i; - do_IRQ(irq); - } - } - return IRQ_HANDLED; -} - -static struct irqaction isac_action = { - jmr3927_isac_interrupt, 0, CPU_MASK_NONE, "ISAC", NULL, NULL, -}; - - -static irqreturn_t jmr3927_isaerr_interrupt(int irq, void *dev_id) -{ - printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); - - return IRQ_HANDLED; -} -static struct irqaction isaerr_action = { - jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL, -}; - static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id) { printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); @@ -358,54 +150,19 @@ static struct irqaction pcierr_action = { jmr3927_pcierr_interrupt, 0, CPU_MASK_NONE, "PCI error", NULL, NULL, }; -int jmr3927_ether1_irq = 0; - -void jmr3927_irq_init(u32 irq_base); +static void __init jmr3927_irq_init(void); void __init arch_init_irq(void) { - /* look for io board's presence */ - int have_isac = jmr3927_have_isac(); - /* Now, interrupt control disabled, */ /* all IRC interrupts are masked, */ /* all IRC interrupt mode are Low Active. */ - if (have_isac) { - - /* ETHER1 (NE2000 compatible 10M-Ether) parameter setup */ - /* temporary enable interrupt control */ - tx3927_ircptr->cer = 1; - /* ETHER1 Int. Is High-Active. */ - if (tx3927_ircptr->ssr & (1 << 0)) - jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT0; -#if 0 /* INT3 may be asserted by ether0 (even after reboot...) */ - else if (tx3927_ircptr->ssr & (1 << 3)) - jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT3; -#endif - /* disable interrupt control */ - tx3927_ircptr->cer = 0; - - /* Ether1: High Active */ - if (jmr3927_ether1_irq) { - int ether1_irc = jmr3927_ether1_irq - JMR3927_IRQ_IRC; - tx3927_ircptr->cr[ether1_irc / 8] |= - TX3927_IRCR_HIGH << ((ether1_irc % 8) * 2); - } - } - /* mask all IOC interrupts */ jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR); /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */ jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR); - if (have_isac) { - /* mask all ISAC interrupts */ - jmr3927_isac_reg_out(0, JMR3927_ISAC_INTM_ADDR); - /* setup ISAC interrupt mode (ISAIRQ3,ISAIRQ5:Low Active ???) */ - jmr3927_isac_reg_out(JMR3927_ISAC_INTF_IRQ3|JMR3927_ISAC_INTF_IRQ5, JMR3927_ISAC_INTP_ADDR); - } - /* clear PCI Soft interrupts */ jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR); /* clear PCI Reset interrupts */ @@ -415,21 +172,11 @@ void __init arch_init_irq(void) tx3927_ircptr->cer = TX3927_IRCER_ICE; tx3927_ircptr->imr = irc_elevel; - jmr3927_irq_init(NR_ISA_IRQS); - - /* setup irq space */ - add_tb_irq_space(&jmr3927_isac_irqspace); - add_tb_irq_space(&jmr3927_ioc_irqspace); - add_tb_irq_space(&jmr3927_irc_irqspace); + jmr3927_irq_init(); /* setup IOC interrupt 1 (PCI, MODEM) */ setup_irq(JMR3927_IRQ_IOCINT, &ioc_action); - if (have_isac) { - setup_irq(JMR3927_IRQ_ISACINT, &isac_action); - setup_irq(JMR3927_IRQ_ISAC_ISAER, &isaerr_action); - } - #ifdef CONFIG_PCI setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action); #endif @@ -438,21 +185,28 @@ void __init arch_init_irq(void) set_c0_status(ST0_IM); /* IE bit is still 0. */ } -static struct irq_chip jmr3927_irq_controller = { - .name = "jmr3927_irq", - .ack = jmr3927_irq_ack, - .mask = jmr3927_irq_disable, - .mask_ack = jmr3927_irq_ack, - .unmask = jmr3927_irq_enable, - .end = jmr3927_irq_end, +static struct irq_chip jmr3927_irq_ioc = { + .name = "jmr3927_ioc", + .ack = mask_irq_ioc, + .mask = mask_irq_ioc, + .mask_ack = mask_irq_ioc, + .unmask = unmask_irq_ioc, }; -void jmr3927_irq_init(u32 irq_base) +static struct irq_chip jmr3927_irq_irc = { + .name = "jmr3927_irc", + .ack = mask_irq_irc, + .mask = mask_irq_irc, + .mask_ack = mask_irq_irc, + .unmask = unmask_irq_irc, +}; + +static void __init jmr3927_irq_init(void) { u32 i; - for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) - set_irq_chip(i, &jmr3927_irq_controller); - - jmr3927_irq_base = irq_base; + for (i = JMR3927_IRQ_IRC; i < JMR3927_IRQ_IRC + JMR3927_NR_IRQ_IRC; i++) + set_irq_chip_and_handler(i, &jmr3927_irq_irc, handle_level_irq); + for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++) + set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq); } diff --git a/arch/mips/jmr3927/rbhma3100/kgdb_io.c b/arch/mips/jmr3927/rbhma3100/kgdb_io.c index 269a42deae0..2604f2c9a96 100644 --- a/arch/mips/jmr3927/rbhma3100/kgdb_io.c +++ b/arch/mips/jmr3927/rbhma3100/kgdb_io.c @@ -31,23 +31,12 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include #include #define TIMEOUT 0xffffff -#define SLOW_DOWN - -static const char digits[16] = "0123456789abcdef"; - -#ifdef SLOW_DOWN -#define slow_down() { int k; for (k=0; k<10000; k++); } -#else -#define slow_down() -#endif static int remoteDebugInitialized = 0; +static void debugInit(int baud) int putDebugChar(unsigned char c) { @@ -103,20 +92,8 @@ unsigned char getDebugChar(void) return c; } -void debugInit(int baud) +static void debugInit(int baud) { - /* - volatile unsigned long lcr; - volatile unsigned long dicr; - volatile unsigned long disr; - volatile unsigned long cisr; - volatile unsigned long fcr; - volatile unsigned long flcr; - volatile unsigned long bgr; - volatile unsigned long tfifo; - volatile unsigned long rfifo; - */ - tx3927_sioptr(0)->lcr = 0x020; tx3927_sioptr(0)->dicr = 0; tx3927_sioptr(0)->disr = 0x4100; @@ -125,31 +102,4 @@ void debugInit(int baud) tx3927_sioptr(0)->flcr = 0x02; tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) | TXx927_SIBGR_BCLK_T0; -#if 0 - /* - * Reset the UART. - */ - tx3927_sioptr(0)->fcr = TXx927_SIFCR_SWRST; - while (tx3927_sioptr(0)->fcr & TXx927_SIFCR_SWRST) - ; - - /* - * and set the speed of the serial port - * (currently hardwired to 9600 8N1 - */ - - tx3927_sioptr(0)->lcr = TXx927_SILCR_UMODE_8BIT | - TXx927_SILCR_USBL_1BIT | - TXx927_SILCR_SCS_IMCLK_BG; - tx3927_sioptr(0)->bgr = - ((JMR3927_BASE_BAUD + baud / 2) / baud) | - TXx927_SIBGR_BCLK_T0; - - /* HW RTS/CTS control */ - if (ser->flags & ASYNC_HAVE_CTS_LINE) - tx3927_sioptr(0)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES | - TXx927_SIFLCR_RTSTL_MAX /* 15 */; - /* Enable RX/TX */ - tx3927_sioptr(0)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE); -#endif } diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index fc523bda068..d1ef2895d56 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c @@ -54,87 +54,18 @@ #include #include -#include -#include #include -#include #include #include -#include -extern void puts(unsigned char *cp); +extern void puts(const char *cp); /* Tick Timer divider */ #define JMR3927_TIMER_CCD 0 /* 1/2 */ #define JMR3927_TIMER_CLK (JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD)) -unsigned char led_state = 0xf; - -struct { - struct resource ram0; - struct resource ram1; - struct resource pcimem; - struct resource iob; - struct resource ioc; - struct resource pciio; - struct resource jmy1394; - struct resource rom1; - struct resource rom0; - struct resource sio0; - struct resource sio1; -} jmr3927_resources = { - { - .start = 0, - .end = 0x01FFFFFF, - .name = "RAM0", - .flags = IORESOURCE_MEM - }, { - .start = 0x02000000, - .end = 0x03FFFFFF, - .name = "RAM1", - .flags = IORESOURCE_MEM - }, { - .start = 0x08000000, - .end = 0x07FFFFFF, - .name = "PCIMEM", - .flags = IORESOURCE_MEM - }, { - .start = 0x10000000, - .end = 0x13FFFFFF, - .name = "IOB" - }, { - .start = 0x14000000, - .end = 0x14FFFFFF, - .name = "IOC" - }, { - .start = 0x15000000, - .end = 0x15FFFFFF, - .name = "PCIIO" - }, { - .start = 0x1D000000, - .end = 0x1D3FFFFF, - .name = "JMY1394" - }, { - .start = 0x1E000000, - .end = 0x1E3FFFFF, - .name = "ROM1" - }, { - .start = 0x1FC00000, - .end = 0x1FFFFFFF, - .name = "ROM0" - }, { - .start = 0xFFFEF300, - .end = 0xFFFEF3FF, - .name = "SIO0" - }, { - .start = 0xFFFEF400, - .end = 0xFFFEF4FF, - .name = "SIO1" - }, -}; - /* don't enable - see errata */ -int jmr3927_ccfg_toeon = 0; +static int jmr3927_ccfg_toeon; static inline void do_reset(void) { @@ -173,9 +104,15 @@ static cycle_t jmr3927_hpt_read(void) return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; } +static void jmr3927_timer_ack(void) +{ + jmr3927_tmrptr->tisr = 0; /* ack interrupt */ +} + static void __init jmr3927_time_init(void) { clocksource_mips.read = jmr3927_hpt_read; + mips_timer_ack = jmr3927_timer_ack; mips_hpt_frequency = JMR3927_TIMER_CLK; } @@ -190,9 +127,6 @@ void __init plat_timer_setup(struct irqaction *irq) setup_irq(JMR3927_IRQ_TICK, irq); } -#define USECS_PER_JIFFY (1000000/HZ) - -//#undef DO_WRITE_THROUGH #define DO_WRITE_THROUGH #define DO_ENABLE_CACHE @@ -224,12 +158,6 @@ void __init plat_mem_setup(void) /* Reboot on panic */ panic_timeout = 180; - { - unsigned int conf; - conf = read_c0_conf(); - } - -#if 1 /* cache setup */ { unsigned int conf; @@ -256,16 +184,14 @@ void __init plat_mem_setup(void) write_c0_conf(conf); write_c0_cache(0); } -#endif /* initialize board */ jmr3927_board_init(); argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "toeon")) != NULL) { - jmr3927_ccfg_toeon = 1; - } + if ((argptr = strstr(argptr, "toeon")) != NULL) + jmr3927_ccfg_toeon = 1; argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "ip=")) == NULL) { argptr = prom_getcmdline(); @@ -281,7 +207,7 @@ void __init plat_mem_setup(void) memset(&req, 0, sizeof(req)); req.line = i; req.iotype = UPIO_MEM; - req.membase = (char *)TX3927_SIO_REG(i); + req.membase = (unsigned char __iomem *)TX3927_SIO_REG(i); req.mapbase = TX3927_SIO_REG(i); req.irq = i == 0 ? JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1; @@ -303,65 +229,33 @@ void __init plat_mem_setup(void) static void tx3927_setup(void); -#ifdef CONFIG_PCI -unsigned long mips_pci_io_base; -unsigned long mips_pci_io_size; -unsigned long mips_pci_mem_base; -unsigned long mips_pci_mem_size; -/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ -unsigned long mips_pci_io_pciaddr = 0; -#endif - static void __init jmr3927_board_init(void) { - char *argptr; - -#ifdef CONFIG_PCI - mips_pci_io_base = JMR3927_PCIIO; - mips_pci_io_size = JMR3927_PCIIO_SIZE; - mips_pci_mem_base = JMR3927_PCIMEM; - mips_pci_mem_size = JMR3927_PCIMEM_SIZE; -#endif - tx3927_setup(); - if (jmr3927_have_isac()) { - -#ifdef CONFIG_FB_E1355 - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=e1355fb:crt16h"); - } -#endif - -#ifdef CONFIG_BLK_DEV_IDE - /* overrides PCI-IDE */ -#endif - } - /* SIO0 DTR on */ jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR); jmr3927_led_set(0); - - if (jmr3927_have_isac()) - jmr3927_io_led_set(0); printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n", jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK, jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK, jmr3927_dipsw1(), jmr3927_dipsw2(), jmr3927_dipsw3(), jmr3927_dipsw4()); - if (jmr3927_have_isac()) - printk("JMI-3927IO2 --- ISAC(Rev %d) DIPSW:%01x\n", - jmr3927_isac_reg_in(JMR3927_ISAC_REV_ADDR) & JMR3927_REV_MASK, - jmr3927_io_dipsw()); } -void __init tx3927_setup(void) +static void __init tx3927_setup(void) { int i; +#ifdef CONFIG_PCI + unsigned long mips_pci_io_base = JMR3927_PCIIO; + unsigned long mips_pci_io_size = JMR3927_PCIIO_SIZE; + unsigned long mips_pci_mem_base = JMR3927_PCIMEM; + unsigned long mips_pci_mem_size = JMR3927_PCIMEM_SIZE; + /* for legacy I/O, PCI I/O PCI Bus address must be 0 */ + unsigned long mips_pci_io_pciaddr = 0; +#endif /* SDRAMC are configured by PROM */ @@ -475,10 +369,8 @@ void __init tx3927_setup(void) tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1); tx3927_pcicptr->mba = 0; tx3927_pcicptr->tlbmma = 0; -#ifndef JMR3927_INIT_INDIRECT_PCI /* Enable Direct mapping Address Space Decoder */ tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; -#endif /* Clear All Local Bus Status */ tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; @@ -491,22 +383,15 @@ void __init tx3927_setup(void) /* PCIC Int => IRC IRQ10 */ tx3927_pcicptr->il = TX3927_IR_PCI; -#if 1 /* Target Control (per errata) */ tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; -#endif /* Enable Bus Arbiter */ -#if 0 - tx3927_pcicptr->req_trace = 0x73737373; -#endif tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | -#if 1 PCI_COMMAND_IO | -#endif PCI_COMMAND_PARITY | PCI_COMMAND_SERR; } #endif /* CONFIG_PCI */ @@ -555,8 +440,6 @@ static int __init jmr3927_rtc_init(void) .flags = IORESOURCE_MEM, }; struct platform_device *dev; - if (!jmr3927_have_nvram()) - return -ENODEV; dev = platform_device_register_simple("ds1742", -1, &res, 1); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index 6e72d213f4c..73d18503517 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -29,7 +29,6 @@ */ #include #include -#include #include #include @@ -81,14 +80,8 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) /* Check OnBoard Ethernet (IDSEL=A24, DevNu=13) */ if (dev->bus->parent == NULL && - slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(24)) { - extern int jmr3927_ether1_irq; - /* check this irq line was reserved for ether1 */ - if (jmr3927_ether1_irq != JMR3927_IRQ_ETHER0) - irq = JMR3927_IRQ_ETHER0; - else - irq = 0; /* disable */ - } + slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(24)) + irq = JMR3927_IRQ_ETHER0; return irq; } diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c index 42530a0b84b..aa698bd0d5e 100644 --- a/arch/mips/pci/ops-tx3927.c +++ b/arch/mips/pci/ops-tx3927.c @@ -40,7 +40,6 @@ #include #include -#include static inline int mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where) @@ -130,234 +129,3 @@ struct pci_ops jmr3927_pci_ops = { jmr3927_pci_read_config, jmr3927_pci_write_config, }; - - -#ifndef JMR3927_INIT_INDIRECT_PCI - -inline unsigned long tc_readl(volatile __u32 * addr) -{ - return readl(addr); -} - -inline void tc_writel(unsigned long data, volatile __u32 * addr) -{ - writel(data, addr); -} -#else - -unsigned long tc_readl(volatile __u32 * addr) -{ - unsigned long val; - - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) CPHYSADDR(addr); - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | - PCI_IPCIBE_IBE_LONG; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - val = - le32_to_cpu(*(volatile u32 *) (unsigned long) & tx3927_pcicptr-> - ipcidata); - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; - return val; -} - -void tc_writel(unsigned long data, volatile __u32 * addr) -{ - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcidata = - cpu_to_le32(data); - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) CPHYSADDR(addr); - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) | - PCI_IPCIBE_IBE_LONG; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; -} - -unsigned char tx_ioinb(unsigned char *addr) -{ - unsigned long val; - __u32 ioaddr; - int offset; - int byte; - - ioaddr = (unsigned long) addr; - offset = ioaddr & 0x3; - byte = 0xf & ~(8 >> offset); - - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) ioaddr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - val = - le32_to_cpu(*(volatile u32 *) (unsigned long) & tx3927_pcicptr-> - ipcidata); - val = val & 0xff; - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; - return val; -} - -void tx_iooutb(unsigned long data, unsigned char *addr) -{ - __u32 ioaddr; - int offset; - int byte; - - data = data | (data << 8) | (data << 16) | (data << 24); - ioaddr = (unsigned long) addr; - offset = ioaddr & 0x3; - byte = 0xf & ~(8 >> offset); - - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcidata = data; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) ioaddr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; -} - -unsigned short tx_ioinw(unsigned short *addr) -{ - unsigned long val; - __u32 ioaddr; - int offset; - int byte; - - ioaddr = (unsigned long) addr; - offset = ioaddr & 0x2; - byte = 3 << offset; - - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) ioaddr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - val = - le32_to_cpu(*(volatile u32 *) (unsigned long) & tx3927_pcicptr-> - ipcidata); - val = val & 0xffff; - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; - return val; - -} - -void tx_iooutw(unsigned long data, unsigned short *addr) -{ - __u32 ioaddr; - int offset; - int byte; - - data = data | (data << 16); - ioaddr = (unsigned long) addr; - offset = ioaddr & 0x2; - byte = 3 << offset; - - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcidata = data; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) ioaddr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; -} - -unsigned long tx_ioinl(unsigned int *addr) -{ - unsigned long val; - __u32 ioaddr; - - ioaddr = (unsigned long) addr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) ioaddr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | - PCI_IPCIBE_IBE_LONG; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - val = - le32_to_cpu(*(volatile u32 *) (unsigned long) & tx3927_pcicptr-> - ipcidata); - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; - return val; -} - -void tx_iooutl(unsigned long data, unsigned int *addr) -{ - __u32 ioaddr; - - ioaddr = (unsigned long) addr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcidata = - cpu_to_le32(data); - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipciaddr = - (unsigned long) ioaddr; - *(volatile u32 *) (unsigned long) & tx3927_pcicptr->ipcibe = - (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | - PCI_IPCIBE_IBE_LONG; - while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); - /* clear by setting */ - tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; -} - -void tx_insbyte(unsigned char *addr, void *buffer, unsigned int count) -{ - unsigned char *ptr = (unsigned char *) buffer; - - while (count--) { - *ptr++ = tx_ioinb(addr); - } -} - -void tx_insword(unsigned short *addr, void *buffer, unsigned int count) -{ - unsigned short *ptr = (unsigned short *) buffer; - - while (count--) { - *ptr++ = tx_ioinw(addr); - } -} - -void tx_inslong(unsigned int *addr, void *buffer, unsigned int count) -{ - unsigned long *ptr = (unsigned long *) buffer; - - while (count--) { - *ptr++ = tx_ioinl(addr); - } -} - -void tx_outsbyte(unsigned char *addr, void *buffer, unsigned int count) -{ - unsigned char *ptr = (unsigned char *) buffer; - - while (count--) { - tx_iooutb(*ptr++, addr); - } -} - -void tx_outsword(unsigned short *addr, void *buffer, unsigned int count) -{ - unsigned short *ptr = (unsigned short *) buffer; - - while (count--) { - tx_iooutw(*ptr++, addr); - } -} - -void tx_outslong(unsigned int *addr, void *buffer, unsigned int count) -{ - unsigned long *ptr = (unsigned long *) buffer; - - while (count--) { - tx_iooutl(*ptr++, addr); - } -} -#endif -- cgit v1.2.3 From 78709b9df35346965b214e0e548412748d147776 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 26 Apr 2007 15:46:24 +0100 Subject: [MIPS] IP22: Get rid of volatile in IP22 core code. Signed-off-by: Ralf Baechle --- arch/mips/sgi-ip22/ip22-nvram.c | 24 ++++++++++++------------ arch/mips/sgi-ip22/ip22-time.c | 14 +++++++------- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c index fd29fd407ae..e19d60d5fcc 100644 --- a/arch/mips/sgi-ip22/ip22-nvram.c +++ b/arch/mips/sgi-ip22/ip22-nvram.c @@ -52,8 +52,7 @@ * national semiconductor nv ram chip the op code is 3 bits and * the address is 6/8 bits. */ -static inline void eeprom_cmd(volatile unsigned int *ctrl, unsigned cmd, - unsigned reg) +static inline void eeprom_cmd(unsigned int *ctrl, unsigned cmd, unsigned reg) { unsigned short ser_cmd; int i; @@ -61,33 +60,34 @@ static inline void eeprom_cmd(volatile unsigned int *ctrl, unsigned cmd, ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND)); for (i = 0; i < BITS_IN_COMMAND; i++) { if (ser_cmd & (1<<15)) /* if high order bit set */ - *ctrl |= EEPROM_DATO; + writel(readl(ctrl) | EEPROM_DATO, ctrl); else - *ctrl &= ~EEPROM_DATO; - *ctrl &= ~EEPROM_ECLK; - *ctrl |= EEPROM_ECLK; + writel(readl(ctrl) & ~EEPROM_DATO, ctrl); + writel(readl(ctrl) & ~EEPROM_ECLK, ctrl); + writel(readl(ctrl) | EEPROM_ECLK, ctrl); ser_cmd <<= 1; } - *ctrl &= ~EEPROM_DATO; /* see data sheet timing diagram */ + /* see data sheet timing diagram */ + writel(readl(ctrl) & ~EEPROM_DATO, ctrl); } -unsigned short ip22_eeprom_read(volatile unsigned int *ctrl, int reg) +unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg) { unsigned short res = 0; int i; - *ctrl &= ~EEPROM_EPROT; + writel(readl(ctrl) & ~EEPROM_EPROT, ctrl); eeprom_cs_on(ctrl); eeprom_cmd(ctrl, EEPROM_READ, reg); /* clock the data ouf of serial mem */ for (i = 0; i < 16; i++) { - *ctrl &= ~EEPROM_ECLK; + writel(readl(ctrl) & ~EEPROM_ECLK, ctrl); delay(); - *ctrl |= EEPROM_ECLK; + writel(readl(ctrl) | EEPROM_ECLK, ctrl); delay(); res <<= 1; - if (*ctrl & EEPROM_DATI) + if (readl(ctrl) & EEPROM_DATI) res |= 1; } diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c index 20555473409..8e88a442b22 100644 --- a/arch/mips/sgi-ip22/ip22-time.c +++ b/arch/mips/sgi-ip22/ip22-time.c @@ -94,7 +94,7 @@ static int indy_rtc_set_time(unsigned long tim) static unsigned long dosample(void) { u32 ct0, ct1; - volatile u8 msb, lsb; + u8 msb, lsb; /* Start the counter. */ sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | @@ -107,21 +107,21 @@ static unsigned long dosample(void) /* Latch and spin until top byte of counter2 is zero */ do { - sgint->tcword = SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT; - lsb = sgint->tcnt2; - msb = sgint->tcnt2; + writeb(SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT, &sgint->tcword); + lsb = readb(&sgint->tcnt2); + msb = readb(&sgint->tcnt2); ct1 = read_c0_count(); } while (msb); /* Stop the counter. */ - sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | - SGINT_TCWORD_MSWST); + writeb(sgint->tcword, (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | + SGINT_TCWORD_MSWST)); /* * Return the difference, this is how far the r4k counter increments * for every 1/HZ seconds. We round off the nearest 1 MHz of master * clock (= 1000000 / HZ / 2). */ - /*return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ);*/ + return (ct1 - ct0) / (500000/HZ) * (500000/HZ); } -- cgit v1.2.3 From f197465384bf7ef1af184c2ed1a4e268911a91e3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 26 Apr 2007 15:46:24 +0100 Subject: [MIPS] MIPS Tech: Get rid of volatile in core code. Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/generic/display.c | 8 ++++---- arch/mips/mips-boards/generic/reset.c | 12 ++++++------ arch/mips/mips-boards/malta/malta_int.c | 2 +- arch/mips/mips-boards/malta/malta_setup.c | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c index f653946afc2..548dbe5ce7c 100644 --- a/arch/mips/mips-boards/generic/display.c +++ b/arch/mips/mips-boards/generic/display.c @@ -24,16 +24,16 @@ void mips_display_message(const char *str) { - static volatile unsigned int *display = NULL; + static unsigned int __iomem *display = NULL; int i; if (unlikely(display == NULL)) - display = (volatile unsigned int *)ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); + display = ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); for (i = 0; i <= 14; i=i+2) { if (*str) - display[i] = *str++; + writel(*str++, display + i); else - display[i] = ' '; + writel(' ', display + i); } } diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c index 0996ba368b2..7a1bb51f81e 100644 --- a/arch/mips/mips-boards/generic/reset.c +++ b/arch/mips/mips-boards/generic/reset.c @@ -39,24 +39,24 @@ static void atlas_machine_power_off(void); static void mips_machine_restart(char *command) { - volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int)); + unsigned int __iomem *softres_reg = ioremap(SOFTRES_REG, sizeof(unsigned int)); - *softres_reg = GORESET; + writew(GORESET, softres_reg); } static void mips_machine_halt(void) { - volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int)); + unsigned int __iomem *softres_reg = ioremap(SOFTRES_REG, sizeof(unsigned int)); - *softres_reg = GORESET; + writew(GORESET, softres_reg); } #if defined(CONFIG_MIPS_ATLAS) static void atlas_machine_power_off(void) { - volatile unsigned int *psustby_reg = (unsigned int *)ioremap(ATLAS_PSUSTBY_REG, sizeof(unsigned int)); + unsigned int __iomem *psustby_reg = ioremap(ATLAS_PSUSTBY_REG, sizeof(unsigned int)); - *psustby_reg = ATLAS_GOSTBY; + writew(ATLAS_GOSTBY, psustby_reg); } #endif diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 3c206bb1716..38428566dce 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c @@ -85,7 +85,7 @@ static inline int mips_pcibios_iack(void) dummy = BONITO_PCIMAP_CFG; iob(); /* sync */ - irq = *(volatile u32 *)(_pcictrl_bonito_pcicfg); + irq = readl((u32 *)_pcictrl_bonito_pcicfg); iob(); /* sync */ irq &= 0xff; BONITO_PCIMAP_CFG = 0; diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index 56ea76679cd..7873932532a 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c @@ -145,7 +145,8 @@ void __init plat_mem_setup(void) #ifdef CONFIG_BLK_DEV_IDE /* Check PCI clock */ { - int jmpr = (*((volatile unsigned int *)ioremap(MALTA_JMPRS_REG, sizeof(unsigned int))) >> 2) & 0x07; + unsigned int __iomem *jmpr_p = (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); + int jmpr = (readw(jmpr_p) >> 2) & 0x07; static const int pciclocks[] __initdata = { 33, 20, 25, 30, 12, 16, 37, 10 }; @@ -179,7 +180,6 @@ void __init plat_mem_setup(void) }; #endif #endif - mips_reboot_setup(); board_time_init = mips_time_init; -- cgit v1.2.3 From 05502339332564ffd545be9ca37b208296a2eaad Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 21 Mar 2007 00:36:02 +0900 Subject: [MIPS] Select ZONE_DMA only if GENERIC_ISA_DMA selected Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 3 ++- arch/mips/mm/init.c | 17 +++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index acceae0e831..f9c4ba58d38 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -10,7 +10,6 @@ menu "Machine selection" config ZONE_DMA bool - default y choice prompt "System type" @@ -923,6 +922,7 @@ config SYS_HAS_EARLY_PRINTK config GENERIC_ISA_DMA bool + select ZONE_DMA config I8259 bool @@ -946,6 +946,7 @@ config MIPS_DISABLE_OBSOLETE_IDE config GENERIC_ISA_DMA_SUPPORT_BROKEN bool + select ZONE_DMA # # Endianess selection. Sufficiently obscure so many users don't know what to diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index e9951c0e689..8800c88cbbf 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -351,18 +351,15 @@ void __init paging_init(void) #endif kmap_coherent_init(); -#ifdef CONFIG_ISA - if (max_low_pfn >= MAX_DMA_PFN) - if (min_low_pfn >= MAX_DMA_PFN) { - zones_size[ZONE_DMA] = 0; - zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; - } else { - zones_size[ZONE_DMA] = MAX_DMA_PFN - min_low_pfn; - zones_size[ZONE_NORMAL] = max_low_pfn - MAX_DMA_PFN; - } +#ifdef CONFIG_ZONE_DMA + if (min_low_pfn < MAX_DMA_PFN && MAX_DMA_PFN <= max_low_pfn) { + zones_size[ZONE_DMA] = MAX_DMA_PFN - min_low_pfn; + zones_size[ZONE_NORMAL] = max_low_pfn - MAX_DMA_PFN; + } else if (max_low_pfn < MAX_DMA_PFN) + zones_size[ZONE_DMA] = max_low_pfn - min_low_pfn; else #endif - zones_size[ZONE_DMA] = max_low_pfn - min_low_pfn; + zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; #ifdef CONFIG_HIGHMEM zones_size[ZONE_HIGHMEM] = highend_pfn - highstart_pfn; -- cgit v1.2.3 From e3cf10e93f42171224e88b06c226d450f3b3a55f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 26 Apr 2007 15:46:25 +0100 Subject: [MIPS] Malta: Delete unused prototype of mips_timer_interrupt. Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/malta/malta_int.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 38428566dce..83d76025d61 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c @@ -42,8 +42,6 @@ #include #include -extern void mips_timer_interrupt(void); - static DEFINE_SPINLOCK(mips_irq_lock); static inline int mips_pcibios_iack(void) -- cgit v1.2.3 From eacb9d61919db56482dcea7ec943c9508175dc16 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 26 Apr 2007 15:46:25 +0100 Subject: [MIPS] Remove unused argument from kunmap_coherent(). Signed-off-by: Ralf Baechle --- arch/mips/mm/cache.c | 2 +- arch/mips/mm/init.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 4e8f1b68337..abf99b1eba1 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -96,7 +96,7 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr) kaddr = kmap_coherent(page, vmaddr); flush_data_cache_page((unsigned long)kaddr); - kunmap_coherent(kaddr); + kunmap_coherent(); } } diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 8800c88cbbf..2d1c2c02482 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -177,7 +177,7 @@ void *kmap_coherent(struct page *page, unsigned long addr) #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) -void kunmap_coherent(struct page *page) +void kunmap_coherent(void) { #ifndef CONFIG_MIPS_MT_SMTC unsigned int wired; @@ -210,7 +210,7 @@ void copy_user_highpage(struct page *to, struct page *from, if (cpu_has_dc_aliases) { vfrom = kmap_coherent(from, vaddr); copy_page(vto, vfrom); - kunmap_coherent(from); + kunmap_coherent(); } else { vfrom = kmap_atomic(from, KM_USER0); copy_page(vto, vfrom); @@ -233,7 +233,7 @@ void copy_to_user_page(struct vm_area_struct *vma, if (cpu_has_dc_aliases) { void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(vto, src, len); - kunmap_coherent(page); + kunmap_coherent(); } else memcpy(dst, src, len); if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) @@ -250,7 +250,7 @@ void copy_from_user_page(struct vm_area_struct *vma, void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(dst, vfrom, len); - kunmap_coherent(page); + kunmap_coherent(); } else memcpy(dst, src, len); } -- cgit v1.2.3 From d619f38fdacb5cec0c841798bbadeaf903868852 Mon Sep 17 00:00:00 2001 From: Mark Mason Date: Thu, 29 Mar 2007 11:39:56 -0700 Subject: [MIPS] Add bcm1480 ZBus trace support, fix wait related bugs Make ZBus tracing generic - moving it to a common direcotry under arch/mips/sibyte, add bcm1480 support and fix some wait related bugs (thanks to Ralf for assistance on that). Signed-off-by: Mark Mason Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 6 +- arch/mips/sibyte/Kconfig | 2 + arch/mips/sibyte/common/Makefile | 5 + arch/mips/sibyte/common/sb_tbprof.c | 601 +++++++++++++++++++++++++++++++ arch/mips/sibyte/sb1250/Makefile | 1 - arch/mips/sibyte/sb1250/bcm1250_tbprof.c | 571 ----------------------------- 6 files changed, 613 insertions(+), 573 deletions(-) create mode 100644 arch/mips/sibyte/common/Makefile create mode 100644 arch/mips/sibyte/common/sb_tbprof.c delete mode 100644 arch/mips/sibyte/sb1250/bcm1250_tbprof.c (limited to 'arch') diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 92bca6ad6ab..f2f742df32c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -530,25 +530,29 @@ cflags-$(CONFIG_SGI_IP32) += -Iinclude/asm-mips/mach-ip32 load-$(CONFIG_SGI_IP32) += 0xffffffff80004000 # -# Sibyte SB1250 SOC +# Sibyte SB1250/BCM1480 SOC # # This is a LIB so that it links at the end, and initcalls are later # the sequence; but it is built as an object so that modules don't get # removed (as happens, even if they have __initcall/module_init) # core-$(CONFIG_SIBYTE_BCM112X) += arch/mips/sibyte/sb1250/ +core-$(CONFIG_SIBYTE_BCM112X) += arch/mips/sibyte/common/ cflags-$(CONFIG_SIBYTE_BCM112X) += -Iinclude/asm-mips/mach-sibyte \ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/sb1250/ +core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/common/ cflags-$(CONFIG_SIBYTE_SB1250) += -Iinclude/asm-mips/mach-sibyte \ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL core-$(CONFIG_SIBYTE_BCM1x55) += arch/mips/sibyte/bcm1480/ +core-$(CONFIG_SIBYTE_BCM1x55) += arch/mips/sibyte/common/ cflags-$(CONFIG_SIBYTE_BCM1x55) += -Iinclude/asm-mips/mach-sibyte \ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL core-$(CONFIG_SIBYTE_BCM1x80) += arch/mips/sibyte/bcm1480/ +core-$(CONFIG_SIBYTE_BCM1x80) += arch/mips/sibyte/common/ cflags-$(CONFIG_SIBYTE_BCM1x80) += -Iinclude/asm-mips/mach-sibyte \ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index bdf24a7b549..e6b003ec671 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -2,6 +2,7 @@ config SIBYTE_SB1250 bool select HW_HAS_PCI select SIBYTE_ENABLE_LDT_IF_PCI + select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC select SYS_SUPPORTS_SMP @@ -34,6 +35,7 @@ config SIBYTE_BCM112X config SIBYTE_BCM1x80 bool select HW_HAS_PCI + select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC select SYS_SUPPORTS_SMP diff --git a/arch/mips/sibyte/common/Makefile b/arch/mips/sibyte/common/Makefile new file mode 100644 index 00000000000..8a06a4fb521 --- /dev/null +++ b/arch/mips/sibyte/common/Makefile @@ -0,0 +1,5 @@ +obj-y := + +obj-$(CONFIG_SIBYTE_TBPROF) += sb_tbprof.o + +EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c new file mode 100644 index 00000000000..4fcdaa8ba51 --- /dev/null +++ b/arch/mips/sibyte/common/sb_tbprof.c @@ -0,0 +1,601 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation + * Copyright (C) 2007 Ralf Baechle + * Copyright (C) 2007 MIPS Technologies, Inc. + * written by Ralf Baechle + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) +#include +#include +#include +#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) +#include +#include +#include +#else +#error invalid SiByte UART configuation +#endif + +#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) +#undef K_INT_TRACE_FREEZE +#define K_INT_TRACE_FREEZE K_BCM1480_INT_TRACE_FREEZE +#undef K_INT_PERF_CNT +#define K_INT_PERF_CNT K_BCM1480_INT_PERF_CNT +#endif + +#include +#include + +#define SBPROF_TB_MAJOR 240 + +typedef u64 tb_sample_t[6*256]; + +enum open_status { + SB_CLOSED, + SB_OPENING, + SB_OPEN +}; + +struct sbprof_tb { + wait_queue_head_t tb_sync; + wait_queue_head_t tb_read; + struct mutex lock; + enum open_status open; + tb_sample_t *sbprof_tbbuf; + int next_tb_sample; + + volatile int tb_enable; + volatile int tb_armed; + +}; + +static struct sbprof_tb sbp; + +#define MAX_SAMPLE_BYTES (24*1024*1024) +#define MAX_TBSAMPLE_BYTES (12*1024*1024) + +#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t)) +#define TB_SAMPLE_SIZE (sizeof(tb_sample_t)) +#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE) + +/* ioctls */ +#define SBPROF_ZBSTART _IOW('s', 0, int) +#define SBPROF_ZBSTOP _IOW('s', 1, int) +#define SBPROF_ZBWAITFULL _IOW('s', 2, int) + +/* + * Routines for using 40-bit SCD cycle counter + * + * Client responsible for either handling interrupts or making sure + * the cycles counter never saturates, e.g., by doing + * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs. + */ + +/* + * Configures SCD counter 0 to count ZCLKs starting from val; + * Configures SCD counters1,2,3 to count nothing. + * Must not be called while gathering ZBbus profiles. + */ + +#define zclk_timer_init(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "sd %0, 0x10($8);" /* write val to counter0 */ \ + "sd %1, 0($8);" /* config counter0 for zclks*/ \ + ".set pop" \ + : /* no outputs */ \ + /* enable, counter0 */ \ + : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \ + : /* modifies */ "$8" ) + + +/* Reads SCD counter 0 and puts result in value + unsigned long long val; */ +#define zclk_get(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "ld %0, 0x10($8);" /* write val to counter0 */ \ + ".set pop" \ + : /* outputs */ "=r"(val) \ + : /* inputs */ \ + : /* modifies */ "$8" ) + +#define DEVNAME "sb_tbprof" + +#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES) + +/* + * Support for ZBbus sampling using the trace buffer + * + * We use the SCD performance counter interrupt, caused by a Zclk counter + * overflow, to trigger the start of tracing. + * + * We set the trace buffer to sample everything and freeze on + * overflow. + * + * We map the interrupt for trace_buffer_freeze to handle it on CPU 0. + * + */ + +static u64 tb_period; + +static void arm_tb(void) +{ + u64 scdperfcnt; + u64 next = (1ULL << 40) - tb_period; + u64 tb_options = M_SCD_TRACE_CFG_FREEZE_FULL; + + /* + * Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to + * trigger start of trace. XXX vary sampling period + */ + __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1)); + scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); + + /* + * Unfortunately, in Pass 2 we must clear all counters to knock down + * a previous interrupt request. This means that bus profiling + * requires ALL of the SCD perf counters. + */ +#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) + __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | + /* keep counters 0,2,3,4,5,6,7 as is */ + V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */ + IOADDR(A_BCM1480_SCD_PERF_CNT_CFG0)); + __raw_writeq( + M_SPC_CFG_ENABLE | /* enable counting */ + M_SPC_CFG_CLEAR | /* clear all counters */ + V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */ + IOADDR(A_BCM1480_SCD_PERF_CNT_CFG1)); +#else + __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | + /* keep counters 0,2,3 as is */ + M_SPC_CFG_ENABLE | /* enable counting */ + M_SPC_CFG_CLEAR | /* clear all counters */ + V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */ + IOADDR(A_SCD_PERF_CNT_CFG)); +#endif + __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1)); + /* Reset the trace buffer */ + __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); +#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) + /* XXXKW may want to expose control to the data-collector */ + tb_options |= M_SCD_TRACE_CFG_FORCECNT; +#endif + __raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG)); + sbp.tb_armed = 1; +} + +static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) +{ + int i; + + pr_debug(DEVNAME ": tb_intr\n"); + + if (sbp.next_tb_sample < MAX_TB_SAMPLES) { + /* XXX should use XKPHYS to make writes bypass L2 */ + u64 *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; + /* Read out trace */ + __raw_writeq(M_SCD_TRACE_CFG_START_READ, + IOADDR(A_SCD_TRACE_CFG)); + __asm__ __volatile__ ("sync" : : : "memory"); + /* Loop runs backwards because bundles are read out in reverse order */ + for (i = 256 * 6; i > 0; i -= 6) { + /* Subscripts decrease to put bundle in the order */ + /* t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi */ + p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); + /* read t2 hi */ + p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); + /* read t2 lo */ + p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); + /* read t1 hi */ + p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); + /* read t1 lo */ + p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); + /* read t0 hi */ + p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); + /* read t0 lo */ + } + if (!sbp.tb_enable) { + pr_debug(DEVNAME ": tb_intr shutdown\n"); + __raw_writeq(M_SCD_TRACE_CFG_RESET, + IOADDR(A_SCD_TRACE_CFG)); + sbp.tb_armed = 0; + wake_up_interruptible(&sbp.tb_sync); + } else { + /* knock down current interrupt and get another one later */ + arm_tb(); + } + } else { + /* No more trace buffer samples */ + pr_debug(DEVNAME ": tb_intr full\n"); + __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); + sbp.tb_armed = 0; + if (!sbp.tb_enable) + wake_up_interruptible(&sbp.tb_sync); + wake_up_interruptible(&sbp.tb_read); + } + return IRQ_HANDLED; +} + +static irqreturn_t sbprof_pc_intr(int irq, void *dev_id) +{ + printk(DEVNAME ": unexpected pc_intr"); + return IRQ_NONE; +} + +/* + * Requires: Already called zclk_timer_init with a value that won't + * saturate 40 bits. No subsequent use of SCD performance counters + * or trace buffer. + */ + +static int sbprof_zbprof_start(struct file *filp) +{ + u64 scdperfcnt; + int err; + + if (xchg(&sbp.tb_enable, 1)) + return -EBUSY; + + pr_debug(DEVNAME ": starting\n"); + + sbp.next_tb_sample = 0; + filp->f_pos = 0; + + err = request_irq (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, + DEVNAME " trace freeze", &sbp); + if (err) + return -EBUSY; + + /* Make sure there isn't a perf-cnt interrupt waiting */ + scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); + /* Disable and clear counters, override SRC_1 */ + __raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) | + M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1), + IOADDR(A_SCD_PERF_CNT_CFG)); + + /* + * We grab this interrupt to prevent others from trying to use + * it, even though we don't want to service the interrupts + * (they only feed into the trace-on-interrupt mechanism) + */ + if (request_irq(K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) { + free_irq(K_INT_TRACE_FREEZE, &sbp); + return -EBUSY; + } + + /* + * I need the core to mask these, but the interrupt mapper to + * pass them through. I am exploiting my knowledge that + * cp0_status masks out IP[5]. krw + */ +#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) + __raw_writeq(K_BCM1480_INT_MAP_I3, + IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_L) + + ((K_BCM1480_INT_PERF_CNT & 0x3f) << 3))); +#else + __raw_writeq(K_INT_MAP_I3, + IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + + (K_INT_PERF_CNT << 3))); +#endif + + /* Initialize address traps */ + __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3)); + + __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3)); + + __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2)); + __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3)); + + /* Initialize Trace Event 0-7 */ + /* when interrupt */ + __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7)); + + /* Initialize Trace Sequence 0-7 */ + /* Start on event 0 (interrupt) */ + __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff, + IOADDR(A_SCD_TRACE_SEQUENCE_0)); + /* dsamp when d used | asamp when a used */ + __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE | + K_SCD_TRSEQ_TRIGGER_ALL, + IOADDR(A_SCD_TRACE_SEQUENCE_1)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6)); + __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7)); + + /* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */ +#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) + __raw_writeq(1ULL << (K_BCM1480_INT_PERF_CNT & 0x3f), + IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_TRACE_L))); +#else + __raw_writeq(1ULL << K_INT_PERF_CNT, + IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE))); +#endif + arm_tb(); + + pr_debug(DEVNAME ": done starting\n"); + + return 0; +} + +static int sbprof_zbprof_stop(void) +{ + int err = 0; + + pr_debug(DEVNAME ": stopping\n"); + + if (sbp.tb_enable) { + /* + * XXXKW there is a window here where the intr handler may run, + * see the disable, and do the wake_up before this sleep + * happens. + */ + pr_debug(DEVNAME ": wait for disarm\n"); + err = wait_event_interruptible(sbp.tb_sync, !sbp.tb_armed); + pr_debug(DEVNAME ": disarm complete, stat %d\n", err); + + if (err) + return err; + + sbp.tb_enable = 0; + free_irq(K_INT_TRACE_FREEZE, &sbp); + free_irq(K_INT_PERF_CNT, &sbp); + } + + pr_debug(DEVNAME ": done stopping\n"); + + return err; +} + +static int sbprof_tb_open(struct inode *inode, struct file *filp) +{ + int minor; + + minor = iminor(inode); + if (minor != 0) + return -ENODEV; + + if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED) + return -EBUSY; + + memset(&sbp, 0, sizeof(struct sbprof_tb)); + sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); + if (!sbp.sbprof_tbbuf) + return -ENOMEM; + memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); + init_waitqueue_head(&sbp.tb_sync); + init_waitqueue_head(&sbp.tb_read); + mutex_init(&sbp.lock); + + sbp.open = SB_OPEN; + + return 0; +} + +static int sbprof_tb_release(struct inode *inode, struct file *filp) +{ + int minor; + + minor = iminor(inode); + if (minor != 0 || !sbp.open) + return -ENODEV; + + mutex_lock(&sbp.lock); + + if (sbp.tb_armed || sbp.tb_enable) + sbprof_zbprof_stop(); + + vfree(sbp.sbprof_tbbuf); + sbp.open = 0; + + mutex_unlock(&sbp.lock); + + return 0; +} + +static ssize_t sbprof_tb_read(struct file *filp, char *buf, + size_t size, loff_t *offp) +{ + int cur_sample, sample_off, cur_count, sample_left; + char *src; + int count = 0; + char *dest = buf; + long cur_off = *offp; + + if (!access_ok(VERIFY_WRITE, buf, size)) + return -EFAULT; + + mutex_lock(&sbp.lock); + + count = 0; + cur_sample = cur_off / TB_SAMPLE_SIZE; + sample_off = cur_off % TB_SAMPLE_SIZE; + sample_left = TB_SAMPLE_SIZE - sample_off; + + while (size && (cur_sample < sbp.next_tb_sample)) { + int err; + + cur_count = size < sample_left ? size : sample_left; + src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off); + err = __copy_to_user(dest, src, cur_count); + if (err) { + *offp = cur_off + cur_count - err; + mutex_unlock(&sbp.lock); + return err; + } + pr_debug(DEVNAME ": read from sample %d, %d bytes\n", + cur_sample, cur_count); + size -= cur_count; + sample_left -= cur_count; + if (!sample_left) { + cur_sample++; + sample_off = 0; + sample_left = TB_SAMPLE_SIZE; + } else { + sample_off += cur_count; + } + cur_off += cur_count; + dest += cur_count; + count += cur_count; + } + *offp = cur_off; + mutex_unlock(&sbp.lock); + + return count; +} + +static long sbprof_tb_ioctl(struct file *filp, + unsigned int command, + unsigned long arg) +{ + int err = 0; + + switch (command) { + case SBPROF_ZBSTART: + mutex_lock(&sbp.lock); + err = sbprof_zbprof_start(filp); + mutex_unlock(&sbp.lock); + break; + + case SBPROF_ZBSTOP: + mutex_lock(&sbp.lock); + err = sbprof_zbprof_stop(); + mutex_unlock(&sbp.lock); + break; + + case SBPROF_ZBWAITFULL: { + err = wait_event_interruptible(sbp.tb_read, TB_FULL); + if (err) + break; + + err = put_user(TB_FULL, (int *) arg); + break; + } + + default: + err = -EINVAL; + break; + } + + return err; +} + +static const struct file_operations sbprof_tb_fops = { + .owner = THIS_MODULE, + .open = sbprof_tb_open, + .release = sbprof_tb_release, + .read = sbprof_tb_read, + .unlocked_ioctl = sbprof_tb_ioctl, + .compat_ioctl = sbprof_tb_ioctl, + .mmap = NULL, +}; + +static struct class *tb_class; +static struct device *tb_dev; + +static int __init sbprof_tb_init(void) +{ + struct device *dev; + struct class *tbc; + int err; + + if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) { + printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n", + SBPROF_TB_MAJOR); + return -EIO; + } + + tbc = class_create(THIS_MODULE, "sb_tracebuffer"); + if (IS_ERR(tbc)) { + err = PTR_ERR(tbc); + goto out_chrdev; + } + + tb_class = tbc; + + dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb"); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + goto out_class; + } + tb_dev = dev; + + sbp.open = 0; + tb_period = zbbus_mhz * 10000LL; + pr_info(DEVNAME ": initialized - tb_period = %lld\n", + (long long) tb_period); + return 0; + +out_class: + class_destroy(tb_class); +out_chrdev: + unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); + + return err; +} + +static void __exit sbprof_tb_cleanup(void) +{ + device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0)); + unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); + class_destroy(tb_class); +} + +module_init(sbprof_tb_init); +module_exit(sbprof_tb_cleanup); + +MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR); +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile index 04c0f1a7f61..df662c61473 100644 --- a/arch/mips/sibyte/sb1250/Makefile +++ b/arch/mips/sibyte/sb1250/Makefile @@ -1,6 +1,5 @@ obj-y := setup.o irq.o time.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c deleted file mode 100644 index ea0ca131a3c..00000000000 --- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) 2001, 2002, 2003 Broadcom Corporation - * Copyright (C) 2007 Ralf Baechle - * Copyright (C) 2007 MIPS Technologies, Inc. - * written by Ralf Baechle - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define SBPROF_TB_MAJOR 240 - -typedef u64 tb_sample_t[6*256]; - -enum open_status { - SB_CLOSED, - SB_OPENING, - SB_OPEN -}; - -struct sbprof_tb { - wait_queue_head_t tb_sync; - wait_queue_head_t tb_read; - struct mutex lock; - enum open_status open; - tb_sample_t *sbprof_tbbuf; - int next_tb_sample; - - volatile int tb_enable; - volatile int tb_armed; - -}; - -static struct sbprof_tb sbp; - -#define MAX_SAMPLE_BYTES (24*1024*1024) -#define MAX_TBSAMPLE_BYTES (12*1024*1024) - -#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t)) -#define TB_SAMPLE_SIZE (sizeof(tb_sample_t)) -#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE) - -/* ioctls */ -#define SBPROF_ZBSTART _IOW('s', 0, int) -#define SBPROF_ZBSTOP _IOW('s', 1, int) -#define SBPROF_ZBWAITFULL _IOW('s', 2, int) - -/* - * Routines for using 40-bit SCD cycle counter - * - * Client responsible for either handling interrupts or making sure - * the cycles counter never saturates, e.g., by doing - * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs. - */ - -/* - * Configures SCD counter 0 to count ZCLKs starting from val; - * Configures SCD counters1,2,3 to count nothing. - * Must not be called while gathering ZBbus profiles. - */ - -#define zclk_timer_init(val) \ - __asm__ __volatile__ (".set push;" \ - ".set mips64;" \ - "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ - "sd %0, 0x10($8);" /* write val to counter0 */ \ - "sd %1, 0($8);" /* config counter0 for zclks*/ \ - ".set pop" \ - : /* no outputs */ \ - /* enable, counter0 */ \ - : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \ - : /* modifies */ "$8" ) - - -/* Reads SCD counter 0 and puts result in value - unsigned long long val; */ -#define zclk_get(val) \ - __asm__ __volatile__ (".set push;" \ - ".set mips64;" \ - "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ - "ld %0, 0x10($8);" /* write val to counter0 */ \ - ".set pop" \ - : /* outputs */ "=r"(val) \ - : /* inputs */ \ - : /* modifies */ "$8" ) - -#define DEVNAME "bcm1250_tbprof" - -#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES) - -/* - * Support for ZBbus sampling using the trace buffer - * - * We use the SCD performance counter interrupt, caused by a Zclk counter - * overflow, to trigger the start of tracing. - * - * We set the trace buffer to sample everything and freeze on - * overflow. - * - * We map the interrupt for trace_buffer_freeze to handle it on CPU 0. - */ - -static u64 tb_period; - -static void arm_tb(void) -{ - u64 scdperfcnt; - u64 next = (1ULL << 40) - tb_period; - u64 tb_options = M_SCD_TRACE_CFG_FREEZE_FULL; - - /* - * Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to trigger - *start of trace. XXX vary sampling period - */ - __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1)); - scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); - - /* - * Unfortunately, in Pass 2 we must clear all counters to knock down a - * previous interrupt request. This means that bus profiling requires - * ALL of the SCD perf counters. - */ - __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | - /* keep counters 0,2,3 as is */ - M_SPC_CFG_ENABLE | /* enable counting */ - M_SPC_CFG_CLEAR | /* clear all counters */ - V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */ - IOADDR(A_SCD_PERF_CNT_CFG)); - __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1)); - - /* Reset the trace buffer */ - __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); -#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) - /* XXXKW may want to expose control to the data-collector */ - tb_options |= M_SCD_TRACE_CFG_FORCECNT; -#endif - __raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG)); - sbp.tb_armed = 1; -} - -static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) -{ - int i; - - pr_debug(DEVNAME ": tb_intr\n"); - - if (sbp.next_tb_sample < MAX_TB_SAMPLES) { - /* XXX should use XKPHYS to make writes bypass L2 */ - u64 *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; - /* Read out trace */ - __raw_writeq(M_SCD_TRACE_CFG_START_READ, - IOADDR(A_SCD_TRACE_CFG)); - __asm__ __volatile__ ("sync" : : : "memory"); - /* Loop runs backwards because bundles are read out in reverse order */ - for (i = 256 * 6; i > 0; i -= 6) { - /* Subscripts decrease to put bundle in the order */ - /* t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi */ - p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - /* read t2 hi */ - p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - /* read t2 lo */ - p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - /* read t1 hi */ - p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - /* read t1 lo */ - p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - /* read t0 hi */ - p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); - /* read t0 lo */ - } - if (!sbp.tb_enable) { - pr_debug(DEVNAME ": tb_intr shutdown\n"); - __raw_writeq(M_SCD_TRACE_CFG_RESET, - IOADDR(A_SCD_TRACE_CFG)); - sbp.tb_armed = 0; - wake_up(&sbp.tb_sync); - } else { - arm_tb(); /* knock down current interrupt and get another one later */ - } - } else { - /* No more trace buffer samples */ - pr_debug(DEVNAME ": tb_intr full\n"); - __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); - sbp.tb_armed = 0; - if (!sbp.tb_enable) { - wake_up(&sbp.tb_sync); - } - wake_up(&sbp.tb_read); - } - - return IRQ_HANDLED; -} - -static irqreturn_t sbprof_pc_intr(int irq, void *dev_id) -{ - printk(DEVNAME ": unexpected pc_intr"); - return IRQ_NONE; -} - -/* - * Requires: Already called zclk_timer_init with a value that won't - * saturate 40 bits. No subsequent use of SCD performance counters - * or trace buffer. - */ - -static int sbprof_zbprof_start(struct file *filp) -{ - u64 scdperfcnt; - int err; - - if (xchg(&sbp.tb_enable, 1)) - return -EBUSY; - - pr_debug(DEVNAME ": starting\n"); - - sbp.next_tb_sample = 0; - filp->f_pos = 0; - - err = request_irq(K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, - DEVNAME " trace freeze", &sbp); - if (err) - return -EBUSY; - - /* Make sure there isn't a perf-cnt interrupt waiting */ - scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); - /* Disable and clear counters, override SRC_1 */ - __raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) | - M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1), - IOADDR(A_SCD_PERF_CNT_CFG)); - - /* - * We grab this interrupt to prevent others from trying to use it, even - * though we don't want to service the interrupts (they only feed into - * the trace-on-interrupt mechanism) - */ - err = request_irq(K_INT_PERF_CNT, sbprof_pc_intr, 0, - DEVNAME " scd perfcnt", &sbp); - if (err) - goto out_free_irq; - - /* - * I need the core to mask these, but the interrupt mapper to pass them - * through. I am exploiting my knowledge that cp0_status masks out - * IP[5]. krw - */ - __raw_writeq(K_INT_MAP_I3, - IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + - (K_INT_PERF_CNT << 3))); - - /* Initialize address traps */ - __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3)); - - __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3)); - - __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2)); - __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3)); - - /* Initialize Trace Event 0-7 */ - /* when interrupt */ - __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7)); - - /* Initialize Trace Sequence 0-7 */ - /* Start on event 0 (interrupt) */ - __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff, - IOADDR(A_SCD_TRACE_SEQUENCE_0)); - /* dsamp when d used | asamp when a used */ - __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE | - K_SCD_TRSEQ_TRIGGER_ALL, - IOADDR(A_SCD_TRACE_SEQUENCE_1)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6)); - __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7)); - - /* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */ - __raw_writeq(1ULL << K_INT_PERF_CNT, - IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE))); - - arm_tb(); - - pr_debug(DEVNAME ": done starting\n"); - - return 0; - -out_free_irq: - free_irq(K_INT_TRACE_FREEZE, &sbp); - - return err; -} - -static int sbprof_zbprof_stop(void) -{ - int err; - - pr_debug(DEVNAME ": stopping\n"); - - if (sbp.tb_enable) { - /* - * XXXKW there is a window here where the intr handler may run, - * see the disable, and do the wake_up before this sleep - * happens. - */ - pr_debug(DEVNAME ": wait for disarm\n"); - err = wait_event_interruptible(sbp.tb_sync, !sbp.tb_armed); - pr_debug(DEVNAME ": disarm complete, stat %d\n", err); - - if (err) - return err; - - sbp.tb_enable = 0; - free_irq(K_INT_TRACE_FREEZE, &sbp); - free_irq(K_INT_PERF_CNT, &sbp); - } - - pr_debug(DEVNAME ": done stopping\n"); - - return 0; -} - -static int sbprof_tb_open(struct inode *inode, struct file *filp) -{ - int minor; - - minor = iminor(inode); - if (minor != 0) - return -ENODEV; - - if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED) - return -EBUSY; - - memset(&sbp, 0, sizeof(struct sbprof_tb)); - - sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); - if (!sbp.sbprof_tbbuf) - return -ENOMEM; - - memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); - init_waitqueue_head(&sbp.tb_sync); - init_waitqueue_head(&sbp.tb_read); - mutex_init(&sbp.lock); - - sbp.open = SB_OPEN; - - return 0; -} - -static int sbprof_tb_release(struct inode *inode, struct file *filp) -{ - int minor = iminor(inode); - - if (minor != 0 || !sbp.open) - return -ENODEV; - - mutex_lock(&sbp.lock); - - if (sbp.tb_armed || sbp.tb_enable) - sbprof_zbprof_stop(); - - vfree(sbp.sbprof_tbbuf); - sbp.open = 0; - - mutex_unlock(&sbp.lock); - - return 0; -} - -static ssize_t sbprof_tb_read(struct file *filp, char *buf, - size_t size, loff_t *offp) -{ - int cur_sample, sample_off, cur_count, sample_left; - long cur_off = *offp; - char *dest = buf; - int count = 0; - char *src; - - if (!access_ok(VERIFY_WRITE, buf, size)) - return -EFAULT; - - mutex_lock(&sbp.lock); - - count = 0; - cur_sample = cur_off / TB_SAMPLE_SIZE; - sample_off = cur_off % TB_SAMPLE_SIZE; - sample_left = TB_SAMPLE_SIZE - sample_off; - - while (size && (cur_sample < sbp.next_tb_sample)) { - int err; - - cur_count = size < sample_left ? size : sample_left; - src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off); - err = __copy_to_user(dest, src, cur_count); - if (err) { - *offp = cur_off + cur_count - err; - mutex_unlock(&sbp.lock); - return err; - } - - pr_debug(DEVNAME ": read from sample %d, %d bytes\n", - cur_sample, cur_count); - size -= cur_count; - sample_left -= cur_count; - if (!sample_left) { - cur_sample++; - sample_off = 0; - sample_left = TB_SAMPLE_SIZE; - } else { - sample_off += cur_count; - } - cur_off += cur_count; - dest += cur_count; - count += cur_count; - } - - *offp = cur_off; - mutex_unlock(&sbp.lock); - - return count; -} - -static long sbprof_tb_ioctl(struct file *filp, unsigned int command, - unsigned long arg) -{ - int error = 0; - - switch (command) { - case SBPROF_ZBSTART: - mutex_lock(&sbp.lock); - error = sbprof_zbprof_start(filp); - mutex_unlock(&sbp.lock); - break; - - case SBPROF_ZBSTOP: - mutex_lock(&sbp.lock); - error = sbprof_zbprof_stop(); - mutex_unlock(&sbp.lock); - break; - - case SBPROF_ZBWAITFULL: - error = wait_event_interruptible(sbp.tb_read, TB_FULL); - if (error) - break; - - error = put_user(TB_FULL, (int *) arg); - break; - - default: - error = -EINVAL; - break; - } - - return error; -} - -static const struct file_operations sbprof_tb_fops = { - .owner = THIS_MODULE, - .open = sbprof_tb_open, - .release = sbprof_tb_release, - .read = sbprof_tb_read, - .unlocked_ioctl = sbprof_tb_ioctl, - .compat_ioctl = sbprof_tb_ioctl, - .mmap = NULL, -}; - -static struct class *tb_class; -static struct device *tb_dev; - -static int __init sbprof_tb_init(void) -{ - struct device *dev; - struct class *tbc; - int err; - - if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) { - printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n", - SBPROF_TB_MAJOR); - return -EIO; - } - - tbc = class_create(THIS_MODULE, "sb_tracebuffer"); - if (IS_ERR(tbc)) { - err = PTR_ERR(tbc); - goto out_chrdev; - } - - tb_class = tbc; - - dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb"); - if (IS_ERR(dev)) { - err = PTR_ERR(dev); - goto out_class; - } - tb_dev = dev; - - sbp.open = 0; - tb_period = zbbus_mhz * 10000LL; - pr_info(DEVNAME ": initialized - tb_period = %lld\n", tb_period); - - return 0; - -out_class: - class_destroy(tb_class); -out_chrdev: - unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); - - return err; -} - -static void __exit sbprof_tb_cleanup(void) -{ - device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0)); - unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); - class_destroy(tb_class); -} - -module_init(sbprof_tb_init); -module_exit(sbprof_tb_cleanup); - -MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR); -MODULE_AUTHOR("Ralf Baechle "); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 3c5e370600c2dda8a4f59f841f323df04e6ce7b2 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 4 Apr 2007 16:40:52 +0900 Subject: [MIPS] Remove pnx8550-v2pci_defconfig Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/configs/pnx8550-v2pci_defconfig | 1540 ----------------------------- 1 file changed, 1540 deletions(-) delete mode 100644 arch/mips/configs/pnx8550-v2pci_defconfig (limited to 'arch') diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig deleted file mode 100644 index 3d6c2d74350..00000000000 --- a/arch/mips/configs/pnx8550-v2pci_defconfig +++ /dev/null @@ -1,1540 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:39 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_DDB5477 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_QEMU is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_PNX8550=y -CONFIG_SOC_PNX8550=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -CONFIG_CPU_MIPS32_R1=y -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_CPU_MIPS32=y -CONFIG_CPU_MIPSR1=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_KEXEC is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK is not set -CONFIG_NF_CONNTRACK_ENABLED=m -CONFIG_NF_CONNTRACK_SUPPORT=y -# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_ACCT=y -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NETFILTER_XTABLES=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -CONFIG_NF_CONNTRACK_IPV6=m -# CONFIG_IP6_NF_QUEUE is not set -# CONFIG_IP6_NF_IPTABLES is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -CONFIG_NET_CLS_ROUTE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -CONFIG_SGI_IOC4=m -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -CONFIG_BLK_DEV_IT8213=m -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_BLK_DEV_TC86C001=m -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_TGT=m -CONFIG_SCSI_NETLINK=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -CONFIG_SCSI_SCAN_ASYNC=y - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=m -CONFIG_SCSI_FC_ATTRS=y -CONFIG_SCSI_ISCSI_ATTRS=m -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -CONFIG_ISCSI_TCP=m -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_DEBUG_ENABLE is not set -CONFIG_AIC7XXX_DEBUG_MASK=0 -# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_DM9000 is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -CONFIG_NATSEMI=y -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=m -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=m - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -CONFIG_PPP_MPPE=m -# CONFIG_PPPOE is not set -# CONFIG_SLIP is not set -CONFIG_SLHC=m -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=m -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -# CONFIG_VT_CONSOLE is not set -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_COMPUTONE is not set -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_DIGIEPCA is not set -# CONFIG_MOXA_INTELLIO is not set -# CONFIG_MOXA_SMARTIO is not set -CONFIG_MOXA_SMARTIO_NEW=m -# CONFIG_ISI is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_SYNCLINK_GT is not set -# CONFIG_N_HDLC is not set -# CONFIG_RISCOM8 is not set -# CONFIG_SPECIALIX is not set -# CONFIG_SX is not set -# CONFIG_RIO is not set -# CONFIG_STALDRV is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_PNX8XXX=y -CONFIG_SERIAL_PNX8XXX_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=m -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PASEMI is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -CONFIG_FIRMWARE_EDID=y -CONFIG_FB=y -# CONFIG_FB_DDC is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_SMIVGX is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -CONFIG_USB_HIDDEV=y -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -CONFIG_XFS_FS=m -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# -CONFIG_DLM=m -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" -CONFIG_SYS_SUPPORTS_KGDB=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=m -CONFIG_CRYPTO_MANAGER=m -# CONFIG_CRYPTO_HMAC is not set -CONFIG_CRYPTO_XCBC=m -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -# CONFIG_CRYPTO_DES is not set -CONFIG_CRYPTO_FCRYPT=m -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -- cgit v1.2.3 From 639702bd725b3cc1a9bd442a7822c83849d66e91 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sun, 8 Apr 2007 13:28:44 +0200 Subject: [MIPS] Register PCI host bridge resource earlier PCI based SNI RM machines have their EISA bus behind an Intel PCI/EISA bridge. So the PCI IO range must start at 0x0000. Changing that will break the PCI bus, because i8259.c already has registered it's IO addresses before the PCI bus gets initialized. Below is a patch, which will register the PCI host bridge resources inside register_pci_controller(). It also changes i8259.c to use insert_region(), because request_resource() will fail, if the IO space of the PIT hanging of the PCI host bridge (maybe passing the resource parent to init_i8259_irqs() is a cleaner fix for that). Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/kernel/i8259.c | 4 ++-- arch/mips/pci/pci.c | 25 ++++++++++++------------- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 9c79703979b..2345160e63f 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -328,8 +328,8 @@ void __init init_i8259_irqs (void) { int i; - request_resource(&ioport_resource, &pic1_io_resource); - request_resource(&ioport_resource, &pic2_io_resource); + insert_resource(&ioport_resource, &pic1_io_resource); + insert_resource(&ioport_resource, &pic2_io_resource); init_8259A(0); diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index de7cfc559dd..8108231f2e2 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -77,6 +77,13 @@ pcibios_align_resource(void *data, struct resource *res, void __init register_pci_controller(struct pci_controller *hose) { + if (request_resource(&iomem_resource, hose->mem_resource) < 0) + goto out; + if (request_resource(&ioport_resource, hose->io_resource) < 0) { + release_resource(hose->mem_resource); + goto out; + } + *hose_tail = hose; hose_tail = &hose->next; @@ -87,6 +94,11 @@ void __init register_pci_controller(struct pci_controller *hose) printk(KERN_WARNING "registering PCI controller with io_map_base unset\n"); } + return; + +out: + printk(KERN_WARNING + "Skipping PCI bus scan due to resource conflict\n"); } /* Most MIPS systems have straight-forward swizzling needs. */ @@ -121,11 +133,6 @@ static int __init pcibios_init(void) /* Scan all of the recorded PCI controllers. */ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { - if (request_resource(&iomem_resource, hose->mem_resource) < 0) - goto out; - if (request_resource(&ioport_resource, hose->io_resource) < 0) - goto out_free_mem_resource; - if (!hose->iommu) PCI_DMA_BUS_IS_PHYS = 1; @@ -144,14 +151,6 @@ static int __init pcibios_init(void) need_domain_info = 1; } } - continue; - -out_free_mem_resource: - release_resource(hose->mem_resource); - -out: - printk(KERN_WARNING - "Skipping PCI bus scan due to resource conflict\n"); } if (!pci_probe_only) -- cgit v1.2.3 From bea771751c116a690054581902b4144fe5a4520e Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sun, 8 Apr 2007 13:34:57 +0200 Subject: [MIPS] Change PCI host bridge setup/resources PCI host bridge setup for SNI RM machines with PCI is quite broken, now that Linux does it's resource setup own its own. It will use IO addresses, which are needed by the EISA config detection and assigns PCI memory addresses, which overlap with ISA legacy addresses (video ram). Below is a patch, which changes the way how the PCI memory addresses are used and sets the minimum IO address to give enough IO space for 8 EISA slots). This patch needs the other PCI resource change, I've posted. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/sni/pcimt.c | 105 +++++-------------------------------------- arch/mips/sni/pcit.c | 122 +++++++++----------------------------------------- 2 files changed, 32 insertions(+), 195 deletions(-) (limited to 'arch') diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 8e8593b64f6..9ee208daa8b 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c @@ -91,7 +91,7 @@ static struct platform_device pcimt_serial8250_device = { }; static struct resource sni_io_resource = { - .start = 0x00001000UL, + .start = 0x00000000UL, .end = 0x03bfffffUL, .name = "PCIMT IO MEM", .flags = IORESOURCE_IO, @@ -132,107 +132,19 @@ static struct resource pcimt_io_resources[] = { }; static struct resource sni_mem_resource = { - .start = 0x10000000UL, - .end = 0xffffffffUL, + .start = 0x18000000UL, + .end = 0x1fbfffffUL, .name = "PCIMT PCI MEM", .flags = IORESOURCE_MEM }; -/* - * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used - * for other purposes. Be paranoid and allocate all of the before the PCI - * code gets a chance to to map anything else there ... - * - * This leaves the following areas available: - * - * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory - * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory - * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory - * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory - * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory - */ -static struct resource pcimt_mem_resources[] = { - { - .start = 0x100a0000, - .end = 0x100bffff, - .name = "Video RAM area", - .flags = IORESOURCE_BUSY - }, { - .start = 0x100c0000, - .end = 0x100fffff, - .name = "ISA Reserved", - .flags = IORESOURCE_BUSY - }, { - .start = 0x14000000, - .end = 0x17bfffff, - .name = "PCI IO", - .flags = IORESOURCE_BUSY - }, { - .start = 0x17c00000, - .end = 0x17ffffff, - .name = "Cache Replacement Area", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1a000000, - .end = 0x1a000003, - .name = "PCI INT Acknowledge", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fc00000, - .end = 0x1fc7ffff, - .name = "Boot PROM", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fc80000, - .end = 0x1fcfffff, - .name = "Diag PROM", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fd00000, - .end = 0x1fdfffff, - .name = "X-Bus", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fe00000, - .end = 0x1fefffff, - .name = "BIOS map", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1ff00000, - .end = 0x1ff7ffff, - .name = "NVRAM / EEPROM", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fff0000, - .end = 0x1fffefff, - .name = "ASIC PCI", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1ffff000, - .end = 0x1fffffff, - .name = "MP Agent", - .flags = IORESOURCE_BUSY - }, { - .start = 0x20000000, - .end = 0x9fffffff, - .name = "Main Memory", - .flags = IORESOURCE_BUSY - } -}; - static void __init sni_pcimt_resource_init(void) { int i; /* request I/O space for devices used on all i[345]86 PCs */ for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) - request_resource(&ioport_resource, pcimt_io_resources + i); - - /* request mem space for pcimt-specific devices */ - for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++) - request_resource(&sni_mem_resource, pcimt_mem_resources + i); - - ioport_resource.end = sni_io_resource.end; + request_resource(&sni_io_resource, pcimt_io_resources + i); } extern struct pci_ops sni_pcimt_ops; @@ -240,9 +152,10 @@ extern struct pci_ops sni_pcimt_ops; static struct pci_controller sni_controller = { .pci_ops = &sni_pcimt_ops, .mem_resource = &sni_mem_resource, - .mem_offset = 0x10000000UL, + .mem_offset = 0x00000000UL, .io_resource = &sni_io_resource, - .io_offset = 0x00000000UL + .io_offset = 0x00000000UL, + .io_map_base = SNI_PORT_BASE }; static void enable_pcimt_irq(unsigned int irq) @@ -363,15 +276,17 @@ void __init sni_pcimt_irq_init(void) void sni_pcimt_init(void) { - sni_pcimt_resource_init(); sni_pcimt_detect(); sni_pcimt_sc_init(); rtc_mips_get_time = mc146818_get_cmos_time; rtc_mips_set_time = mc146818_set_rtc_mmss; board_time_init = sni_cpu_time_init; + ioport_resource.end = sni_io_resource.end; #ifdef CONFIG_PCI + PCIBIOS_MIN_IO = 0x9000; register_pci_controller(&sni_controller); #endif + sni_pcimt_resource_init(); } static int __init snirm_pcimt_setup_devinit(void) diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c index 1dfc3f00bbd..00d151f4d12 100644 --- a/arch/mips/sni/pcit.c +++ b/arch/mips/sni/pcit.c @@ -43,7 +43,7 @@ static struct platform_device pcit_serial8250_device = { }; static struct plat_serial8250_port pcit_cplus_data[] = { - PORT(0x3f8, 4), + PORT(0x3f8, 0), PORT(0x2f8, 3), PORT(0x3e8, 4), PORT(0x2e8, 3), @@ -59,9 +59,9 @@ static struct platform_device pcit_cplus_serial8250_device = { }; static struct resource sni_io_resource = { - .start = 0x00001000UL, + .start = 0x00000000UL, .end = 0x03bfffffUL, - .name = "PCIT IO MEM", + .name = "PCIT IO", .flags = IORESOURCE_IO, }; @@ -91,6 +91,11 @@ static struct resource pcit_io_resources[] = { .end = 0xdf, .name = "dma2", .flags = IORESOURCE_BUSY + }, { + .start = 0xcf8, + .end = 0xcfb, + .name = "PCI config addr", + .flags = IORESOURCE_BUSY }, { .start = 0xcfc, .end = 0xcff, @@ -100,107 +105,19 @@ static struct resource pcit_io_resources[] = { }; static struct resource sni_mem_resource = { - .start = 0x10000000UL, - .end = 0xffffffffUL, + .start = 0x18000000UL, + .end = 0x1fbfffffUL, .name = "PCIT PCI MEM", .flags = IORESOURCE_MEM }; -/* - * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used - * for other purposes. Be paranoid and allocate all of the before the PCI - * code gets a chance to to map anything else there ... - * - * This leaves the following areas available: - * - * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory - * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory - * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory - * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory - * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory - */ -static struct resource pcit_mem_resources[] = { - { - .start = 0x14000000, - .end = 0x17bfffff, - .name = "PCI IO", - .flags = IORESOURCE_BUSY - }, { - .start = 0x17c00000, - .end = 0x17ffffff, - .name = "Cache Replacement Area", - .flags = IORESOURCE_BUSY - }, { - .start = 0x180a0000, - .end = 0x180bffff, - .name = "Video RAM area", - .flags = IORESOURCE_BUSY - }, { - .start = 0x180c0000, - .end = 0x180fffff, - .name = "ISA Reserved", - .flags = IORESOURCE_BUSY - }, { - .start = 0x19000000, - .end = 0x1fbfffff, - .name = "PCI MEM", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fc00000, - .end = 0x1fc7ffff, - .name = "Boot PROM", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fc80000, - .end = 0x1fcfffff, - .name = "Diag PROM", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fd00000, - .end = 0x1fdfffff, - .name = "X-Bus", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fe00000, - .end = 0x1fefffff, - .name = "BIOS map", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1ff00000, - .end = 0x1ff7ffff, - .name = "NVRAM / EEPROM", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1fff0000, - .end = 0x1fffefff, - .name = "MAUI ASIC", - .flags = IORESOURCE_BUSY - }, { - .start = 0x1ffff000, - .end = 0x1fffffff, - .name = "MP Agent", - .flags = IORESOURCE_BUSY - }, { - .start = 0x20000000, - .end = 0x9fffffff, - .name = "Main Memory", - .flags = IORESOURCE_BUSY - } -}; - static void __init sni_pcit_resource_init(void) { int i; /* request I/O space for devices used on all i[345]86 PCs */ for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++) - request_resource(&ioport_resource, pcit_io_resources + i); - - /* request mem space for pcimt-specific devices */ - for (i = 0; i < ARRAY_SIZE(pcit_mem_resources); i++) - request_resource(&sni_mem_resource, pcit_mem_resources + i); - - ioport_resource.end = sni_io_resource.end; + request_resource(&sni_io_resource, pcit_io_resources + i); } @@ -209,9 +126,10 @@ extern struct pci_ops sni_pcit_ops; static struct pci_controller sni_pcit_controller = { .pci_ops = &sni_pcit_ops, .mem_resource = &sni_mem_resource, - .mem_offset = 0x10000000UL, + .mem_offset = 0x00000000UL, .io_resource = &sni_io_resource, - .io_offset = 0x00000000UL + .io_offset = 0x00000000UL, + .io_map_base = SNI_PORT_BASE }; static void enable_pcit_irq(unsigned int irq) @@ -262,7 +180,7 @@ static void pcit_hwint0(void) int irq; clear_c0_status(IE_IRQ0); - irq = ffs((pending >> 16) & 0x7f); + irq = ffs((pending >> 16) & 0x3f); if (likely(irq > 0)) do_IRQ (irq + SNI_PCIT_INT_START - 1); @@ -289,6 +207,8 @@ static void sni_pcit_hwint_cplus(void) if (pending & C_IRQ0) pcit_hwint0(); + else if (pending & C_IRQ1) + do_IRQ (MIPS_CPU_IRQ_BASE + 3); else if (pending & C_IRQ2) do_IRQ (MIPS_CPU_IRQ_BASE + 4); else if (pending & C_IRQ3) @@ -317,21 +237,23 @@ void __init sni_pcit_cplus_irq_init(void) mips_cpu_irq_init(); for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) set_irq_chip(i, &pcit_irq_type); - *(volatile u32 *)SNI_PCIT_INT_REG = 0; + *(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000; sni_hwint = sni_pcit_hwint_cplus; change_c0_status(ST0_IM, IE_IRQ0); - setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq); + setup_irq (MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq); } void sni_pcit_init(void) { - sni_pcit_resource_init(); rtc_mips_get_time = mc146818_get_cmos_time; rtc_mips_set_time = mc146818_set_rtc_mmss; board_time_init = sni_cpu_time_init; + ioport_resource.end = sni_io_resource.end; #ifdef CONFIG_PCI + PCIBIOS_MIN_IO = 0x9000; register_pci_controller(&sni_pcit_controller); #endif + sni_pcit_resource_init(); } static int __init snirm_pcit_setup_devinit(void) -- cgit v1.2.3 From 05bc284a719b778243f51e23c88fe6cefe6b219b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 26 Apr 2007 15:46:28 +0100 Subject: [MIPS] Remove unused _THREAD_SIZE_ORDER from asm-offset.c. Signed-off-by: Ralf Baechle --- arch/mips/kernel/asm-offsets.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 222de465db7..761a779d5c4 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -102,7 +102,6 @@ void output_thread_info_defines(void) offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); offset("#define TI_REGS ", struct thread_info, regs); - constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER); constant("#define _THREAD_SIZE ", THREAD_SIZE); constant("#define _THREAD_MASK ", THREAD_MASK); linefeed; -- cgit v1.2.3 From 820c229f6c82bb91c0dbfbce90f7e6eb9639c7ab Mon Sep 17 00:00:00 2001 From: Milind Arun Choudhary Date: Thu, 19 Apr 2007 15:05:16 +0530 Subject: [MIPS] Use DEFINE_SPINLOCK instead of SPIN_LOCK_UNLOCKED. Signed-off-by: Milind Arun Choudhary Signed-off-by: Ralf Baechle --- arch/mips/basler/excite/excite_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/basler/excite/excite_setup.c b/arch/mips/basler/excite/excite_setup.c index 42f0eda1d51..2f0e4c08eb0 100644 --- a/arch/mips/basler/excite/excite_setup.c +++ b/arch/mips/basler/excite/excite_setup.c @@ -63,7 +63,7 @@ volatile void __iomem * const ocd_base = (void *) (EXCITE_ADDR_OCD); volatile void __iomem * const titan_base = (void *) (EXCITE_ADDR_TITAN); /* Protect access to shared GPI registers */ -spinlock_t titan_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(titan_lock); int titan_irqflags; -- cgit v1.2.3 From 74142d65b23b46587ea329202e957c901d9a57a1 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 26 Apr 2007 19:45:09 +0900 Subject: [MIPS] rename VR41XX to VR4100 series This patch has renamed VR41XX to VR4100 series. That's better. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f9c4ba58d38..4edff8d54a6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -500,7 +500,7 @@ config DDB5477 ether port USB, AC97, PCI, etc. config MACH_VR41XX - bool "NEC VR41XX-based machines" + bool "NEC VR4100 series based machines" select SYS_HAS_CPU_VR41XX select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL -- cgit v1.2.3 From 678f4e34a66eb364f4f8e7dc82746c3df14dc1e8 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 26 Apr 2007 19:51:31 +0900 Subject: [MIPS] remove 2 select entries for VR41xx This patch has removed 2 select entries for VR41xx. These entries are selected in arch/mips/vr41xx/Kconfig. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4edff8d54a6..130d825e543 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -502,8 +502,6 @@ config DDB5477 config MACH_VR41XX bool "NEC VR4100 series based machines" select SYS_HAS_CPU_VR41XX - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL select GENERIC_HARDIRQS_NO__DO_IRQ config PMC_YOSEMITE -- cgit v1.2.3 From c4be17370b76bc6c23a239ca512fe360785d2369 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 26 Apr 2007 19:53:59 +0900 Subject: [MIPS] update vr41xx Kconfig This patch has updated vr41xx/Kconfig. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/vr41xx/Kconfig | 92 +++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index 92f41f6f934..8f4d3e74c23 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig @@ -1,6 +1,10 @@ -config CASIO_E55 - bool "Support for CASIO CASSIOPEIA E-10/15/55/65" +choice + prompt "Machine type" depends on MACH_VR41XX + default TANBAC_TB022X + +config CASIO_E55 + bool "CASIO CASSIOPEIA E-10/15/55/65" select DMA_NONCOHERENT select IRQ_CPU select ISA @@ -8,8 +12,7 @@ config CASIO_E55 select SYS_SUPPORTS_LITTLE_ENDIAN config IBM_WORKPAD - bool "Support for IBM WorkPad z50" - depends on MACH_VR41XX + bool "IBM WorkPad z50" select DMA_NONCOHERENT select IRQ_CPU select ISA @@ -17,26 +20,18 @@ config IBM_WORKPAD select SYS_SUPPORTS_LITTLE_ENDIAN config NEC_CMBVR4133 - bool "Support for NEC CMB-VR4133" - depends on MACH_VR41XX + bool "NEC CMB-VR4133" select DMA_NONCOHERENT select IRQ_CPU select HW_HAS_PCI select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN -config ROCKHOPPER - bool "Support for Rockhopper baseboard" - depends on NEC_CMBVR4133 - select I8259 - select HAVE_STD_PC_SERIAL_PORT - config TANBAC_TB022X - bool "Support for TANBAC VR4131 multichip module and TANBAC VR4131DIMM" - depends on MACH_VR41XX + bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM" select DMA_NONCOHERENT - select HW_HAS_PCI select IRQ_CPU + select HW_HAS_PCI select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN help @@ -46,40 +41,65 @@ config TANBAC_TB022X Please refer to about VR4131 multichip module and VR4131DIMM. -config TANBAC_TB0226 - bool "Support for TANBAC Mbase(TB0226)" +config VICTOR_MPC30X + bool "Victor MP-C303/304" + select DMA_NONCOHERENT + select IRQ_CPU + select HW_HAS_PCI + select PCI_VR41XX + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + +config ZAO_CAPCELLA + bool "ZAO Networks Capcella" + select DMA_NONCOHERENT + select IRQ_CPU + select HW_HAS_PCI + select PCI_VR41XX + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + +endchoice + +config ROCKHOPPER + bool "Support for Rockhopper base board" + depends on NEC_CMBVR4133 + select PCI_VR41XX + select I8259 + select HAVE_STD_PC_SERIAL_PORT + +choice + prompt "Base board type" depends on TANBAC_TB022X + default TANBAC_TB0287 + +config TANBAC_TB0219 + bool "TANBAC DIMM Evaluation Kit(TB0219)" select GPIO_VR41XX + select PCI_VR41XX + help + The TANBAC DIMM Evaluation Kit(TB0219) is a MIPS-based platform + manufactured by TANBAC. + Please refer to about DIMM Evaluation Kit. + +config TANBAC_TB0226 + bool "TANBAC Mbase(TB0226)" + select GPIO_VR41XX + select PCI_VR41XX help The TANBAC Mbase(TB0226) is a MIPS-based platform manufactured by TANBAC. Please refer to about Mbase. config TANBAC_TB0287 - bool "Support for TANBAC Mini-ITX DIMM base(TB0287)" - depends on TANBAC_TB022X + bool "TANBAC Mini-ITX DIMM base(TB0287)" + select PCI_VR41XX help The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform manufactured by TANBAC. Please refer to about Mini-ITX DIMM base. -config VICTOR_MPC30X - bool "Support for Victor MP-C303/304" - depends on MACH_VR41XX - select DMA_NONCOHERENT - select HW_HAS_PCI - select IRQ_CPU - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - -config ZAO_CAPCELLA - bool "Support for ZAO Networks Capcella" - depends on MACH_VR41XX - select DMA_NONCOHERENT - select HW_HAS_PCI - select IRQ_CPU - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN +endchoice config PCI_VR41XX bool "Add PCI control unit support of NEC VR4100 series" -- cgit v1.2.3 From eed40d3ad2ba652c08422d62a5ff6f62ac0be16d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 5 Feb 2007 16:15:25 -0800 Subject: powerpc: make it compile for multithread change arch/powerpc/kernel/of_platform.c:479: error: unknown field `multithread_probe' specified in initializer Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/of_platform.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index b7345176b39..9e7a4d249f0 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -475,9 +475,6 @@ static struct of_platform_driver of_pci_phb_driver = { .name = "of-pci", .match_table = of_pci_phb_ids, .probe = of_pci_phb_probe, - .driver = { - .multithread_probe = 1, - }, }; static __init int of_pci_phb_init(void) -- cgit v1.2.3 From b1bdb691c3c38b4fbaf99fa8474f5cfa99b2d774 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 27 Apr 2007 15:28:45 -0700 Subject: [AF_RXRPC/AFS]: Arch-specific fixes. Fixes for various arch compilation problems: (*) Missing module exports. (*) Variable name collision when rxkad and af_rxrpc both built in (rxrpc_debug). (*) Large constant representation problem (AFS_UUID_TO_UNIX_TIME). (*) Configuration dependencies. (*) printk() format warnings. Signed-off-by: David Howells Signed-off-by: David S. Miller --- arch/ia64/lib/csum_partial_copy.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/ia64/lib/csum_partial_copy.c b/arch/ia64/lib/csum_partial_copy.c index 503dfe6d145..118daf5a063 100644 --- a/arch/ia64/lib/csum_partial_copy.c +++ b/arch/ia64/lib/csum_partial_copy.c @@ -128,6 +128,8 @@ csum_partial_copy_from_user(const void __user *src, void *dst, return (__force __wsum)result; } +EXPORT_SYMBOL(csum_partial_copy_from_user); + __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { -- cgit v1.2.3