aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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 /drivers
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 ...
Diffstat (limited to 'drivers')
-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
10 files changed, 393 insertions, 396 deletions
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