aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-03-03 13:35:38 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-03-03 13:35:38 -0500
commit5ce6386b900c83aa31d0490335df421a8d544381 (patch)
treea22ff66d0bf343db369309be84cfeced6275311c
parenta64e715fc74b1a7dcc5944f848acc38b2c4d4ee2 (diff)
parent3cecdda3f169f22f324f78fd544beee68e3cc6a4 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (24 commits) [POWERPC] Convert the cell IOMMU fixed mapping to 16M IOMMU pages [POWERPC] Allow for different IOMMU page sizes in cell IOMMU code [POWERPC] Cell IOMMU: n_pte_pages is in 4K page units, not IOMMU_PAGE_SIZE [POWERPC] Split setup of IOMMU stab and ptab, allocate dynamic/fixed ptabs separately [POWERPC] Move allocation of cell IOMMU pad page [POWERPC] Remove unused pte_offset variable [POWERPC] Use it_offset not pte_offset in cell IOMMU code [POWERPC] Clearup cell IOMMU fixed mapping terminology [POWERPC] enable hardware watchpoints on cell blades [POWERPC] move celleb DABRX definitions [POWERPC] OProfile: enable callgraph support for Cell [POWERPC] spufs: fix use time accounting on SPE-overcommit [POWERPC] spufs: serialize SLB invalidation against SLB loading [POWERPC] spufs: invalidate SLB translation before adding a new entry [POWERPC] spufs: synchronize IRQ when disabling [POWERPC] spufs: fix order of sputrace thread IDs [POWERPC] Xilinx: hwicap cleanup [POWERPC] 4xx: Use correct board info structure in cuboot wrappers [POWERPC] spufs: fix invalid scheduling of forgotten contexts [POWERPC] 44x: add missing define TARGET_4xx and TARGET_440GX to cuboot-taishan ...
-rw-r--r--arch/powerpc/boot/cuboot-bamboo.c1
-rw-r--r--arch/powerpc/boot/cuboot-ebony.c1
-rw-r--r--arch/powerpc/boot/cuboot-katmai.c1
-rw-r--r--arch/powerpc/boot/cuboot-taishan.c2
-rw-r--r--arch/powerpc/boot/cuboot-warp.c1
-rw-r--r--arch/powerpc/boot/dts/haleakala.dts2
-rw-r--r--arch/powerpc/boot/dts/katmai.dts58
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c1
-rw-r--r--arch/powerpc/platforms/cell/iommu.c151
-rw-r--r--arch/powerpc/platforms/cell/setup.c7
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c16
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c12
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c6
-rw-r--r--arch/powerpc/platforms/celleb/beat.h3
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.c80
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.c60
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c138
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.h24
-rw-r--r--include/asm-powerpc/reg.h3
23 files changed, 318 insertions, 267 deletions
diff --git a/arch/powerpc/boot/cuboot-bamboo.c b/arch/powerpc/boot/cuboot-bamboo.c
index 900c7ff2b7e9..b5c30f766c40 100644
--- a/arch/powerpc/boot/cuboot-bamboo.c
+++ b/arch/powerpc/boot/cuboot-bamboo.c
@@ -17,6 +17,7 @@
17#include "44x.h" 17#include "44x.h"
18#include "cuboot.h" 18#include "cuboot.h"
19 19
20#define TARGET_4xx
20#define TARGET_44x 21#define TARGET_44x
21#include "ppcboot.h" 22#include "ppcboot.h"
22 23
diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c
index c5f37ce172ea..56564ba37f62 100644
--- a/arch/powerpc/boot/cuboot-ebony.c
+++ b/arch/powerpc/boot/cuboot-ebony.c
@@ -17,6 +17,7 @@
17#include "44x.h" 17#include "44x.h"
18#include "cuboot.h" 18#include "cuboot.h"
19 19
20#define TARGET_4xx
20#define TARGET_44x 21#define TARGET_44x
21#include "ppcboot.h" 22#include "ppcboot.h"
22 23
diff --git a/arch/powerpc/boot/cuboot-katmai.c b/arch/powerpc/boot/cuboot-katmai.c
index c021167f9381..5434d70b5660 100644
--- a/arch/powerpc/boot/cuboot-katmai.c
+++ b/arch/powerpc/boot/cuboot-katmai.c
@@ -22,6 +22,7 @@
22#include "44x.h" 22#include "44x.h"
23#include "cuboot.h" 23#include "cuboot.h"
24 24
25#define TARGET_4xx
25#define TARGET_44x 26#define TARGET_44x
26#include "ppcboot.h" 27#include "ppcboot.h"
27 28
diff --git a/arch/powerpc/boot/cuboot-taishan.c b/arch/powerpc/boot/cuboot-taishan.c
index f66455a45ab1..b55b80467eed 100644
--- a/arch/powerpc/boot/cuboot-taishan.c
+++ b/arch/powerpc/boot/cuboot-taishan.c
@@ -21,7 +21,9 @@
21#include "dcr.h" 21#include "dcr.h"
22#include "4xx.h" 22#include "4xx.h"
23 23
24#define TARGET_4xx
24#define TARGET_44x 25#define TARGET_44x
26#define TARGET_440GX
25#include "ppcboot.h" 27#include "ppcboot.h"
26 28
27static bd_t bd; 29static bd_t bd;
diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c
index bdedebe1bc14..3db93e85e9ea 100644
--- a/arch/powerpc/boot/cuboot-warp.c
+++ b/arch/powerpc/boot/cuboot-warp.c
@@ -11,6 +11,7 @@
11#include "4xx.h" 11#include "4xx.h"
12#include "cuboot.h" 12#include "cuboot.h"
13 13
14#define TARGET_4xx
14#define TARGET_44x 15#define TARGET_44x
15#include "ppcboot.h" 16#include "ppcboot.h"
16 17
diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts
index 5dd3d15f0feb..ae68fefc01b6 100644
--- a/arch/powerpc/boot/dts/haleakala.dts
+++ b/arch/powerpc/boot/dts/haleakala.dts
@@ -235,7 +235,7 @@
235 #interrupt-cells = <1>; 235 #interrupt-cells = <1>;
236 #size-cells = <2>; 236 #size-cells = <2>;
237 #address-cells = <3>; 237 #address-cells = <3>;
238 compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex"; 238 compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
239 primary; 239 primary;
240 port = <0>; /* port number */ 240 port = <0>; /* port number */
241 reg = <a0000000 20000000 /* Config space access */ 241 reg = <a0000000 20000000 /* Config space access */
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index bc32ac7250ec..fc86e5a3afc4 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -38,8 +38,8 @@
38 timebase-frequency = <0>; /* Filled in by zImage */ 38 timebase-frequency = <0>; /* Filled in by zImage */
39 i-cache-line-size = <20>; 39 i-cache-line-size = <20>;
40 d-cache-line-size = <20>; 40 d-cache-line-size = <20>;
41 i-cache-size = <20000>; 41 i-cache-size = <8000>;
42 d-cache-size = <20000>; 42 d-cache-size = <8000>;
43 dcr-controller; 43 dcr-controller;
44 dcr-access-method = "native"; 44 dcr-access-method = "native";
45 }; 45 };
@@ -136,11 +136,11 @@
136 }; 136 };
137 137
138 POB0: opb { 138 POB0: opb {
139 compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; 139 compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
140 #address-cells = <1>; 140 #address-cells = <1>;
141 #size-cells = <1>; 141 #size-cells = <1>;
142 ranges = <00000000 4 e0000000 20000000>; 142 ranges = <00000000 4 e0000000 20000000>;
143 clock-frequency = <0>; /* Filled in by zImage */ 143 clock-frequency = <0>; /* Filled in by zImage */
144 144
145 EBC0: ebc { 145 EBC0: ebc {
146 compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; 146 compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
@@ -153,38 +153,38 @@
153 }; 153 };
154 154
155 UART0: serial@10000200 { 155 UART0: serial@10000200 {
156 device_type = "serial"; 156 device_type = "serial";
157 compatible = "ns16550"; 157 compatible = "ns16550";
158 reg = <10000200 8>; 158 reg = <10000200 8>;
159 virtual-reg = <a0000200>; 159 virtual-reg = <a0000200>;
160 clock-frequency = <0>; /* Filled in by zImage */ 160 clock-frequency = <0>; /* Filled in by zImage */
161 current-speed = <1c200>; 161 current-speed = <1c200>;
162 interrupt-parent = <&UIC0>; 162 interrupt-parent = <&UIC0>;
163 interrupts = <0 4>; 163 interrupts = <0 4>;
164 }; 164 };
165 165
166 UART1: serial@10000300 { 166 UART1: serial@10000300 {
167 device_type = "serial"; 167 device_type = "serial";
168 compatible = "ns16550"; 168 compatible = "ns16550";
169 reg = <10000300 8>; 169 reg = <10000300 8>;
170 virtual-reg = <a0000300>; 170 virtual-reg = <a0000300>;
171 clock-frequency = <0>; 171 clock-frequency = <0>;
172 current-speed = <0>; 172 current-speed = <0>;
173 interrupt-parent = <&UIC0>; 173 interrupt-parent = <&UIC0>;
174 interrupts = <1 4>; 174 interrupts = <1 4>;
175 }; 175 };
176 176
177 177
178 UART2: serial@10000600 { 178 UART2: serial@10000600 {
179 device_type = "serial"; 179 device_type = "serial";
180 compatible = "ns16550"; 180 compatible = "ns16550";
181 reg = <10000600 8>; 181 reg = <10000600 8>;
182 virtual-reg = <a0000600>; 182 virtual-reg = <a0000600>;
183 clock-frequency = <0>; 183 clock-frequency = <0>;
184 current-speed = <0>; 184 current-speed = <0>;
185 interrupt-parent = <&UIC1>; 185 interrupt-parent = <&UIC1>;
186 interrupts = <5 4>; 186 interrupts = <5 4>;
187 }; 187 };
188 188
189 IIC0: i2c@10000400 { 189 IIC0: i2c@10000400 {
190 compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; 190 compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index 13929771bee7..9eed1f68fcab 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs,
1151 for (i = 0; i < num_counters; ++i) { 1151 for (i = 0; i < num_counters; ++i) {
1152 if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i)) 1152 if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i))
1153 && ctr[i].enabled) { 1153 && ctr[i].enabled) {
1154 oprofile_add_pc(pc, is_kernel, i); 1154 oprofile_add_ext_sample(pc, regs, i, is_kernel);
1155 cbe_write_ctr(cpu, i, reset_value[i]); 1155 cbe_write_ctr(cpu, i, reset_value[i]);
1156 } 1156 }
1157 } 1157 }
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 9aa4425d80b2..4d5fd1dbd400 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -199,6 +199,7 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
199 199
200 return 0; 200 return 0;
201} 201}
202EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
202 203
203/** 204/**
204 * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer 205 * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index edab631a8dcb..20ea0e118f24 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -113,7 +113,7 @@
113 113
114/* IOMMU sizing */ 114/* IOMMU sizing */
115#define IO_SEGMENT_SHIFT 28 115#define IO_SEGMENT_SHIFT 28
116#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT) 116#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift))
117 117
118/* The high bit needs to be set on every DMA address */ 118/* The high bit needs to be set on every DMA address */
119#define SPIDER_DMA_OFFSET 0x80000000ul 119#define SPIDER_DMA_OFFSET 0x80000000ul
@@ -123,7 +123,6 @@ struct iommu_window {
123 struct cbe_iommu *iommu; 123 struct cbe_iommu *iommu;
124 unsigned long offset; 124 unsigned long offset;
125 unsigned long size; 125 unsigned long size;
126 unsigned long pte_offset;
127 unsigned int ioid; 126 unsigned int ioid;
128 struct iommu_table table; 127 struct iommu_table table;
129}; 128};
@@ -200,7 +199,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
200 (window->ioid & IOPTE_IOID_Mask); 199 (window->ioid & IOPTE_IOID_Mask);
201#endif 200#endif
202 201
203 io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); 202 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
204 203
205 for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) 204 for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
206 io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); 205 io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
@@ -232,7 +231,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
232 | (window->ioid & IOPTE_IOID_Mask); 231 | (window->ioid & IOPTE_IOID_Mask);
233#endif 232#endif
234 233
235 io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); 234 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
236 235
237 for (i = 0; i < npages; i++) 236 for (i = 0; i < npages; i++)
238 io_pte[i] = pte; 237 io_pte[i] = pte;
@@ -307,76 +306,84 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
307 return -ENODEV; 306 return -ENODEV;
308} 307}
309 308
310static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu, 309static void cell_iommu_setup_stab(struct cbe_iommu *iommu,
311 unsigned long dbase, unsigned long dsize, 310 unsigned long dbase, unsigned long dsize,
312 unsigned long fbase, unsigned long fsize) 311 unsigned long fbase, unsigned long fsize)
313{ 312{
314 struct page *page; 313 struct page *page;
315 int i; 314 unsigned long segments, stab_size;
316 unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
317 n_pte_pages, base;
318
319 base = dbase;
320 if (fsize != 0)
321 base = min(fbase, dbase);
322 315
323 segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT; 316 segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;
324 pages_per_segment = 1ull << IO_PAGENO_BITS;
325 317
326 pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n", 318 pr_debug("%s: iommu[%d]: segments: %lu\n",
327 __FUNCTION__, iommu->nid, segments, pages_per_segment); 319 __FUNCTION__, iommu->nid, segments);
328 320
329 /* set up the segment table */ 321 /* set up the segment table */
330 stab_size = segments * sizeof(unsigned long); 322 stab_size = segments * sizeof(unsigned long);
331 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); 323 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
332 BUG_ON(!page); 324 BUG_ON(!page);
333 iommu->stab = page_address(page); 325 iommu->stab = page_address(page);
334 clear_page(iommu->stab); 326 memset(iommu->stab, 0, stab_size);
327}
328
329static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
330 unsigned long base, unsigned long size, unsigned long gap_base,
331 unsigned long gap_size, unsigned long page_shift)
332{
333 struct page *page;
334 int i;
335 unsigned long reg, segments, pages_per_segment, ptab_size,
336 n_pte_pages, start_seg, *ptab;
337
338 start_seg = base >> IO_SEGMENT_SHIFT;
339 segments = size >> IO_SEGMENT_SHIFT;
340 pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift);
341 /* PTEs for each segment must start on a 4K bounday */
342 pages_per_segment = max(pages_per_segment,
343 (1 << 12) / sizeof(unsigned long));
335 344
336 /* ... and the page tables. Since these are contiguous, we can treat
337 * the page tables as one array of ptes, like pSeries does.
338 */
339 ptab_size = segments * pages_per_segment * sizeof(unsigned long); 345 ptab_size = segments * pages_per_segment * sizeof(unsigned long);
340 pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__, 346 pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
341 iommu->nid, ptab_size, get_order(ptab_size)); 347 iommu->nid, ptab_size, get_order(ptab_size));
342 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size)); 348 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
343 BUG_ON(!page); 349 BUG_ON(!page);
344 350
345 iommu->ptab = page_address(page); 351 ptab = page_address(page);
346 memset(iommu->ptab, 0, ptab_size); 352 memset(ptab, 0, ptab_size);
347 353
348 /* allocate a bogus page for the end of each mapping */ 354 /* number of 4K pages needed for a page table */
349 page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); 355 n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12;
350 BUG_ON(!page);
351 iommu->pad_page = page_address(page);
352 clear_page(iommu->pad_page);
353
354 /* number of pages needed for a page table */
355 n_pte_pages = (pages_per_segment *
356 sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
357 356
358 pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n", 357 pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
359 __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab, 358 __FUNCTION__, iommu->nid, iommu->stab, ptab,
360 n_pte_pages); 359 n_pte_pages);
361 360
362 /* initialise the STEs */ 361 /* initialise the STEs */
363 reg = IOSTE_V | ((n_pte_pages - 1) << 5); 362 reg = IOSTE_V | ((n_pte_pages - 1) << 5);
364 363
365 if (IOMMU_PAGE_SIZE == 0x1000) 364 switch (page_shift) {
366 reg |= IOSTE_PS_4K; 365 case 12: reg |= IOSTE_PS_4K; break;
367 else if (IOMMU_PAGE_SIZE == 0x10000) 366 case 16: reg |= IOSTE_PS_64K; break;
368 reg |= IOSTE_PS_64K; 367 case 20: reg |= IOSTE_PS_1M; break;
369 else { 368 case 24: reg |= IOSTE_PS_16M; break;
370 extern void __unknown_page_size_error(void); 369 default: BUG();
371 __unknown_page_size_error();
372 } 370 }
373 371
372 gap_base = gap_base >> IO_SEGMENT_SHIFT;
373 gap_size = gap_size >> IO_SEGMENT_SHIFT;
374
374 pr_debug("Setting up IOMMU stab:\n"); 375 pr_debug("Setting up IOMMU stab:\n");
375 for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) { 376 for (i = start_seg; i < (start_seg + segments); i++) {
376 iommu->stab[i] = reg | 377 if (i >= gap_base && i < (gap_base + gap_size)) {
377 (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i); 378 pr_debug("\toverlap at %d, skipping\n", i);
379 continue;
380 }
381 iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) *
382 (i - start_seg));
378 pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]); 383 pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
379 } 384 }
385
386 return ptab;
380} 387}
381 388
382static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) 389static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
@@ -423,7 +430,9 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
423static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, 430static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
424 unsigned long base, unsigned long size) 431 unsigned long base, unsigned long size)
425{ 432{
426 cell_iommu_setup_page_tables(iommu, base, size, 0, 0); 433 cell_iommu_setup_stab(iommu, base, size, 0, 0);
434 iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0,
435 IOMMU_PAGE_SHIFT);
427 cell_iommu_enable_hardware(iommu); 436 cell_iommu_enable_hardware(iommu);
428} 437}
429 438
@@ -464,6 +473,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
464 unsigned long pte_offset) 473 unsigned long pte_offset)
465{ 474{
466 struct iommu_window *window; 475 struct iommu_window *window;
476 struct page *page;
467 u32 ioid; 477 u32 ioid;
468 478
469 ioid = cell_iommu_get_ioid(np); 479 ioid = cell_iommu_get_ioid(np);
@@ -475,13 +485,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
475 window->size = size; 485 window->size = size;
476 window->ioid = ioid; 486 window->ioid = ioid;
477 window->iommu = iommu; 487 window->iommu = iommu;
478 window->pte_offset = pte_offset;
479 488
480 window->table.it_blocksize = 16; 489 window->table.it_blocksize = 16;
481 window->table.it_base = (unsigned long)iommu->ptab; 490 window->table.it_base = (unsigned long)iommu->ptab;
482 window->table.it_index = iommu->nid; 491 window->table.it_index = iommu->nid;
483 window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + 492 window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset;
484 window->pte_offset;
485 window->table.it_size = size >> IOMMU_PAGE_SHIFT; 493 window->table.it_size = size >> IOMMU_PAGE_SHIFT;
486 494
487 iommu_init_table(&window->table, iommu->nid); 495 iommu_init_table(&window->table, iommu->nid);
@@ -504,6 +512,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
504 * This code also assumes that we have a window that starts at 0, 512 * This code also assumes that we have a window that starts at 0,
505 * which is the case on all spider based blades. 513 * which is the case on all spider based blades.
506 */ 514 */
515 page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
516 BUG_ON(!page);
517 iommu->pad_page = page_address(page);
518 clear_page(iommu->pad_page);
519
507 __set_bit(0, window->table.it_map); 520 __set_bit(0, window->table.it_map);
508 tce_build_cell(&window->table, window->table.it_offset, 1, 521 tce_build_cell(&window->table, window->table.it_offset, 1,
509 (unsigned long)iommu->pad_page, DMA_TO_DEVICE); 522 (unsigned long)iommu->pad_page, DMA_TO_DEVICE);
@@ -549,7 +562,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
549 archdata->dma_data = &window->table; 562 archdata->dma_data = &window->table;
550} 563}
551 564
552static void cell_dma_dev_setup_static(struct device *dev); 565static void cell_dma_dev_setup_fixed(struct device *dev);
553 566
554static void cell_dma_dev_setup(struct device *dev) 567static void cell_dma_dev_setup(struct device *dev)
555{ 568{
@@ -557,7 +570,7 @@ static void cell_dma_dev_setup(struct device *dev)
557 570
558 /* Order is important here, these are not mutually exclusive */ 571 /* Order is important here, these are not mutually exclusive */
559 if (get_dma_ops(dev) == &dma_iommu_fixed_ops) 572 if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
560 cell_dma_dev_setup_static(dev); 573 cell_dma_dev_setup_fixed(dev);
561 else if (get_pci_dma_ops() == &dma_iommu_ops) 574 else if (get_pci_dma_ops() == &dma_iommu_ops)
562 cell_dma_dev_setup_iommu(dev); 575 cell_dma_dev_setup_iommu(dev);
563 else if (get_pci_dma_ops() == &dma_direct_ops) 576 else if (get_pci_dma_ops() == &dma_direct_ops)
@@ -858,7 +871,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
858 return 0; 871 return 0;
859} 872}
860 873
861static void cell_dma_dev_setup_static(struct device *dev) 874static void cell_dma_dev_setup_fixed(struct device *dev)
862{ 875{
863 struct dev_archdata *archdata = &dev->archdata; 876 struct dev_archdata *archdata = &dev->archdata;
864 u64 addr; 877 u64 addr;
@@ -869,35 +882,45 @@ static void cell_dma_dev_setup_static(struct device *dev)
869 dev_dbg(dev, "iommu: fixed addr = %lx\n", addr); 882 dev_dbg(dev, "iommu: fixed addr = %lx\n", addr);
870} 883}
871 884
885static void insert_16M_pte(unsigned long addr, unsigned long *ptab,
886 unsigned long base_pte)
887{
888 unsigned long segment, offset;
889
890 segment = addr >> IO_SEGMENT_SHIFT;
891 offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24));
892 ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long));
893
894 pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
895 addr, ptab, segment, offset);
896
897 ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask);
898}
899
872static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, 900static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
873 struct device_node *np, unsigned long dbase, unsigned long dsize, 901 struct device_node *np, unsigned long dbase, unsigned long dsize,
874 unsigned long fbase, unsigned long fsize) 902 unsigned long fbase, unsigned long fsize)
875{ 903{
876 unsigned long base_pte, uaddr, *io_pte; 904 unsigned long base_pte, uaddr, ioaddr, *ptab;
877 int i;
878 905
879 dma_iommu_fixed_base = fbase; 906 ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24);
880 907
881 /* convert from bytes into page table indices */ 908 dma_iommu_fixed_base = fbase;
882 dbase = dbase >> IOMMU_PAGE_SHIFT;
883 dsize = dsize >> IOMMU_PAGE_SHIFT;
884 fbase = fbase >> IOMMU_PAGE_SHIFT;
885 fsize = fsize >> IOMMU_PAGE_SHIFT;
886 909
887 pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase); 910 pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
888 911
889 io_pte = iommu->ptab;
890 base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW 912 base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
891 | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask); 913 | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
892 914
893 uaddr = 0; 915 for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
894 for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
895 /* Don't touch the dynamic region */ 916 /* Don't touch the dynamic region */
896 if (i >= dbase && i < (dbase + dsize)) { 917 ioaddr = uaddr + fbase;
897 pr_debug("iommu: static/dynamic overlap, skipping\n"); 918 if (ioaddr >= dbase && ioaddr < (dbase + dsize)) {
919 pr_debug("iommu: fixed/dynamic overlap, skipping\n");
898 continue; 920 continue;
899 } 921 }
900 io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); 922
923 insert_16M_pte(uaddr, ptab, base_pte);
901 } 924 }
902 925
903 mb(); 926 mb();
@@ -995,7 +1018,9 @@ static int __init cell_iommu_fixed_mapping_init(void)
995 "fixed window 0x%lx-0x%lx\n", iommu->nid, dbase, 1018 "fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
996 dbase + dsize, fbase, fbase + fsize); 1019 dbase + dsize, fbase, fbase + fsize);
997 1020
998 cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize); 1021 cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize);
1022 iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0,
1023 IOMMU_PAGE_SHIFT);
999 cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize, 1024 cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
1000 fbase, fsize); 1025 fbase, fsize);
1001 cell_iommu_enable_hardware(iommu); 1026 cell_iommu_enable_hardware(iommu);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index a7f609b3b876..dda34650cb07 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -149,6 +149,11 @@ static void __init cell_init_irq(void)
149 mpic_init_IRQ(); 149 mpic_init_IRQ();
150} 150}
151 151
152static void __init cell_set_dabrx(void)
153{
154 mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
155}
156
152static void __init cell_setup_arch(void) 157static void __init cell_setup_arch(void)
153{ 158{
154#ifdef CONFIG_SPU_BASE 159#ifdef CONFIG_SPU_BASE
@@ -158,6 +163,8 @@ static void __init cell_setup_arch(void)
158 163
159 cbe_regs_init(); 164 cbe_regs_init();
160 165
166 cell_set_dabrx();
167
161#ifdef CONFIG_CBE_RAS 168#ifdef CONFIG_CBE_RAS
162 cbe_ras_init(); 169 cbe_ras_init();
163#endif 170#endif
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 87eb07f94c5f..712001f6b7da 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -81,9 +81,12 @@ struct spu_slb {
81void spu_invalidate_slbs(struct spu *spu) 81void spu_invalidate_slbs(struct spu *spu)
82{ 82{
83 struct spu_priv2 __iomem *priv2 = spu->priv2; 83 struct spu_priv2 __iomem *priv2 = spu->priv2;
84 unsigned long flags;
84 85
86 spin_lock_irqsave(&spu->register_lock, flags);
85 if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) 87 if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
86 out_be64(&priv2->slb_invalidate_all_W, 0UL); 88 out_be64(&priv2->slb_invalidate_all_W, 0UL);
89 spin_unlock_irqrestore(&spu->register_lock, flags);
87} 90}
88EXPORT_SYMBOL_GPL(spu_invalidate_slbs); 91EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
89 92
@@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
148 __func__, slbe, slb->vsid, slb->esid); 151 __func__, slbe, slb->vsid, slb->esid);
149 152
150 out_be64(&priv2->slb_index_W, slbe); 153 out_be64(&priv2->slb_index_W, slbe);
154 /* set invalid before writing vsid */
155 out_be64(&priv2->slb_esid_RW, 0);
156 /* now it's safe to write the vsid */
151 out_be64(&priv2->slb_vsid_RW, slb->vsid); 157 out_be64(&priv2->slb_vsid_RW, slb->vsid);
158 /* setting the new esid makes the entry valid again */
152 out_be64(&priv2->slb_esid_RW, slb->esid); 159 out_be64(&priv2->slb_esid_RW, slb->esid);
153} 160}
154 161
@@ -290,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
290 nr_slbs++; 297 nr_slbs++;
291 } 298 }
292 299
300 spin_lock_irq(&spu->register_lock);
293 /* Add the set of SLBs */ 301 /* Add the set of SLBs */
294 for (i = 0; i < nr_slbs; i++) 302 for (i = 0; i < nr_slbs; i++)
295 spu_load_slb(spu, i, &slbs[i]); 303 spu_load_slb(spu, i, &slbs[i]);
304 spin_unlock_irq(&spu->register_lock);
296} 305}
297EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs); 306EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
298 307
@@ -337,13 +346,14 @@ spu_irq_class_1(int irq, void *data)
337 if (stat & CLASS1_STORAGE_FAULT_INTR) 346 if (stat & CLASS1_STORAGE_FAULT_INTR)
338 spu_mfc_dsisr_set(spu, 0ul); 347 spu_mfc_dsisr_set(spu, 0ul);
339 spu_int_stat_clear(spu, 1, stat); 348 spu_int_stat_clear(spu, 1, stat);
340 spin_unlock(&spu->register_lock);
341 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
342 dar, dsisr);
343 349
344 if (stat & CLASS1_SEGMENT_FAULT_INTR) 350 if (stat & CLASS1_SEGMENT_FAULT_INTR)
345 __spu_trap_data_seg(spu, dar); 351 __spu_trap_data_seg(spu, dar);
346 352
353 spin_unlock(&spu->register_lock);
354 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
355 dar, dsisr);
356
347 if (stat & CLASS1_STORAGE_FAULT_INTR) 357 if (stat & CLASS1_STORAGE_FAULT_INTR)
348 __spu_trap_data_map(spu, dar, dsisr); 358 __spu_trap_data_map(spu, dar, dsisr);
349 359
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 133995ed5cc7..cf6c2c89211d 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -109,13 +109,12 @@ void spu_forget(struct spu_context *ctx)
109 109
110 /* 110 /*
111 * This is basically an open-coded spu_acquire_saved, except that 111 * This is basically an open-coded spu_acquire_saved, except that
112 * we don't acquire the state mutex interruptible. 112 * we don't acquire the state mutex interruptible, and we don't
113 * want this context to be rescheduled on release.
113 */ 114 */
114 mutex_lock(&ctx->state_mutex); 115 mutex_lock(&ctx->state_mutex);
115 if (ctx->state != SPU_STATE_SAVED) { 116 if (ctx->state != SPU_STATE_SAVED)
116 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
117 spu_deactivate(ctx); 117 spu_deactivate(ctx);
118 }
119 118
120 mm = ctx->owner; 119 mm = ctx->owner;
121 ctx->owner = NULL; 120 ctx->owner = NULL;
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index c66c3756970d..f7a7e8635fb6 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -367,6 +367,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
367 return NOPFN_SIGBUS; 367 return NOPFN_SIGBUS;
368 368
369 /* 369 /*
370 * Because we release the mmap_sem, the context may be destroyed while
371 * we're in spu_wait. Grab an extra reference so it isn't destroyed
372 * in the meantime.
373 */
374 get_spu_context(ctx);
375
376 /*
370 * We have to wait for context to be loaded before we have 377 * We have to wait for context to be loaded before we have
371 * pages to hand out to the user, but we don't want to wait 378 * pages to hand out to the user, but we don't want to wait
372 * with the mmap_sem held. 379 * with the mmap_sem held.
@@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
375 * hanged. 382 * hanged.
376 */ 383 */
377 if (spu_acquire(ctx)) 384 if (spu_acquire(ctx))
378 return NOPFN_REFAULT; 385 goto refault;
379 386
380 if (ctx->state == SPU_STATE_SAVED) { 387 if (ctx->state == SPU_STATE_SAVED) {
381 up_read(&current->mm->mmap_sem); 388 up_read(&current->mm->mmap_sem);
@@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
391 398
392 if (!ret) 399 if (!ret)
393 spu_release(ctx); 400 spu_release(ctx);
401
402refault:
403 put_spu_context(ctx);
394 return NOPFN_REFAULT; 404 return NOPFN_REFAULT;
395} 405}
396 406
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 3a5972117de7..5d5f680cd0b8 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
246 spu_switch_notify(spu, ctx); 246 spu_switch_notify(spu, ctx);
247 ctx->state = SPU_STATE_RUNNABLE; 247 ctx->state = SPU_STATE_RUNNABLE;
248 248
249 spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); 249 spuctx_switch_state(ctx, SPU_UTIL_USER);
250} 250}
251 251
252/* 252/*
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
index 01974f7776e1..79aa773f3c99 100644
--- a/arch/powerpc/platforms/cell/spufs/sputrace.c
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n)
58 ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start)); 58 ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
59 59
60 return snprintf(tbuf, n, 60 return snprintf(tbuf, n,
61 "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n", 61 "[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n",
62 (unsigned long) tv.tv_sec, 62 (unsigned long) tv.tv_sec,
63 (unsigned long) tv.tv_nsec, 63 (unsigned long) tv.tv_nsec,
64 t->owner_tid,
65 t->name,
66 t->curr_tid, 64 t->curr_tid,
65 t->name,
66 t->owner_tid,
67 t->number); 67 t->number);
68} 68}
69 69
@@ -188,6 +188,7 @@ struct spu_probe spu_probes[] = {
188 { "spufs_ps_nopfn__insert", "%p %p", spu_context_event }, 188 { "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
189 { "spu_acquire_saved__enter", "%p", spu_context_nospu_event }, 189 { "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
190 { "destroy_spu_context__enter", "%p", spu_context_nospu_event }, 190 { "destroy_spu_context__enter", "%p", spu_context_nospu_event },
191 { "spufs_stop_callback__enter", "%p %p", spu_context_event },
191}; 192};
192 193
193static int __init sputrace_init(void) 194static int __init sputrace_init(void)
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 6f5886c7b1f9..e9dc7a55d1b9 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -34,6 +34,7 @@
34 34
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <linux/hardirq.h>
37#include <linux/sched.h> 38#include <linux/sched.h>
38#include <linux/kernel.h> 39#include <linux/kernel.h>
39#include <linux/mm.h> 40#include <linux/mm.h>
@@ -117,6 +118,8 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
117 * Write INT_MASK_class1 with value of 0. 118 * Write INT_MASK_class1 with value of 0.
118 * Save INT_Mask_class2 in CSA. 119 * Save INT_Mask_class2 in CSA.
119 * Write INT_MASK_class2 with value of 0. 120 * Write INT_MASK_class2 with value of 0.
121 * Synchronize all three interrupts to be sure
122 * we no longer execute a handler on another CPU.
120 */ 123 */
121 spin_lock_irq(&spu->register_lock); 124 spin_lock_irq(&spu->register_lock);
122 if (csa) { 125 if (csa) {
@@ -129,6 +132,9 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
129 spu_int_mask_set(spu, 2, 0ul); 132 spu_int_mask_set(spu, 2, 0ul);
130 eieio(); 133 eieio();
131 spin_unlock_irq(&spu->register_lock); 134 spin_unlock_irq(&spu->register_lock);
135 synchronize_irq(spu->irqs[0]);
136 synchronize_irq(spu->irqs[1]);
137 synchronize_irq(spu->irqs[2]);
132} 138}
133 139
134static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu) 140static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)
diff --git a/arch/powerpc/platforms/celleb/beat.h b/arch/powerpc/platforms/celleb/beat.h
index b2e292df13ca..ac82ac35b991 100644
--- a/arch/powerpc/platforms/celleb/beat.h
+++ b/arch/powerpc/platforms/celleb/beat.h
@@ -21,9 +21,6 @@
21#ifndef _CELLEB_BEAT_H 21#ifndef _CELLEB_BEAT_H
22#define _CELLEB_BEAT_H 22#define _CELLEB_BEAT_H
23 23
24#define DABRX_KERNEL (1UL<<1)
25#define DABRX_USER (1UL<<0)
26
27int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*); 24int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*);
28int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t); 25int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t);
29int64_t beat_repository_encode(int, const char *, uint64_t[4]); 26int64_t beat_repository_encode(int, const char *, uint64_t[4]);
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c
index dfea2bde162b..f577daedb630 100644
--- a/drivers/char/xilinx_hwicap/buffer_icap.c
+++ b/drivers/char/xilinx_hwicap/buffer_icap.c
@@ -73,8 +73,8 @@
73#define XHI_BUFFER_START 0 73#define XHI_BUFFER_START 0
74 74
75/** 75/**
76 * buffer_icap_get_status: Get the contents of the status register. 76 * buffer_icap_get_status - Get the contents of the status register.
77 * @parameter base_address: is the base address of the device 77 * @base_address: is the base address of the device
78 * 78 *
79 * The status register contains the ICAP status and the done bit. 79 * The status register contains the ICAP status and the done bit.
80 * 80 *
@@ -94,9 +94,9 @@ static inline u32 buffer_icap_get_status(void __iomem *base_address)
94} 94}
95 95
96/** 96/**
97 * buffer_icap_get_bram: Reads data from the storage buffer bram. 97 * buffer_icap_get_bram - Reads data from the storage buffer bram.
98 * @parameter base_address: contains the base address of the component. 98 * @base_address: contains the base address of the component.
99 * @parameter offset: The word offset from which the data should be read. 99 * @offset: The word offset from which the data should be read.
100 * 100 *
101 * A bram is used as a configuration memory cache. One frame of data can 101 * A bram is used as a configuration memory cache. One frame of data can
102 * be stored in this "storage buffer". 102 * be stored in this "storage buffer".
@@ -108,8 +108,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address,
108} 108}
109 109
110/** 110/**
111 * buffer_icap_busy: Return true if the icap device is busy 111 * buffer_icap_busy - Return true if the icap device is busy
112 * @parameter base_address: is the base address of the device 112 * @base_address: is the base address of the device
113 * 113 *
114 * The queries the low order bit of the status register, which 114 * The queries the low order bit of the status register, which
115 * indicates whether the current configuration or readback operation 115 * indicates whether the current configuration or readback operation
@@ -121,8 +121,8 @@ static inline bool buffer_icap_busy(void __iomem *base_address)
121} 121}
122 122
123/** 123/**
124 * buffer_icap_busy: Return true if the icap device is not busy 124 * buffer_icap_busy - Return true if the icap device is not busy
125 * @parameter base_address: is the base address of the device 125 * @base_address: is the base address of the device
126 * 126 *
127 * The queries the low order bit of the status register, which 127 * The queries the low order bit of the status register, which
128 * indicates whether the current configuration or readback operation 128 * indicates whether the current configuration or readback operation
@@ -134,9 +134,9 @@ static inline bool buffer_icap_done(void __iomem *base_address)
134} 134}
135 135
136/** 136/**
137 * buffer_icap_set_size: Set the size register. 137 * buffer_icap_set_size - Set the size register.
138 * @parameter base_address: is the base address of the device 138 * @base_address: is the base address of the device
139 * @parameter data: The size in bytes. 139 * @data: The size in bytes.
140 * 140 *
141 * The size register holds the number of 8 bit bytes to transfer between 141 * The size register holds the number of 8 bit bytes to transfer between
142 * bram and the icap (or icap to bram). 142 * bram and the icap (or icap to bram).
@@ -148,9 +148,9 @@ static inline void buffer_icap_set_size(void __iomem *base_address,
148} 148}
149 149
150/** 150/**
151 * buffer_icap_mSetoffsetReg: Set the bram offset register. 151 * buffer_icap_set_offset - Set the bram offset register.
152 * @parameter base_address: contains the base address of the device. 152 * @base_address: contains the base address of the device.
153 * @parameter data: is the value to be written to the data register. 153 * @data: is the value to be written to the data register.
154 * 154 *
155 * The bram offset register holds the starting bram address to transfer 155 * The bram offset register holds the starting bram address to transfer
156 * data from during configuration or write data to during readback. 156 * 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,
162} 162}
163 163
164/** 164/**
165 * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register. 165 * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register.
166 * @parameter base_address: contains the base address of the device. 166 * @base_address: contains the base address of the device.
167 * @parameter data: is the value to be written to the data register. 167 * @data: is the value to be written to the data register.
168 * 168 *
169 * The RNC register determines the direction of the data transfer. It 169 * The RNC register determines the direction of the data transfer. It
170 * controls whether a configuration or readback take place. Writing to 170 * 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,
178} 178}
179 179
180/** 180/**
181 * buffer_icap_set_bram: Write data to the storage buffer bram. 181 * buffer_icap_set_bram - Write data to the storage buffer bram.
182 * @parameter base_address: contains the base address of the component. 182 * @base_address: contains the base address of the component.
183 * @parameter offset: The word offset at which the data should be written. 183 * @offset: The word offset at which the data should be written.
184 * @parameter data: The value to be written to the bram offset. 184 * @data: The value to be written to the bram offset.
185 * 185 *
186 * A bram is used as a configuration memory cache. One frame of data can 186 * A bram is used as a configuration memory cache. One frame of data can
187 * be stored in this "storage buffer". 187 * be stored in this "storage buffer".
@@ -193,10 +193,10 @@ static inline void buffer_icap_set_bram(void __iomem *base_address,
193} 193}
194 194
195/** 195/**
196 * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer. 196 * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer.
197 * @parameter drvdata: a pointer to the drvdata. 197 * @drvdata: a pointer to the drvdata.
198 * @parameter offset: The storage buffer start address. 198 * @offset: The storage buffer start address.
199 * @parameter count: The number of words (32 bit) to read from the 199 * @count: The number of words (32 bit) to read from the
200 * device (ICAP). 200 * device (ICAP).
201 **/ 201 **/
202static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, 202static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
@@ -227,10 +227,10 @@ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
227}; 227};
228 228
229/** 229/**
230 * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer. 230 * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer.
231 * @parameter drvdata: a pointer to the drvdata. 231 * @drvdata: a pointer to the drvdata.
232 * @parameter offset: The storage buffer start address. 232 * @offset: The storage buffer start address.
233 * @parameter count: The number of words (32 bit) to read from the 233 * @count: The number of words (32 bit) to read from the
234 * device (ICAP). 234 * device (ICAP).
235 **/ 235 **/
236static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, 236static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
@@ -261,8 +261,8 @@ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
261}; 261};
262 262
263/** 263/**
264 * buffer_icap_reset: Reset the logic of the icap device. 264 * buffer_icap_reset - Reset the logic of the icap device.
265 * @parameter drvdata: a pointer to the drvdata. 265 * @drvdata: a pointer to the drvdata.
266 * 266 *
267 * Writing to the status register resets the ICAP logic in an internal 267 * Writing to the status register resets the ICAP logic in an internal
268 * version of the core. For the version of the core published in EDK, 268 * 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)
274} 274}
275 275
276/** 276/**
277 * buffer_icap_set_configuration: Load a partial bitstream from system memory. 277 * buffer_icap_set_configuration - Load a partial bitstream from system memory.
278 * @parameter drvdata: a pointer to the drvdata. 278 * @drvdata: a pointer to the drvdata.
279 * @parameter data: Kernel address of the partial bitstream. 279 * @data: Kernel address of the partial bitstream.
280 * @parameter size: the size of the partial bitstream in 32 bit words. 280 * @size: the size of the partial bitstream in 32 bit words.
281 **/ 281 **/
282int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, 282int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
283 u32 size) 283 u32 size)
@@ -333,10 +333,10 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
333}; 333};
334 334
335/** 335/**
336 * buffer_icap_get_configuration: Read configuration data from the device. 336 * buffer_icap_get_configuration - Read configuration data from the device.
337 * @parameter drvdata: a pointer to the drvdata. 337 * @drvdata: a pointer to the drvdata.
338 * @parameter data: Address of the data representing the partial bitstream 338 * @data: Address of the data representing the partial bitstream
339 * @parameter size: the size of the partial bitstream in 32 bit words. 339 * @size: the size of the partial bitstream in 32 bit words.
340 **/ 340 **/
341int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, 341int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
342 u32 size) 342 u32 size)
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c
index 0988314694a6..6f45dbd47125 100644
--- a/drivers/char/xilinx_hwicap/fifo_icap.c
+++ b/drivers/char/xilinx_hwicap/fifo_icap.c
@@ -94,9 +94,9 @@
94 94
95 95
96/** 96/**
97 * fifo_icap_fifo_write: Write data to the write FIFO. 97 * fifo_icap_fifo_write - Write data to the write FIFO.
98 * @parameter drvdata: a pointer to the drvdata. 98 * @drvdata: a pointer to the drvdata.
99 * @parameter data: the 32-bit value to be written to the FIFO. 99 * @data: the 32-bit value to be written to the FIFO.
100 * 100 *
101 * This function will silently fail if the fifo is full. 101 * This function will silently fail if the fifo is full.
102 **/ 102 **/
@@ -108,8 +108,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
108} 108}
109 109
110/** 110/**
111 * fifo_icap_fifo_read: Read data from the Read FIFO. 111 * fifo_icap_fifo_read - Read data from the Read FIFO.
112 * @parameter drvdata: a pointer to the drvdata. 112 * @drvdata: a pointer to the drvdata.
113 * 113 *
114 * This function will silently fail if the fifo is empty. 114 * This function will silently fail if the fifo is empty.
115 **/ 115 **/
@@ -121,9 +121,9 @@ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
121} 121}
122 122
123/** 123/**
124 * fifo_icap_set_read_size: Set the the size register. 124 * fifo_icap_set_read_size - Set the the size register.
125 * @parameter drvdata: a pointer to the drvdata. 125 * @drvdata: a pointer to the drvdata.
126 * @parameter data: the size of the following read transaction, in words. 126 * @data: the size of the following read transaction, in words.
127 **/ 127 **/
128static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, 128static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
129 u32 data) 129 u32 data)
@@ -132,8 +132,8 @@ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
132} 132}
133 133
134/** 134/**
135 * fifo_icap_start_config: Initiate a configuration (write) to the device. 135 * fifo_icap_start_config - Initiate a configuration (write) to the device.
136 * @parameter drvdata: a pointer to the drvdata. 136 * @drvdata: a pointer to the drvdata.
137 **/ 137 **/
138static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) 138static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
139{ 139{
@@ -142,8 +142,8 @@ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
142} 142}
143 143
144/** 144/**
145 * fifo_icap_start_readback: Initiate a readback from the device. 145 * fifo_icap_start_readback - Initiate a readback from the device.
146 * @parameter drvdata: a pointer to the drvdata. 146 * @drvdata: a pointer to the drvdata.
147 **/ 147 **/
148static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) 148static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
149{ 149{
@@ -152,8 +152,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
152} 152}
153 153
154/** 154/**
155 * fifo_icap_busy: Return true if the ICAP is still processing a transaction. 155 * fifo_icap_busy - Return true if the ICAP is still processing a transaction.
156 * @parameter drvdata: a pointer to the drvdata. 156 * @drvdata: a pointer to the drvdata.
157 **/ 157 **/
158static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) 158static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
159{ 159{
@@ -163,8 +163,8 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
163} 163}
164 164
165/** 165/**
166 * fifo_icap_write_fifo_vacancy: Query the write fifo available space. 166 * fifo_icap_write_fifo_vacancy - Query the write fifo available space.
167 * @parameter drvdata: a pointer to the drvdata. 167 * @drvdata: a pointer to the drvdata.
168 * 168 *
169 * Return the number of words that can be safely pushed into the write fifo. 169 * Return the number of words that can be safely pushed into the write fifo.
170 **/ 170 **/
@@ -175,8 +175,8 @@ static inline u32 fifo_icap_write_fifo_vacancy(
175} 175}
176 176
177/** 177/**
178 * fifo_icap_read_fifo_occupancy: Query the read fifo available data. 178 * fifo_icap_read_fifo_occupancy - Query the read fifo available data.
179 * @parameter drvdata: a pointer to the drvdata. 179 * @drvdata: a pointer to the drvdata.
180 * 180 *
181 * Return the number of words that can be safely read from the read fifo. 181 * Return the number of words that can be safely read from the read fifo.
182 **/ 182 **/
@@ -187,11 +187,11 @@ static inline u32 fifo_icap_read_fifo_occupancy(
187} 187}
188 188
189/** 189/**
190 * fifo_icap_set_configuration: Send configuration data to the ICAP. 190 * fifo_icap_set_configuration - Send configuration data to the ICAP.
191 * @parameter drvdata: a pointer to the drvdata. 191 * @drvdata: a pointer to the drvdata.
192 * @parameter frame_buffer: a pointer to the data to be written to the 192 * @frame_buffer: a pointer to the data to be written to the
193 * ICAP device. 193 * ICAP device.
194 * @parameter num_words: the number of words (32 bit) to write to the ICAP 194 * @num_words: the number of words (32 bit) to write to the ICAP
195 * device. 195 * device.
196 196
197 * This function writes the given user data to the Write FIFO in 197 * 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,
266} 266}
267 267
268/** 268/**
269 * fifo_icap_get_configuration: Read configuration data from the device. 269 * fifo_icap_get_configuration - Read configuration data from the device.
270 * @parameter drvdata: a pointer to the drvdata. 270 * @drvdata: a pointer to the drvdata.
271 * @parameter data: Address of the data representing the partial bitstream 271 * @data: Address of the data representing the partial bitstream
272 * @parameter size: the size of the partial bitstream in 32 bit words. 272 * @size: the size of the partial bitstream in 32 bit words.
273 * 273 *
274 * This function reads the specified number of words from the ICAP device in 274 * This function reads the specified number of words from the ICAP device in
275 * the polled mode. 275 * the polled mode.
@@ -335,8 +335,8 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
335} 335}
336 336
337/** 337/**
338 * buffer_icap_reset: Reset the logic of the icap device. 338 * buffer_icap_reset - Reset the logic of the icap device.
339 * @parameter drvdata: a pointer to the drvdata. 339 * @drvdata: a pointer to the drvdata.
340 * 340 *
341 * This function forces the software reset of the complete HWICAP device. 341 * This function forces the software reset of the complete HWICAP device.
342 * All the registers will return to the default value and the FIFO is also 342 * 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)
360} 360}
361 361
362/** 362/**
363 * fifo_icap_flush_fifo: This function flushes the FIFOs in the device. 363 * fifo_icap_flush_fifo - This function flushes the FIFOs in the device.
364 * @parameter drvdata: a pointer to the drvdata. 364 * @drvdata: a pointer to the drvdata.
365 */ 365 */
366void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata) 366void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
367{ 367{
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 24f6aef0fd3c..2284fa2a5a57 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -84,7 +84,7 @@
84#include <linux/init.h> 84#include <linux/init.h>
85#include <linux/poll.h> 85#include <linux/poll.h>
86#include <linux/proc_fs.h> 86#include <linux/proc_fs.h>
87#include <asm/semaphore.h> 87#include <linux/mutex.h>
88#include <linux/sysctl.h> 88#include <linux/sysctl.h>
89#include <linux/version.h> 89#include <linux/version.h>
90#include <linux/fs.h> 90#include <linux/fs.h>
@@ -119,6 +119,7 @@ module_param(xhwicap_minor, int, S_IRUGO);
119 119
120/* An array, which is set to true when the device is registered. */ 120/* An array, which is set to true when the device is registered. */
121static bool probed_devices[HWICAP_DEVICES]; 121static bool probed_devices[HWICAP_DEVICES];
122static struct mutex icap_sem;
122 123
123static struct class *icap_class; 124static struct class *icap_class;
124 125
@@ -199,14 +200,14 @@ static const struct config_registers v5_config_registers = {
199}; 200};
200 201
201/** 202/**
202 * hwicap_command_desync: Send a DESYNC command to the ICAP port. 203 * hwicap_command_desync - Send a DESYNC command to the ICAP port.
203 * @parameter drvdata: a pointer to the drvdata. 204 * @drvdata: a pointer to the drvdata.
204 * 205 *
205 * This command desynchronizes the ICAP After this command, a 206 * This command desynchronizes the ICAP After this command, a
206 * bitstream containing a NULL packet, followed by a SYNCH packet is 207 * bitstream containing a NULL packet, followed by a SYNCH packet is
207 * required before the ICAP will recognize commands. 208 * required before the ICAP will recognize commands.
208 */ 209 */
209int hwicap_command_desync(struct hwicap_drvdata *drvdata) 210static int hwicap_command_desync(struct hwicap_drvdata *drvdata)
210{ 211{
211 u32 buffer[4]; 212 u32 buffer[4];
212 u32 index = 0; 213 u32 index = 0;
@@ -228,51 +229,18 @@ int hwicap_command_desync(struct hwicap_drvdata *drvdata)
228} 229}
229 230
230/** 231/**
231 * hwicap_command_capture: Send a CAPTURE command to the ICAP port. 232 * hwicap_get_configuration_register - Query a configuration register.
232 * @parameter drvdata: a pointer to the drvdata. 233 * @drvdata: a pointer to the drvdata.
233 * 234 * @reg: a constant which represents the configuration
234 * This command captures all of the flip flop states so they will be
235 * available during readback. One can use this command instead of
236 * enabling the CAPTURE block in the design.
237 */
238int hwicap_command_capture(struct hwicap_drvdata *drvdata)
239{
240 u32 buffer[7];
241 u32 index = 0;
242
243 /*
244 * Create the data to be written to the ICAP.
245 */
246 buffer[index++] = XHI_DUMMY_PACKET;
247 buffer[index++] = XHI_SYNC_PACKET;
248 buffer[index++] = XHI_NOOP_PACKET;
249 buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
250 buffer[index++] = XHI_CMD_GCAPTURE;
251 buffer[index++] = XHI_DUMMY_PACKET;
252 buffer[index++] = XHI_DUMMY_PACKET;
253
254 /*
255 * Write the data to the FIFO and intiate the transfer of data
256 * present in the FIFO to the ICAP device.
257 */
258 return drvdata->config->set_configuration(drvdata,
259 &buffer[0], index);
260
261}
262
263/**
264 * hwicap_get_configuration_register: Query a configuration register.
265 * @parameter drvdata: a pointer to the drvdata.
266 * @parameter reg: a constant which represents the configuration
267 * register value to be returned. 235 * register value to be returned.
268 * Examples: XHI_IDCODE, XHI_FLR. 236 * Examples: XHI_IDCODE, XHI_FLR.
269 * @parameter RegData: returns the value of the register. 237 * @reg_data: returns the value of the register.
270 * 238 *
271 * Sends a query packet to the ICAP and then receives the response. 239 * Sends a query packet to the ICAP and then receives the response.
272 * The icap is left in Synched state. 240 * The icap is left in Synched state.
273 */ 241 */
274int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, 242static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
275 u32 reg, u32 *RegData) 243 u32 reg, u32 *reg_data)
276{ 244{
277 int status; 245 int status;
278 u32 buffer[6]; 246 u32 buffer[6];
@@ -300,14 +268,14 @@ int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
300 /* 268 /*
301 * Read the configuration register 269 * Read the configuration register
302 */ 270 */
303 status = drvdata->config->get_configuration(drvdata, RegData, 1); 271 status = drvdata->config->get_configuration(drvdata, reg_data, 1);
304 if (status) 272 if (status)
305 return status; 273 return status;
306 274
307 return 0; 275 return 0;
308} 276}
309 277
310int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) 278static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
311{ 279{
312 int status; 280 int status;
313 u32 idcode; 281 u32 idcode;
@@ -344,7 +312,7 @@ int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
344} 312}
345 313
346static ssize_t 314static ssize_t
347hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) 315hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
348{ 316{
349 struct hwicap_drvdata *drvdata = file->private_data; 317 struct hwicap_drvdata *drvdata = file->private_data;
350 ssize_t bytes_to_read = 0; 318 ssize_t bytes_to_read = 0;
@@ -353,8 +321,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
353 u32 bytes_remaining; 321 u32 bytes_remaining;
354 int status; 322 int status;
355 323
356 if (down_interruptible(&drvdata->sem)) 324 status = mutex_lock_interruptible(&drvdata->sem);
357 return -ERESTARTSYS; 325 if (status)
326 return status;
358 327
359 if (drvdata->read_buffer_in_use) { 328 if (drvdata->read_buffer_in_use) {
360 /* If there are leftover bytes in the buffer, just */ 329 /* If there are leftover bytes in the buffer, just */
@@ -370,8 +339,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
370 goto error; 339 goto error;
371 } 340 }
372 drvdata->read_buffer_in_use -= bytes_to_read; 341 drvdata->read_buffer_in_use -= bytes_to_read;
373 memcpy(drvdata->read_buffer + bytes_to_read, 342 memmove(drvdata->read_buffer,
374 drvdata->read_buffer, 4 - bytes_to_read); 343 drvdata->read_buffer + bytes_to_read,
344 4 - bytes_to_read);
375 } else { 345 } else {
376 /* Get new data from the ICAP, and return was was requested. */ 346 /* Get new data from the ICAP, and return was was requested. */
377 kbuf = (u32 *) get_zeroed_page(GFP_KERNEL); 347 kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
@@ -414,18 +384,20 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
414 status = -EFAULT; 384 status = -EFAULT;
415 goto error; 385 goto error;
416 } 386 }
417 memcpy(kbuf, drvdata->read_buffer, bytes_remaining); 387 memcpy(drvdata->read_buffer,
388 kbuf,
389 bytes_remaining);
418 drvdata->read_buffer_in_use = bytes_remaining; 390 drvdata->read_buffer_in_use = bytes_remaining;
419 free_page((unsigned long)kbuf); 391 free_page((unsigned long)kbuf);
420 } 392 }
421 status = bytes_to_read; 393 status = bytes_to_read;
422 error: 394 error:
423 up(&drvdata->sem); 395 mutex_unlock(&drvdata->sem);
424 return status; 396 return status;
425} 397}
426 398
427static ssize_t 399static ssize_t
428hwicap_write(struct file *file, const char *buf, 400hwicap_write(struct file *file, const char __user *buf,
429 size_t count, loff_t *ppos) 401 size_t count, loff_t *ppos)
430{ 402{
431 struct hwicap_drvdata *drvdata = file->private_data; 403 struct hwicap_drvdata *drvdata = file->private_data;
@@ -435,8 +407,9 @@ hwicap_write(struct file *file, const char *buf,
435 ssize_t len; 407 ssize_t len;
436 ssize_t status; 408 ssize_t status;
437 409
438 if (down_interruptible(&drvdata->sem)) 410 status = mutex_lock_interruptible(&drvdata->sem);
439 return -ERESTARTSYS; 411 if (status)
412 return status;
440 413
441 left += drvdata->write_buffer_in_use; 414 left += drvdata->write_buffer_in_use;
442 415
@@ -465,7 +438,7 @@ hwicap_write(struct file *file, const char *buf,
465 memcpy(kbuf, drvdata->write_buffer, 438 memcpy(kbuf, drvdata->write_buffer,
466 drvdata->write_buffer_in_use); 439 drvdata->write_buffer_in_use);
467 if (copy_from_user( 440 if (copy_from_user(
468 (((char *)kbuf) + (drvdata->write_buffer_in_use)), 441 (((char *)kbuf) + drvdata->write_buffer_in_use),
469 buf + written, 442 buf + written,
470 len - (drvdata->write_buffer_in_use))) { 443 len - (drvdata->write_buffer_in_use))) {
471 free_page((unsigned long)kbuf); 444 free_page((unsigned long)kbuf);
@@ -508,7 +481,7 @@ hwicap_write(struct file *file, const char *buf,
508 free_page((unsigned long)kbuf); 481 free_page((unsigned long)kbuf);
509 status = written; 482 status = written;
510 error: 483 error:
511 up(&drvdata->sem); 484 mutex_unlock(&drvdata->sem);
512 return status; 485 return status;
513} 486}
514 487
@@ -519,8 +492,9 @@ static int hwicap_open(struct inode *inode, struct file *file)
519 492
520 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); 493 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
521 494
522 if (down_interruptible(&drvdata->sem)) 495 status = mutex_lock_interruptible(&drvdata->sem);
523 return -ERESTARTSYS; 496 if (status)
497 return status;
524 498
525 if (drvdata->is_open) { 499 if (drvdata->is_open) {
526 status = -EBUSY; 500 status = -EBUSY;
@@ -539,7 +513,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
539 drvdata->is_open = 1; 513 drvdata->is_open = 1;
540 514
541 error: 515 error:
542 up(&drvdata->sem); 516 mutex_unlock(&drvdata->sem);
543 return status; 517 return status;
544} 518}
545 519
@@ -549,8 +523,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
549 int i; 523 int i;
550 int status = 0; 524 int status = 0;
551 525
552 if (down_interruptible(&drvdata->sem)) 526 mutex_lock(&drvdata->sem);
553 return -ERESTARTSYS;
554 527
555 if (drvdata->write_buffer_in_use) { 528 if (drvdata->write_buffer_in_use) {
556 /* Flush write buffer. */ 529 /* Flush write buffer. */
@@ -569,7 +542,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
569 542
570 error: 543 error:
571 drvdata->is_open = 0; 544 drvdata->is_open = 0;
572 up(&drvdata->sem); 545 mutex_unlock(&drvdata->sem);
573 return status; 546 return status;
574} 547}
575 548
@@ -592,31 +565,36 @@ static int __devinit hwicap_setup(struct device *dev, int id,
592 565
593 dev_info(dev, "Xilinx icap port driver\n"); 566 dev_info(dev, "Xilinx icap port driver\n");
594 567
568 mutex_lock(&icap_sem);
569
595 if (id < 0) { 570 if (id < 0) {
596 for (id = 0; id < HWICAP_DEVICES; id++) 571 for (id = 0; id < HWICAP_DEVICES; id++)
597 if (!probed_devices[id]) 572 if (!probed_devices[id])
598 break; 573 break;
599 } 574 }
600 if (id < 0 || id >= HWICAP_DEVICES) { 575 if (id < 0 || id >= HWICAP_DEVICES) {
576 mutex_unlock(&icap_sem);
601 dev_err(dev, "%s%i too large\n", DRIVER_NAME, id); 577 dev_err(dev, "%s%i too large\n", DRIVER_NAME, id);
602 return -EINVAL; 578 return -EINVAL;
603 } 579 }
604 if (probed_devices[id]) { 580 if (probed_devices[id]) {
581 mutex_unlock(&icap_sem);
605 dev_err(dev, "cannot assign to %s%i; it is already in use\n", 582 dev_err(dev, "cannot assign to %s%i; it is already in use\n",
606 DRIVER_NAME, id); 583 DRIVER_NAME, id);
607 return -EBUSY; 584 return -EBUSY;
608 } 585 }
609 586
610 probed_devices[id] = 1; 587 probed_devices[id] = 1;
588 mutex_unlock(&icap_sem);
611 589
612 devt = MKDEV(xhwicap_major, xhwicap_minor + id); 590 devt = MKDEV(xhwicap_major, xhwicap_minor + id);
613 591
614 drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); 592 drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
615 if (!drvdata) { 593 if (!drvdata) {
616 dev_err(dev, "Couldn't allocate device private record\n"); 594 dev_err(dev, "Couldn't allocate device private record\n");
617 return -ENOMEM; 595 retval = -ENOMEM;
596 goto failed0;
618 } 597 }
619 memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata));
620 dev_set_drvdata(dev, (void *)drvdata); 598 dev_set_drvdata(dev, (void *)drvdata);
621 599
622 if (!regs_res) { 600 if (!regs_res) {
@@ -648,7 +626,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
648 drvdata->config = config; 626 drvdata->config = config;
649 drvdata->config_regs = config_regs; 627 drvdata->config_regs = config_regs;
650 628
651 init_MUTEX(&drvdata->sem); 629 mutex_init(&drvdata->sem);
652 drvdata->is_open = 0; 630 drvdata->is_open = 0;
653 631
654 dev_info(dev, "ioremap %lx to %p with size %x\n", 632 dev_info(dev, "ioremap %lx to %p with size %x\n",
@@ -663,7 +641,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
663 goto failed3; 641 goto failed3;
664 } 642 }
665 /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */ 643 /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */
666 class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME); 644 device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id);
667 return 0; /* success */ 645 return 0; /* success */
668 646
669 failed3: 647 failed3:
@@ -675,6 +653,11 @@ static int __devinit hwicap_setup(struct device *dev, int id,
675 failed1: 653 failed1:
676 kfree(drvdata); 654 kfree(drvdata);
677 655
656 failed0:
657 mutex_lock(&icap_sem);
658 probed_devices[id] = 0;
659 mutex_unlock(&icap_sem);
660
678 return retval; 661 return retval;
679} 662}
680 663
@@ -699,14 +682,16 @@ static int __devexit hwicap_remove(struct device *dev)
699 if (!drvdata) 682 if (!drvdata)
700 return 0; 683 return 0;
701 684
702 class_device_destroy(icap_class, drvdata->devt); 685 device_destroy(icap_class, drvdata->devt);
703 cdev_del(&drvdata->cdev); 686 cdev_del(&drvdata->cdev);
704 iounmap(drvdata->base_address); 687 iounmap(drvdata->base_address);
705 release_mem_region(drvdata->mem_start, drvdata->mem_size); 688 release_mem_region(drvdata->mem_start, drvdata->mem_size);
706 kfree(drvdata); 689 kfree(drvdata);
707 dev_set_drvdata(dev, NULL); 690 dev_set_drvdata(dev, NULL);
708 probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
709 691
692 mutex_lock(&icap_sem);
693 probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
694 mutex_unlock(&icap_sem);
710 return 0; /* success */ 695 return 0; /* success */
711} 696}
712 697
@@ -821,28 +806,29 @@ static struct of_platform_driver hwicap_of_driver = {
821}; 806};
822 807
823/* Registration helpers to keep the number of #ifdefs to a minimum */ 808/* Registration helpers to keep the number of #ifdefs to a minimum */
824static inline int __devinit hwicap_of_register(void) 809static inline int __init hwicap_of_register(void)
825{ 810{
826 pr_debug("hwicap: calling of_register_platform_driver()\n"); 811 pr_debug("hwicap: calling of_register_platform_driver()\n");
827 return of_register_platform_driver(&hwicap_of_driver); 812 return of_register_platform_driver(&hwicap_of_driver);
828} 813}
829 814
830static inline void __devexit hwicap_of_unregister(void) 815static inline void __exit hwicap_of_unregister(void)
831{ 816{
832 of_unregister_platform_driver(&hwicap_of_driver); 817 of_unregister_platform_driver(&hwicap_of_driver);
833} 818}
834#else /* CONFIG_OF */ 819#else /* CONFIG_OF */
835/* CONFIG_OF not enabled; do nothing helpers */ 820/* CONFIG_OF not enabled; do nothing helpers */
836static inline int __devinit hwicap_of_register(void) { return 0; } 821static inline int __init hwicap_of_register(void) { return 0; }
837static inline void __devexit hwicap_of_unregister(void) { } 822static inline void __exit hwicap_of_unregister(void) { }
838#endif /* CONFIG_OF */ 823#endif /* CONFIG_OF */
839 824
840static int __devinit hwicap_module_init(void) 825static int __init hwicap_module_init(void)
841{ 826{
842 dev_t devt; 827 dev_t devt;
843 int retval; 828 int retval;
844 829
845 icap_class = class_create(THIS_MODULE, "xilinx_config"); 830 icap_class = class_create(THIS_MODULE, "xilinx_config");
831 mutex_init(&icap_sem);
846 832
847 if (xhwicap_major) { 833 if (xhwicap_major) {
848 devt = MKDEV(xhwicap_major, xhwicap_minor); 834 devt = MKDEV(xhwicap_major, xhwicap_minor);
@@ -883,7 +869,7 @@ static int __devinit hwicap_module_init(void)
883 return retval; 869 return retval;
884} 870}
885 871
886static void __devexit hwicap_module_cleanup(void) 872static void __exit hwicap_module_cleanup(void)
887{ 873{
888 dev_t devt = MKDEV(xhwicap_major, xhwicap_minor); 874 dev_t devt = MKDEV(xhwicap_major, xhwicap_minor);
889 875
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
index ae771cac1629..405fee7e189b 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
@@ -48,9 +48,9 @@ struct hwicap_drvdata {
48 u8 write_buffer[4]; 48 u8 write_buffer[4];
49 u32 read_buffer_in_use; /* Always in [0,3] */ 49 u32 read_buffer_in_use; /* Always in [0,3] */
50 u8 read_buffer[4]; 50 u8 read_buffer[4];
51 u32 mem_start; /* phys. address of the control registers */ 51 resource_size_t mem_start;/* phys. address of the control registers */
52 u32 mem_end; /* phys. address of the control registers */ 52 resource_size_t mem_end; /* phys. address of the control registers */
53 u32 mem_size; 53 resource_size_t mem_size;
54 void __iomem *base_address;/* virt. address of the control registers */ 54 void __iomem *base_address;/* virt. address of the control registers */
55 55
56 struct device *dev; 56 struct device *dev;
@@ -61,7 +61,7 @@ struct hwicap_drvdata {
61 const struct config_registers *config_regs; 61 const struct config_registers *config_regs;
62 void *private_data; 62 void *private_data;
63 bool is_open; 63 bool is_open;
64 struct semaphore sem; 64 struct mutex sem;
65}; 65};
66 66
67struct hwicap_driver_config { 67struct hwicap_driver_config {
@@ -164,29 +164,29 @@ struct config_registers {
164#define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL 164#define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL
165 165
166/** 166/**
167 * hwicap_type_1_read: Generates a Type 1 read packet header. 167 * hwicap_type_1_read - Generates a Type 1 read packet header.
168 * @parameter: Register is the address of the register to be read back. 168 * @reg: is the address of the register to be read back.
169 * 169 *
170 * Generates a Type 1 read packet header, which is used to indirectly 170 * Generates a Type 1 read packet header, which is used to indirectly
171 * read registers in the configuration logic. This packet must then 171 * read registers in the configuration logic. This packet must then
172 * be sent through the icap device, and a return packet received with 172 * be sent through the icap device, and a return packet received with
173 * the information. 173 * the information.
174 **/ 174 **/
175static inline u32 hwicap_type_1_read(u32 Register) 175static inline u32 hwicap_type_1_read(u32 reg)
176{ 176{
177 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | 177 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
178 (Register << XHI_REGISTER_SHIFT) | 178 (reg << XHI_REGISTER_SHIFT) |
179 (XHI_OP_READ << XHI_OP_SHIFT); 179 (XHI_OP_READ << XHI_OP_SHIFT);
180} 180}
181 181
182/** 182/**
183 * hwicap_type_1_write: Generates a Type 1 write packet header 183 * hwicap_type_1_write - Generates a Type 1 write packet header
184 * @parameter: Register is the address of the register to be read back. 184 * @reg: is the address of the register to be read back.
185 **/ 185 **/
186static inline u32 hwicap_type_1_write(u32 Register) 186static inline u32 hwicap_type_1_write(u32 reg)
187{ 187{
188 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | 188 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
189 (Register << XHI_REGISTER_SHIFT) | 189 (reg << XHI_REGISTER_SHIFT) |
190 (XHI_OP_WRITE << XHI_OP_SHIFT); 190 (XHI_OP_WRITE << XHI_OP_SHIFT);
191} 191}
192 192
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 0d6238987df8..edc0cfd7f6e2 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -153,6 +153,9 @@
153#define CTRL_RUNLATCH 0x1 153#define CTRL_RUNLATCH 0x1
154#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ 154#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
155#define DABR_TRANSLATION (1UL << 2) 155#define DABR_TRANSLATION (1UL << 2)
156#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */
157#define DABRX_USER (1UL << 0)
158#define DABRX_KERNEL (1UL << 1)
156#define SPRN_DAR 0x013 /* Data Address Register */ 159#define SPRN_DAR 0x013 /* Data Address Register */
157#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ 160#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
158#define DSISR_NOHPTE 0x40000000 /* no translation found */ 161#define DSISR_NOHPTE 0x40000000 /* no translation found */