aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 14:30:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 14:30:37 -0400
commit609106b9ac968adbc76ce78c979fc3903a56e16c (patch)
tree4af8b305ab4095870a927ffdb9a5e14eb2107401
parent69257cae20640a396f03aa0bf169b815ba66a58a (diff)
parent42e27bfc4bfa42bd905e53be93d862b8e3d80a00 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (38 commits) ps3flash: Always read chunks of 256 KiB, and cache them ps3flash: Cache the last accessed FLASH chunk ps3: Replace direct file operations by callback ps3: Switch ps3_os_area_[gs]et_rtc_diff to EXPORT_SYMBOL_GPL() ps3: Correct debug message in dma_ioc0_map_pages() drivers/ps3: Add missing annotations ps3fb: Use ps3_system_bus_[gs]et_drvdata() instead of direct access ps3flash: Use ps3_system_bus_[gs]et_drvdata() instead of direct access ps3: shorten ps3_system_bus_[gs]et_driver_data to ps3_system_bus_[gs]et_drvdata ps3: Use dev_[gs]et_drvdata() instead of direct access for system bus devices block/ps3: remove driver_data direct access of struct device ps3vram: Make ps3vram_priv.reports a void * ps3vram: Remove no longer used ps3vram_priv.ddr_base ps3vram: Replace mutex by spinlock + bio_list block: Add bio_list_peek() powerpc: Use generic atomic64_t implementation on 32-bit processors lib: Provide generic atomic64_t implementation powerpc: Add compiler memory barrier to mtmsr macro powerpc/iseries: Mark signal_vsp_instruction() as maybe unused powerpc/iseries: Fix unused function warning in iSeries DT code ...
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/boot/install.sh3
-rw-r--r--arch/powerpc/include/asm/atomic.h3
-rw-r--r--arch/powerpc/include/asm/hw_irq.h5
-rw-r--r--arch/powerpc/include/asm/iommu.h10
-rw-r--r--arch/powerpc/include/asm/ps3.h18
-rw-r--r--arch/powerpc/include/asm/ps3gpu.h86
-rw-r--r--arch/powerpc/include/asm/reg.h4
-rw-r--r--arch/powerpc/include/asm/systbl.h1
-rw-r--r--arch/powerpc/include/asm/unistd.h3
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/setup_64.c4
-rw-r--r--arch/powerpc/kernel/time.c10
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c4
-rw-r--r--arch/powerpc/platforms/cell/iommu.c37
-rw-r--r--arch/powerpc/platforms/iseries/dt.c3
-rw-r--r--arch/powerpc/platforms/iseries/mf.c3
-rw-r--r--arch/powerpc/platforms/ps3/mm.c12
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c142
-rw-r--r--arch/powerpc/platforms/ps3/platform.h10
-rw-r--r--arch/powerpc/platforms/ps3/setup.c1
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c15
-rw-r--r--drivers/block/ps3disk.c18
-rw-r--r--drivers/block/ps3vram.c168
-rw-r--r--drivers/char/ps3flash.c296
-rw-r--r--drivers/net/ps3_gelic_net.c8
-rw-r--r--drivers/ps3/ps3-sys-manager.c2
-rw-r--r--drivers/ps3/ps3av.c8
-rw-r--r--drivers/ps3/ps3av_cmd.c3
-rw-r--r--drivers/usb/host/ehci-ps3.c7
-rw-r--r--drivers/usb/host/ohci-ps3.c7
-rw-r--r--drivers/video/ps3fb.c272
-rw-r--r--include/asm-generic/atomic64.h42
-rw-r--r--include/linux/bio.h5
-rw-r--r--lib/Kconfig6
-rw-r--r--lib/Makefile2
-rw-r--r--lib/atomic64.c175
37 files changed, 873 insertions, 527 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 93a61898b259..9fb344d5a86a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -93,10 +93,6 @@ config GENERIC_HWEIGHT
93 bool 93 bool
94 default y 94 default y
95 95
96config GENERIC_CALIBRATE_DELAY
97 bool
98 default y
99
100config GENERIC_FIND_NEXT_BIT 96config GENERIC_FIND_NEXT_BIT
101 bool 97 bool
102 default y 98 default y
@@ -129,6 +125,7 @@ config PPC
129 select USE_GENERIC_SMP_HELPERS if SMP 125 select USE_GENERIC_SMP_HELPERS if SMP
130 select HAVE_OPROFILE 126 select HAVE_OPROFILE
131 select HAVE_SYSCALL_WRAPPERS if PPC64 127 select HAVE_SYSCALL_WRAPPERS if PPC64
128 select GENERIC_ATOMIC64 if PPC32
132 129
133config EARLY_PRINTK 130config EARLY_PRINTK
134 bool 131 bool
diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh
index 51b2387bdba0..98312d169c85 100644
--- a/arch/powerpc/boot/install.sh
+++ b/arch/powerpc/boot/install.sh
@@ -18,6 +18,9 @@
18# $5 and more - kernel boot files; zImage*, uImage, cuImage.*, etc. 18# $5 and more - kernel boot files; zImage*, uImage, cuImage.*, etc.
19# 19#
20 20
21# Bail with error code if anything goes wrong
22set -e
23
21# User may have a custom install script 24# User may have a custom install script
22 25
23if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi 26if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index b7d2d07b6f96..4012483b1899 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -470,6 +470,9 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
470 470
471#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) 471#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
472 472
473#else /* __powerpc64__ */
474#include <asm-generic/atomic64.h>
475
473#endif /* __powerpc64__ */ 476#endif /* __powerpc64__ */
474 477
475#include <asm-generic/atomic-long.h> 478#include <asm-generic/atomic-long.h>
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 53512374e1c9..b7f8f4a87cc0 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -80,7 +80,7 @@ static inline void local_irq_disable(void)
80 __asm__ __volatile__("wrteei 0": : :"memory"); 80 __asm__ __volatile__("wrteei 0": : :"memory");
81#else 81#else
82 unsigned long msr; 82 unsigned long msr;
83 __asm__ __volatile__("": : :"memory"); 83
84 msr = mfmsr(); 84 msr = mfmsr();
85 SET_MSR_EE(msr & ~MSR_EE); 85 SET_MSR_EE(msr & ~MSR_EE);
86#endif 86#endif
@@ -92,7 +92,7 @@ static inline void local_irq_enable(void)
92 __asm__ __volatile__("wrteei 1": : :"memory"); 92 __asm__ __volatile__("wrteei 1": : :"memory");
93#else 93#else
94 unsigned long msr; 94 unsigned long msr;
95 __asm__ __volatile__("": : :"memory"); 95
96 msr = mfmsr(); 96 msr = mfmsr();
97 SET_MSR_EE(msr | MSR_EE); 97 SET_MSR_EE(msr | MSR_EE);
98#endif 98#endif
@@ -108,7 +108,6 @@ static inline void local_irq_save_ptr(unsigned long *flags)
108#else 108#else
109 SET_MSR_EE(msr & ~MSR_EE); 109 SET_MSR_EE(msr & ~MSR_EE);
110#endif 110#endif
111 __asm__ __volatile__("": : :"memory");
112} 111}
113 112
114#define local_save_flags(flags) ((flags) = mfmsr()) 113#define local_save_flags(flags) ((flags) = mfmsr())
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 7464c0daddd1..7ead7c16fb7c 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -35,6 +35,16 @@
35#define IOMMU_PAGE_MASK (~((1 << IOMMU_PAGE_SHIFT) - 1)) 35#define IOMMU_PAGE_MASK (~((1 << IOMMU_PAGE_SHIFT) - 1))
36#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE) 36#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
37 37
38/* Cell page table entries */
39#define CBE_IOPTE_PP_W 0x8000000000000000ul /* protection: write */
40#define CBE_IOPTE_PP_R 0x4000000000000000ul /* protection: read */
41#define CBE_IOPTE_M 0x2000000000000000ul /* coherency required */
42#define CBE_IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
43#define CBE_IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
44#define CBE_IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
45#define CBE_IOPTE_H 0x0000000000000800ul /* cache hint */
46#define CBE_IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
47
38/* Boot time flags */ 48/* Boot time flags */
39extern int iommu_is_off; 49extern int iommu_is_off;
40extern int iommu_force_on; 50extern int iommu_force_on;
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index cdb6fd814de8..7f065e178ec4 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -53,6 +53,13 @@ enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
53extern u64 ps3_os_area_get_rtc_diff(void); 53extern u64 ps3_os_area_get_rtc_diff(void);
54extern void ps3_os_area_set_rtc_diff(u64 rtc_diff); 54extern void ps3_os_area_set_rtc_diff(u64 rtc_diff);
55 55
56struct ps3_os_area_flash_ops {
57 ssize_t (*read)(void *buf, size_t count, loff_t pos);
58 ssize_t (*write)(const void *buf, size_t count, loff_t pos);
59};
60
61extern void ps3_os_area_flash_register(const struct ps3_os_area_flash_ops *ops);
62
56/* dma routines */ 63/* dma routines */
57 64
58enum ps3_dma_page_size { 65enum ps3_dma_page_size {
@@ -418,15 +425,15 @@ static inline struct ps3_system_bus_driver *
418 * @data: Data to set 425 * @data: Data to set
419 */ 426 */
420 427
421static inline void ps3_system_bus_set_driver_data( 428static inline void ps3_system_bus_set_drvdata(
422 struct ps3_system_bus_device *dev, void *data) 429 struct ps3_system_bus_device *dev, void *data)
423{ 430{
424 dev->core.driver_data = data; 431 dev_set_drvdata(&dev->core, data);
425} 432}
426static inline void *ps3_system_bus_get_driver_data( 433static inline void *ps3_system_bus_get_drvdata(
427 struct ps3_system_bus_device *dev) 434 struct ps3_system_bus_device *dev)
428{ 435{
429 return dev->core.driver_data; 436 return dev_get_drvdata(&dev->core);
430} 437}
431 438
432/* These two need global scope for get_dma_ops(). */ 439/* These two need global scope for get_dma_ops(). */
@@ -520,7 +527,4 @@ void ps3_sync_irq(int node);
520u32 ps3_get_hw_thread_id(int cpu); 527u32 ps3_get_hw_thread_id(int cpu);
521u64 ps3_get_spe_id(void *arg); 528u64 ps3_get_spe_id(void *arg);
522 529
523/* mutex synchronizing GPU accesses and video mode changes */
524extern struct mutex ps3_gpu_mutex;
525
526#endif 530#endif
diff --git a/arch/powerpc/include/asm/ps3gpu.h b/arch/powerpc/include/asm/ps3gpu.h
new file mode 100644
index 000000000000..b2b89591907c
--- /dev/null
+++ b/arch/powerpc/include/asm/ps3gpu.h
@@ -0,0 +1,86 @@
1/*
2 * PS3 GPU declarations.
3 *
4 * Copyright 2009 Sony Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.
17 * If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef _ASM_POWERPC_PS3GPU_H
21#define _ASM_POWERPC_PS3GPU_H
22
23#include <linux/mutex.h>
24
25#include <asm/lv1call.h>
26
27
28#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
29#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
30
31#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
32#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
33#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602
34#define L1GPU_CONTEXT_ATTRIBUTE_FB_CLOSE 0x603
35
36#define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32)
37
38#define L1GPU_DISPLAY_SYNC_HSYNC 1
39#define L1GPU_DISPLAY_SYNC_VSYNC 2
40
41
42/* mutex synchronizing GPU accesses and video mode changes */
43extern struct mutex ps3_gpu_mutex;
44
45
46static inline int lv1_gpu_display_sync(u64 context_handle, u64 head,
47 u64 ddr_offset)
48{
49 return lv1_gpu_context_attribute(context_handle,
50 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
51 head, ddr_offset, 0, 0);
52}
53
54static inline int lv1_gpu_display_flip(u64 context_handle, u64 head,
55 u64 ddr_offset)
56{
57 return lv1_gpu_context_attribute(context_handle,
58 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
59 head, ddr_offset, 0, 0);
60}
61
62static inline int lv1_gpu_fb_setup(u64 context_handle, u64 xdr_lpar,
63 u64 xdr_size, u64 ioif_offset)
64{
65 return lv1_gpu_context_attribute(context_handle,
66 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
67 xdr_lpar, xdr_size, ioif_offset, 0);
68}
69
70static inline int lv1_gpu_fb_blit(u64 context_handle, u64 ddr_offset,
71 u64 ioif_offset, u64 sync_width, u64 pitch)
72{
73 return lv1_gpu_context_attribute(context_handle,
74 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
75 ddr_offset, ioif_offset, sync_width,
76 pitch);
77}
78
79static inline int lv1_gpu_fb_close(u64 context_handle)
80{
81 return lv1_gpu_context_attribute(context_handle,
82 L1GPU_CONTEXT_ATTRIBUTE_FB_CLOSE, 0,
83 0, 0, 0);
84}
85
86#endif /* _ASM_POWERPC_PS3GPU_H */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index fb359b0a6937..a3c28e46947c 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -745,11 +745,11 @@
745 asm volatile("mfmsr %0" : "=r" (rval)); rval;}) 745 asm volatile("mfmsr %0" : "=r" (rval)); rval;})
746#ifdef CONFIG_PPC64 746#ifdef CONFIG_PPC64
747#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ 747#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
748 : : "r" (v)) 748 : : "r" (v) : "memory")
749#define mtmsrd(v) __mtmsrd((v), 0) 749#define mtmsrd(v) __mtmsrd((v), 0)
750#define mtmsr(v) mtmsrd(v) 750#define mtmsr(v) mtmsrd(v)
751#else 751#else
752#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) 752#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v) : "memory")
753#endif 753#endif
754 754
755#define mfspr(rn) ({unsigned long rval; \ 755#define mfspr(rn) ({unsigned long rval; \
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index a0b92de51c7e..370600ca2765 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -325,3 +325,4 @@ SYSCALL(inotify_init1)
325SYSCALL_SPU(perf_counter_open) 325SYSCALL_SPU(perf_counter_open)
326COMPAT_SYS_SPU(preadv) 326COMPAT_SYS_SPU(preadv)
327COMPAT_SYS_SPU(pwritev) 327COMPAT_SYS_SPU(pwritev)
328COMPAT_SYS(rt_tgsigqueueinfo)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 4badac2d11d1..cef080bfc607 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -344,10 +344,11 @@
344#define __NR_perf_counter_open 319 344#define __NR_perf_counter_open 319
345#define __NR_preadv 320 345#define __NR_preadv 320
346#define __NR_pwritev 321 346#define __NR_pwritev 321
347#define __NR_rt_tgsigqueueinfo 322
347 348
348#ifdef __KERNEL__ 349#ifdef __KERNEL__
349 350
350#define __NR_syscalls 322 351#define __NR_syscalls 323
351 352
352#define __NR__exit __NR_exit 353#define __NR__exit __NR_exit
353#define NR_syscalls __NR_syscalls 354#define NR_syscalls __NR_syscalls
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index a7def5f90cad..612b0c4dc26d 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -125,6 +125,7 @@ PHONY += systbl_chk
125systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i 125systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i
126 $(call cmd,systbl_chk) 126 $(call cmd,systbl_chk)
127 127
128ifeq ($(CONFIG_PPC_OF_BOOT_TRAMPOLINE),y)
128$(obj)/built-in.o: prom_init_check 129$(obj)/built-in.o: prom_init_check
129 130
130quiet_cmd_prom_init_check = CALL $< 131quiet_cmd_prom_init_check = CALL $<
@@ -133,5 +134,6 @@ quiet_cmd_prom_init_check = CALL $<
133PHONY += prom_init_check 134PHONY += prom_init_check
134prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o 135prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o
135 $(call cmd,prom_init_check) 136 $(call cmd,prom_init_check)
137endif
136 138
137clean-files := vmlinux.lds 139clean-files := vmlinux.lds
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index f46548e66045..1f6816003ebe 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -424,8 +424,8 @@ void __init setup_system(void)
424 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); 424 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
425#endif /* CONFIG_PPC_STD_MMU_64 */ 425#endif /* CONFIG_PPC_STD_MMU_64 */
426 if (PHYSICAL_START > 0) 426 if (PHYSICAL_START > 0)
427 printk("physical_start = 0x%lx\n", 427 printk("physical_start = 0x%llx\n",
428 PHYSICAL_START); 428 (unsigned long long)PHYSICAL_START);
429 printk("-----------------------------------------------------\n"); 429 printk("-----------------------------------------------------\n");
430 430
431 DBG(" <- setup_system()\n"); 431 DBG(" <- setup_system()\n");
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index bee1443da763..15391c2ab013 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -52,6 +52,7 @@
52#include <linux/jiffies.h> 52#include <linux/jiffies.h>
53#include <linux/posix-timers.h> 53#include <linux/posix-timers.h>
54#include <linux/irq.h> 54#include <linux/irq.h>
55#include <linux/delay.h>
55 56
56#include <asm/io.h> 57#include <asm/io.h>
57#include <asm/processor.h> 58#include <asm/processor.h>
@@ -1143,6 +1144,15 @@ void div128_by_32(u64 dividend_high, u64 dividend_low,
1143 1144
1144} 1145}
1145 1146
1147/* We don't need to calibrate delay, we use the CPU timebase for that */
1148void calibrate_delay(void)
1149{
1150 /* Some generic code (such as spinlock debug) use loops_per_jiffy
1151 * as the number of __delay(1) in a jiffy, so make it so
1152 */
1153 loops_per_jiffy = tb_ticks_per_jiffy;
1154}
1155
1146static int __init rtc_init(void) 1156static int __init rtc_init(void)
1147{ 1157{
1148 struct platform_device *pdev; 1158 struct platform_device *pdev;
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 0ce45c2b42f8..c71498dbf211 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -329,7 +329,7 @@ static struct irq_host_ops msic_host_ops = {
329 329
330static int axon_msi_shutdown(struct of_device *device) 330static int axon_msi_shutdown(struct of_device *device)
331{ 331{
332 struct axon_msic *msic = device->dev.platform_data; 332 struct axon_msic *msic = dev_get_drvdata(&device->dev);
333 u32 tmp; 333 u32 tmp;
334 334
335 pr_debug("axon_msi: disabling %s\n", 335 pr_debug("axon_msi: disabling %s\n",
@@ -416,7 +416,7 @@ static int axon_msi_probe(struct of_device *device,
416 msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG) 416 msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG)
417 & MSIC_FIFO_SIZE_MASK; 417 & MSIC_FIFO_SIZE_MASK;
418 418
419 device->dev.platform_data = msic; 419 dev_set_drvdata(&device->dev, msic);
420 420
421 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; 421 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
422 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; 422 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index bed4690de394..5b34fc211f35 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -100,16 +100,6 @@
100#define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */ 100#define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */
101#define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */ 101#define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */
102 102
103/* Page table entries */
104#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
105#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
106#define IOPTE_M 0x2000000000000000ul /* coherency required */
107#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
108#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
109#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
110#define IOPTE_H 0x0000000000000800ul /* cache hint */
111#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
112
113 103
114/* IOMMU sizing */ 104/* IOMMU sizing */
115#define IO_SEGMENT_SHIFT 28 105#define IO_SEGMENT_SHIFT 28
@@ -193,19 +183,21 @@ static int tce_build_cell(struct iommu_table *tbl, long index, long npages,
193 */ 183 */
194 const unsigned long prot = 0xc48; 184 const unsigned long prot = 0xc48;
195 base_pte = 185 base_pte =
196 ((prot << (52 + 4 * direction)) & (IOPTE_PP_W | IOPTE_PP_R)) 186 ((prot << (52 + 4 * direction)) &
197 | IOPTE_M | IOPTE_SO_RW | (window->ioid & IOPTE_IOID_Mask); 187 (CBE_IOPTE_PP_W | CBE_IOPTE_PP_R)) |
188 CBE_IOPTE_M | CBE_IOPTE_SO_RW |
189 (window->ioid & CBE_IOPTE_IOID_Mask);
198#else 190#else
199 base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | 191 base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M |
200 (window->ioid & IOPTE_IOID_Mask); 192 CBE_IOPTE_SO_RW | (window->ioid & CBE_IOPTE_IOID_Mask);
201#endif 193#endif
202 if (unlikely(dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))) 194 if (unlikely(dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)))
203 base_pte &= ~IOPTE_SO_RW; 195 base_pte &= ~CBE_IOPTE_SO_RW;
204 196
205 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); 197 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
206 198
207 for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) 199 for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
208 io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); 200 io_pte[i] = base_pte | (__pa(uaddr) & CBE_IOPTE_RPN_Mask);
209 201
210 mb(); 202 mb();
211 203
@@ -231,8 +223,9 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
231#else 223#else
232 /* spider bridge does PCI reads after freeing - insert a mapping 224 /* spider bridge does PCI reads after freeing - insert a mapping
233 * to a scratch page instead of an invalid entry */ 225 * to a scratch page instead of an invalid entry */
234 pte = IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | __pa(window->iommu->pad_page) 226 pte = CBE_IOPTE_PP_R | CBE_IOPTE_M | CBE_IOPTE_SO_RW |
235 | (window->ioid & IOPTE_IOID_Mask); 227 __pa(window->iommu->pad_page) |
228 (window->ioid & CBE_IOPTE_IOID_Mask);
236#endif 229#endif
237 230
238 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); 231 io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
@@ -1001,7 +994,7 @@ static void insert_16M_pte(unsigned long addr, unsigned long *ptab,
1001 pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n", 994 pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
1002 addr, ptab, segment, offset); 995 addr, ptab, segment, offset);
1003 996
1004 ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask); 997 ptab[offset] = base_pte | (__pa(addr) & CBE_IOPTE_RPN_Mask);
1005} 998}
1006 999
1007static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, 1000static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
@@ -1016,14 +1009,14 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
1016 1009
1017 pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase); 1010 pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
1018 1011
1019 base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M 1012 base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M |
1020 | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask); 1013 (cell_iommu_get_ioid(np) & CBE_IOPTE_IOID_Mask);
1021 1014
1022 if (iommu_fixed_is_weak) 1015 if (iommu_fixed_is_weak)
1023 pr_info("IOMMU: Using weak ordering for fixed mapping\n"); 1016 pr_info("IOMMU: Using weak ordering for fixed mapping\n");
1024 else { 1017 else {
1025 pr_info("IOMMU: Using strong ordering for fixed mapping\n"); 1018 pr_info("IOMMU: Using strong ordering for fixed mapping\n");
1026 base_pte |= IOPTE_SO_RW; 1019 base_pte |= CBE_IOPTE_SO_RW;
1027 } 1020 }
1028 1021
1029 for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) { 1022 for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 4543c4bc3a56..c5a87a72057b 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -204,7 +204,8 @@ static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
204 dt_prop(dt, name, &data, sizeof(u32)); 204 dt_prop(dt, name, &data, sizeof(u32));
205} 205}
206 206
207static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name, 207static void __init __maybe_unused dt_prop_u64(struct iseries_flat_dt *dt,
208 const char *name,
208 u64 data) 209 u64 data)
209{ 210{
210 dt_prop(dt, name, &data, sizeof(u64)); 211 dt_prop(dt, name, &data, sizeof(u64));
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 3689c2413d24..fef4d5150517 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -267,7 +267,8 @@ static struct pending_event *new_pending_event(void)
267 return ev; 267 return ev;
268} 268}
269 269
270static int signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd) 270static int __maybe_unused
271signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd)
271{ 272{
272 struct pending_event *ev = new_pending_event(); 273 struct pending_event *ev = new_pending_event();
273 int rc; 274 int rc;
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 9a2b6d948610..846eb8b57fd1 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -24,6 +24,7 @@
24#include <linux/lmb.h> 24#include <linux/lmb.h>
25 25
26#include <asm/firmware.h> 26#include <asm/firmware.h>
27#include <asm/iommu.h>
27#include <asm/prom.h> 28#include <asm/prom.h>
28#include <asm/udbg.h> 29#include <asm/udbg.h>
29#include <asm/lv1call.h> 30#include <asm/lv1call.h>
@@ -605,9 +606,8 @@ static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
605 r->ioid, 606 r->ioid,
606 iopte_flag); 607 iopte_flag);
607 if (result) { 608 if (result) {
608 printk(KERN_WARNING "%s:%d: lv1_map_device_dma_region " 609 pr_warning("%s:%d: lv1_put_iopte failed: %s\n",
609 "failed: %s\n", __func__, __LINE__, 610 __func__, __LINE__, ps3_result(result));
610 ps3_result(result));
611 goto fail_map; 611 goto fail_map;
612 } 612 }
613 DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__, 613 DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__,
@@ -1001,7 +1001,8 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r)
1001 if (len > r->len) 1001 if (len > r->len)
1002 len = r->len; 1002 len = r->len;
1003 result = dma_sb_map_area(r, virt_addr, len, &tmp, 1003 result = dma_sb_map_area(r, virt_addr, len, &tmp,
1004 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); 1004 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_SO_RW |
1005 CBE_IOPTE_M);
1005 BUG_ON(result); 1006 BUG_ON(result);
1006 } 1007 }
1007 1008
@@ -1014,7 +1015,8 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r)
1014 else 1015 else
1015 len -= map.rm.size - r->offset; 1016 len -= map.rm.size - r->offset;
1016 result = dma_sb_map_area(r, virt_addr, len, &tmp, 1017 result = dma_sb_map_area(r, virt_addr, len, &tmp,
1017 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); 1018 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_SO_RW |
1019 CBE_IOPTE_M);
1018 BUG_ON(result); 1020 BUG_ON(result);
1019 } 1021 }
1020 1022
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index cf1cd0f8c18f..d6487a9c8019 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -226,6 +226,44 @@ static struct property property_av_multi_out = {
226 .value = &saved_params.av_multi_out, 226 .value = &saved_params.av_multi_out,
227}; 227};
228 228
229
230static DEFINE_MUTEX(os_area_flash_mutex);
231
232static const struct ps3_os_area_flash_ops *os_area_flash_ops;
233
234void ps3_os_area_flash_register(const struct ps3_os_area_flash_ops *ops)
235{
236 mutex_lock(&os_area_flash_mutex);
237 os_area_flash_ops = ops;
238 mutex_unlock(&os_area_flash_mutex);
239}
240EXPORT_SYMBOL_GPL(ps3_os_area_flash_register);
241
242static ssize_t os_area_flash_read(void *buf, size_t count, loff_t pos)
243{
244 ssize_t res = -ENODEV;
245
246 mutex_lock(&os_area_flash_mutex);
247 if (os_area_flash_ops)
248 res = os_area_flash_ops->read(buf, count, pos);
249 mutex_unlock(&os_area_flash_mutex);
250
251 return res;
252}
253
254static ssize_t os_area_flash_write(const void *buf, size_t count, loff_t pos)
255{
256 ssize_t res = -ENODEV;
257
258 mutex_lock(&os_area_flash_mutex);
259 if (os_area_flash_ops)
260 res = os_area_flash_ops->write(buf, count, pos);
261 mutex_unlock(&os_area_flash_mutex);
262
263 return res;
264}
265
266
229/** 267/**
230 * os_area_set_property - Add or overwrite a saved_params value to the device tree. 268 * os_area_set_property - Add or overwrite a saved_params value to the device tree.
231 * 269 *
@@ -352,12 +390,12 @@ static int db_verify(const struct os_area_db *db)
352 if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM, 390 if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM,
353 sizeof(db->magic_num))) { 391 sizeof(db->magic_num))) {
354 pr_debug("%s:%d magic_num failed\n", __func__, __LINE__); 392 pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
355 return -1; 393 return -EINVAL;
356 } 394 }
357 395
358 if (db->version != 1) { 396 if (db->version != 1) {
359 pr_debug("%s:%d version failed\n", __func__, __LINE__); 397 pr_debug("%s:%d version failed\n", __func__, __LINE__);
360 return -1; 398 return -EINVAL;
361 } 399 }
362 400
363 return 0; 401 return 0;
@@ -578,59 +616,48 @@ static void os_area_db_init(struct os_area_db *db)
578 * 616 *
579 */ 617 */
580 618
581static void __maybe_unused update_flash_db(void) 619static int update_flash_db(void)
582{ 620{
583 int result; 621 const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
584 int file; 622 struct os_area_header *header;
585 off_t offset;
586 ssize_t count; 623 ssize_t count;
587 static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE; 624 int error;
588 const struct os_area_header *header; 625 loff_t pos;
589 struct os_area_db* db; 626 struct os_area_db* db;
590 627
591 /* Read in header and db from flash. */ 628 /* Read in header and db from flash. */
592 629
593 file = sys_open("/dev/ps3flash", O_RDWR, 0);
594
595 if (file < 0) {
596 pr_debug("%s:%d sys_open failed\n", __func__, __LINE__);
597 goto fail_open;
598 }
599
600 header = kmalloc(buf_len, GFP_KERNEL); 630 header = kmalloc(buf_len, GFP_KERNEL);
601
602 if (!header) { 631 if (!header) {
603 pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__); 632 pr_debug("%s: kmalloc failed\n", __func__);
604 goto fail_malloc; 633 return -ENOMEM;
605 } 634 }
606 635
607 offset = sys_lseek(file, 0, SEEK_SET); 636 count = os_area_flash_read(header, buf_len, 0);
608 637 if (count < 0) {
609 if (offset != 0) { 638 pr_debug("%s: os_area_flash_read failed %zd\n", __func__,
610 pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__); 639 count);
611 goto fail_header_seek; 640 error = count;
641 goto fail;
612 } 642 }
613 643
614 count = sys_read(file, (char __user *)header, buf_len); 644 pos = header->db_area_offset * OS_AREA_SEGMENT_SIZE;
615 645 if (count < OS_AREA_SEGMENT_SIZE || verify_header(header) ||
616 result = count < OS_AREA_SEGMENT_SIZE || verify_header(header) 646 count < pos) {
617 || count < header->db_area_offset * OS_AREA_SEGMENT_SIZE; 647 pr_debug("%s: verify_header failed\n", __func__);
618
619 if (result) {
620 pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
621 dump_header(header); 648 dump_header(header);
622 goto fail_header; 649 error = -EINVAL;
650 goto fail;
623 } 651 }
624 652
625 /* Now got a good db offset and some maybe good db data. */ 653 /* Now got a good db offset and some maybe good db data. */
626 654
627 db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE; 655 db = (void *)header + pos;
628 656
629 result = db_verify(db); 657 error = db_verify(db);
630 658 if (error) {
631 if (result) { 659 pr_notice("%s: Verify of flash database failed, formatting.\n",
632 printk(KERN_NOTICE "%s:%d: Verify of flash database failed, " 660 __func__);
633 "formatting.\n", __func__, __LINE__);
634 dump_db(db); 661 dump_db(db);
635 os_area_db_init(db); 662 os_area_db_init(db);
636 } 663 }
@@ -639,29 +666,16 @@ static void __maybe_unused update_flash_db(void)
639 666
640 db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff); 667 db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff);
641 668
642 offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE, 669 count = os_area_flash_write(db, sizeof(struct os_area_db), pos);
643 SEEK_SET);
644
645 if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) {
646 pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
647 goto fail_db_seek;
648 }
649
650 count = sys_write(file, (const char __user *)db,
651 sizeof(struct os_area_db));
652
653 if (count < sizeof(struct os_area_db)) { 670 if (count < sizeof(struct os_area_db)) {
654 pr_debug("%s:%d sys_write failed\n", __func__, __LINE__); 671 pr_debug("%s: os_area_flash_write failed %zd\n", __func__,
672 count);
673 error = count < 0 ? count : -EIO;
655 } 674 }
656 675
657fail_db_seek: 676fail:
658fail_header:
659fail_header_seek:
660 kfree(header); 677 kfree(header);
661fail_malloc: 678 return error;
662 sys_close(file);
663fail_open:
664 return;
665} 679}
666 680
667/** 681/**
@@ -674,11 +688,11 @@ fail_open:
674static void os_area_queue_work_handler(struct work_struct *work) 688static void os_area_queue_work_handler(struct work_struct *work)
675{ 689{
676 struct device_node *node; 690 struct device_node *node;
691 int error;
677 692
678 pr_debug(" -> %s:%d\n", __func__, __LINE__); 693 pr_debug(" -> %s:%d\n", __func__, __LINE__);
679 694
680 node = of_find_node_by_path("/"); 695 node = of_find_node_by_path("/");
681
682 if (node) { 696 if (node) {
683 os_area_set_property(node, &property_rtc_diff); 697 os_area_set_property(node, &property_rtc_diff);
684 of_node_put(node); 698 of_node_put(node);
@@ -686,12 +700,10 @@ static void os_area_queue_work_handler(struct work_struct *work)
686 pr_debug("%s:%d of_find_node_by_path failed\n", 700 pr_debug("%s:%d of_find_node_by_path failed\n",
687 __func__, __LINE__); 701 __func__, __LINE__);
688 702
689#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) 703 error = update_flash_db();
690 update_flash_db(); 704 if (error)
691#else 705 pr_warning("%s: Could not update FLASH ROM\n", __func__);
692 printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n", 706
693 __func__, __LINE__);
694#endif
695 pr_debug(" <- %s:%d\n", __func__, __LINE__); 707 pr_debug(" <- %s:%d\n", __func__, __LINE__);
696} 708}
697 709
@@ -808,7 +820,7 @@ u64 ps3_os_area_get_rtc_diff(void)
808{ 820{
809 return saved_params.rtc_diff; 821 return saved_params.rtc_diff;
810} 822}
811EXPORT_SYMBOL(ps3_os_area_get_rtc_diff); 823EXPORT_SYMBOL_GPL(ps3_os_area_get_rtc_diff);
812 824
813/** 825/**
814 * ps3_os_area_set_rtc_diff - Set the rtc diff value. 826 * ps3_os_area_set_rtc_diff - Set the rtc diff value.
@@ -824,7 +836,7 @@ void ps3_os_area_set_rtc_diff(u64 rtc_diff)
824 os_area_queue_work(); 836 os_area_queue_work();
825 } 837 }
826} 838}
827EXPORT_SYMBOL(ps3_os_area_set_rtc_diff); 839EXPORT_SYMBOL_GPL(ps3_os_area_set_rtc_diff);
828 840
829/** 841/**
830 * ps3_os_area_get_av_multi_out - Returns the default video mode. 842 * ps3_os_area_get_av_multi_out - Returns the default video mode.
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 136aa0637d9c..9a196a88eda7 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -232,14 +232,4 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
232int ps3_repository_read_vuart_av_port(unsigned int *port); 232int ps3_repository_read_vuart_av_port(unsigned int *port);
233int ps3_repository_read_vuart_sysmgr_port(unsigned int *port); 233int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
234 234
235/* Page table entries */
236#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
237#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
238#define IOPTE_M 0x2000000000000000ul /* coherency required */
239#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
240#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
241#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
242#define IOPTE_H 0x0000000000000800ul /* cache hint */
243#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
244
245#endif 235#endif
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 1a7b5ae0c83e..149bea2ce583 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -32,6 +32,7 @@
32#include <asm/udbg.h> 32#include <asm/udbg.h>
33#include <asm/prom.h> 33#include <asm/prom.h>
34#include <asm/lv1call.h> 34#include <asm/lv1call.h>
35#include <asm/ps3gpu.h>
35 36
36#include "platform.h" 37#include "platform.h"
37 38
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 9a73d0238639..9fead0faf38b 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -27,6 +27,7 @@
27#include <asm/udbg.h> 27#include <asm/udbg.h>
28#include <asm/lv1call.h> 28#include <asm/lv1call.h>
29#include <asm/firmware.h> 29#include <asm/firmware.h>
30#include <asm/iommu.h>
30 31
31#include "platform.h" 32#include "platform.h"
32 33
@@ -531,7 +532,8 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size,
531 } 532 }
532 533
533 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle, 534 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
534 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); 535 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
536 CBE_IOPTE_SO_RW | CBE_IOPTE_M);
535 537
536 if (result) { 538 if (result) {
537 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 539 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -575,7 +577,8 @@ static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
575 577
576 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, 578 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
577 &bus_addr, 579 &bus_addr,
578 IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M); 580 CBE_IOPTE_PP_R | CBE_IOPTE_PP_W |
581 CBE_IOPTE_SO_RW | CBE_IOPTE_M);
579 582
580 if (result) { 583 if (result) {
581 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 584 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -596,16 +599,16 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
596 u64 iopte_flag; 599 u64 iopte_flag;
597 void *ptr = page_address(page) + offset; 600 void *ptr = page_address(page) + offset;
598 601
599 iopte_flag = IOPTE_M; 602 iopte_flag = CBE_IOPTE_M;
600 switch (direction) { 603 switch (direction) {
601 case DMA_BIDIRECTIONAL: 604 case DMA_BIDIRECTIONAL:
602 iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW; 605 iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
603 break; 606 break;
604 case DMA_TO_DEVICE: 607 case DMA_TO_DEVICE:
605 iopte_flag |= IOPTE_PP_R | IOPTE_SO_R; 608 iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R;
606 break; 609 break;
607 case DMA_FROM_DEVICE: 610 case DMA_FROM_DEVICE:
608 iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW; 611 iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
609 break; 612 break;
610 default: 613 default:
611 /* not happned */ 614 /* not happned */
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index aaeeb544228a..34cbb7f3efa8 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -120,7 +120,7 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
120static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, 120static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
121 struct request *req) 121 struct request *req)
122{ 122{
123 struct ps3disk_private *priv = dev->sbd.core.driver_data; 123 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
124 int write = rq_data_dir(req), res; 124 int write = rq_data_dir(req), res;
125 const char *op = write ? "write" : "read"; 125 const char *op = write ? "write" : "read";
126 u64 start_sector, sectors; 126 u64 start_sector, sectors;
@@ -168,7 +168,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
168static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, 168static int ps3disk_submit_flush_request(struct ps3_storage_device *dev,
169 struct request *req) 169 struct request *req)
170{ 170{
171 struct ps3disk_private *priv = dev->sbd.core.driver_data; 171 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
172 u64 res; 172 u64 res;
173 173
174 dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__); 174 dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__);
@@ -213,7 +213,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
213static void ps3disk_request(struct request_queue *q) 213static void ps3disk_request(struct request_queue *q)
214{ 214{
215 struct ps3_storage_device *dev = q->queuedata; 215 struct ps3_storage_device *dev = q->queuedata;
216 struct ps3disk_private *priv = dev->sbd.core.driver_data; 216 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
217 217
218 if (priv->req) { 218 if (priv->req) {
219 dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__); 219 dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
@@ -245,7 +245,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
245 return IRQ_HANDLED; 245 return IRQ_HANDLED;
246 } 246 }
247 247
248 priv = dev->sbd.core.driver_data; 248 priv = ps3_system_bus_get_drvdata(&dev->sbd);
249 req = priv->req; 249 req = priv->req;
250 if (!req) { 250 if (!req) {
251 dev_dbg(&dev->sbd.core, 251 dev_dbg(&dev->sbd.core,
@@ -364,7 +364,7 @@ static void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs,
364 364
365static int ps3disk_identify(struct ps3_storage_device *dev) 365static int ps3disk_identify(struct ps3_storage_device *dev)
366{ 366{
367 struct ps3disk_private *priv = dev->sbd.core.driver_data; 367 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
368 struct lv1_ata_cmnd_block ata_cmnd; 368 struct lv1_ata_cmnd_block ata_cmnd;
369 u16 *id = dev->bounce_buf; 369 u16 *id = dev->bounce_buf;
370 u64 res; 370 u64 res;
@@ -445,7 +445,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
445 goto fail; 445 goto fail;
446 } 446 }
447 447
448 dev->sbd.core.driver_data = priv; 448 ps3_system_bus_set_drvdata(_dev, priv);
449 spin_lock_init(&priv->lock); 449 spin_lock_init(&priv->lock);
450 450
451 dev->bounce_size = BOUNCE_SIZE; 451 dev->bounce_size = BOUNCE_SIZE;
@@ -523,7 +523,7 @@ fail_free_bounce:
523 kfree(dev->bounce_buf); 523 kfree(dev->bounce_buf);
524fail_free_priv: 524fail_free_priv:
525 kfree(priv); 525 kfree(priv);
526 dev->sbd.core.driver_data = NULL; 526 ps3_system_bus_set_drvdata(_dev, NULL);
527fail: 527fail:
528 mutex_lock(&ps3disk_mask_mutex); 528 mutex_lock(&ps3disk_mask_mutex);
529 __clear_bit(devidx, &ps3disk_mask); 529 __clear_bit(devidx, &ps3disk_mask);
@@ -534,7 +534,7 @@ fail:
534static int ps3disk_remove(struct ps3_system_bus_device *_dev) 534static int ps3disk_remove(struct ps3_system_bus_device *_dev)
535{ 535{
536 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); 536 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
537 struct ps3disk_private *priv = dev->sbd.core.driver_data; 537 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
538 538
539 mutex_lock(&ps3disk_mask_mutex); 539 mutex_lock(&ps3disk_mask_mutex);
540 __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS, 540 __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
@@ -548,7 +548,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev)
548 ps3stor_teardown(dev); 548 ps3stor_teardown(dev);
549 kfree(dev->bounce_buf); 549 kfree(dev->bounce_buf);
550 kfree(priv); 550 kfree(priv);
551 dev->sbd.core.driver_data = NULL; 551 ps3_system_bus_set_drvdata(_dev, NULL);
552 return 0; 552 return 0;
553} 553}
554 554
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 8eddef373a91..095f97e60665 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -14,8 +14,10 @@
14#include <linux/seq_file.h> 14#include <linux/seq_file.h>
15 15
16#include <asm/firmware.h> 16#include <asm/firmware.h>
17#include <asm/iommu.h>
17#include <asm/lv1call.h> 18#include <asm/lv1call.h>
18#include <asm/ps3.h> 19#include <asm/ps3.h>
20#include <asm/ps3gpu.h>
19 21
20 22
21#define DEVICE_NAME "ps3vram" 23#define DEVICE_NAME "ps3vram"
@@ -45,8 +47,6 @@
45#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c 47#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
46#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 48#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104
47 49
48#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
49
50#define CACHE_PAGE_PRESENT 1 50#define CACHE_PAGE_PRESENT 1
51#define CACHE_PAGE_DIRTY 2 51#define CACHE_PAGE_DIRTY 2
52 52
@@ -72,8 +72,7 @@ struct ps3vram_priv {
72 u64 memory_handle; 72 u64 memory_handle;
73 u64 context_handle; 73 u64 context_handle;
74 u32 *ctrl; 74 u32 *ctrl;
75 u32 *reports; 75 void *reports;
76 u8 __iomem *ddr_base;
77 u8 *xdr_buf; 76 u8 *xdr_buf;
78 77
79 u32 *fifo_base; 78 u32 *fifo_base;
@@ -81,8 +80,8 @@ struct ps3vram_priv {
81 80
82 struct ps3vram_cache cache; 81 struct ps3vram_cache cache;
83 82
84 /* Used to serialize cache/DMA operations */ 83 spinlock_t lock; /* protecting list of bios */
85 struct mutex lock; 84 struct bio_list list;
86}; 85};
87 86
88 87
@@ -103,15 +102,15 @@ static char *size = "256M";
103module_param(size, charp, 0); 102module_param(size, charp, 0);
104MODULE_PARM_DESC(size, "memory size"); 103MODULE_PARM_DESC(size, "memory size");
105 104
106static u32 *ps3vram_get_notifier(u32 *reports, int notifier) 105static u32 *ps3vram_get_notifier(void *reports, int notifier)
107{ 106{
108 return (void *)reports + DMA_NOTIFIER_OFFSET_BASE + 107 return reports + DMA_NOTIFIER_OFFSET_BASE +
109 DMA_NOTIFIER_SIZE * notifier; 108 DMA_NOTIFIER_SIZE * notifier;
110} 109}
111 110
112static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) 111static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
113{ 112{
114 struct ps3vram_priv *priv = dev->core.driver_data; 113 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
115 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); 114 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
116 int i; 115 int i;
117 116
@@ -122,7 +121,7 @@ static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
122static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, 121static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
123 unsigned int timeout_ms) 122 unsigned int timeout_ms)
124{ 123{
125 struct ps3vram_priv *priv = dev->core.driver_data; 124 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
126 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); 125 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
127 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); 126 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
128 127
@@ -137,7 +136,7 @@ static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
137 136
138static void ps3vram_init_ring(struct ps3_system_bus_device *dev) 137static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
139{ 138{
140 struct ps3vram_priv *priv = dev->core.driver_data; 139 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
141 140
142 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; 141 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
143 priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; 142 priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
@@ -146,7 +145,7 @@ static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
146static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, 145static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
147 unsigned int timeout_ms) 146 unsigned int timeout_ms)
148{ 147{
149 struct ps3vram_priv *priv = dev->core.driver_data; 148 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
150 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); 149 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
151 150
152 do { 151 do {
@@ -175,7 +174,7 @@ static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag,
175 174
176static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) 175static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
177{ 176{
178 struct ps3vram_priv *priv = dev->core.driver_data; 177 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
179 int status; 178 int status;
180 179
181 ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); 180 ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
@@ -183,20 +182,17 @@ static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
183 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; 182 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
184 183
185 /* asking the HV for a blit will kick the FIFO */ 184 /* asking the HV for a blit will kick the FIFO */
186 status = lv1_gpu_context_attribute(priv->context_handle, 185 status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
187 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
188 0, 0, 0);
189 if (status) 186 if (status)
190 dev_err(&dev->core, 187 dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n",
191 "%s: lv1_gpu_context_attribute failed %d\n", __func__, 188 __func__, status);
192 status);
193 189
194 priv->fifo_ptr = priv->fifo_base; 190 priv->fifo_ptr = priv->fifo_base;
195} 191}
196 192
197static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) 193static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
198{ 194{
199 struct ps3vram_priv *priv = dev->core.driver_data; 195 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
200 int status; 196 int status;
201 197
202 mutex_lock(&ps3_gpu_mutex); 198 mutex_lock(&ps3_gpu_mutex);
@@ -205,13 +201,10 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
205 (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); 201 (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
206 202
207 /* asking the HV for a blit will kick the FIFO */ 203 /* asking the HV for a blit will kick the FIFO */
208 status = lv1_gpu_context_attribute(priv->context_handle, 204 status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
209 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
210 0, 0, 0);
211 if (status) 205 if (status)
212 dev_err(&dev->core, 206 dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n",
213 "%s: lv1_gpu_context_attribute failed %d\n", __func__, 207 __func__, status);
214 status);
215 208
216 if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > 209 if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
217 FIFO_SIZE - 1024) { 210 FIFO_SIZE - 1024) {
@@ -225,7 +218,7 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
225 218
226static void ps3vram_bind(struct ps3_system_bus_device *dev) 219static void ps3vram_bind(struct ps3_system_bus_device *dev)
227{ 220{
228 struct ps3vram_priv *priv = dev->core.driver_data; 221 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
229 222
230 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); 223 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
231 ps3vram_out_ring(priv, 0x31337303); 224 ps3vram_out_ring(priv, 0x31337303);
@@ -248,7 +241,7 @@ static int ps3vram_upload(struct ps3_system_bus_device *dev,
248 unsigned int src_offset, unsigned int dst_offset, 241 unsigned int src_offset, unsigned int dst_offset,
249 int len, int count) 242 int len, int count)
250{ 243{
251 struct ps3vram_priv *priv = dev->core.driver_data; 244 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
252 245
253 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 246 ps3vram_begin_ring(priv, UPLOAD_SUBCH,
254 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); 247 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
@@ -280,7 +273,7 @@ static int ps3vram_download(struct ps3_system_bus_device *dev,
280 unsigned int src_offset, unsigned int dst_offset, 273 unsigned int src_offset, unsigned int dst_offset,
281 int len, int count) 274 int len, int count)
282{ 275{
283 struct ps3vram_priv *priv = dev->core.driver_data; 276 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
284 277
285 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 278 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
286 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); 279 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
@@ -310,7 +303,7 @@ static int ps3vram_download(struct ps3_system_bus_device *dev,
310 303
311static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) 304static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
312{ 305{
313 struct ps3vram_priv *priv = dev->core.driver_data; 306 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
314 struct ps3vram_cache *cache = &priv->cache; 307 struct ps3vram_cache *cache = &priv->cache;
315 308
316 if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY)) 309 if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY))
@@ -332,7 +325,7 @@ static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
332static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, 325static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
333 unsigned int address) 326 unsigned int address)
334{ 327{
335 struct ps3vram_priv *priv = dev->core.driver_data; 328 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
336 struct ps3vram_cache *cache = &priv->cache; 329 struct ps3vram_cache *cache = &priv->cache;
337 330
338 dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address); 331 dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address);
@@ -352,7 +345,7 @@ static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
352 345
353static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) 346static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
354{ 347{
355 struct ps3vram_priv *priv = dev->core.driver_data; 348 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
356 struct ps3vram_cache *cache = &priv->cache; 349 struct ps3vram_cache *cache = &priv->cache;
357 int i; 350 int i;
358 351
@@ -366,7 +359,7 @@ static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
366static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, 359static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
367 loff_t address) 360 loff_t address)
368{ 361{
369 struct ps3vram_priv *priv = dev->core.driver_data; 362 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
370 struct ps3vram_cache *cache = &priv->cache; 363 struct ps3vram_cache *cache = &priv->cache;
371 unsigned int base; 364 unsigned int base;
372 unsigned int offset; 365 unsigned int offset;
@@ -400,7 +393,7 @@ static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
400 393
401static int ps3vram_cache_init(struct ps3_system_bus_device *dev) 394static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
402{ 395{
403 struct ps3vram_priv *priv = dev->core.driver_data; 396 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
404 397
405 priv->cache.page_count = CACHE_PAGE_COUNT; 398 priv->cache.page_count = CACHE_PAGE_COUNT;
406 priv->cache.page_size = CACHE_PAGE_SIZE; 399 priv->cache.page_size = CACHE_PAGE_SIZE;
@@ -419,7 +412,7 @@ static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
419 412
420static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) 413static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
421{ 414{
422 struct ps3vram_priv *priv = dev->core.driver_data; 415 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
423 416
424 ps3vram_cache_flush(dev); 417 ps3vram_cache_flush(dev);
425 kfree(priv->cache.tags); 418 kfree(priv->cache.tags);
@@ -428,7 +421,7 @@ static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
428static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, 421static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
429 size_t len, size_t *retlen, u_char *buf) 422 size_t len, size_t *retlen, u_char *buf)
430{ 423{
431 struct ps3vram_priv *priv = dev->core.driver_data; 424 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
432 unsigned int cached, count; 425 unsigned int cached, count;
433 426
434 dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__, 427 dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__,
@@ -449,8 +442,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
449 offset = (unsigned int) (from & (priv->cache.page_size - 1)); 442 offset = (unsigned int) (from & (priv->cache.page_size - 1));
450 avail = priv->cache.page_size - offset; 443 avail = priv->cache.page_size - offset;
451 444
452 mutex_lock(&priv->lock);
453
454 entry = ps3vram_cache_match(dev, from); 445 entry = ps3vram_cache_match(dev, from);
455 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; 446 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
456 447
@@ -462,8 +453,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
462 avail = count; 453 avail = count;
463 memcpy(buf, priv->xdr_buf + cached, avail); 454 memcpy(buf, priv->xdr_buf + cached, avail);
464 455
465 mutex_unlock(&priv->lock);
466
467 buf += avail; 456 buf += avail;
468 count -= avail; 457 count -= avail;
469 from += avail; 458 from += avail;
@@ -476,7 +465,7 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
476static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, 465static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
477 size_t len, size_t *retlen, const u_char *buf) 466 size_t len, size_t *retlen, const u_char *buf)
478{ 467{
479 struct ps3vram_priv *priv = dev->core.driver_data; 468 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
480 unsigned int cached, count; 469 unsigned int cached, count;
481 470
482 if (to >= priv->size) 471 if (to >= priv->size)
@@ -494,8 +483,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
494 offset = (unsigned int) (to & (priv->cache.page_size - 1)); 483 offset = (unsigned int) (to & (priv->cache.page_size - 1));
495 avail = priv->cache.page_size - offset; 484 avail = priv->cache.page_size - offset;
496 485
497 mutex_lock(&priv->lock);
498
499 entry = ps3vram_cache_match(dev, to); 486 entry = ps3vram_cache_match(dev, to);
500 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; 487 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
501 488
@@ -509,8 +496,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
509 496
510 priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; 497 priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
511 498
512 mutex_unlock(&priv->lock);
513
514 buf += avail; 499 buf += avail;
515 count -= avail; 500 count -= avail;
516 to += avail; 501 to += avail;
@@ -543,28 +528,26 @@ static const struct file_operations ps3vram_proc_fops = {
543 528
544static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) 529static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
545{ 530{
546 struct ps3vram_priv *priv = dev->core.driver_data; 531 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
547 struct proc_dir_entry *pde; 532 struct proc_dir_entry *pde;
548 533
549 pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops); 534 pde = proc_create_data(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops,
550 if (!pde) { 535 priv);
536 if (!pde)
551 dev_warn(&dev->core, "failed to create /proc entry\n"); 537 dev_warn(&dev->core, "failed to create /proc entry\n");
552 return;
553 }
554 pde->data = priv;
555} 538}
556 539
557static int ps3vram_make_request(struct request_queue *q, struct bio *bio) 540static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
541 struct bio *bio)
558{ 542{
559 struct ps3_system_bus_device *dev = q->queuedata; 543 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
560 int write = bio_data_dir(bio) == WRITE; 544 int write = bio_data_dir(bio) == WRITE;
561 const char *op = write ? "write" : "read"; 545 const char *op = write ? "write" : "read";
562 loff_t offset = bio->bi_sector << 9; 546 loff_t offset = bio->bi_sector << 9;
563 int error = 0; 547 int error = 0;
564 struct bio_vec *bvec; 548 struct bio_vec *bvec;
565 unsigned int i; 549 unsigned int i;
566 550 struct bio *next;
567 dev_dbg(&dev->core, "%s\n", __func__);
568 551
569 bio_for_each_segment(bvec, bio, i) { 552 bio_for_each_segment(bvec, bio, i) {
570 /* PS3 is ppc64, so we don't handle highmem */ 553 /* PS3 is ppc64, so we don't handle highmem */
@@ -585,6 +568,7 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
585 568
586 if (retlen != len) { 569 if (retlen != len) {
587 dev_err(&dev->core, "Short %s\n", op); 570 dev_err(&dev->core, "Short %s\n", op);
571 error = -EIO;
588 goto out; 572 goto out;
589 } 573 }
590 574
@@ -594,7 +578,35 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
594 dev_dbg(&dev->core, "%s completed\n", op); 578 dev_dbg(&dev->core, "%s completed\n", op);
595 579
596out: 580out:
581 spin_lock_irq(&priv->lock);
582 bio_list_pop(&priv->list);
583 next = bio_list_peek(&priv->list);
584 spin_unlock_irq(&priv->lock);
585
597 bio_endio(bio, error); 586 bio_endio(bio, error);
587 return next;
588}
589
590static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
591{
592 struct ps3_system_bus_device *dev = q->queuedata;
593 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
594 int busy;
595
596 dev_dbg(&dev->core, "%s\n", __func__);
597
598 spin_lock_irq(&priv->lock);
599 busy = !bio_list_empty(&priv->list);
600 bio_list_add(&priv->list, bio);
601 spin_unlock_irq(&priv->lock);
602
603 if (busy)
604 return 0;
605
606 do {
607 bio = ps3vram_do_bio(dev, bio);
608 } while (bio);
609
598 return 0; 610 return 0;
599} 611}
600 612
@@ -604,8 +616,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
604 int error, status; 616 int error, status;
605 struct request_queue *queue; 617 struct request_queue *queue;
606 struct gendisk *gendisk; 618 struct gendisk *gendisk;
607 u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size, 619 u64 ddr_size, ddr_lpar, ctrl_lpar, info_lpar, reports_lpar,
608 reports_size; 620 reports_size, xdr_lpar;
609 char *rest; 621 char *rest;
610 622
611 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 623 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -614,10 +626,9 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
614 goto fail; 626 goto fail;
615 } 627 }
616 628
617 mutex_init(&priv->lock); 629 spin_lock_init(&priv->lock);
618 dev->core.driver_data = priv; 630 bio_list_init(&priv->list);
619 631 ps3_system_bus_set_drvdata(dev, priv);
620 priv = dev->core.driver_data;
621 632
622 /* Allocate XDR buffer (1MiB aligned) */ 633 /* Allocate XDR buffer (1MiB aligned) */
623 priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, 634 priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
@@ -636,7 +647,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
636 if (ps3_open_hv_device(dev)) { 647 if (ps3_open_hv_device(dev)) {
637 dev_err(&dev->core, "ps3_open_hv_device failed\n"); 648 dev_err(&dev->core, "ps3_open_hv_device failed\n");
638 error = -EAGAIN; 649 error = -EAGAIN;
639 goto out_close_gpu; 650 goto out_free_xdr_buf;
640 } 651 }
641 652
642 /* Request memory */ 653 /* Request memory */
@@ -660,7 +671,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
660 dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n", 671 dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n",
661 status); 672 status);
662 error = -ENOMEM; 673 error = -ENOMEM;
663 goto out_free_xdr_buf; 674 goto out_close_gpu;
664 } 675 }
665 676
666 /* Request context */ 677 /* Request context */
@@ -676,9 +687,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
676 } 687 }
677 688
678 /* Map XDR buffer to RSX */ 689 /* Map XDR buffer to RSX */
690 xdr_lpar = ps3_mm_phys_to_lpar(__pa(priv->xdr_buf));
679 status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, 691 status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
680 ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), 692 xdr_lpar, XDR_BUF_SIZE,
681 XDR_BUF_SIZE, 0); 693 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
694 CBE_IOPTE_M);
682 if (status) { 695 if (status) {
683 dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n", 696 dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n",
684 status); 697 status);
@@ -686,19 +699,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
686 goto out_free_context; 699 goto out_free_context;
687 } 700 }
688 701
689 priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
690
691 if (!priv->ddr_base) {
692 dev_err(&dev->core, "ioremap DDR failed\n");
693 error = -ENOMEM;
694 goto out_free_context;
695 }
696
697 priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); 702 priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
698 if (!priv->ctrl) { 703 if (!priv->ctrl) {
699 dev_err(&dev->core, "ioremap CTRL failed\n"); 704 dev_err(&dev->core, "ioremap CTRL failed\n");
700 error = -ENOMEM; 705 error = -ENOMEM;
701 goto out_unmap_vram; 706 goto out_unmap_context;
702 } 707 }
703 708
704 priv->reports = ioremap(reports_lpar, reports_size); 709 priv->reports = ioremap(reports_lpar, reports_size);
@@ -775,8 +780,9 @@ out_unmap_reports:
775 iounmap(priv->reports); 780 iounmap(priv->reports);
776out_unmap_ctrl: 781out_unmap_ctrl:
777 iounmap(priv->ctrl); 782 iounmap(priv->ctrl);
778out_unmap_vram: 783out_unmap_context:
779 iounmap(priv->ddr_base); 784 lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, xdr_lpar,
785 XDR_BUF_SIZE, CBE_IOPTE_M);
780out_free_context: 786out_free_context:
781 lv1_gpu_context_free(priv->context_handle); 787 lv1_gpu_context_free(priv->context_handle);
782out_free_memory: 788out_free_memory:
@@ -787,14 +793,14 @@ out_free_xdr_buf:
787 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); 793 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
788fail_free_priv: 794fail_free_priv:
789 kfree(priv); 795 kfree(priv);
790 dev->core.driver_data = NULL; 796 ps3_system_bus_set_drvdata(dev, NULL);
791fail: 797fail:
792 return error; 798 return error;
793} 799}
794 800
795static int ps3vram_remove(struct ps3_system_bus_device *dev) 801static int ps3vram_remove(struct ps3_system_bus_device *dev)
796{ 802{
797 struct ps3vram_priv *priv = dev->core.driver_data; 803 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
798 804
799 del_gendisk(priv->gendisk); 805 del_gendisk(priv->gendisk);
800 put_disk(priv->gendisk); 806 put_disk(priv->gendisk);
@@ -803,13 +809,15 @@ static int ps3vram_remove(struct ps3_system_bus_device *dev)
803 ps3vram_cache_cleanup(dev); 809 ps3vram_cache_cleanup(dev);
804 iounmap(priv->reports); 810 iounmap(priv->reports);
805 iounmap(priv->ctrl); 811 iounmap(priv->ctrl);
806 iounmap(priv->ddr_base); 812 lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
813 ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
814 XDR_BUF_SIZE, CBE_IOPTE_M);
807 lv1_gpu_context_free(priv->context_handle); 815 lv1_gpu_context_free(priv->context_handle);
808 lv1_gpu_memory_free(priv->memory_handle); 816 lv1_gpu_memory_free(priv->memory_handle);
809 ps3_close_hv_device(dev); 817 ps3_close_hv_device(dev);
810 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); 818 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
811 kfree(priv); 819 kfree(priv);
812 dev->core.driver_data = NULL; 820 ps3_system_bus_set_drvdata(dev, NULL);
813 return 0; 821 return 0;
814} 822}
815 823
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index afbe45676d71..f424d394a286 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -33,48 +33,64 @@
33 33
34struct ps3flash_private { 34struct ps3flash_private {
35 struct mutex mutex; /* Bounce buffer mutex */ 35 struct mutex mutex; /* Bounce buffer mutex */
36 u64 chunk_sectors;
37 int tag; /* Start sector of buffer, -1 if invalid */
38 bool dirty;
36}; 39};
37 40
38static struct ps3_storage_device *ps3flash_dev; 41static struct ps3_storage_device *ps3flash_dev;
39 42
40static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev, 43static int ps3flash_read_write_sectors(struct ps3_storage_device *dev,
41 u64 lpar, u64 start_sector, 44 u64 start_sector, int write)
42 u64 sectors, int write)
43{ 45{
44 u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, 46 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
47 u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar,
48 start_sector, priv->chunk_sectors,
45 write); 49 write);
46 if (res) { 50 if (res) {
47 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, 51 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
48 __LINE__, write ? "write" : "read", res); 52 __LINE__, write ? "write" : "read", res);
49 return -EIO; 53 return -EIO;
50 } 54 }
51 return sectors; 55 return 0;
52} 56}
53 57
54static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev, 58static int ps3flash_writeback(struct ps3_storage_device *dev)
55 u64 start_sector, u64 sectors,
56 unsigned int sector_offset)
57{ 59{
58 u64 max_sectors, lpar; 60 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
61 int res;
59 62
60 max_sectors = dev->bounce_size / dev->blk_size; 63 if (!priv->dirty || priv->tag < 0)
61 if (sectors > max_sectors) { 64 return 0;
62 dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %llu\n",
63 __func__, __LINE__, max_sectors);
64 sectors = max_sectors;
65 }
66 65
67 lpar = dev->bounce_lpar + sector_offset * dev->blk_size; 66 res = ps3flash_read_write_sectors(dev, priv->tag, 1);
68 return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, 67 if (res)
69 0); 68 return res;
69
70 priv->dirty = false;
71 return 0;
70} 72}
71 73
72static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev, 74static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector)
73 u64 start_sector)
74{ 75{
75 u64 sectors = dev->bounce_size / dev->blk_size; 76 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
76 return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector, 77 int res;
77 sectors, 1); 78
79 if (start_sector == priv->tag)
80 return 0;
81
82 res = ps3flash_writeback(dev);
83 if (res)
84 return res;
85
86 priv->tag = -1;
87
88 res = ps3flash_read_write_sectors(dev, start_sector, 0);
89 if (res)
90 return res;
91
92 priv->tag = start_sector;
93 return 0;
78} 94}
79 95
80static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) 96static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
@@ -104,18 +120,19 @@ out:
104 return res; 120 return res;
105} 121}
106 122
107static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, 123static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf,
108 loff_t *pos) 124 size_t count, loff_t *pos)
109{ 125{
110 struct ps3_storage_device *dev = ps3flash_dev; 126 struct ps3_storage_device *dev = ps3flash_dev;
111 struct ps3flash_private *priv = dev->sbd.core.driver_data; 127 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
112 u64 size, start_sector, end_sector, offset; 128 u64 size, sector, offset;
113 ssize_t sectors_read; 129 int res;
114 size_t remaining, n; 130 size_t remaining, n;
131 const void *src;
115 132
116 dev_dbg(&dev->sbd.core, 133 dev_dbg(&dev->sbd.core,
117 "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n", 134 "%s:%u: Reading %zu bytes at position %lld to U0x%p/K0x%p\n",
118 __func__, __LINE__, count, *pos, buf); 135 __func__, __LINE__, count, *pos, userbuf, kernelbuf);
119 136
120 size = dev->regions[dev->region_idx].size*dev->blk_size; 137 size = dev->regions[dev->region_idx].size*dev->blk_size;
121 if (*pos >= size || !count) 138 if (*pos >= size || !count)
@@ -128,61 +145,63 @@ static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count,
128 count = size - *pos; 145 count = size - *pos;
129 } 146 }
130 147
131 start_sector = *pos / dev->blk_size; 148 sector = *pos / dev->bounce_size * priv->chunk_sectors;
132 offset = *pos % dev->blk_size; 149 offset = *pos % dev->bounce_size;
133 end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size);
134 150
135 remaining = count; 151 remaining = count;
136 do { 152 do {
153 n = min_t(u64, remaining, dev->bounce_size - offset);
154 src = dev->bounce_buf + offset;
155
137 mutex_lock(&priv->mutex); 156 mutex_lock(&priv->mutex);
138 157
139 sectors_read = ps3flash_read_sectors(dev, start_sector, 158 res = ps3flash_fetch(dev, sector);
140 end_sector-start_sector, 159 if (res)
141 0);
142 if (sectors_read < 0) {
143 mutex_unlock(&priv->mutex);
144 goto fail; 160 goto fail;
145 }
146 161
147 n = min_t(u64, remaining, sectors_read*dev->blk_size-offset);
148 dev_dbg(&dev->sbd.core, 162 dev_dbg(&dev->sbd.core,
149 "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n", 163 "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n",
150 __func__, __LINE__, n, dev->bounce_buf+offset, buf); 164 __func__, __LINE__, n, src, userbuf, kernelbuf);
151 if (copy_to_user(buf, dev->bounce_buf+offset, n)) { 165 if (userbuf) {
152 mutex_unlock(&priv->mutex); 166 if (copy_to_user(userbuf, src, n)) {
153 sectors_read = -EFAULT; 167 res = -EFAULT;
154 goto fail; 168 goto fail;
169 }
170 userbuf += n;
171 }
172 if (kernelbuf) {
173 memcpy(kernelbuf, src, n);
174 kernelbuf += n;
155 } 175 }
156 176
157 mutex_unlock(&priv->mutex); 177 mutex_unlock(&priv->mutex);
158 178
159 *pos += n; 179 *pos += n;
160 buf += n;
161 remaining -= n; 180 remaining -= n;
162 start_sector += sectors_read; 181 sector += priv->chunk_sectors;
163 offset = 0; 182 offset = 0;
164 } while (remaining > 0); 183 } while (remaining > 0);
165 184
166 return count; 185 return count;
167 186
168fail: 187fail:
169 return sectors_read; 188 mutex_unlock(&priv->mutex);
189 return res;
170} 190}
171 191
172static ssize_t ps3flash_write(struct file *file, const char __user *buf, 192static ssize_t ps3flash_write(const char __user *userbuf,
173 size_t count, loff_t *pos) 193 const void *kernelbuf, size_t count, loff_t *pos)
174{ 194{
175 struct ps3_storage_device *dev = ps3flash_dev; 195 struct ps3_storage_device *dev = ps3flash_dev;
176 struct ps3flash_private *priv = dev->sbd.core.driver_data; 196 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
177 u64 size, chunk_sectors, start_write_sector, end_write_sector, 197 u64 size, sector, offset;
178 end_read_sector, start_read_sector, head, tail, offset; 198 int res = 0;
179 ssize_t res;
180 size_t remaining, n; 199 size_t remaining, n;
181 unsigned int sec_off; 200 void *dst;
182 201
183 dev_dbg(&dev->sbd.core, 202 dev_dbg(&dev->sbd.core,
184 "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n", 203 "%s:%u: Writing %zu bytes at position %lld from U0x%p/K0x%p\n",
185 __func__, __LINE__, count, *pos, buf); 204 __func__, __LINE__, count, *pos, userbuf, kernelbuf);
186 205
187 size = dev->regions[dev->region_idx].size*dev->blk_size; 206 size = dev->regions[dev->region_idx].size*dev->blk_size;
188 if (*pos >= size || !count) 207 if (*pos >= size || !count)
@@ -195,89 +214,46 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf,
195 count = size - *pos; 214 count = size - *pos;
196 } 215 }
197 216
198 chunk_sectors = dev->bounce_size / dev->blk_size; 217 sector = *pos / dev->bounce_size * priv->chunk_sectors;
199
200 start_write_sector = *pos / dev->bounce_size * chunk_sectors;
201 offset = *pos % dev->bounce_size; 218 offset = *pos % dev->bounce_size;
202 end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) *
203 chunk_sectors;
204
205 end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size);
206 start_read_sector = (*pos + count) / dev->blk_size;
207
208 /*
209 * As we have to write in 256 KiB chunks, while we can read in blk_size
210 * (usually 512 bytes) chunks, we perform the following steps:
211 * 1. Read from start_write_sector to end_read_sector ("head")
212 * 2. Read from start_read_sector to end_write_sector ("tail")
213 * 3. Copy data to buffer
214 * 4. Write from start_write_sector to end_write_sector
215 * All of this is complicated by using only one 256 KiB bounce buffer.
216 */
217
218 head = end_read_sector - start_write_sector;
219 tail = end_write_sector - start_read_sector;
220 219
221 remaining = count; 220 remaining = count;
222 do { 221 do {
222 n = min_t(u64, remaining, dev->bounce_size - offset);
223 dst = dev->bounce_buf + offset;
224
223 mutex_lock(&priv->mutex); 225 mutex_lock(&priv->mutex);
224 226
225 if (end_read_sector >= start_read_sector) { 227 if (n != dev->bounce_size)
226 /* Merge head and tail */ 228 res = ps3flash_fetch(dev, sector);
227 dev_dbg(&dev->sbd.core, 229 else if (sector != priv->tag)
228 "Merged head and tail: %llu sectors at %llu\n", 230 res = ps3flash_writeback(dev);
229 chunk_sectors, start_write_sector); 231 if (res)
230 res = ps3flash_read_sectors(dev, start_write_sector, 232 goto fail;
231 chunk_sectors, 0); 233
232 if (res < 0) 234 dev_dbg(&dev->sbd.core,
235 "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n",
236 __func__, __LINE__, n, userbuf, kernelbuf, dst);
237 if (userbuf) {
238 if (copy_from_user(dst, userbuf, n)) {
239 res = -EFAULT;
233 goto fail; 240 goto fail;
234 } else {
235 if (head) {
236 /* Read head */
237 dev_dbg(&dev->sbd.core,
238 "head: %llu sectors at %llu\n", head,
239 start_write_sector);
240 res = ps3flash_read_sectors(dev,
241 start_write_sector,
242 head, 0);
243 if (res < 0)
244 goto fail;
245 }
246 if (start_read_sector <
247 start_write_sector+chunk_sectors) {
248 /* Read tail */
249 dev_dbg(&dev->sbd.core,
250 "tail: %llu sectors at %llu\n", tail,
251 start_read_sector);
252 sec_off = start_read_sector-start_write_sector;
253 res = ps3flash_read_sectors(dev,
254 start_read_sector,
255 tail, sec_off);
256 if (res < 0)
257 goto fail;
258 } 241 }
242 userbuf += n;
259 } 243 }
260 244 if (kernelbuf) {
261 n = min_t(u64, remaining, dev->bounce_size-offset); 245 memcpy(dst, kernelbuf, n);
262 dev_dbg(&dev->sbd.core, 246 kernelbuf += n;
263 "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n",
264 __func__, __LINE__, n, buf, dev->bounce_buf+offset);
265 if (copy_from_user(dev->bounce_buf+offset, buf, n)) {
266 res = -EFAULT;
267 goto fail;
268 } 247 }
269 248
270 res = ps3flash_write_chunk(dev, start_write_sector); 249 priv->tag = sector;
271 if (res < 0) 250 priv->dirty = true;
272 goto fail;
273 251
274 mutex_unlock(&priv->mutex); 252 mutex_unlock(&priv->mutex);
275 253
276 *pos += n; 254 *pos += n;
277 buf += n;
278 remaining -= n; 255 remaining -= n;
279 start_write_sector += chunk_sectors; 256 sector += priv->chunk_sectors;
280 head = 0;
281 offset = 0; 257 offset = 0;
282 } while (remaining > 0); 258 } while (remaining > 0);
283 259
@@ -288,6 +264,51 @@ fail:
288 return res; 264 return res;
289} 265}
290 266
267static ssize_t ps3flash_user_read(struct file *file, char __user *buf,
268 size_t count, loff_t *pos)
269{
270 return ps3flash_read(buf, NULL, count, pos);
271}
272
273static ssize_t ps3flash_user_write(struct file *file, const char __user *buf,
274 size_t count, loff_t *pos)
275{
276 return ps3flash_write(buf, NULL, count, pos);
277}
278
279static ssize_t ps3flash_kernel_read(void *buf, size_t count, loff_t pos)
280{
281 return ps3flash_read(NULL, buf, count, &pos);
282}
283
284static ssize_t ps3flash_kernel_write(const void *buf, size_t count,
285 loff_t pos)
286{
287 ssize_t res;
288 int wb;
289
290 res = ps3flash_write(NULL, buf, count, &pos);
291 if (res < 0)
292 return res;
293
294 /* Make kernel writes synchronous */
295 wb = ps3flash_writeback(ps3flash_dev);
296 if (wb)
297 return wb;
298
299 return res;
300}
301
302static int ps3flash_flush(struct file *file, fl_owner_t id)
303{
304 return ps3flash_writeback(ps3flash_dev);
305}
306
307static int ps3flash_fsync(struct file *file, struct dentry *dentry,
308 int datasync)
309{
310 return ps3flash_writeback(ps3flash_dev);
311}
291 312
292static irqreturn_t ps3flash_interrupt(int irq, void *data) 313static irqreturn_t ps3flash_interrupt(int irq, void *data)
293{ 314{
@@ -312,12 +333,18 @@ static irqreturn_t ps3flash_interrupt(int irq, void *data)
312 return IRQ_HANDLED; 333 return IRQ_HANDLED;
313} 334}
314 335
315
316static const struct file_operations ps3flash_fops = { 336static const struct file_operations ps3flash_fops = {
317 .owner = THIS_MODULE, 337 .owner = THIS_MODULE,
318 .llseek = ps3flash_llseek, 338 .llseek = ps3flash_llseek,
319 .read = ps3flash_read, 339 .read = ps3flash_user_read,
320 .write = ps3flash_write, 340 .write = ps3flash_user_write,
341 .flush = ps3flash_flush,
342 .fsync = ps3flash_fsync,
343};
344
345static const struct ps3_os_area_flash_ops ps3flash_kernel_ops = {
346 .read = ps3flash_kernel_read,
347 .write = ps3flash_kernel_write,
321}; 348};
322 349
323static struct miscdevice ps3flash_misc = { 350static struct miscdevice ps3flash_misc = {
@@ -366,11 +393,13 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
366 goto fail; 393 goto fail;
367 } 394 }
368 395
369 dev->sbd.core.driver_data = priv; 396 ps3_system_bus_set_drvdata(&dev->sbd, priv);
370 mutex_init(&priv->mutex); 397 mutex_init(&priv->mutex);
398 priv->tag = -1;
371 399
372 dev->bounce_size = ps3flash_bounce_buffer.size; 400 dev->bounce_size = ps3flash_bounce_buffer.size;
373 dev->bounce_buf = ps3flash_bounce_buffer.address; 401 dev->bounce_buf = ps3flash_bounce_buffer.address;
402 priv->chunk_sectors = dev->bounce_size / dev->blk_size;
374 403
375 error = ps3stor_setup(dev, ps3flash_interrupt); 404 error = ps3stor_setup(dev, ps3flash_interrupt);
376 if (error) 405 if (error)
@@ -386,13 +415,15 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
386 415
387 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n", 416 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n",
388 __func__, __LINE__, ps3flash_misc.minor); 417 __func__, __LINE__, ps3flash_misc.minor);
418
419 ps3_os_area_flash_register(&ps3flash_kernel_ops);
389 return 0; 420 return 0;
390 421
391fail_teardown: 422fail_teardown:
392 ps3stor_teardown(dev); 423 ps3stor_teardown(dev);
393fail_free_priv: 424fail_free_priv:
394 kfree(priv); 425 kfree(priv);
395 dev->sbd.core.driver_data = NULL; 426 ps3_system_bus_set_drvdata(&dev->sbd, NULL);
396fail: 427fail:
397 ps3flash_dev = NULL; 428 ps3flash_dev = NULL;
398 return error; 429 return error;
@@ -402,10 +433,11 @@ static int ps3flash_remove(struct ps3_system_bus_device *_dev)
402{ 433{
403 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); 434 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
404 435
436 ps3_os_area_flash_register(NULL);
405 misc_deregister(&ps3flash_misc); 437 misc_deregister(&ps3flash_misc);
406 ps3stor_teardown(dev); 438 ps3stor_teardown(dev);
407 kfree(dev->sbd.core.driver_data); 439 kfree(ps3_system_bus_get_drvdata(&dev->sbd));
408 dev->sbd.core.driver_data = NULL; 440 ps3_system_bus_set_drvdata(&dev->sbd, NULL);
409 ps3flash_dev = NULL; 441 ps3flash_dev = NULL;
410 return 0; 442 return 0;
411} 443}
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 30900b30d532..2b38f39924a6 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -1648,7 +1648,7 @@ static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
1648 result = -ENOMEM; 1648 result = -ENOMEM;
1649 goto fail_alloc_card; 1649 goto fail_alloc_card;
1650 } 1650 }
1651 ps3_system_bus_set_driver_data(dev, card); 1651 ps3_system_bus_set_drvdata(dev, card);
1652 card->dev = dev; 1652 card->dev = dev;
1653 1653
1654 /* get internal vlan info */ 1654 /* get internal vlan info */
@@ -1749,7 +1749,7 @@ fail_alloc_irq:
1749 bus_id(card), 1749 bus_id(card),
1750 0, 0); 1750 0, 0);
1751fail_status_indicator: 1751fail_status_indicator:
1752 ps3_system_bus_set_driver_data(dev, NULL); 1752 ps3_system_bus_set_drvdata(dev, NULL);
1753 kfree(netdev_card(netdev)->unalign); 1753 kfree(netdev_card(netdev)->unalign);
1754 free_netdev(netdev); 1754 free_netdev(netdev);
1755fail_alloc_card: 1755fail_alloc_card:
@@ -1766,7 +1766,7 @@ fail_open:
1766 1766
1767static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) 1767static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev)
1768{ 1768{
1769 struct gelic_card *card = ps3_system_bus_get_driver_data(dev); 1769 struct gelic_card *card = ps3_system_bus_get_drvdata(dev);
1770 struct net_device *netdev0; 1770 struct net_device *netdev0;
1771 pr_debug("%s: called\n", __func__); 1771 pr_debug("%s: called\n", __func__);
1772 1772
@@ -1803,7 +1803,7 @@ static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev)
1803 kfree(netdev_card(netdev0)->unalign); 1803 kfree(netdev_card(netdev0)->unalign);
1804 free_netdev(netdev0); 1804 free_netdev(netdev0);
1805 1805
1806 ps3_system_bus_set_driver_data(dev, NULL); 1806 ps3_system_bus_set_drvdata(dev, NULL);
1807 1807
1808 ps3_dma_region_free(dev->d_region); 1808 ps3_dma_region_free(dev->d_region);
1809 1809
diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c
index f17513dd9d4b..88cb74088611 100644
--- a/drivers/ps3/ps3-sys-manager.c
+++ b/drivers/ps3/ps3-sys-manager.c
@@ -706,7 +706,7 @@ static void ps3_sys_manager_work(struct ps3_system_bus_device *dev)
706 ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN); 706 ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);
707} 707}
708 708
709static int ps3_sys_manager_probe(struct ps3_system_bus_device *dev) 709static int __devinit ps3_sys_manager_probe(struct ps3_system_bus_device *dev)
710{ 710{
711 int result; 711 int result;
712 struct ps3_sys_manager_ops ops; 712 struct ps3_sys_manager_ops ops;
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 235e87fcb49f..e82d8c9c6cda 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -80,12 +80,12 @@ static const struct avset_video_mode {
80 { 0, }, /* auto */ 80 { 0, }, /* auto */
81 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480}, 81 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480},
82 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480}, 82 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480},
83 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720}, 83 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_W, 1280, 720},
84 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080}, 84 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080},
85 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080}, 85 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080},
86 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576}, 86 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576},
87 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576}, 87 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576},
88 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720}, 88 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_W, 1280, 720},
89 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080}, 89 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080},
90 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080}, 90 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080},
91 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768}, 91 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768},
@@ -937,7 +937,7 @@ int ps3av_audio_mute(int mute)
937 937
938EXPORT_SYMBOL_GPL(ps3av_audio_mute); 938EXPORT_SYMBOL_GPL(ps3av_audio_mute);
939 939
940static int ps3av_probe(struct ps3_system_bus_device *dev) 940static int __devinit ps3av_probe(struct ps3_system_bus_device *dev)
941{ 941{
942 int res; 942 int res;
943 int id; 943 int id;
@@ -1048,7 +1048,7 @@ static struct ps3_vuart_port_driver ps3av_driver = {
1048 .shutdown = ps3av_shutdown, 1048 .shutdown = ps3av_shutdown,
1049}; 1049};
1050 1050
1051static int ps3av_module_init(void) 1051static int __init ps3av_module_init(void)
1052{ 1052{
1053 int error; 1053 int error;
1054 1054
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index 716596e8e5b0..f555fedd5073 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -21,9 +21,10 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24
24#include <asm/ps3av.h> 25#include <asm/ps3av.h>
25#include <asm/ps3fb.h>
26#include <asm/ps3.h> 26#include <asm/ps3.h>
27#include <asm/ps3gpu.h>
27 28
28#include "vuart.h" 29#include "vuart.h"
29 30
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 1ba9f9a8c308..bb870b8f81bc 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -162,7 +162,7 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, 162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__,
163 (unsigned long)virq); 163 (unsigned long)virq);
164 164
165 ps3_system_bus_set_driver_data(dev, hcd); 165 ps3_system_bus_set_drvdata(dev, hcd);
166 166
167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED); 167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED);
168 168
@@ -195,8 +195,7 @@ fail_start:
195static int ps3_ehci_remove(struct ps3_system_bus_device *dev) 195static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
196{ 196{
197 unsigned int tmp; 197 unsigned int tmp;
198 struct usb_hcd *hcd = 198 struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev);
199 (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
200 199
201 BUG_ON(!hcd); 200 BUG_ON(!hcd);
202 201
@@ -208,7 +207,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
208 ehci_shutdown(hcd); 207 ehci_shutdown(hcd);
209 usb_remove_hcd(hcd); 208 usb_remove_hcd(hcd);
210 209
211 ps3_system_bus_set_driver_data(dev, NULL); 210 ps3_system_bus_set_drvdata(dev, NULL);
212 211
213 BUG_ON(!hcd->regs); 212 BUG_ON(!hcd->regs);
214 iounmap(hcd->regs); 213 iounmap(hcd->regs);
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 3d1910317328..1d56259c5db1 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -162,7 +162,7 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, 162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__,
163 (unsigned long)virq); 163 (unsigned long)virq);
164 164
165 ps3_system_bus_set_driver_data(dev, hcd); 165 ps3_system_bus_set_drvdata(dev, hcd);
166 166
167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED); 167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED);
168 168
@@ -195,8 +195,7 @@ fail_start:
195static int ps3_ohci_remove(struct ps3_system_bus_device *dev) 195static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
196{ 196{
197 unsigned int tmp; 197 unsigned int tmp;
198 struct usb_hcd *hcd = 198 struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev);
199 (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
200 199
201 BUG_ON(!hcd); 200 BUG_ON(!hcd);
202 201
@@ -208,7 +207,7 @@ static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
208 ohci_shutdown(hcd); 207 ohci_shutdown(hcd);
209 usb_remove_hcd(hcd); 208 usb_remove_hcd(hcd);
210 209
211 ps3_system_bus_set_driver_data(dev, NULL); 210 ps3_system_bus_set_drvdata(dev, NULL);
212 211
213 BUG_ON(!hcd->regs); 212 BUG_ON(!hcd->regs);
214 iounmap(hcd->regs); 213 iounmap(hcd->regs);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index e00c1dff55de..c0af638fe702 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -32,25 +32,16 @@
32#include <linux/init.h> 32#include <linux/init.h>
33 33
34#include <asm/abs_addr.h> 34#include <asm/abs_addr.h>
35#include <asm/iommu.h>
35#include <asm/lv1call.h> 36#include <asm/lv1call.h>
36#include <asm/ps3av.h> 37#include <asm/ps3av.h>
37#include <asm/ps3fb.h> 38#include <asm/ps3fb.h>
38#include <asm/ps3.h> 39#include <asm/ps3.h>
40#include <asm/ps3gpu.h>
39 41
40 42
41#define DEVICE_NAME "ps3fb" 43#define DEVICE_NAME "ps3fb"
42 44
43#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
44#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
45#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
46#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
47#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602
48
49#define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32)
50
51#define L1GPU_DISPLAY_SYNC_HSYNC 1
52#define L1GPU_DISPLAY_SYNC_VSYNC 2
53
54#define GPU_CMD_BUF_SIZE (2 * 1024 * 1024) 45#define GPU_CMD_BUF_SIZE (2 * 1024 * 1024)
55#define GPU_FB_START (64 * 1024) 46#define GPU_FB_START (64 * 1024)
56#define GPU_IOIF (0x0d000000UL) 47#define GPU_IOIF (0x0d000000UL)
@@ -462,33 +453,27 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
462 src_offset += GPU_FB_START; 453 src_offset += GPU_FB_START;
463 454
464 mutex_lock(&ps3_gpu_mutex); 455 mutex_lock(&ps3_gpu_mutex);
465 status = lv1_gpu_context_attribute(ps3fb.context_handle, 456 status = lv1_gpu_fb_blit(ps3fb.context_handle, dst_offset,
466 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 457 GPU_IOIF + src_offset,
467 dst_offset, GPU_IOIF + src_offset, 458 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
468 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | 459 (width << 16) | height,
469 (width << 16) | height, 460 line_length);
470 line_length);
471 mutex_unlock(&ps3_gpu_mutex); 461 mutex_unlock(&ps3_gpu_mutex);
472 462
473 if (status) 463 if (status)
474 dev_err(dev, 464 dev_err(dev, "%s: lv1_gpu_fb_blit failed: %d\n", __func__,
475 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", 465 status);
476 __func__, status);
477#ifdef HEAD_A 466#ifdef HEAD_A
478 status = lv1_gpu_context_attribute(ps3fb.context_handle, 467 status = lv1_gpu_display_flip(ps3fb.context_handle, 0, frame_offset);
479 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
480 0, frame_offset, 0, 0);
481 if (status) 468 if (status)
482 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 469 dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__,
483 __func__, status); 470 status);
484#endif 471#endif
485#ifdef HEAD_B 472#ifdef HEAD_B
486 status = lv1_gpu_context_attribute(ps3fb.context_handle, 473 status = lv1_gpu_display_flip(ps3fb.context_handle, 1, frame_offset);
487 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
488 1, frame_offset, 0, 0);
489 if (status) 474 if (status)
490 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 475 dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__,
491 __func__, status); 476 status);
492#endif 477#endif
493} 478}
494 479
@@ -956,73 +941,6 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
956} 941}
957 942
958 943
959static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
960 struct device *dev)
961{
962 int error;
963
964 dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver);
965 dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet);
966 dev_dbg(dev,
967 "version_gpu: %x memory_size: %x ch: %x core_freq: %d "
968 "mem_freq:%d\n",
969 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
970 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
971
972 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
973 dev_err(dev, "%s: version_driver err:%x\n", __func__,
974 dinfo->version_driver);
975 return -EINVAL;
976 }
977
978 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
979 &ps3fb.irq_no);
980 if (error) {
981 dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error);
982 return error;
983 }
984
985 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
986 DEVICE_NAME, dev);
987 if (error) {
988 dev_err(dev, "%s: request_irq failed %d\n", __func__, error);
989 ps3_irq_plug_destroy(ps3fb.irq_no);
990 return error;
991 }
992
993 dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
994 (1 << GPU_INTR_STATUS_FLIP_1);
995 return 0;
996}
997
998static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
999{
1000 int status;
1001
1002 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
1003 xdr_lpar, ps3fb_videomemory.size, 0);
1004 if (status) {
1005 dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n",
1006 __func__, status);
1007 return -ENXIO;
1008 }
1009 dev_dbg(dev, "video:%p ioif:%lx lpar:%llx size:%lx\n",
1010 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
1011 ps3fb_videomemory.size);
1012
1013 status = lv1_gpu_context_attribute(ps3fb.context_handle,
1014 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
1015 xdr_lpar, GPU_CMD_BUF_SIZE,
1016 GPU_IOIF, 0);
1017 if (status) {
1018 dev_err(dev,
1019 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
1020 __func__, status);
1021 return -ENXIO;
1022 }
1023 return 0;
1024}
1025
1026static struct fb_ops ps3fb_ops = { 944static struct fb_ops ps3fb_ops = {
1027 .fb_open = ps3fb_open, 945 .fb_open = ps3fb_open,
1028 .fb_release = ps3fb_release, 946 .fb_release = ps3fb_release,
@@ -1048,49 +966,18 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = {
1048 .accel = FB_ACCEL_NONE, 966 .accel = FB_ACCEL_NONE,
1049}; 967};
1050 968
1051static int ps3fb_set_sync(struct device *dev)
1052{
1053 int status;
1054
1055#ifdef HEAD_A
1056 status = lv1_gpu_context_attribute(0x0,
1057 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1058 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1059 if (status) {
1060 dev_err(dev,
1061 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1062 "%d\n",
1063 __func__, status);
1064 return -1;
1065 }
1066#endif
1067#ifdef HEAD_B
1068 status = lv1_gpu_context_attribute(0x0,
1069 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1070 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1071
1072 if (status) {
1073 dev_err(dev,
1074 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1075 "%d\n",
1076 __func__, status);
1077 return -1;
1078 }
1079#endif
1080 return 0;
1081}
1082
1083static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) 969static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1084{ 970{
1085 struct fb_info *info; 971 struct fb_info *info;
1086 struct ps3fb_par *par; 972 struct ps3fb_par *par;
1087 int retval = -ENOMEM; 973 int retval;
1088 u64 ddr_lpar = 0; 974 u64 ddr_lpar = 0;
1089 u64 lpar_dma_control = 0; 975 u64 lpar_dma_control = 0;
1090 u64 lpar_driver_info = 0; 976 u64 lpar_driver_info = 0;
1091 u64 lpar_reports = 0; 977 u64 lpar_reports = 0;
1092 u64 lpar_reports_size = 0; 978 u64 lpar_reports_size = 0;
1093 u64 xdr_lpar; 979 u64 xdr_lpar;
980 struct gpu_driver_info *dinfo;
1094 void *fb_start; 981 void *fb_start;
1095 int status; 982 int status;
1096 struct task_struct *task; 983 struct task_struct *task;
@@ -1101,8 +988,8 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1101 return -ENOMEM; 988 return -ENOMEM;
1102 } 989 }
1103 990
1104 status = ps3_open_hv_device(dev); 991 retval = ps3_open_hv_device(dev);
1105 if (status) { 992 if (retval) {
1106 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n", 993 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n",
1107 __func__); 994 __func__);
1108 goto err; 995 goto err;
@@ -1116,7 +1003,24 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1116 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1003 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
1117 init_waitqueue_head(&ps3fb.wait_vsync); 1004 init_waitqueue_head(&ps3fb.wait_vsync);
1118 1005
1119 ps3fb_set_sync(&dev->core); 1006#ifdef HEAD_A
1007 status = lv1_gpu_display_sync(0x0, 0, L1GPU_DISPLAY_SYNC_VSYNC);
1008 if (status) {
1009 dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n",
1010 __func__, status);
1011 retval = -ENODEV;
1012 goto err_close_device;
1013 }
1014#endif
1015#ifdef HEAD_B
1016 status = lv1_gpu_display_sync(0x0, 1, L1GPU_DISPLAY_SYNC_VSYNC);
1017 if (status) {
1018 dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n",
1019 __func__, status);
1020 retval = -ENODEV;
1021 goto err_close_device;
1022 }
1023#endif
1120 1024
1121 max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF; 1025 max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
1122 if (ps3fb_videomemory.size > max_ps3fb_size) { 1026 if (ps3fb_videomemory.size > max_ps3fb_size) {
@@ -1131,7 +1035,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1131 if (status) { 1035 if (status) {
1132 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n", 1036 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
1133 __func__, status); 1037 __func__, status);
1134 goto err; 1038 goto err_close_device;
1135 } 1039 }
1136 dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar); 1040 dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar);
1137 1041
@@ -1141,33 +1045,85 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1141 &lpar_reports, &lpar_reports_size); 1045 &lpar_reports, &lpar_reports_size);
1142 if (status) { 1046 if (status) {
1143 dev_err(&dev->core, 1047 dev_err(&dev->core,
1144 "%s: lv1_gpu_context_attribute failed: %d\n", __func__, 1048 "%s: lv1_gpu_context_allocate failed: %d\n", __func__,
1145 status); 1049 status);
1146 goto err_gpu_memory_free; 1050 goto err_gpu_memory_free;
1147 } 1051 }
1148 1052
1149 /* vsync interrupt */ 1053 /* vsync interrupt */
1150 ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024); 1054 dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
1151 if (!ps3fb.dinfo) { 1055 if (!dinfo) {
1152 dev_err(&dev->core, "%s: ioremap failed\n", __func__); 1056 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
1153 goto err_gpu_context_free; 1057 goto err_gpu_context_free;
1154 } 1058 }
1155 1059
1156 retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core); 1060 ps3fb.dinfo = dinfo;
1157 if (retval) 1061 dev_dbg(&dev->core, "version_driver:%x\n", dinfo->version_driver);
1062 dev_dbg(&dev->core, "irq outlet:%x\n", dinfo->irq.irq_outlet);
1063 dev_dbg(&dev->core, "version_gpu: %x memory_size: %x ch: %x "
1064 "core_freq: %d mem_freq:%d\n", dinfo->version_gpu,
1065 dinfo->memory_size, dinfo->hardware_channel,
1066 dinfo->nvcore_frequency/1000000,
1067 dinfo->memory_frequency/1000000);
1068
1069 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
1070 dev_err(&dev->core, "%s: version_driver err:%x\n", __func__,
1071 dinfo->version_driver);
1072 retval = -EINVAL;
1073 goto err_iounmap_dinfo;
1074 }
1075
1076 retval = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
1077 &ps3fb.irq_no);
1078 if (retval) {
1079 dev_err(&dev->core, "%s: ps3_alloc_irq failed %d\n", __func__,
1080 retval);
1158 goto err_iounmap_dinfo; 1081 goto err_iounmap_dinfo;
1082 }
1083
1084 retval = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt,
1085 IRQF_DISABLED, DEVICE_NAME, &dev->core);
1086 if (retval) {
1087 dev_err(&dev->core, "%s: request_irq failed %d\n", __func__,
1088 retval);
1089 goto err_destroy_plug;
1090 }
1091
1092 dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
1093 (1 << GPU_INTR_STATUS_FLIP_1);
1159 1094
1160 /* Clear memory to prevent kernel info leakage into userspace */ 1095 /* Clear memory to prevent kernel info leakage into userspace */
1161 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size); 1096 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size);
1162 1097
1163 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address)); 1098 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
1164 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); 1099
1165 if (retval) 1100 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
1101 xdr_lpar, ps3fb_videomemory.size,
1102 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
1103 CBE_IOPTE_M);
1104 if (status) {
1105 dev_err(&dev->core, "%s: lv1_gpu_context_iomap failed: %d\n",
1106 __func__, status);
1107 retval = -ENXIO;
1166 goto err_free_irq; 1108 goto err_free_irq;
1109 }
1110
1111 dev_dbg(&dev->core, "video:%p ioif:%lx lpar:%llx size:%lx\n",
1112 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
1113 ps3fb_videomemory.size);
1114
1115 status = lv1_gpu_fb_setup(ps3fb.context_handle, xdr_lpar,
1116 GPU_CMD_BUF_SIZE, GPU_IOIF);
1117 if (status) {
1118 dev_err(&dev->core, "%s: lv1_gpu_fb_setup failed: %d\n",
1119 __func__, status);
1120 retval = -ENXIO;
1121 goto err_context_unmap;
1122 }
1167 1123
1168 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core); 1124 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
1169 if (!info) 1125 if (!info)
1170 goto err_free_irq; 1126 goto err_context_fb_close;
1171 1127
1172 par = info->par; 1128 par = info->par;
1173 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ 1129 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
@@ -1210,7 +1166,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1210 if (retval < 0) 1166 if (retval < 0)
1211 goto err_fb_dealloc; 1167 goto err_fb_dealloc;
1212 1168
1213 dev->core.driver_data = info; 1169 ps3_system_bus_set_drvdata(dev, info);
1214 1170
1215 dev_info(info->device, "%s %s, using %u KiB of video memory\n", 1171 dev_info(info->device, "%s %s, using %u KiB of video memory\n",
1216 dev_driver_string(info->dev), dev_name(info->dev), 1172 dev_driver_string(info->dev), dev_name(info->dev),
@@ -1232,8 +1188,14 @@ err_fb_dealloc:
1232 fb_dealloc_cmap(&info->cmap); 1188 fb_dealloc_cmap(&info->cmap);
1233err_framebuffer_release: 1189err_framebuffer_release:
1234 framebuffer_release(info); 1190 framebuffer_release(info);
1191err_context_fb_close:
1192 lv1_gpu_fb_close(ps3fb.context_handle);
1193err_context_unmap:
1194 lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar,
1195 ps3fb_videomemory.size, CBE_IOPTE_M);
1235err_free_irq: 1196err_free_irq:
1236 free_irq(ps3fb.irq_no, &dev->core); 1197 free_irq(ps3fb.irq_no, &dev->core);
1198err_destroy_plug:
1237 ps3_irq_plug_destroy(ps3fb.irq_no); 1199 ps3_irq_plug_destroy(ps3fb.irq_no);
1238err_iounmap_dinfo: 1200err_iounmap_dinfo:
1239 iounmap((u8 __force __iomem *)ps3fb.dinfo); 1201 iounmap((u8 __force __iomem *)ps3fb.dinfo);
@@ -1241,14 +1203,16 @@ err_gpu_context_free:
1241 lv1_gpu_context_free(ps3fb.context_handle); 1203 lv1_gpu_context_free(ps3fb.context_handle);
1242err_gpu_memory_free: 1204err_gpu_memory_free:
1243 lv1_gpu_memory_free(ps3fb.memory_handle); 1205 lv1_gpu_memory_free(ps3fb.memory_handle);
1206err_close_device:
1207 ps3_close_hv_device(dev);
1244err: 1208err:
1245 return retval; 1209 return retval;
1246} 1210}
1247 1211
1248static int ps3fb_shutdown(struct ps3_system_bus_device *dev) 1212static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1249{ 1213{
1250 int status; 1214 struct fb_info *info = ps3_system_bus_get_drvdata(dev);
1251 struct fb_info *info = dev->core.driver_data; 1215 u64 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
1252 1216
1253 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 1217 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1254 1218
@@ -1268,20 +1232,14 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1268 unregister_framebuffer(info); 1232 unregister_framebuffer(info);
1269 fb_dealloc_cmap(&info->cmap); 1233 fb_dealloc_cmap(&info->cmap);
1270 framebuffer_release(info); 1234 framebuffer_release(info);
1271 info = dev->core.driver_data = NULL; 1235 ps3_system_bus_set_drvdata(dev, NULL);
1272 } 1236 }
1273 iounmap((u8 __force __iomem *)ps3fb.dinfo); 1237 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1274 1238 lv1_gpu_fb_close(ps3fb.context_handle);
1275 status = lv1_gpu_context_free(ps3fb.context_handle); 1239 lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar,
1276 if (status) 1240 ps3fb_videomemory.size, CBE_IOPTE_M);
1277 dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n", 1241 lv1_gpu_context_free(ps3fb.context_handle);
1278 status); 1242 lv1_gpu_memory_free(ps3fb.memory_handle);
1279
1280 status = lv1_gpu_memory_free(ps3fb.memory_handle);
1281 if (status)
1282 dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n",
1283 status);
1284
1285 ps3_close_hv_device(dev); 1243 ps3_close_hv_device(dev);
1286 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 1244 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1287 1245
diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h
new file mode 100644
index 000000000000..b18ce4f9ee3d
--- /dev/null
+++ b/include/asm-generic/atomic64.h
@@ -0,0 +1,42 @@
1/*
2 * Generic implementation of 64-bit atomics using spinlocks,
3 * useful on processors that don't have 64-bit atomic instructions.
4 *
5 * Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12#ifndef _ASM_GENERIC_ATOMIC64_H
13#define _ASM_GENERIC_ATOMIC64_H
14
15typedef struct {
16 long long counter;
17} atomic64_t;
18
19#define ATOMIC64_INIT(i) { (i) }
20
21extern long long atomic64_read(const atomic64_t *v);
22extern void atomic64_set(atomic64_t *v, long long i);
23extern void atomic64_add(long long a, atomic64_t *v);
24extern long long atomic64_add_return(long long a, atomic64_t *v);
25extern void atomic64_sub(long long a, atomic64_t *v);
26extern long long atomic64_sub_return(long long a, atomic64_t *v);
27extern long long atomic64_dec_if_positive(atomic64_t *v);
28extern long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n);
29extern long long atomic64_xchg(atomic64_t *v, long long new);
30extern int atomic64_add_unless(atomic64_t *v, long long a, long long u);
31
32#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
33#define atomic64_inc(v) atomic64_add(1LL, (v))
34#define atomic64_inc_return(v) atomic64_add_return(1LL, (v))
35#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
36#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
37#define atomic64_dec(v) atomic64_sub(1LL, (v))
38#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v))
39#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
40#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
41
42#endif /* _ASM_GENERIC_ATOMIC64_H */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 12737be58601..2a04eb54c0dd 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -590,6 +590,11 @@ static inline void bio_list_merge_head(struct bio_list *bl,
590 bl->head = bl2->head; 590 bl->head = bl2->head;
591} 591}
592 592
593static inline struct bio *bio_list_peek(struct bio_list *bl)
594{
595 return bl->head;
596}
597
593static inline struct bio *bio_list_pop(struct bio_list *bl) 598static inline struct bio *bio_list_pop(struct bio_list *bl)
594{ 599{
595 struct bio *bio = bl->head; 600 struct bio *bio = bl->head;
diff --git a/lib/Kconfig b/lib/Kconfig
index 9960be04cbbe..bb1326d3839c 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -194,4 +194,10 @@ config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS
194config NLATTR 194config NLATTR
195 bool 195 bool
196 196
197#
198# Generic 64-bit atomic support is selected if needed
199#
200config GENERIC_ATOMIC64
201 bool
202
197endmenu 203endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 34c5c0e6222e..8e9bcf9d3261 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -95,6 +95,8 @@ obj-$(CONFIG_DMA_API_DEBUG) += dma-debug.o
95 95
96obj-$(CONFIG_GENERIC_CSUM) += checksum.o 96obj-$(CONFIG_GENERIC_CSUM) += checksum.o
97 97
98obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o
99
98hostprogs-y := gen_crc32table 100hostprogs-y := gen_crc32table
99clean-files := crc32table.h 101clean-files := crc32table.h
100 102
diff --git a/lib/atomic64.c b/lib/atomic64.c
new file mode 100644
index 000000000000..c5e725562416
--- /dev/null
+++ b/lib/atomic64.c
@@ -0,0 +1,175 @@
1/*
2 * Generic implementation of 64-bit atomics using spinlocks,
3 * useful on processors that don't have 64-bit atomic instructions.
4 *
5 * Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12#include <linux/types.h>
13#include <linux/cache.h>
14#include <linux/spinlock.h>
15#include <linux/init.h>
16#include <asm/atomic.h>
17
18/*
19 * We use a hashed array of spinlocks to provide exclusive access
20 * to each atomic64_t variable. Since this is expected to used on
21 * systems with small numbers of CPUs (<= 4 or so), we use a
22 * relatively small array of 16 spinlocks to avoid wasting too much
23 * memory on the spinlock array.
24 */
25#define NR_LOCKS 16
26
27/*
28 * Ensure each lock is in a separate cacheline.
29 */
30static union {
31 spinlock_t lock;
32 char pad[L1_CACHE_BYTES];
33} atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp;
34
35static inline spinlock_t *lock_addr(const atomic64_t *v)
36{
37 unsigned long addr = (unsigned long) v;
38
39 addr >>= L1_CACHE_SHIFT;
40 addr ^= (addr >> 8) ^ (addr >> 16);
41 return &atomic64_lock[addr & (NR_LOCKS - 1)].lock;
42}
43
44long long atomic64_read(const atomic64_t *v)
45{
46 unsigned long flags;
47 spinlock_t *lock = lock_addr(v);
48 long long val;
49
50 spin_lock_irqsave(lock, flags);
51 val = v->counter;
52 spin_unlock_irqrestore(lock, flags);
53 return val;
54}
55
56void atomic64_set(atomic64_t *v, long long i)
57{
58 unsigned long flags;
59 spinlock_t *lock = lock_addr(v);
60
61 spin_lock_irqsave(lock, flags);
62 v->counter = i;
63 spin_unlock_irqrestore(lock, flags);
64}
65
66void atomic64_add(long long a, atomic64_t *v)
67{
68 unsigned long flags;
69 spinlock_t *lock = lock_addr(v);
70
71 spin_lock_irqsave(lock, flags);
72 v->counter += a;
73 spin_unlock_irqrestore(lock, flags);
74}
75
76long long atomic64_add_return(long long a, atomic64_t *v)
77{
78 unsigned long flags;
79 spinlock_t *lock = lock_addr(v);
80 long long val;
81
82 spin_lock_irqsave(lock, flags);
83 val = v->counter += a;
84 spin_unlock_irqrestore(lock, flags);
85 return val;
86}
87
88void atomic64_sub(long long a, atomic64_t *v)
89{
90 unsigned long flags;
91 spinlock_t *lock = lock_addr(v);
92
93 spin_lock_irqsave(lock, flags);
94 v->counter -= a;
95 spin_unlock_irqrestore(lock, flags);
96}
97
98long long atomic64_sub_return(long long a, atomic64_t *v)
99{
100 unsigned long flags;
101 spinlock_t *lock = lock_addr(v);
102 long long val;
103
104 spin_lock_irqsave(lock, flags);
105 val = v->counter -= a;
106 spin_unlock_irqrestore(lock, flags);
107 return val;
108}
109
110long long atomic64_dec_if_positive(atomic64_t *v)
111{
112 unsigned long flags;
113 spinlock_t *lock = lock_addr(v);
114 long long val;
115
116 spin_lock_irqsave(lock, flags);
117 val = v->counter - 1;
118 if (val >= 0)
119 v->counter = val;
120 spin_unlock_irqrestore(lock, flags);
121 return val;
122}
123
124long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n)
125{
126 unsigned long flags;
127 spinlock_t *lock = lock_addr(v);
128 long long val;
129
130 spin_lock_irqsave(lock, flags);
131 val = v->counter;
132 if (val == o)
133 v->counter = n;
134 spin_unlock_irqrestore(lock, flags);
135 return val;
136}
137
138long long atomic64_xchg(atomic64_t *v, long long new)
139{
140 unsigned long flags;
141 spinlock_t *lock = lock_addr(v);
142 long long val;
143
144 spin_lock_irqsave(lock, flags);
145 val = v->counter;
146 v->counter = new;
147 spin_unlock_irqrestore(lock, flags);
148 return val;
149}
150
151int atomic64_add_unless(atomic64_t *v, long long a, long long u)
152{
153 unsigned long flags;
154 spinlock_t *lock = lock_addr(v);
155 int ret = 1;
156
157 spin_lock_irqsave(lock, flags);
158 if (v->counter != u) {
159 v->counter += a;
160 ret = 0;
161 }
162 spin_unlock_irqrestore(lock, flags);
163 return ret;
164}
165
166static int init_atomic64_lock(void)
167{
168 int i;
169
170 for (i = 0; i < NR_LOCKS; ++i)
171 spin_lock_init(&atomic64_lock[i].lock);
172 return 0;
173}
174
175pure_initcall(init_atomic64_lock);