From 288810784ad723fad30020f03a295c31c3b330f3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 3 Mar 2008 01:17:37 +0100 Subject: [PATCH] --- yaml --- r: 86656 b: refs/heads/master c: 9b5cf48b06a52c04b85c88642c3b620db8e1d592 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/powerpc/boot/cuboot-bamboo.c | 1 - trunk/arch/powerpc/boot/cuboot-ebony.c | 1 - trunk/arch/powerpc/boot/cuboot-katmai.c | 1 - trunk/arch/powerpc/boot/cuboot-taishan.c | 2 - trunk/arch/powerpc/boot/cuboot-warp.c | 1 - trunk/arch/powerpc/boot/dts/haleakala.dts | 2 +- trunk/arch/powerpc/boot/dts/katmai.dts | 58 +++---- trunk/arch/powerpc/oprofile/op_model_cell.c | 2 +- .../powerpc/platforms/52xx/mpc52xx_common.c | 1 - trunk/arch/powerpc/platforms/cell/iommu.c | 151 ++++++++---------- trunk/arch/powerpc/platforms/cell/setup.c | 7 - trunk/arch/powerpc/platforms/cell/spu_base.c | 16 +- .../powerpc/platforms/cell/spufs/context.c | 7 +- .../arch/powerpc/platforms/cell/spufs/file.c | 12 +- .../arch/powerpc/platforms/cell/spufs/sched.c | 2 +- .../powerpc/platforms/cell/spufs/sputrace.c | 7 +- .../powerpc/platforms/cell/spufs/switch.c | 6 - trunk/arch/powerpc/platforms/celleb/beat.h | 3 + trunk/arch/x86/mm/pageattr.c | 21 ++- .../drivers/char/xilinx_hwicap/buffer_icap.c | 80 +++++----- trunk/drivers/char/xilinx_hwicap/fifo_icap.c | 60 +++---- .../char/xilinx_hwicap/xilinx_hwicap.c | 138 +++++++++------- .../char/xilinx_hwicap/xilinx_hwicap.h | 24 +-- trunk/fs/exec.c | 10 +- trunk/include/asm-powerpc/reg.h | 3 - trunk/include/asm-x86/pgtable_32.h | 4 +- trunk/include/asm-x86/pgtable_64.h | 6 +- 28 files changed, 286 insertions(+), 342 deletions(-) diff --git a/[refs] b/[refs] index cfbd2bc22e86..56e1b4527aa0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5ce6386b900c83aa31d0490335df421a8d544381 +refs/heads/master: 9b5cf48b06a52c04b85c88642c3b620db8e1d592 diff --git a/trunk/arch/powerpc/boot/cuboot-bamboo.c b/trunk/arch/powerpc/boot/cuboot-bamboo.c index b5c30f766c40..900c7ff2b7e9 100644 --- a/trunk/arch/powerpc/boot/cuboot-bamboo.c +++ b/trunk/arch/powerpc/boot/cuboot-bamboo.c @@ -17,7 +17,6 @@ #include "44x.h" #include "cuboot.h" -#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/trunk/arch/powerpc/boot/cuboot-ebony.c b/trunk/arch/powerpc/boot/cuboot-ebony.c index 56564ba37f62..c5f37ce172ea 100644 --- a/trunk/arch/powerpc/boot/cuboot-ebony.c +++ b/trunk/arch/powerpc/boot/cuboot-ebony.c @@ -17,7 +17,6 @@ #include "44x.h" #include "cuboot.h" -#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/trunk/arch/powerpc/boot/cuboot-katmai.c b/trunk/arch/powerpc/boot/cuboot-katmai.c index 5434d70b5660..c021167f9381 100644 --- a/trunk/arch/powerpc/boot/cuboot-katmai.c +++ b/trunk/arch/powerpc/boot/cuboot-katmai.c @@ -22,7 +22,6 @@ #include "44x.h" #include "cuboot.h" -#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/trunk/arch/powerpc/boot/cuboot-taishan.c b/trunk/arch/powerpc/boot/cuboot-taishan.c index b55b80467eed..f66455a45ab1 100644 --- a/trunk/arch/powerpc/boot/cuboot-taishan.c +++ b/trunk/arch/powerpc/boot/cuboot-taishan.c @@ -21,9 +21,7 @@ #include "dcr.h" #include "4xx.h" -#define TARGET_4xx #define TARGET_44x -#define TARGET_440GX #include "ppcboot.h" static bd_t bd; diff --git a/trunk/arch/powerpc/boot/cuboot-warp.c b/trunk/arch/powerpc/boot/cuboot-warp.c index 3db93e85e9ea..bdedebe1bc14 100644 --- a/trunk/arch/powerpc/boot/cuboot-warp.c +++ b/trunk/arch/powerpc/boot/cuboot-warp.c @@ -11,7 +11,6 @@ #include "4xx.h" #include "cuboot.h" -#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/trunk/arch/powerpc/boot/dts/haleakala.dts b/trunk/arch/powerpc/boot/dts/haleakala.dts index ae68fefc01b6..5dd3d15f0feb 100644 --- a/trunk/arch/powerpc/boot/dts/haleakala.dts +++ b/trunk/arch/powerpc/boot/dts/haleakala.dts @@ -235,7 +235,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; + compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex"; primary; port = <0>; /* port number */ reg = ; /* Filled in by zImage */ i-cache-line-size = <20>; d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-size = <20000>; + d-cache-size = <20000>; dcr-controller; dcr-access-method = "native"; }; @@ -136,11 +136,11 @@ }; POB0: opb { - compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; + compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 4 e0000000 20000000>; - clock-frequency = <0>; /* Filled in by zImage */ + ranges = <00000000 4 e0000000 20000000>; + clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; @@ -153,38 +153,38 @@ }; UART0: serial@10000200 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000200 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000200 8>; virtual-reg = ; - clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; - interrupt-parent = <&UIC0>; - interrupts = <0 4>; - }; + clock-frequency = <0>; /* Filled in by zImage */ + current-speed = <1c200>; + interrupt-parent = <&UIC0>; + interrupts = <0 4>; + }; UART1: serial@10000300 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000300 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000300 8>; virtual-reg = ; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC0>; - interrupts = <1 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC0>; + interrupts = <1 4>; + }; UART2: serial@10000600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000600 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000600 8>; virtual-reg = ; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC1>; - interrupts = <5 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC1>; + interrupts = <5 4>; + }; IIC0: i2c@10000400 { compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; diff --git a/trunk/arch/powerpc/oprofile/op_model_cell.c b/trunk/arch/powerpc/oprofile/op_model_cell.c index 9eed1f68fcab..13929771bee7 100644 --- a/trunk/arch/powerpc/oprofile/op_model_cell.c +++ b/trunk/arch/powerpc/oprofile/op_model_cell.c @@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs, for (i = 0; i < num_counters; ++i) { if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i)) && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel, i); cbe_write_ctr(cpu, i, reset_value[i]); } } diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c index 4d5fd1dbd400..9aa4425d80b2 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -199,7 +199,6 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv) return 0; } -EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv); /** * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index 20ea0e118f24..edab631a8dcb 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -113,7 +113,7 @@ /* IOMMU sizing */ #define IO_SEGMENT_SHIFT 28 -#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift)) +#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT) /* The high bit needs to be set on every DMA address */ #define SPIDER_DMA_OFFSET 0x80000000ul @@ -123,6 +123,7 @@ struct iommu_window { struct cbe_iommu *iommu; unsigned long offset; unsigned long size; + unsigned long pte_offset; unsigned int ioid; struct iommu_table table; }; @@ -199,7 +200,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages, (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); + io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); @@ -231,7 +232,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages) | (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); + io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); for (i = 0; i < npages; i++) io_pte[i] = pte; @@ -306,84 +307,76 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base) return -ENODEV; } -static void cell_iommu_setup_stab(struct cbe_iommu *iommu, +static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { struct page *page; - unsigned long segments, stab_size; + int i; + unsigned long reg, segments, pages_per_segment, ptab_size, stab_size, + n_pte_pages, base; + + base = dbase; + if (fsize != 0) + base = min(fbase, dbase); segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT; + pages_per_segment = 1ull << IO_PAGENO_BITS; - pr_debug("%s: iommu[%d]: segments: %lu\n", - __FUNCTION__, iommu->nid, segments); + pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n", + __FUNCTION__, iommu->nid, segments, pages_per_segment); /* set up the segment table */ stab_size = segments * sizeof(unsigned long); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); BUG_ON(!page); iommu->stab = page_address(page); - memset(iommu->stab, 0, stab_size); -} - -static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu, - unsigned long base, unsigned long size, unsigned long gap_base, - unsigned long gap_size, unsigned long page_shift) -{ - struct page *page; - int i; - unsigned long reg, segments, pages_per_segment, ptab_size, - n_pte_pages, start_seg, *ptab; - - start_seg = base >> IO_SEGMENT_SHIFT; - segments = size >> IO_SEGMENT_SHIFT; - pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift); - /* PTEs for each segment must start on a 4K bounday */ - pages_per_segment = max(pages_per_segment, - (1 << 12) / sizeof(unsigned long)); + clear_page(iommu->stab); + /* ... and the page tables. Since these are contiguous, we can treat + * the page tables as one array of ptes, like pSeries does. + */ ptab_size = segments * pages_per_segment * sizeof(unsigned long); pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__, iommu->nid, ptab_size, get_order(ptab_size)); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size)); BUG_ON(!page); - ptab = page_address(page); - memset(ptab, 0, ptab_size); + iommu->ptab = page_address(page); + memset(iommu->ptab, 0, ptab_size); - /* number of 4K pages needed for a page table */ - n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12; + /* allocate a bogus page for the end of each mapping */ + page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); + BUG_ON(!page); + iommu->pad_page = page_address(page); + clear_page(iommu->pad_page); + + /* number of pages needed for a page table */ + n_pte_pages = (pages_per_segment * + sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT; pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n", - __FUNCTION__, iommu->nid, iommu->stab, ptab, + __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab, n_pte_pages); /* initialise the STEs */ reg = IOSTE_V | ((n_pte_pages - 1) << 5); - switch (page_shift) { - case 12: reg |= IOSTE_PS_4K; break; - case 16: reg |= IOSTE_PS_64K; break; - case 20: reg |= IOSTE_PS_1M; break; - case 24: reg |= IOSTE_PS_16M; break; - default: BUG(); + if (IOMMU_PAGE_SIZE == 0x1000) + reg |= IOSTE_PS_4K; + else if (IOMMU_PAGE_SIZE == 0x10000) + reg |= IOSTE_PS_64K; + else { + extern void __unknown_page_size_error(void); + __unknown_page_size_error(); } - gap_base = gap_base >> IO_SEGMENT_SHIFT; - gap_size = gap_size >> IO_SEGMENT_SHIFT; - pr_debug("Setting up IOMMU stab:\n"); - for (i = start_seg; i < (start_seg + segments); i++) { - if (i >= gap_base && i < (gap_base + gap_size)) { - pr_debug("\toverlap at %d, skipping\n", i); - continue; - } - iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) * - (i - start_seg)); + for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) { + iommu->stab[i] = reg | + (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i); pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]); } - - return ptab; } static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) @@ -430,9 +423,7 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long base, unsigned long size) { - cell_iommu_setup_stab(iommu, base, size, 0, 0); - iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0, - IOMMU_PAGE_SHIFT); + cell_iommu_setup_page_tables(iommu, base, size, 0, 0); cell_iommu_enable_hardware(iommu); } @@ -473,7 +464,6 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, unsigned long pte_offset) { struct iommu_window *window; - struct page *page; u32 ioid; ioid = cell_iommu_get_ioid(np); @@ -485,11 +475,13 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, window->size = size; window->ioid = ioid; window->iommu = iommu; + window->pte_offset = pte_offset; window->table.it_blocksize = 16; window->table.it_base = (unsigned long)iommu->ptab; window->table.it_index = iommu->nid; - window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset; + window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + + window->pte_offset; window->table.it_size = size >> IOMMU_PAGE_SHIFT; iommu_init_table(&window->table, iommu->nid); @@ -512,11 +504,6 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, * This code also assumes that we have a window that starts at 0, * which is the case on all spider based blades. */ - page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); - BUG_ON(!page); - iommu->pad_page = page_address(page); - clear_page(iommu->pad_page); - __set_bit(0, window->table.it_map); tce_build_cell(&window->table, window->table.it_offset, 1, (unsigned long)iommu->pad_page, DMA_TO_DEVICE); @@ -562,7 +549,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev) archdata->dma_data = &window->table; } -static void cell_dma_dev_setup_fixed(struct device *dev); +static void cell_dma_dev_setup_static(struct device *dev); static void cell_dma_dev_setup(struct device *dev) { @@ -570,7 +557,7 @@ static void cell_dma_dev_setup(struct device *dev) /* Order is important here, these are not mutually exclusive */ if (get_dma_ops(dev) == &dma_iommu_fixed_ops) - cell_dma_dev_setup_fixed(dev); + cell_dma_dev_setup_static(dev); else if (get_pci_dma_ops() == &dma_iommu_ops) cell_dma_dev_setup_iommu(dev); else if (get_pci_dma_ops() == &dma_direct_ops) @@ -871,7 +858,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) return 0; } -static void cell_dma_dev_setup_fixed(struct device *dev) +static void cell_dma_dev_setup_static(struct device *dev) { struct dev_archdata *archdata = &dev->archdata; u64 addr; @@ -882,45 +869,35 @@ static void cell_dma_dev_setup_fixed(struct device *dev) dev_dbg(dev, "iommu: fixed addr = %lx\n", addr); } -static void insert_16M_pte(unsigned long addr, unsigned long *ptab, - unsigned long base_pte) -{ - unsigned long segment, offset; - - segment = addr >> IO_SEGMENT_SHIFT; - offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24)); - ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long)); - - pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n", - addr, ptab, segment, offset); - - ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask); -} - static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, struct device_node *np, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { - unsigned long base_pte, uaddr, ioaddr, *ptab; - - ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24); + unsigned long base_pte, uaddr, *io_pte; + int i; dma_iommu_fixed_base = fbase; + /* convert from bytes into page table indices */ + dbase = dbase >> IOMMU_PAGE_SHIFT; + dsize = dsize >> IOMMU_PAGE_SHIFT; + fbase = fbase >> IOMMU_PAGE_SHIFT; + fsize = fsize >> IOMMU_PAGE_SHIFT; + pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase); + io_pte = iommu->ptab; base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask); - for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) { + uaddr = 0; + for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) { /* Don't touch the dynamic region */ - ioaddr = uaddr + fbase; - if (ioaddr >= dbase && ioaddr < (dbase + dsize)) { - pr_debug("iommu: fixed/dynamic overlap, skipping\n"); + if (i >= dbase && i < (dbase + dsize)) { + pr_debug("iommu: static/dynamic overlap, skipping\n"); continue; } - - insert_16M_pte(uaddr, ptab, base_pte); + io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); } mb(); @@ -1018,9 +995,7 @@ static int __init cell_iommu_fixed_mapping_init(void) "fixed window 0x%lx-0x%lx\n", iommu->nid, dbase, dbase + dsize, fbase, fbase + fsize); - cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize); - iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0, - IOMMU_PAGE_SHIFT); + cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize); cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize, fbase, fsize); cell_iommu_enable_hardware(iommu); diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index dda34650cb07..a7f609b3b876 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -149,11 +149,6 @@ static void __init cell_init_irq(void) mpic_init_IRQ(); } -static void __init cell_set_dabrx(void) -{ - mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); -} - static void __init cell_setup_arch(void) { #ifdef CONFIG_SPU_BASE @@ -163,8 +158,6 @@ static void __init cell_setup_arch(void) cbe_regs_init(); - cell_set_dabrx(); - #ifdef CONFIG_CBE_RAS cbe_ras_init(); #endif diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index 712001f6b7da..87eb07f94c5f 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -81,12 +81,9 @@ struct spu_slb { void spu_invalidate_slbs(struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - unsigned long flags; - spin_lock_irqsave(&spu->register_lock, flags); if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) out_be64(&priv2->slb_invalidate_all_W, 0UL); - spin_unlock_irqrestore(&spu->register_lock, flags); } EXPORT_SYMBOL_GPL(spu_invalidate_slbs); @@ -151,11 +148,7 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) __func__, slbe, slb->vsid, slb->esid); out_be64(&priv2->slb_index_W, slbe); - /* set invalid before writing vsid */ - out_be64(&priv2->slb_esid_RW, 0); - /* now it's safe to write the vsid */ out_be64(&priv2->slb_vsid_RW, slb->vsid); - /* setting the new esid makes the entry valid again */ out_be64(&priv2->slb_esid_RW, slb->esid); } @@ -297,11 +290,9 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, nr_slbs++; } - spin_lock_irq(&spu->register_lock); /* Add the set of SLBs */ for (i = 0; i < nr_slbs; i++) spu_load_slb(spu, i, &slbs[i]); - spin_unlock_irq(&spu->register_lock); } EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs); @@ -346,14 +337,13 @@ spu_irq_class_1(int irq, void *data) if (stat & CLASS1_STORAGE_FAULT_INTR) spu_mfc_dsisr_set(spu, 0ul); spu_int_stat_clear(spu, 1, stat); - - if (stat & CLASS1_SEGMENT_FAULT_INTR) - __spu_trap_data_seg(spu, dar); - spin_unlock(&spu->register_lock); pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, dar, dsisr); + if (stat & CLASS1_SEGMENT_FAULT_INTR) + __spu_trap_data_seg(spu, dar); + if (stat & CLASS1_STORAGE_FAULT_INTR) __spu_trap_data_map(spu, dar, dsisr); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c index cf6c2c89211d..133995ed5cc7 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c @@ -109,12 +109,13 @@ void spu_forget(struct spu_context *ctx) /* * This is basically an open-coded spu_acquire_saved, except that - * we don't acquire the state mutex interruptible, and we don't - * want this context to be rescheduled on release. + * we don't acquire the state mutex interruptible. */ mutex_lock(&ctx->state_mutex); - if (ctx->state != SPU_STATE_SAVED) + if (ctx->state != SPU_STATE_SAVED) { + set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); spu_deactivate(ctx); + } mm = ctx->owner; ctx->owner = NULL; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index f7a7e8635fb6..c66c3756970d 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -366,13 +366,6 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, if (offset >= ps_size) return NOPFN_SIGBUS; - /* - * Because we release the mmap_sem, the context may be destroyed while - * we're in spu_wait. Grab an extra reference so it isn't destroyed - * in the meantime. - */ - get_spu_context(ctx); - /* * We have to wait for context to be loaded before we have * pages to hand out to the user, but we don't want to wait @@ -382,7 +375,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, * hanged. */ if (spu_acquire(ctx)) - goto refault; + return NOPFN_REFAULT; if (ctx->state == SPU_STATE_SAVED) { up_read(¤t->mm->mmap_sem); @@ -398,9 +391,6 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, if (!ret) spu_release(ctx); - -refault: - put_spu_context(ctx); return NOPFN_REFAULT; } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c index 5d5f680cd0b8..3a5972117de7 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c @@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) spu_switch_notify(spu, ctx); ctx->state = SPU_STATE_RUNNABLE; - spuctx_switch_state(ctx, SPU_UTIL_USER); + spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); } /* diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c b/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c index 79aa773f3c99..01974f7776e1 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n) ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start)); return snprintf(tbuf, n, - "[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n", + "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n", (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec, - t->curr_tid, - t->name, t->owner_tid, + t->name, + t->curr_tid, t->number); } @@ -188,7 +188,6 @@ struct spu_probe spu_probes[] = { { "spufs_ps_nopfn__insert", "%p %p", spu_context_event }, { "spu_acquire_saved__enter", "%p", spu_context_nospu_event }, { "destroy_spu_context__enter", "%p", spu_context_nospu_event }, - { "spufs_stop_callback__enter", "%p %p", spu_context_event }, }; static int __init sputrace_init(void) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index e9dc7a55d1b9..6f5886c7b1f9 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -118,8 +117,6 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) * Write INT_MASK_class1 with value of 0. * Save INT_Mask_class2 in CSA. * Write INT_MASK_class2 with value of 0. - * Synchronize all three interrupts to be sure - * we no longer execute a handler on another CPU. */ spin_lock_irq(&spu->register_lock); if (csa) { @@ -132,9 +129,6 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) spu_int_mask_set(spu, 2, 0ul); eieio(); spin_unlock_irq(&spu->register_lock); - synchronize_irq(spu->irqs[0]); - synchronize_irq(spu->irqs[1]); - synchronize_irq(spu->irqs[2]); } static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu) diff --git a/trunk/arch/powerpc/platforms/celleb/beat.h b/trunk/arch/powerpc/platforms/celleb/beat.h index ac82ac35b991..b2e292df13ca 100644 --- a/trunk/arch/powerpc/platforms/celleb/beat.h +++ b/trunk/arch/powerpc/platforms/celleb/beat.h @@ -21,6 +21,9 @@ #ifndef _CELLEB_BEAT_H #define _CELLEB_BEAT_H +#define DABRX_KERNEL (1UL<<1) +#define DABRX_USER (1UL<<0) + int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*); int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t); int64_t beat_repository_encode(int, const char *, uint64_t[4]); diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index 7049294fb469..14e48b5a94ba 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -26,7 +26,6 @@ struct cpa_data { pgprot_t mask_set; pgprot_t mask_clr; int numpages; - int processed; int flushtlb; unsigned long pfn; }; @@ -291,8 +290,8 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, */ nextpage_addr = (address + psize) & pmask; numpages = (nextpage_addr - address) >> PAGE_SHIFT; - if (numpages < cpa->processed) - cpa->processed = numpages; + if (numpages < cpa->numpages) + cpa->numpages = numpages; /* * We are safe now. Check whether the new pgprot is the same: @@ -319,7 +318,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, */ addr = address + PAGE_SIZE; pfn++; - for (i = 1; i < cpa->processed; i++, addr += PAGE_SIZE, pfn++) { + for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE, pfn++) { pgprot_t chk_prot = static_protections(new_prot, addr, pfn); if (pgprot_val(chk_prot) != pgprot_val(new_prot)) @@ -343,7 +342,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, * that we limited the number of possible pages already to * the number of pages in the large page. */ - if (address == (nextpage_addr - psize) && cpa->processed == numpages) { + if (address == (nextpage_addr - psize) && cpa->numpages == numpages) { /* * The address is aligned and the number of pages * covers the full page. @@ -573,7 +572,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) set_pte_atomic(kpte, new_pte); cpa->flushtlb = 1; } - cpa->processed = 1; + cpa->numpages = 1; return 0; } @@ -584,7 +583,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) do_split = try_preserve_large_page(kpte, address, cpa); /* * When the range fits into the existing large page, - * return. cp->processed and cpa->tlbflush have been updated in + * return. cp->numpages and cpa->tlbflush have been updated in * try_large_page: */ if (do_split <= 0) @@ -663,7 +662,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) * Store the remaining nr of pages for the large page * preservation check. */ - cpa->numpages = cpa->processed = numpages; + cpa->numpages = numpages; ret = __change_page_attr(cpa, checkalias); if (ret) @@ -680,9 +679,9 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) * CPA operation. Either a large page has been * preserved or a single page update happened. */ - BUG_ON(cpa->processed > numpages); - numpages -= cpa->processed; - cpa->vaddr += cpa->processed * PAGE_SIZE; + BUG_ON(cpa->numpages > numpages); + numpages -= cpa->numpages; + cpa->vaddr += cpa->numpages * PAGE_SIZE; } return 0; } diff --git a/trunk/drivers/char/xilinx_hwicap/buffer_icap.c b/trunk/drivers/char/xilinx_hwicap/buffer_icap.c index f577daedb630..dfea2bde162b 100644 --- a/trunk/drivers/char/xilinx_hwicap/buffer_icap.c +++ b/trunk/drivers/char/xilinx_hwicap/buffer_icap.c @@ -73,8 +73,8 @@ #define XHI_BUFFER_START 0 /** - * buffer_icap_get_status - Get the contents of the status register. - * @base_address: is the base address of the device + * buffer_icap_get_status: Get the contents of the status register. + * @parameter base_address: is the base address of the device * * The status register contains the ICAP status and the done bit. * @@ -94,9 +94,9 @@ static inline u32 buffer_icap_get_status(void __iomem *base_address) } /** - * buffer_icap_get_bram - Reads data from the storage buffer bram. - * @base_address: contains the base address of the component. - * @offset: The word offset from which the data should be read. + * buffer_icap_get_bram: Reads data from the storage buffer bram. + * @parameter base_address: contains the base address of the component. + * @parameter offset: The word offset from which the data should be read. * * A bram is used as a configuration memory cache. One frame of data can * be stored in this "storage buffer". @@ -108,8 +108,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address, } /** - * buffer_icap_busy - Return true if the icap device is busy - * @base_address: is the base address of the device + * buffer_icap_busy: Return true if the icap device is busy + * @parameter base_address: is the base address of the device * * The queries the low order bit of the status register, which * indicates whether the current configuration or readback operation @@ -121,8 +121,8 @@ static inline bool buffer_icap_busy(void __iomem *base_address) } /** - * buffer_icap_busy - Return true if the icap device is not busy - * @base_address: is the base address of the device + * buffer_icap_busy: Return true if the icap device is not busy + * @parameter base_address: is the base address of the device * * The queries the low order bit of the status register, which * indicates whether the current configuration or readback operation @@ -134,9 +134,9 @@ static inline bool buffer_icap_done(void __iomem *base_address) } /** - * buffer_icap_set_size - Set the size register. - * @base_address: is the base address of the device - * @data: The size in bytes. + * buffer_icap_set_size: Set the size register. + * @parameter base_address: is the base address of the device + * @parameter data: The size in bytes. * * The size register holds the number of 8 bit bytes to transfer between * bram and the icap (or icap to bram). @@ -148,9 +148,9 @@ static inline void buffer_icap_set_size(void __iomem *base_address, } /** - * buffer_icap_set_offset - Set the bram offset register. - * @base_address: contains the base address of the device. - * @data: is the value to be written to the data register. + * buffer_icap_mSetoffsetReg: Set the bram offset register. + * @parameter base_address: contains the base address of the device. + * @parameter data: is the value to be written to the data register. * * The bram offset register holds the starting bram address to transfer * data from during configuration or write data to during readback. @@ -162,9 +162,9 @@ static inline void buffer_icap_set_offset(void __iomem *base_address, } /** - * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register. - * @base_address: contains the base address of the device. - * @data: is the value to be written to the data register. + * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register. + * @parameter base_address: contains the base address of the device. + * @parameter data: is the value to be written to the data register. * * The RNC register determines the direction of the data transfer. It * controls whether a configuration or readback take place. Writing to @@ -178,10 +178,10 @@ static inline void buffer_icap_set_rnc(void __iomem *base_address, } /** - * buffer_icap_set_bram - Write data to the storage buffer bram. - * @base_address: contains the base address of the component. - * @offset: The word offset at which the data should be written. - * @data: The value to be written to the bram offset. + * buffer_icap_set_bram: Write data to the storage buffer bram. + * @parameter base_address: contains the base address of the component. + * @parameter offset: The word offset at which the data should be written. + * @parameter data: The value to be written to the bram offset. * * A bram is used as a configuration memory cache. One frame of data can * be stored in this "storage buffer". @@ -193,10 +193,10 @@ static inline void buffer_icap_set_bram(void __iomem *base_address, } /** - * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer. - * @drvdata: a pointer to the drvdata. - * @offset: The storage buffer start address. - * @count: The number of words (32 bit) to read from the + * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer. + * @parameter drvdata: a pointer to the drvdata. + * @parameter offset: The storage buffer start address. + * @parameter count: The number of words (32 bit) to read from the * device (ICAP). **/ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, @@ -227,10 +227,10 @@ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, }; /** - * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer. - * @drvdata: a pointer to the drvdata. - * @offset: The storage buffer start address. - * @count: The number of words (32 bit) to read from the + * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer. + * @parameter drvdata: a pointer to the drvdata. + * @parameter offset: The storage buffer start address. + * @parameter count: The number of words (32 bit) to read from the * device (ICAP). **/ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, @@ -261,8 +261,8 @@ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, }; /** - * buffer_icap_reset - Reset the logic of the icap device. - * @drvdata: a pointer to the drvdata. + * buffer_icap_reset: Reset the logic of the icap device. + * @parameter drvdata: a pointer to the drvdata. * * Writing to the status register resets the ICAP logic in an internal * version of the core. For the version of the core published in EDK, @@ -274,10 +274,10 @@ void buffer_icap_reset(struct hwicap_drvdata *drvdata) } /** - * buffer_icap_set_configuration - Load a partial bitstream from system memory. - * @drvdata: a pointer to the drvdata. - * @data: Kernel address of the partial bitstream. - * @size: the size of the partial bitstream in 32 bit words. + * buffer_icap_set_configuration: Load a partial bitstream from system memory. + * @parameter drvdata: a pointer to the drvdata. + * @parameter data: Kernel address of the partial bitstream. + * @parameter size: the size of the partial bitstream in 32 bit words. **/ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, u32 size) @@ -333,10 +333,10 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, }; /** - * buffer_icap_get_configuration - Read configuration data from the device. - * @drvdata: a pointer to the drvdata. - * @data: Address of the data representing the partial bitstream - * @size: the size of the partial bitstream in 32 bit words. + * buffer_icap_get_configuration: Read configuration data from the device. + * @parameter drvdata: a pointer to the drvdata. + * @parameter data: Address of the data representing the partial bitstream + * @parameter size: the size of the partial bitstream in 32 bit words. **/ int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, u32 size) diff --git a/trunk/drivers/char/xilinx_hwicap/fifo_icap.c b/trunk/drivers/char/xilinx_hwicap/fifo_icap.c index 6f45dbd47125..0988314694a6 100644 --- a/trunk/drivers/char/xilinx_hwicap/fifo_icap.c +++ b/trunk/drivers/char/xilinx_hwicap/fifo_icap.c @@ -94,9 +94,9 @@ /** - * fifo_icap_fifo_write - Write data to the write FIFO. - * @drvdata: a pointer to the drvdata. - * @data: the 32-bit value to be written to the FIFO. + * fifo_icap_fifo_write: Write data to the write FIFO. + * @parameter drvdata: a pointer to the drvdata. + * @parameter data: the 32-bit value to be written to the FIFO. * * This function will silently fail if the fifo is full. **/ @@ -108,8 +108,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_fifo_read - Read data from the Read FIFO. - * @drvdata: a pointer to the drvdata. + * fifo_icap_fifo_read: Read data from the Read FIFO. + * @parameter drvdata: a pointer to the drvdata. * * This function will silently fail if the fifo is empty. **/ @@ -121,9 +121,9 @@ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_set_read_size - Set the the size register. - * @drvdata: a pointer to the drvdata. - * @data: the size of the following read transaction, in words. + * fifo_icap_set_read_size: Set the the size register. + * @parameter drvdata: a pointer to the drvdata. + * @parameter data: the size of the following read transaction, in words. **/ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, u32 data) @@ -132,8 +132,8 @@ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_start_config - Initiate a configuration (write) to the device. - * @drvdata: a pointer to the drvdata. + * fifo_icap_start_config: Initiate a configuration (write) to the device. + * @parameter drvdata: a pointer to the drvdata. **/ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) { @@ -142,8 +142,8 @@ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_start_readback - Initiate a readback from the device. - * @drvdata: a pointer to the drvdata. + * fifo_icap_start_readback: Initiate a readback from the device. + * @parameter drvdata: a pointer to the drvdata. **/ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) { @@ -152,8 +152,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_busy - Return true if the ICAP is still processing a transaction. - * @drvdata: a pointer to the drvdata. + * fifo_icap_busy: Return true if the ICAP is still processing a transaction. + * @parameter drvdata: a pointer to the drvdata. **/ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) { @@ -163,8 +163,8 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_write_fifo_vacancy - Query the write fifo available space. - * @drvdata: a pointer to the drvdata. + * fifo_icap_write_fifo_vacancy: Query the write fifo available space. + * @parameter drvdata: a pointer to the drvdata. * * Return the number of words that can be safely pushed into the write fifo. **/ @@ -175,8 +175,8 @@ static inline u32 fifo_icap_write_fifo_vacancy( } /** - * fifo_icap_read_fifo_occupancy - Query the read fifo available data. - * @drvdata: a pointer to the drvdata. + * fifo_icap_read_fifo_occupancy: Query the read fifo available data. + * @parameter drvdata: a pointer to the drvdata. * * Return the number of words that can be safely read from the read fifo. **/ @@ -187,11 +187,11 @@ static inline u32 fifo_icap_read_fifo_occupancy( } /** - * fifo_icap_set_configuration - Send configuration data to the ICAP. - * @drvdata: a pointer to the drvdata. - * @frame_buffer: a pointer to the data to be written to the + * fifo_icap_set_configuration: Send configuration data to the ICAP. + * @parameter drvdata: a pointer to the drvdata. + * @parameter frame_buffer: a pointer to the data to be written to the * ICAP device. - * @num_words: the number of words (32 bit) to write to the ICAP + * @parameter num_words: the number of words (32 bit) to write to the ICAP * device. * This function writes the given user data to the Write FIFO in @@ -266,10 +266,10 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_get_configuration - Read configuration data from the device. - * @drvdata: a pointer to the drvdata. - * @data: Address of the data representing the partial bitstream - * @size: the size of the partial bitstream in 32 bit words. + * fifo_icap_get_configuration: Read configuration data from the device. + * @parameter drvdata: a pointer to the drvdata. + * @parameter data: Address of the data representing the partial bitstream + * @parameter size: the size of the partial bitstream in 32 bit words. * * This function reads the specified number of words from the ICAP device in * the polled mode. @@ -335,8 +335,8 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata, } /** - * buffer_icap_reset - Reset the logic of the icap device. - * @drvdata: a pointer to the drvdata. + * buffer_icap_reset: Reset the logic of the icap device. + * @parameter drvdata: a pointer to the drvdata. * * This function forces the software reset of the complete HWICAP device. * All the registers will return to the default value and the FIFO is also @@ -360,8 +360,8 @@ void fifo_icap_reset(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_flush_fifo - This function flushes the FIFOs in the device. - * @drvdata: a pointer to the drvdata. + * fifo_icap_flush_fifo: This function flushes the FIFOs in the device. + * @parameter drvdata: a pointer to the drvdata. */ void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata) { diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 2284fa2a5a57..24f6aef0fd3c 100644 --- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -84,7 +84,7 @@ #include #include #include -#include +#include #include #include #include @@ -119,7 +119,6 @@ module_param(xhwicap_minor, int, S_IRUGO); /* An array, which is set to true when the device is registered. */ static bool probed_devices[HWICAP_DEVICES]; -static struct mutex icap_sem; static struct class *icap_class; @@ -200,14 +199,14 @@ static const struct config_registers v5_config_registers = { }; /** - * hwicap_command_desync - Send a DESYNC command to the ICAP port. - * @drvdata: a pointer to the drvdata. + * hwicap_command_desync: Send a DESYNC command to the ICAP port. + * @parameter drvdata: a pointer to the drvdata. * * This command desynchronizes the ICAP After this command, a * bitstream containing a NULL packet, followed by a SYNCH packet is * required before the ICAP will recognize commands. */ -static int hwicap_command_desync(struct hwicap_drvdata *drvdata) +int hwicap_command_desync(struct hwicap_drvdata *drvdata) { u32 buffer[4]; u32 index = 0; @@ -229,18 +228,51 @@ static int hwicap_command_desync(struct hwicap_drvdata *drvdata) } /** - * hwicap_get_configuration_register - Query a configuration register. - * @drvdata: a pointer to the drvdata. - * @reg: a constant which represents the configuration + * hwicap_command_capture: Send a CAPTURE command to the ICAP port. + * @parameter drvdata: a pointer to the drvdata. + * + * This command captures all of the flip flop states so they will be + * available during readback. One can use this command instead of + * enabling the CAPTURE block in the design. + */ +int hwicap_command_capture(struct hwicap_drvdata *drvdata) +{ + u32 buffer[7]; + u32 index = 0; + + /* + * Create the data to be written to the ICAP. + */ + buffer[index++] = XHI_DUMMY_PACKET; + buffer[index++] = XHI_SYNC_PACKET; + buffer[index++] = XHI_NOOP_PACKET; + buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1; + buffer[index++] = XHI_CMD_GCAPTURE; + buffer[index++] = XHI_DUMMY_PACKET; + buffer[index++] = XHI_DUMMY_PACKET; + + /* + * Write the data to the FIFO and intiate the transfer of data + * present in the FIFO to the ICAP device. + */ + return drvdata->config->set_configuration(drvdata, + &buffer[0], index); + +} + +/** + * hwicap_get_configuration_register: Query a configuration register. + * @parameter drvdata: a pointer to the drvdata. + * @parameter reg: a constant which represents the configuration * register value to be returned. * Examples: XHI_IDCODE, XHI_FLR. - * @reg_data: returns the value of the register. + * @parameter RegData: returns the value of the register. * * Sends a query packet to the ICAP and then receives the response. * The icap is left in Synched state. */ -static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, - u32 reg, u32 *reg_data) +int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, + u32 reg, u32 *RegData) { int status; u32 buffer[6]; @@ -268,14 +300,14 @@ static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, /* * Read the configuration register */ - status = drvdata->config->get_configuration(drvdata, reg_data, 1); + status = drvdata->config->get_configuration(drvdata, RegData, 1); if (status) return status; return 0; } -static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) +int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) { int status; u32 idcode; @@ -312,7 +344,7 @@ static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) } static ssize_t -hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct hwicap_drvdata *drvdata = file->private_data; ssize_t bytes_to_read = 0; @@ -321,9 +353,8 @@ hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) u32 bytes_remaining; int status; - status = mutex_lock_interruptible(&drvdata->sem); - if (status) - return status; + if (down_interruptible(&drvdata->sem)) + return -ERESTARTSYS; if (drvdata->read_buffer_in_use) { /* If there are leftover bytes in the buffer, just */ @@ -339,9 +370,8 @@ hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) goto error; } drvdata->read_buffer_in_use -= bytes_to_read; - memmove(drvdata->read_buffer, - drvdata->read_buffer + bytes_to_read, - 4 - bytes_to_read); + memcpy(drvdata->read_buffer + bytes_to_read, + drvdata->read_buffer, 4 - bytes_to_read); } else { /* Get new data from the ICAP, and return was was requested. */ kbuf = (u32 *) get_zeroed_page(GFP_KERNEL); @@ -384,20 +414,18 @@ hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) status = -EFAULT; goto error; } - memcpy(drvdata->read_buffer, - kbuf, - bytes_remaining); + memcpy(kbuf, drvdata->read_buffer, bytes_remaining); drvdata->read_buffer_in_use = bytes_remaining; free_page((unsigned long)kbuf); } status = bytes_to_read; error: - mutex_unlock(&drvdata->sem); + up(&drvdata->sem); return status; } static ssize_t -hwicap_write(struct file *file, const char __user *buf, +hwicap_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct hwicap_drvdata *drvdata = file->private_data; @@ -407,9 +435,8 @@ hwicap_write(struct file *file, const char __user *buf, ssize_t len; ssize_t status; - status = mutex_lock_interruptible(&drvdata->sem); - if (status) - return status; + if (down_interruptible(&drvdata->sem)) + return -ERESTARTSYS; left += drvdata->write_buffer_in_use; @@ -438,7 +465,7 @@ hwicap_write(struct file *file, const char __user *buf, memcpy(kbuf, drvdata->write_buffer, drvdata->write_buffer_in_use); if (copy_from_user( - (((char *)kbuf) + drvdata->write_buffer_in_use), + (((char *)kbuf) + (drvdata->write_buffer_in_use)), buf + written, len - (drvdata->write_buffer_in_use))) { free_page((unsigned long)kbuf); @@ -481,7 +508,7 @@ hwicap_write(struct file *file, const char __user *buf, free_page((unsigned long)kbuf); status = written; error: - mutex_unlock(&drvdata->sem); + up(&drvdata->sem); return status; } @@ -492,9 +519,8 @@ static int hwicap_open(struct inode *inode, struct file *file) drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); - status = mutex_lock_interruptible(&drvdata->sem); - if (status) - return status; + if (down_interruptible(&drvdata->sem)) + return -ERESTARTSYS; if (drvdata->is_open) { status = -EBUSY; @@ -513,7 +539,7 @@ static int hwicap_open(struct inode *inode, struct file *file) drvdata->is_open = 1; error: - mutex_unlock(&drvdata->sem); + up(&drvdata->sem); return status; } @@ -523,7 +549,8 @@ static int hwicap_release(struct inode *inode, struct file *file) int i; int status = 0; - mutex_lock(&drvdata->sem); + if (down_interruptible(&drvdata->sem)) + return -ERESTARTSYS; if (drvdata->write_buffer_in_use) { /* Flush write buffer. */ @@ -542,7 +569,7 @@ static int hwicap_release(struct inode *inode, struct file *file) error: drvdata->is_open = 0; - mutex_unlock(&drvdata->sem); + up(&drvdata->sem); return status; } @@ -565,36 +592,31 @@ static int __devinit hwicap_setup(struct device *dev, int id, dev_info(dev, "Xilinx icap port driver\n"); - mutex_lock(&icap_sem); - if (id < 0) { for (id = 0; id < HWICAP_DEVICES; id++) if (!probed_devices[id]) break; } if (id < 0 || id >= HWICAP_DEVICES) { - mutex_unlock(&icap_sem); dev_err(dev, "%s%i too large\n", DRIVER_NAME, id); return -EINVAL; } if (probed_devices[id]) { - mutex_unlock(&icap_sem); dev_err(dev, "cannot assign to %s%i; it is already in use\n", DRIVER_NAME, id); return -EBUSY; } probed_devices[id] = 1; - mutex_unlock(&icap_sem); devt = MKDEV(xhwicap_major, xhwicap_minor + id); - drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); + drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); if (!drvdata) { dev_err(dev, "Couldn't allocate device private record\n"); - retval = -ENOMEM; - goto failed0; + return -ENOMEM; } + memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata)); dev_set_drvdata(dev, (void *)drvdata); if (!regs_res) { @@ -626,7 +648,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, drvdata->config = config; drvdata->config_regs = config_regs; - mutex_init(&drvdata->sem); + init_MUTEX(&drvdata->sem); drvdata->is_open = 0; dev_info(dev, "ioremap %lx to %p with size %x\n", @@ -641,7 +663,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, goto failed3; } /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */ - device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id); + class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME); return 0; /* success */ failed3: @@ -653,11 +675,6 @@ static int __devinit hwicap_setup(struct device *dev, int id, failed1: kfree(drvdata); - failed0: - mutex_lock(&icap_sem); - probed_devices[id] = 0; - mutex_unlock(&icap_sem); - return retval; } @@ -682,16 +699,14 @@ static int __devexit hwicap_remove(struct device *dev) if (!drvdata) return 0; - device_destroy(icap_class, drvdata->devt); + class_device_destroy(icap_class, drvdata->devt); cdev_del(&drvdata->cdev); iounmap(drvdata->base_address); release_mem_region(drvdata->mem_start, drvdata->mem_size); kfree(drvdata); dev_set_drvdata(dev, NULL); - - mutex_lock(&icap_sem); probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0; - mutex_unlock(&icap_sem); + return 0; /* success */ } @@ -806,29 +821,28 @@ static struct of_platform_driver hwicap_of_driver = { }; /* Registration helpers to keep the number of #ifdefs to a minimum */ -static inline int __init hwicap_of_register(void) +static inline int __devinit hwicap_of_register(void) { pr_debug("hwicap: calling of_register_platform_driver()\n"); return of_register_platform_driver(&hwicap_of_driver); } -static inline void __exit hwicap_of_unregister(void) +static inline void __devexit hwicap_of_unregister(void) { of_unregister_platform_driver(&hwicap_of_driver); } #else /* CONFIG_OF */ /* CONFIG_OF not enabled; do nothing helpers */ -static inline int __init hwicap_of_register(void) { return 0; } -static inline void __exit hwicap_of_unregister(void) { } +static inline int __devinit hwicap_of_register(void) { return 0; } +static inline void __devexit hwicap_of_unregister(void) { } #endif /* CONFIG_OF */ -static int __init hwicap_module_init(void) +static int __devinit hwicap_module_init(void) { dev_t devt; int retval; icap_class = class_create(THIS_MODULE, "xilinx_config"); - mutex_init(&icap_sem); if (xhwicap_major) { devt = MKDEV(xhwicap_major, xhwicap_minor); @@ -869,7 +883,7 @@ static int __init hwicap_module_init(void) return retval; } -static void __exit hwicap_module_cleanup(void) +static void __devexit hwicap_module_cleanup(void) { dev_t devt = MKDEV(xhwicap_major, xhwicap_minor); diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h index 405fee7e189b..ae771cac1629 100644 --- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h +++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h @@ -48,9 +48,9 @@ struct hwicap_drvdata { u8 write_buffer[4]; u32 read_buffer_in_use; /* Always in [0,3] */ u8 read_buffer[4]; - resource_size_t mem_start;/* phys. address of the control registers */ - resource_size_t mem_end; /* phys. address of the control registers */ - resource_size_t mem_size; + u32 mem_start; /* phys. address of the control registers */ + u32 mem_end; /* phys. address of the control registers */ + u32 mem_size; void __iomem *base_address;/* virt. address of the control registers */ struct device *dev; @@ -61,7 +61,7 @@ struct hwicap_drvdata { const struct config_registers *config_regs; void *private_data; bool is_open; - struct mutex sem; + struct semaphore sem; }; struct hwicap_driver_config { @@ -164,29 +164,29 @@ struct config_registers { #define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL /** - * hwicap_type_1_read - Generates a Type 1 read packet header. - * @reg: is the address of the register to be read back. + * hwicap_type_1_read: Generates a Type 1 read packet header. + * @parameter: Register is the address of the register to be read back. * * Generates a Type 1 read packet header, which is used to indirectly * read registers in the configuration logic. This packet must then * be sent through the icap device, and a return packet received with * the information. **/ -static inline u32 hwicap_type_1_read(u32 reg) +static inline u32 hwicap_type_1_read(u32 Register) { return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | - (reg << XHI_REGISTER_SHIFT) | + (Register << XHI_REGISTER_SHIFT) | (XHI_OP_READ << XHI_OP_SHIFT); } /** - * hwicap_type_1_write - Generates a Type 1 write packet header - * @reg: is the address of the register to be read back. + * hwicap_type_1_write: Generates a Type 1 write packet header + * @parameter: Register is the address of the register to be read back. **/ -static inline u32 hwicap_type_1_write(u32 reg) +static inline u32 hwicap_type_1_write(u32 Register) { return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | - (reg << XHI_REGISTER_SHIFT) | + (Register << XHI_REGISTER_SHIFT) | (XHI_OP_WRITE << XHI_OP_SHIFT); } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 54a0a557b678..a44b142fb460 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -173,15 +173,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, return NULL; if (write) { + struct rlimit *rlim = current->signal->rlim; unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; - struct rlimit *rlim; - - /* - * We've historically supported up to 32 pages (ARG_MAX) - * of argument strings even with small stacks - */ - if (size <= ARG_MAX) - return page; /* * Limit to 1/4-th the stack size for the argv+env strings. @@ -190,7 +183,6 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, * - the program will have a reasonable amount of stack left * to work from. */ - rlim = current->signal->rlim; if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { put_page(page); return NULL; diff --git a/trunk/include/asm-powerpc/reg.h b/trunk/include/asm-powerpc/reg.h index edc0cfd7f6e2..0d6238987df8 100644 --- a/trunk/include/asm-powerpc/reg.h +++ b/trunk/include/asm-powerpc/reg.h @@ -153,9 +153,6 @@ #define CTRL_RUNLATCH 0x1 #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ #define DABR_TRANSLATION (1UL << 2) -#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */ -#define DABRX_USER (1UL << 0) -#define DABRX_KERNEL (1UL << 1) #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define DSISR_NOHPTE 0x40000000 /* no translation found */ diff --git a/trunk/include/asm-x86/pgtable_32.h b/trunk/include/asm-x86/pgtable_32.h index a842c7222b1e..b478efa971e0 100644 --- a/trunk/include/asm-x86/pgtable_32.h +++ b/trunk/include/asm-x86/pgtable_32.h @@ -91,7 +91,9 @@ extern unsigned long pg0[]; /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ #define pmd_none(x) (!(unsigned long)pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) +#define pmd_bad(x) ((pmd_val(x) \ + & ~(PAGE_MASK | _PAGE_USER | _PAGE_PSE | _PAGE_NX)) \ + != _KERNPG_TABLE) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) diff --git a/trunk/include/asm-x86/pgtable_64.h b/trunk/include/asm-x86/pgtable_64.h index 0a0b77bc736a..0a9258333cbd 100644 --- a/trunk/include/asm-x86/pgtable_64.h +++ b/trunk/include/asm-x86/pgtable_64.h @@ -153,12 +153,14 @@ static inline unsigned long pgd_bad(pgd_t pgd) static inline unsigned long pud_bad(pud_t pud) { - return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); + return pud_val(pud) & + ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); } static inline unsigned long pmd_bad(pmd_t pmd) { - return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); + return pmd_val(pmd) & + ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); } #define pte_none(x) (!pte_val(x))