some more kernel config cleanup.. last for today :)
[openwrt.git] / target / linux / ps3 / patches-2.6.28 / 0015-ps3-block-Replace-mtd-ps3vram-by-block-ps3vram.patch
1 From f507cd22035fdadd5dbb476dd05e9e7ee21c3b84 Mon Sep 17 00:00:00 2001
2 From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
3 Date: Fri, 6 Mar 2009 02:54:09 +0000
4 Subject: [PATCH] ps3/block: Replace mtd/ps3vram by block/ps3vram
5
6 Convert the PS3 Video RAM Storage Driver from an MTD driver to a plain block
7 device driver.
8
9 The ps3vram driver exposes unused video RAM on the PS3 as a block device
10 suitable for storage or swap.  Fast data transfer is achieved using a local
11 cache in system RAM and DMA transfers via the GPU.
12
13 The new driver is ca. 50% faster for reading, and ca. 10% for writing.
14
15 Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
16 Acked-by: Geoff Levand <geoffrey.levand@am.sony.com>
17 Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
18 ---
19  arch/powerpc/platforms/ps3/Kconfig |    7 +
20  drivers/block/Makefile             |    1 +
21  drivers/block/ps3vram.c            |  865 ++++++++++++++++++++++++++++++++++++
22  drivers/mtd/devices/Kconfig        |    7 -
23  drivers/mtd/devices/Makefile       |    1 -
24  drivers/mtd/devices/ps3vram.c      |  768 --------------------------------
25  6 files changed, 873 insertions(+), 776 deletions(-)
26  create mode 100644 drivers/block/ps3vram.c
27  delete mode 100644 drivers/mtd/devices/ps3vram.c
28
29 diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
30 index 920cf7a..740ef56 100644
31 --- a/arch/powerpc/platforms/ps3/Kconfig
32 +++ b/arch/powerpc/platforms/ps3/Kconfig
33 @@ -128,6 +128,13 @@ config PS3_FLASH
34           be disabled on the kernel command line using "ps3flash=off", to
35           not allocate this fixed buffer.
36  
37 +config PS3_VRAM
38 +       tristate "PS3 Video RAM Storage Driver"
39 +       depends on FB_PS3=y && BLOCK && m
40 +       help
41 +         This driver allows you to use excess PS3 video RAM as volatile
42 +         storage or system swap.
43 +
44  config PS3_LPM
45         tristate "PS3 Logical Performance Monitor support"
46         depends on PPC_PS3
47 diff --git a/drivers/block/Makefile b/drivers/block/Makefile
48 index 204332b..87e120e 100644
49 --- a/drivers/block/Makefile
50 +++ b/drivers/block/Makefile
51 @@ -9,6 +9,7 @@ obj-$(CONFIG_MAC_FLOPPY)        += swim3.o
52  obj-$(CONFIG_BLK_DEV_FD)       += floppy.o
53  obj-$(CONFIG_AMIGA_FLOPPY)     += amiflop.o
54  obj-$(CONFIG_PS3_DISK)         += ps3disk.o
55 +obj-$(CONFIG_PS3_VRAM)         += ps3vram.o
56  obj-$(CONFIG_ATARI_FLOPPY)     += ataflop.o
57  obj-$(CONFIG_AMIGA_Z2RAM)      += z2ram.o
58  obj-$(CONFIG_BLK_DEV_RAM)      += brd.o
59 diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
60 new file mode 100644
61 index 0000000..393ed67
62 --- /dev/null
63 +++ b/drivers/block/ps3vram.c
64 @@ -0,0 +1,865 @@
65 +/*
66 + * ps3vram - Use extra PS3 video ram as MTD block device.
67 + *
68 + * Copyright 2009 Sony Corporation
69 + *
70 + * Based on the MTD ps3vram driver, which is
71 + * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
72 + * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
73 + */
74 +
75 +#include <linux/blkdev.h>
76 +#include <linux/delay.h>
77 +#include <linux/proc_fs.h>
78 +#include <linux/seq_file.h>
79 +
80 +#include <asm/firmware.h>
81 +#include <asm/lv1call.h>
82 +#include <asm/ps3.h>
83 +
84 +
85 +#define DEVICE_NAME            "ps3vram"
86 +
87 +
88 +#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
89 +#define XDR_IOIF 0x0c000000
90 +
91 +#define FIFO_BASE XDR_IOIF
92 +#define FIFO_SIZE (64 * 1024)
93 +
94 +#define DMA_PAGE_SIZE (4 * 1024)
95 +
96 +#define CACHE_PAGE_SIZE (256 * 1024)
97 +#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
98 +
99 +#define CACHE_OFFSET CACHE_PAGE_SIZE
100 +#define FIFO_OFFSET 0
101 +
102 +#define CTRL_PUT 0x10
103 +#define CTRL_GET 0x11
104 +#define CTRL_TOP 0x15
105 +
106 +#define UPLOAD_SUBCH   1
107 +#define DOWNLOAD_SUBCH 2
108 +
109 +#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN   0x0000030c
110 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY      0x00000104
111 +
112 +#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
113 +
114 +#define CACHE_PAGE_PRESENT 1
115 +#define CACHE_PAGE_DIRTY   2
116 +
117 +struct ps3vram_tag {
118 +       unsigned int address;
119 +       unsigned int flags;
120 +};
121 +
122 +struct ps3vram_cache {
123 +       unsigned int page_count;
124 +       unsigned int page_size;
125 +       struct ps3vram_tag *tags;
126 +       unsigned int hit;
127 +       unsigned int miss;
128 +};
129 +
130 +struct ps3vram_priv {
131 +       struct request_queue *queue;
132 +       struct gendisk *gendisk;
133 +
134 +       u64 size;
135 +
136 +       u64 memory_handle;
137 +       u64 context_handle;
138 +       u32 *ctrl;
139 +       u32 *reports;
140 +       u8 __iomem *ddr_base;
141 +       u8 *xdr_buf;
142 +
143 +       u32 *fifo_base;
144 +       u32 *fifo_ptr;
145 +
146 +       struct ps3vram_cache cache;
147 +
148 +       /* Used to serialize cache/DMA operations */
149 +       struct mutex lock;
150 +};
151 +
152 +
153 +static int ps3vram_major;
154 +
155 +
156 +static struct block_device_operations ps3vram_fops = {
157 +       .owner          = THIS_MODULE,
158 +};
159 +
160 +
161 +#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
162 +#define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */
163 +#define DMA_NOTIFIER_SIZE        0x40
164 +#define NOTIFIER 7     /* notifier used for completion report */
165 +
166 +static char *size = "256M";
167 +module_param(size, charp, 0);
168 +MODULE_PARM_DESC(size, "memory size");
169 +
170 +static u32 *ps3vram_get_notifier(u32 *reports, int notifier)
171 +{
172 +       return (void *)reports + DMA_NOTIFIER_OFFSET_BASE +
173 +              DMA_NOTIFIER_SIZE * notifier;
174 +}
175 +
176 +static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
177 +{
178 +       struct ps3vram_priv *priv = dev->core.driver_data;
179 +       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
180 +       int i;
181 +
182 +       for (i = 0; i < 4; i++)
183 +               notify[i] = 0xffffffff;
184 +}
185 +
186 +static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
187 +                                unsigned int timeout_ms)
188 +{
189 +       struct ps3vram_priv *priv = dev->core.driver_data;
190 +       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
191 +       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
192 +
193 +       do {
194 +               if (!notify[3])
195 +                       return 0;
196 +               msleep(1);
197 +       } while (time_before(jiffies, timeout));
198 +
199 +       return -ETIMEDOUT;
200 +}
201 +
202 +static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
203 +{
204 +       struct ps3vram_priv *priv = dev->core.driver_data;
205 +
206 +       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
207 +       priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
208 +}
209 +
210 +static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
211 +                            unsigned int timeout_ms)
212 +{
213 +       struct ps3vram_priv *priv = dev->core.driver_data;
214 +       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
215 +
216 +       do {
217 +               if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET])
218 +                       return 0;
219 +               msleep(1);
220 +       } while (time_before(jiffies, timeout));
221 +
222 +       dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n",
223 +                priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET],
224 +                priv->ctrl[CTRL_TOP]);
225 +
226 +       return -ETIMEDOUT;
227 +}
228 +
229 +static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
230 +{
231 +       *(priv->fifo_ptr)++ = data;
232 +}
233 +
234 +static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag,
235 +                              u32 size)
236 +{
237 +       ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
238 +}
239 +
240 +static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
241 +{
242 +       struct ps3vram_priv *priv = dev->core.driver_data;
243 +       int status;
244 +
245 +       ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
246 +
247 +       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
248 +
249 +       /* asking the HV for a blit will kick the FIFO */
250 +       status = lv1_gpu_context_attribute(priv->context_handle,
251 +                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
252 +                                          0, 0, 0);
253 +       if (status)
254 +               dev_err(&dev->core,
255 +                       "%s: lv1_gpu_context_attribute failed %d\n", __func__,
256 +                       status);
257 +
258 +       priv->fifo_ptr = priv->fifo_base;
259 +}
260 +
261 +static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
262 +{
263 +       struct ps3vram_priv *priv = dev->core.driver_data;
264 +       int status;
265 +
266 +       mutex_lock(&ps3_gpu_mutex);
267 +
268 +       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET +
269 +                              (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
270 +
271 +       /* asking the HV for a blit will kick the FIFO */
272 +       status = lv1_gpu_context_attribute(priv->context_handle,
273 +                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
274 +                                          0, 0, 0);
275 +       if (status)
276 +               dev_err(&dev->core,
277 +                       "%s: lv1_gpu_context_attribute failed %d\n", __func__,
278 +                       status);
279 +
280 +       if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
281 +           FIFO_SIZE - 1024) {
282 +               dev_dbg(&dev->core, "FIFO full, rewinding\n");
283 +               ps3vram_wait_ring(dev, 200);
284 +               ps3vram_rewind_ring(dev);
285 +       }
286 +
287 +       mutex_unlock(&ps3_gpu_mutex);
288 +}
289 +
290 +static void ps3vram_bind(struct ps3_system_bus_device *dev)
291 +{
292 +       struct ps3vram_priv *priv = dev->core.driver_data;
293 +
294 +       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
295 +       ps3vram_out_ring(priv, 0x31337303);
296 +       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
297 +       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
298 +       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
299 +       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
300 +
301 +       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
302 +       ps3vram_out_ring(priv, 0x3137c0de);
303 +       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
304 +       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
305 +       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
306 +       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
307 +
308 +       ps3vram_fire_ring(dev);
309 +}
310 +
311 +static int ps3vram_upload(struct ps3_system_bus_device *dev,
312 +                         unsigned int src_offset, unsigned int dst_offset,
313 +                         int len, int count)
314 +{
315 +       struct ps3vram_priv *priv = dev->core.driver_data;
316 +
317 +       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
318 +                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
319 +       ps3vram_out_ring(priv, XDR_IOIF + src_offset);
320 +       ps3vram_out_ring(priv, dst_offset);
321 +       ps3vram_out_ring(priv, len);
322 +       ps3vram_out_ring(priv, len);
323 +       ps3vram_out_ring(priv, len);
324 +       ps3vram_out_ring(priv, count);
325 +       ps3vram_out_ring(priv, (1 << 8) | 1);
326 +       ps3vram_out_ring(priv, 0);
327 +
328 +       ps3vram_notifier_reset(dev);
329 +       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
330 +                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
331 +       ps3vram_out_ring(priv, 0);
332 +       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
333 +       ps3vram_out_ring(priv, 0);
334 +       ps3vram_fire_ring(dev);
335 +       if (ps3vram_notifier_wait(dev, 200) < 0) {
336 +               dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
337 +               return -1;
338 +       }
339 +
340 +       return 0;
341 +}
342 +
343 +static int ps3vram_download(struct ps3_system_bus_device *dev,
344 +                           unsigned int src_offset, unsigned int dst_offset,
345 +                           int len, int count)
346 +{
347 +       struct ps3vram_priv *priv = dev->core.driver_data;
348 +
349 +       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
350 +                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
351 +       ps3vram_out_ring(priv, src_offset);
352 +       ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
353 +       ps3vram_out_ring(priv, len);
354 +       ps3vram_out_ring(priv, len);
355 +       ps3vram_out_ring(priv, len);
356 +       ps3vram_out_ring(priv, count);
357 +       ps3vram_out_ring(priv, (1 << 8) | 1);
358 +       ps3vram_out_ring(priv, 0);
359 +
360 +       ps3vram_notifier_reset(dev);
361 +       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
362 +                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
363 +       ps3vram_out_ring(priv, 0);
364 +       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
365 +       ps3vram_out_ring(priv, 0);
366 +       ps3vram_fire_ring(dev);
367 +       if (ps3vram_notifier_wait(dev, 200) < 0) {
368 +               dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
369 +               return -1;
370 +       }
371 +
372 +       return 0;
373 +}
374 +
375 +static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
376 +{
377 +       struct ps3vram_priv *priv = dev->core.driver_data;
378 +       struct ps3vram_cache *cache = &priv->cache;
379 +
380 +       if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY))
381 +               return;
382 +
383 +       dev_dbg(&dev->core, "Flushing %d: 0x%08x\n", entry,
384 +               cache->tags[entry].address);
385 +       if (ps3vram_upload(dev, CACHE_OFFSET + entry * cache->page_size,
386 +                          cache->tags[entry].address, DMA_PAGE_SIZE,
387 +                          cache->page_size / DMA_PAGE_SIZE) < 0) {
388 +               dev_err(&dev->core,
389 +                       "Failed to upload from 0x%x to " "0x%x size 0x%x\n",
390 +                       entry * cache->page_size, cache->tags[entry].address,
391 +                       cache->page_size);
392 +       }
393 +       cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
394 +}
395 +
396 +static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
397 +                              unsigned int address)
398 +{
399 +       struct ps3vram_priv *priv = dev->core.driver_data;
400 +       struct ps3vram_cache *cache = &priv->cache;
401 +
402 +       dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address);
403 +       if (ps3vram_download(dev, address,
404 +                            CACHE_OFFSET + entry * cache->page_size,
405 +                            DMA_PAGE_SIZE,
406 +                            cache->page_size / DMA_PAGE_SIZE) < 0) {
407 +               dev_err(&dev->core,
408 +                       "Failed to download from 0x%x to 0x%x size 0x%x\n",
409 +                       address, entry * cache->page_size, cache->page_size);
410 +       }
411 +
412 +       cache->tags[entry].address = address;
413 +       cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
414 +}
415 +
416 +
417 +static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
418 +{
419 +       struct ps3vram_priv *priv = dev->core.driver_data;
420 +       struct ps3vram_cache *cache = &priv->cache;
421 +       int i;
422 +
423 +       dev_dbg(&dev->core, "FLUSH\n");
424 +       for (i = 0; i < cache->page_count; i++) {
425 +               ps3vram_cache_evict(dev, i);
426 +               cache->tags[i].flags = 0;
427 +       }
428 +}
429 +
430 +static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
431 +                                       loff_t address)
432 +{
433 +       struct ps3vram_priv *priv = dev->core.driver_data;
434 +       struct ps3vram_cache *cache = &priv->cache;
435 +       unsigned int base;
436 +       unsigned int offset;
437 +       int i;
438 +       static int counter;
439 +
440 +       offset = (unsigned int) (address & (cache->page_size - 1));
441 +       base = (unsigned int) (address - offset);
442 +
443 +       /* fully associative check */
444 +       for (i = 0; i < cache->page_count; i++) {
445 +               if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
446 +                   cache->tags[i].address == base) {
447 +                       cache->hit++;
448 +                       dev_dbg(&dev->core, "Found entry %d: 0x%08x\n", i,
449 +                               cache->tags[i].address);
450 +                       return i;
451 +               }
452 +       }
453 +
454 +       /* choose a random entry */
455 +       i = (jiffies + (counter++)) % cache->page_count;
456 +       dev_dbg(&dev->core, "Using entry %d\n", i);
457 +
458 +       ps3vram_cache_evict(dev, i);
459 +       ps3vram_cache_load(dev, i, base);
460 +
461 +       cache->miss++;
462 +       return i;
463 +}
464 +
465 +static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
466 +{
467 +       struct ps3vram_priv *priv = dev->core.driver_data;
468 +
469 +       priv->cache.page_count = CACHE_PAGE_COUNT;
470 +       priv->cache.page_size = CACHE_PAGE_SIZE;
471 +       priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) *
472 +                                  CACHE_PAGE_COUNT, GFP_KERNEL);
473 +       if (priv->cache.tags == NULL) {
474 +               dev_err(&dev->core, "Could not allocate cache tags\n");
475 +               return -ENOMEM;
476 +       }
477 +
478 +       dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n",
479 +               CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
480 +
481 +       return 0;
482 +}
483 +
484 +static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
485 +{
486 +       struct ps3vram_priv *priv = dev->core.driver_data;
487 +
488 +       ps3vram_cache_flush(dev);
489 +       kfree(priv->cache.tags);
490 +}
491 +
492 +static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
493 +                       size_t len, size_t *retlen, u_char *buf)
494 +{
495 +       struct ps3vram_priv *priv = dev->core.driver_data;
496 +       unsigned int cached, count;
497 +
498 +       dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__,
499 +               (unsigned int)from, len);
500 +
501 +       if (from >= priv->size)
502 +               return -EIO;
503 +
504 +       if (len > priv->size - from)
505 +               len = priv->size - from;
506 +
507 +       /* Copy from vram to buf */
508 +       count = len;
509 +       while (count) {
510 +               unsigned int offset, avail;
511 +               unsigned int entry;
512 +
513 +               offset = (unsigned int) (from & (priv->cache.page_size - 1));
514 +               avail  = priv->cache.page_size - offset;
515 +
516 +               mutex_lock(&priv->lock);
517 +
518 +               entry = ps3vram_cache_match(dev, from);
519 +               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
520 +
521 +               dev_dbg(&dev->core, "%s: from=%08x cached=%08x offset=%08x "
522 +                       "avail=%08x count=%08x\n", __func__,
523 +                       (unsigned int)from, cached, offset, avail, count);
524 +
525 +               if (avail > count)
526 +                       avail = count;
527 +               memcpy(buf, priv->xdr_buf + cached, avail);
528 +
529 +               mutex_unlock(&priv->lock);
530 +
531 +               buf += avail;
532 +               count -= avail;
533 +               from += avail;
534 +       }
535 +
536 +       *retlen = len;
537 +       return 0;
538 +}
539 +
540 +static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
541 +                        size_t len, size_t *retlen, const u_char *buf)
542 +{
543 +       struct ps3vram_priv *priv = dev->core.driver_data;
544 +       unsigned int cached, count;
545 +
546 +       if (to >= priv->size)
547 +               return -EIO;
548 +
549 +       if (len > priv->size - to)
550 +               len = priv->size - to;
551 +
552 +       /* Copy from buf to vram */
553 +       count = len;
554 +       while (count) {
555 +               unsigned int offset, avail;
556 +               unsigned int entry;
557 +
558 +               offset = (unsigned int) (to & (priv->cache.page_size - 1));
559 +               avail  = priv->cache.page_size - offset;
560 +
561 +               mutex_lock(&priv->lock);
562 +
563 +               entry = ps3vram_cache_match(dev, to);
564 +               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
565 +
566 +               dev_dbg(&dev->core, "%s: to=%08x cached=%08x offset=%08x "
567 +                       "avail=%08x count=%08x\n", __func__, (unsigned int)to,
568 +                       cached, offset, avail, count);
569 +
570 +               if (avail > count)
571 +                       avail = count;
572 +               memcpy(priv->xdr_buf + cached, buf, avail);
573 +
574 +               priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
575 +
576 +               mutex_unlock(&priv->lock);
577 +
578 +               buf += avail;
579 +               count -= avail;
580 +               to += avail;
581 +       }
582 +
583 +       *retlen = len;
584 +       return 0;
585 +}
586 +
587 +static int ps3vram_proc_show(struct seq_file *m, void *v)
588 +{
589 +       struct ps3vram_priv *priv = m->private;
590 +
591 +       seq_printf(m, "hit:%u\nmiss:%u\n", priv->cache.hit, priv->cache.miss);
592 +       return 0;
593 +}
594 +
595 +static int ps3vram_proc_open(struct inode *inode, struct file *file)
596 +{
597 +       return single_open(file, ps3vram_proc_show, PDE(inode)->data);
598 +}
599 +
600 +static const struct file_operations ps3vram_proc_fops = {
601 +       .owner          = THIS_MODULE,
602 +       .open           = ps3vram_proc_open,
603 +       .read           = seq_read,
604 +       .llseek         = seq_lseek,
605 +       .release        = single_release,
606 +};
607 +
608 +static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
609 +{
610 +       struct ps3vram_priv *priv = dev->core.driver_data;
611 +       struct proc_dir_entry *pde;
612 +
613 +       pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops);
614 +       if (!pde) {
615 +               dev_warn(&dev->core, "failed to create /proc entry\n");
616 +               return;
617 +       }
618 +
619 +       pde->owner = THIS_MODULE;
620 +       pde->data = priv;
621 +}
622 +
623 +static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
624 +{
625 +       struct ps3_system_bus_device *dev = q->queuedata;
626 +       int write = bio_data_dir(bio) == WRITE;
627 +       const char *op = write ? "write" : "read";
628 +       loff_t offset = bio->bi_sector << 9;
629 +       int error = 0;
630 +       struct bio_vec *bvec;
631 +       unsigned int i;
632 +
633 +       dev_dbg(&dev->core, "%s\n", __func__);
634 +
635 +       bio_for_each_segment(bvec, bio, i) {
636 +               /* PS3 is ppc64, so we don't handle highmem */
637 +               char *ptr = page_address(bvec->bv_page) + bvec->bv_offset;
638 +               size_t len = bvec->bv_len, retlen;
639 +
640 +               dev_dbg(&dev->core, "    %s %zu bytes at offset %llu\n", op,
641 +                       len, offset);
642 +               if (write)
643 +                       error = ps3vram_write(dev, offset, len, &retlen, ptr);
644 +               else
645 +                       error = ps3vram_read(dev, offset, len, &retlen, ptr);
646 +
647 +               if (error) {
648 +                       dev_err(&dev->core, "%s failed\n", op);
649 +                       goto out;
650 +               }
651 +
652 +               if (retlen != len) {
653 +                       dev_err(&dev->core, "Short %s\n", op);
654 +                       goto out;
655 +               }
656 +
657 +               offset += len;
658 +       }
659 +
660 +       dev_dbg(&dev->core, "%s completed\n", op);
661 +
662 +out:
663 +       bio_endio(bio, error);
664 +       return 0;
665 +}
666 +
667 +static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
668 +{
669 +       struct ps3vram_priv *priv;
670 +       int error, status;
671 +       struct request_queue *queue;
672 +       struct gendisk *gendisk;
673 +       u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size,
674 +           reports_size;
675 +       char *rest;
676 +
677 +       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
678 +       if (!priv) {
679 +               error = -ENOMEM;
680 +               goto fail;
681 +       }
682 +
683 +       mutex_init(&priv->lock);
684 +       dev->core.driver_data = priv;
685 +
686 +       priv = dev->core.driver_data;
687 +
688 +       /* Allocate XDR buffer (1MiB aligned) */
689 +       priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
690 +               get_order(XDR_BUF_SIZE));
691 +       if (priv->xdr_buf == NULL) {
692 +               dev_err(&dev->core, "Could not allocate XDR buffer\n");
693 +               error = -ENOMEM;
694 +               goto fail_free_priv;
695 +       }
696 +
697 +       /* Put FIFO at begginning of XDR buffer */
698 +       priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
699 +       priv->fifo_ptr = priv->fifo_base;
700 +
701 +       /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
702 +       if (ps3_open_hv_device(dev)) {
703 +               dev_err(&dev->core, "ps3_open_hv_device failed\n");
704 +               error = -EAGAIN;
705 +               goto out_close_gpu;
706 +       }
707 +
708 +       /* Request memory */
709 +       status = -1;
710 +       ddr_size = ALIGN(memparse(size, &rest), 1024*1024);
711 +       if (!ddr_size) {
712 +               dev_err(&dev->core, "Specified size is too small\n");
713 +               error = -EINVAL;
714 +               goto out_close_gpu;
715 +       }
716 +
717 +       while (ddr_size > 0) {
718 +               status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
719 +                                                &priv->memory_handle,
720 +                                                &ddr_lpar);
721 +               if (!status)
722 +                       break;
723 +               ddr_size -= 1024*1024;
724 +       }
725 +       if (status) {
726 +               dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n",
727 +                       status);
728 +               error = -ENOMEM;
729 +               goto out_free_xdr_buf;
730 +       }
731 +
732 +       /* Request context */
733 +       status = lv1_gpu_context_allocate(priv->memory_handle, 0,
734 +                                         &priv->context_handle, &ctrl_lpar,
735 +                                         &info_lpar, &reports_lpar,
736 +                                         &reports_size);
737 +       if (status) {
738 +               dev_err(&dev->core, "lv1_gpu_context_allocate failed %d\n",
739 +                       status);
740 +               error = -ENOMEM;
741 +               goto out_free_memory;
742 +       }
743 +
744 +       /* Map XDR buffer to RSX */
745 +       status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
746 +                                      ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
747 +                                      XDR_BUF_SIZE, 0);
748 +       if (status) {
749 +               dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n",
750 +                       status);
751 +               error = -ENOMEM;
752 +               goto out_free_context;
753 +       }
754 +
755 +       priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
756 +
757 +       if (!priv->ddr_base) {
758 +               dev_err(&dev->core, "ioremap DDR failed\n");
759 +               error = -ENOMEM;
760 +               goto out_free_context;
761 +       }
762 +
763 +       priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
764 +       if (!priv->ctrl) {
765 +               dev_err(&dev->core, "ioremap CTRL failed\n");
766 +               error = -ENOMEM;
767 +               goto out_unmap_vram;
768 +       }
769 +
770 +       priv->reports = ioremap(reports_lpar, reports_size);
771 +       if (!priv->reports) {
772 +               dev_err(&dev->core, "ioremap REPORTS failed\n");
773 +               error = -ENOMEM;
774 +               goto out_unmap_ctrl;
775 +       }
776 +
777 +       mutex_lock(&ps3_gpu_mutex);
778 +       ps3vram_init_ring(dev);
779 +       mutex_unlock(&ps3_gpu_mutex);
780 +
781 +       priv->size = ddr_size;
782 +
783 +       ps3vram_bind(dev);
784 +
785 +       mutex_lock(&ps3_gpu_mutex);
786 +       error = ps3vram_wait_ring(dev, 100);
787 +       mutex_unlock(&ps3_gpu_mutex);
788 +       if (error < 0) {
789 +               dev_err(&dev->core, "Failed to initialize channels\n");
790 +               error = -ETIMEDOUT;
791 +               goto out_unmap_reports;
792 +       }
793 +
794 +       ps3vram_cache_init(dev);
795 +       ps3vram_proc_init(dev);
796 +
797 +       queue = blk_alloc_queue(GFP_KERNEL);
798 +       if (!queue) {
799 +               dev_err(&dev->core, "blk_alloc_queue failed\n");
800 +               error = -ENOMEM;
801 +               goto out_cache_cleanup;
802 +       }
803 +
804 +       priv->queue = queue;
805 +       queue->queuedata = dev;
806 +       blk_queue_make_request(queue, ps3vram_make_request);
807 +       blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS);
808 +       blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS);
809 +       blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE);
810 +       blk_queue_max_sectors(queue, SAFE_MAX_SECTORS);
811 +
812 +       gendisk = alloc_disk(1);
813 +       if (!gendisk) {
814 +               dev_err(&dev->core, "alloc_disk failed\n");
815 +               error = -ENOMEM;
816 +               goto fail_cleanup_queue;
817 +       }
818 +
819 +       priv->gendisk = gendisk;
820 +       gendisk->major = ps3vram_major;
821 +       gendisk->first_minor = 0;
822 +       gendisk->fops = &ps3vram_fops;
823 +       gendisk->queue = queue;
824 +       gendisk->private_data = dev;
825 +       gendisk->driverfs_dev = &dev->core;
826 +       strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name));
827 +       set_capacity(gendisk, priv->size >> 9);
828 +
829 +       dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n",
830 +                gendisk->disk_name, get_capacity(gendisk) >> 11);
831 +
832 +       add_disk(gendisk);
833 +       return 0;
834 +
835 +fail_cleanup_queue:
836 +       blk_cleanup_queue(queue);
837 +out_cache_cleanup:
838 +       remove_proc_entry(DEVICE_NAME, NULL);
839 +       ps3vram_cache_cleanup(dev);
840 +out_unmap_reports:
841 +       iounmap(priv->reports);
842 +out_unmap_ctrl:
843 +       iounmap(priv->ctrl);
844 +out_unmap_vram:
845 +       iounmap(priv->ddr_base);
846 +out_free_context:
847 +       lv1_gpu_context_free(priv->context_handle);
848 +out_free_memory:
849 +       lv1_gpu_memory_free(priv->memory_handle);
850 +out_close_gpu:
851 +       ps3_close_hv_device(dev);
852 +out_free_xdr_buf:
853 +       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
854 +fail_free_priv:
855 +       kfree(priv);
856 +       dev->core.driver_data = NULL;
857 +fail:
858 +       return error;
859 +}
860 +
861 +static int ps3vram_remove(struct ps3_system_bus_device *dev)
862 +{
863 +       struct ps3vram_priv *priv = dev->core.driver_data;
864 +
865 +       del_gendisk(priv->gendisk);
866 +       put_disk(priv->gendisk);
867 +       blk_cleanup_queue(priv->queue);
868 +       remove_proc_entry(DEVICE_NAME, NULL);
869 +       ps3vram_cache_cleanup(dev);
870 +       iounmap(priv->reports);
871 +       iounmap(priv->ctrl);
872 +       iounmap(priv->ddr_base);
873 +       lv1_gpu_context_free(priv->context_handle);
874 +       lv1_gpu_memory_free(priv->memory_handle);
875 +       ps3_close_hv_device(dev);
876 +       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
877 +       kfree(priv);
878 +       dev->core.driver_data = NULL;
879 +       return 0;
880 +}
881 +
882 +static struct ps3_system_bus_driver ps3vram = {
883 +       .match_id       = PS3_MATCH_ID_GPU,
884 +       .match_sub_id   = PS3_MATCH_SUB_ID_GPU_RAMDISK,
885 +       .core.name      = DEVICE_NAME,
886 +       .core.owner     = THIS_MODULE,
887 +       .probe          = ps3vram_probe,
888 +       .remove         = ps3vram_remove,
889 +       .shutdown       = ps3vram_remove,
890 +};
891 +
892 +
893 +static int __init ps3vram_init(void)
894 +{
895 +       int error;
896 +
897 +       if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
898 +               return -ENODEV;
899 +
900 +       error = register_blkdev(0, DEVICE_NAME);
901 +       if (error <= 0) {
902 +               pr_err("%s: register_blkdev failed %d\n", DEVICE_NAME, error);
903 +               return error;
904 +       }
905 +       ps3vram_major = error;
906 +
907 +       pr_info("%s: registered block device major %d\n", DEVICE_NAME,
908 +               ps3vram_major);
909 +
910 +       error = ps3_system_bus_driver_register(&ps3vram);
911 +       if (error)
912 +               unregister_blkdev(ps3vram_major, DEVICE_NAME);
913 +
914 +       return error;
915 +}
916 +
917 +static void __exit ps3vram_exit(void)
918 +{
919 +       ps3_system_bus_driver_unregister(&ps3vram);
920 +       unregister_blkdev(ps3vram_major, DEVICE_NAME);
921 +}
922 +
923 +module_init(ps3vram_init);
924 +module_exit(ps3vram_exit);
925 +
926 +MODULE_LICENSE("GPL");
927 +MODULE_DESCRIPTION("PS3 Video RAM Storage Driver");
928 +MODULE_AUTHOR("Sony Corporation");
929 +MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);
930 diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
931 index bc33200..6fde0a2 100644
932 --- a/drivers/mtd/devices/Kconfig
933 +++ b/drivers/mtd/devices/Kconfig
934 @@ -120,13 +120,6 @@ config MTD_PHRAM
935           doesn't have access to, memory beyond the mem=xxx limit, nvram,
936           memory on the video card, etc...
937  
938 -config MTD_PS3VRAM
939 -       tristate "PS3 video RAM"
940 -       depends on FB_PS3
941 -       help
942 -         This driver allows you to use excess PS3 video RAM as volatile
943 -         storage or system swap.
944 -
945  config MTD_LART
946         tristate "28F160xx flash driver for LART"
947         depends on SA1100_LART
948 diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
949 index e51521d..0993d5c 100644
950 --- a/drivers/mtd/devices/Makefile
951 +++ b/drivers/mtd/devices/Makefile
952 @@ -16,4 +16,3 @@ obj-$(CONFIG_MTD_LART)                += lart.o
953  obj-$(CONFIG_MTD_BLOCK2MTD)    += block2mtd.o
954  obj-$(CONFIG_MTD_DATAFLASH)    += mtd_dataflash.o
955  obj-$(CONFIG_MTD_M25P80)       += m25p80.o
956 -obj-$(CONFIG_MTD_PS3VRAM)      += ps3vram.o
957 diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c
958 deleted file mode 100644
959 index d21e9be..0000000
960 --- a/drivers/mtd/devices/ps3vram.c
961 +++ /dev/null
962 @@ -1,768 +0,0 @@
963 -/**
964 - * ps3vram - Use extra PS3 video ram as MTD block device.
965 - *
966 - * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
967 - * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
968 - */
969 -
970 -#include <linux/io.h>
971 -#include <linux/mm.h>
972 -#include <linux/init.h>
973 -#include <linux/kernel.h>
974 -#include <linux/list.h>
975 -#include <linux/module.h>
976 -#include <linux/moduleparam.h>
977 -#include <linux/slab.h>
978 -#include <linux/version.h>
979 -#include <linux/gfp.h>
980 -#include <linux/delay.h>
981 -#include <linux/mtd/mtd.h>
982 -
983 -#include <asm/lv1call.h>
984 -#include <asm/ps3.h>
985 -
986 -#define DEVICE_NAME            "ps3vram"
987 -
988 -#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
989 -#define XDR_IOIF 0x0c000000
990 -
991 -#define FIFO_BASE XDR_IOIF
992 -#define FIFO_SIZE (64 * 1024)
993 -
994 -#define DMA_PAGE_SIZE (4 * 1024)
995 -
996 -#define CACHE_PAGE_SIZE (256 * 1024)
997 -#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
998 -
999 -#define CACHE_OFFSET CACHE_PAGE_SIZE
1000 -#define FIFO_OFFSET 0
1001 -
1002 -#define CTRL_PUT 0x10
1003 -#define CTRL_GET 0x11
1004 -#define CTRL_TOP 0x15
1005 -
1006 -#define UPLOAD_SUBCH   1
1007 -#define DOWNLOAD_SUBCH 2
1008 -
1009 -#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN   0x0000030c
1010 -#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY      0x00000104
1011 -
1012 -#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
1013 -
1014 -struct mtd_info ps3vram_mtd;
1015 -
1016 -#define CACHE_PAGE_PRESENT 1
1017 -#define CACHE_PAGE_DIRTY   2
1018 -
1019 -struct ps3vram_tag {
1020 -       unsigned int address;
1021 -       unsigned int flags;
1022 -};
1023 -
1024 -struct ps3vram_cache {
1025 -       unsigned int page_count;
1026 -       unsigned int page_size;
1027 -       struct ps3vram_tag *tags;
1028 -};
1029 -
1030 -struct ps3vram_priv {
1031 -       u64 memory_handle;
1032 -       u64 context_handle;
1033 -       u32 *ctrl;
1034 -       u32 *reports;
1035 -       u8 __iomem *ddr_base;
1036 -       u8 *xdr_buf;
1037 -
1038 -       u32 *fifo_base;
1039 -       u32 *fifo_ptr;
1040 -
1041 -       struct device *dev;
1042 -       struct ps3vram_cache cache;
1043 -
1044 -       /* Used to serialize cache/DMA operations */
1045 -       struct mutex lock;
1046 -};
1047 -
1048 -#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
1049 -#define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */
1050 -#define DMA_NOTIFIER_SIZE        0x40
1051 -#define NOTIFIER 7     /* notifier used for completion report */
1052 -
1053 -/* A trailing '-' means to subtract off ps3fb_videomemory.size */
1054 -char *size = "256M-";
1055 -module_param(size, charp, 0);
1056 -MODULE_PARM_DESC(size, "memory size");
1057 -
1058 -static u32 *ps3vram_get_notifier(u32 *reports, int notifier)
1059 -{
1060 -       return (void *) reports +
1061 -               DMA_NOTIFIER_OFFSET_BASE +
1062 -               DMA_NOTIFIER_SIZE * notifier;
1063 -}
1064 -
1065 -static void ps3vram_notifier_reset(struct mtd_info *mtd)
1066 -{
1067 -       int i;
1068 -
1069 -       struct ps3vram_priv *priv = mtd->priv;
1070 -       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
1071 -       for (i = 0; i < 4; i++)
1072 -               notify[i] = 0xffffffff;
1073 -}
1074 -
1075 -static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms)
1076 -{
1077 -       struct ps3vram_priv *priv = mtd->priv;
1078 -       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
1079 -       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
1080 -
1081 -       do {
1082 -               if (!notify[3])
1083 -                       return 0;
1084 -               msleep(1);
1085 -       } while (time_before(jiffies, timeout));
1086 -
1087 -       return -ETIMEDOUT;
1088 -}
1089 -
1090 -static void ps3vram_init_ring(struct mtd_info *mtd)
1091 -{
1092 -       struct ps3vram_priv *priv = mtd->priv;
1093 -
1094 -       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
1095 -       priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
1096 -}
1097 -
1098 -static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms)
1099 -{
1100 -       struct ps3vram_priv *priv = mtd->priv;
1101 -       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
1102 -
1103 -       do {
1104 -               if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET])
1105 -                       return 0;
1106 -               msleep(1);
1107 -       } while (time_before(jiffies, timeout));
1108 -
1109 -       dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__,
1110 -               __LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET],
1111 -               priv->ctrl[CTRL_TOP]);
1112 -
1113 -       return -ETIMEDOUT;
1114 -}
1115 -
1116 -static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
1117 -{
1118 -       *(priv->fifo_ptr)++ = data;
1119 -}
1120 -
1121 -static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan,
1122 -                                     u32 tag, u32 size)
1123 -{
1124 -       ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
1125 -}
1126 -
1127 -static void ps3vram_rewind_ring(struct mtd_info *mtd)
1128 -{
1129 -       struct ps3vram_priv *priv = mtd->priv;
1130 -       u64 status;
1131 -
1132 -       ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
1133 -
1134 -       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
1135 -
1136 -       /* asking the HV for a blit will kick the fifo */
1137 -       status = lv1_gpu_context_attribute(priv->context_handle,
1138 -                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
1139 -                                          0, 0, 0, 0);
1140 -       if (status)
1141 -               dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
1142 -                       __func__, __LINE__);
1143 -
1144 -       priv->fifo_ptr = priv->fifo_base;
1145 -}
1146 -
1147 -static void ps3vram_fire_ring(struct mtd_info *mtd)
1148 -{
1149 -       struct ps3vram_priv *priv = mtd->priv;
1150 -       u64 status;
1151 -
1152 -       mutex_lock(&ps3_gpu_mutex);
1153 -
1154 -       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET +
1155 -               (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
1156 -
1157 -       /* asking the HV for a blit will kick the fifo */
1158 -       status = lv1_gpu_context_attribute(priv->context_handle,
1159 -                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
1160 -                                          0, 0, 0, 0);
1161 -       if (status)
1162 -               dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
1163 -                       __func__, __LINE__);
1164 -
1165 -       if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
1166 -               FIFO_SIZE - 1024) {
1167 -               dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__,
1168 -                       __LINE__);
1169 -               ps3vram_wait_ring(mtd, 200);
1170 -               ps3vram_rewind_ring(mtd);
1171 -       }
1172 -
1173 -       mutex_unlock(&ps3_gpu_mutex);
1174 -}
1175 -
1176 -static void ps3vram_bind(struct mtd_info *mtd)
1177 -{
1178 -       struct ps3vram_priv *priv = mtd->priv;
1179 -
1180 -       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
1181 -       ps3vram_out_ring(priv, 0x31337303);
1182 -       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
1183 -       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
1184 -       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
1185 -       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
1186 -
1187 -       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
1188 -       ps3vram_out_ring(priv, 0x3137c0de);
1189 -       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
1190 -       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
1191 -       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
1192 -       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
1193 -
1194 -       ps3vram_fire_ring(mtd);
1195 -}
1196 -
1197 -static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset,
1198 -                         unsigned int dst_offset, int len, int count)
1199 -{
1200 -       struct ps3vram_priv *priv = mtd->priv;
1201 -
1202 -       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
1203 -                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
1204 -       ps3vram_out_ring(priv, XDR_IOIF + src_offset);
1205 -       ps3vram_out_ring(priv, dst_offset);
1206 -       ps3vram_out_ring(priv, len);
1207 -       ps3vram_out_ring(priv, len);
1208 -       ps3vram_out_ring(priv, len);
1209 -       ps3vram_out_ring(priv, count);
1210 -       ps3vram_out_ring(priv, (1 << 8) | 1);
1211 -       ps3vram_out_ring(priv, 0);
1212 -
1213 -       ps3vram_notifier_reset(mtd);
1214 -       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
1215 -                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
1216 -       ps3vram_out_ring(priv, 0);
1217 -       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
1218 -       ps3vram_out_ring(priv, 0);
1219 -       ps3vram_fire_ring(mtd);
1220 -       if (ps3vram_notifier_wait(mtd, 200) < 0) {
1221 -               dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
1222 -                       __LINE__);
1223 -               return -1;
1224 -       }
1225 -
1226 -       return 0;
1227 -}
1228 -
1229 -static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset,
1230 -                           unsigned int dst_offset, int len, int count)
1231 -{
1232 -       struct ps3vram_priv *priv = mtd->priv;
1233 -
1234 -       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
1235 -                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
1236 -       ps3vram_out_ring(priv, src_offset);
1237 -       ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
1238 -       ps3vram_out_ring(priv, len);
1239 -       ps3vram_out_ring(priv, len);
1240 -       ps3vram_out_ring(priv, len);
1241 -       ps3vram_out_ring(priv, count);
1242 -       ps3vram_out_ring(priv, (1 << 8) | 1);
1243 -       ps3vram_out_ring(priv, 0);
1244 -
1245 -       ps3vram_notifier_reset(mtd);
1246 -       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
1247 -                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
1248 -       ps3vram_out_ring(priv, 0);
1249 -       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
1250 -       ps3vram_out_ring(priv, 0);
1251 -       ps3vram_fire_ring(mtd);
1252 -       if (ps3vram_notifier_wait(mtd, 200) < 0) {
1253 -               dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
1254 -                       __LINE__);
1255 -               return -1;
1256 -       }
1257 -
1258 -       return 0;
1259 -}
1260 -
1261 -static void ps3vram_cache_evict(struct mtd_info *mtd, int entry)
1262 -{
1263 -       struct ps3vram_priv *priv = mtd->priv;
1264 -       struct ps3vram_cache *cache = &priv->cache;
1265 -
1266 -       if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) {
1267 -               dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__,
1268 -                       __LINE__, entry, cache->tags[entry].address);
1269 -               if (ps3vram_upload(mtd,
1270 -                                  CACHE_OFFSET + entry * cache->page_size,
1271 -                                  cache->tags[entry].address,
1272 -                                  DMA_PAGE_SIZE,
1273 -                                  cache->page_size / DMA_PAGE_SIZE) < 0) {
1274 -                       dev_dbg(priv->dev, "%s:%d: failed to upload from "
1275 -                               "0x%x to 0x%x size 0x%x\n", __func__, __LINE__,
1276 -                               entry * cache->page_size,
1277 -                               cache->tags[entry].address, cache->page_size);
1278 -               }
1279 -               cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
1280 -       }
1281 -}
1282 -
1283 -static void ps3vram_cache_load(struct mtd_info *mtd, int entry,
1284 -                              unsigned int address)
1285 -{
1286 -       struct ps3vram_priv *priv = mtd->priv;
1287 -       struct ps3vram_cache *cache = &priv->cache;
1288 -
1289 -       dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__,
1290 -               entry, address);
1291 -       if (ps3vram_download(mtd,
1292 -                            address,
1293 -                            CACHE_OFFSET + entry * cache->page_size,
1294 -                            DMA_PAGE_SIZE,
1295 -                            cache->page_size / DMA_PAGE_SIZE) < 0) {
1296 -               dev_err(priv->dev, "%s:%d: failed to download from "
1297 -                       "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address,
1298 -                       entry * cache->page_size, cache->page_size);
1299 -       }
1300 -
1301 -       cache->tags[entry].address = address;
1302 -       cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
1303 -}
1304 -
1305 -
1306 -static void ps3vram_cache_flush(struct mtd_info *mtd)
1307 -{
1308 -       struct ps3vram_priv *priv = mtd->priv;
1309 -       struct ps3vram_cache *cache = &priv->cache;
1310 -       int i;
1311 -
1312 -       dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__);
1313 -       for (i = 0; i < cache->page_count; i++) {
1314 -               ps3vram_cache_evict(mtd, i);
1315 -               cache->tags[i].flags = 0;
1316 -       }
1317 -}
1318 -
1319 -static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address)
1320 -{
1321 -       struct ps3vram_priv *priv = mtd->priv;
1322 -       struct ps3vram_cache *cache = &priv->cache;
1323 -       unsigned int base;
1324 -       unsigned int offset;
1325 -       int i;
1326 -       static int counter;
1327 -
1328 -       offset = (unsigned int) (address & (cache->page_size - 1));
1329 -       base = (unsigned int) (address - offset);
1330 -
1331 -       /* fully associative check */
1332 -       for (i = 0; i < cache->page_count; i++) {
1333 -               if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
1334 -                   cache->tags[i].address == base) {
1335 -                       dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n",
1336 -                               __func__, __LINE__, i, cache->tags[i].address);
1337 -                       return i;
1338 -               }
1339 -       }
1340 -
1341 -       /* choose a random entry */
1342 -       i = (jiffies + (counter++)) % cache->page_count;
1343 -       dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i);
1344 -
1345 -       ps3vram_cache_evict(mtd, i);
1346 -       ps3vram_cache_load(mtd, i, base);
1347 -
1348 -       return i;
1349 -}
1350 -
1351 -static int ps3vram_cache_init(struct mtd_info *mtd)
1352 -{
1353 -       struct ps3vram_priv *priv = mtd->priv;
1354 -
1355 -       priv->cache.page_count = CACHE_PAGE_COUNT;
1356 -       priv->cache.page_size = CACHE_PAGE_SIZE;
1357 -       priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) *
1358 -                                  CACHE_PAGE_COUNT, GFP_KERNEL);
1359 -       if (priv->cache.tags == NULL) {
1360 -               dev_err(priv->dev, "%s:%d: could not allocate cache tags\n",
1361 -                       __func__, __LINE__);
1362 -               return -ENOMEM;
1363 -       }
1364 -
1365 -       dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n",
1366 -               CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
1367 -
1368 -       return 0;
1369 -}
1370 -
1371 -static void ps3vram_cache_cleanup(struct mtd_info *mtd)
1372 -{
1373 -       struct ps3vram_priv *priv = mtd->priv;
1374 -
1375 -       ps3vram_cache_flush(mtd);
1376 -       kfree(priv->cache.tags);
1377 -}
1378 -
1379 -static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr)
1380 -{
1381 -       struct ps3vram_priv *priv = mtd->priv;
1382 -
1383 -       if (instr->addr + instr->len > mtd->size)
1384 -               return -EINVAL;
1385 -
1386 -       mutex_lock(&priv->lock);
1387 -
1388 -       ps3vram_cache_flush(mtd);
1389 -
1390 -       /* Set bytes to 0xFF */
1391 -       memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len);
1392 -
1393 -       mutex_unlock(&priv->lock);
1394 -
1395 -       instr->state = MTD_ERASE_DONE;
1396 -       mtd_erase_callback(instr);
1397 -
1398 -       return 0;
1399 -}
1400 -
1401 -static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len,
1402 -                       size_t *retlen, u_char *buf)
1403 -{
1404 -       struct ps3vram_priv *priv = mtd->priv;
1405 -       unsigned int cached, count;
1406 -
1407 -       dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__,
1408 -               (unsigned int)from, len);
1409 -
1410 -       if (from >= mtd->size)
1411 -               return -EINVAL;
1412 -
1413 -       if (len > mtd->size - from)
1414 -               len = mtd->size - from;
1415 -
1416 -       /* Copy from vram to buf */
1417 -       count = len;
1418 -       while (count) {
1419 -               unsigned int offset, avail;
1420 -               unsigned int entry;
1421 -
1422 -               offset = (unsigned int) (from & (priv->cache.page_size - 1));
1423 -               avail  = priv->cache.page_size - offset;
1424 -
1425 -               mutex_lock(&priv->lock);
1426 -
1427 -               entry = ps3vram_cache_match(mtd, from);
1428 -               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
1429 -
1430 -               dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x "
1431 -                       "avail=%08x count=%08x\n", __func__, __LINE__,
1432 -                       (unsigned int)from, cached, offset, avail, count);
1433 -
1434 -               if (avail > count)
1435 -                       avail = count;
1436 -               memcpy(buf, priv->xdr_buf + cached, avail);
1437 -
1438 -               mutex_unlock(&priv->lock);
1439 -
1440 -               buf += avail;
1441 -               count -= avail;
1442 -               from += avail;
1443 -       }
1444 -
1445 -       *retlen = len;
1446 -       return 0;
1447 -}
1448 -
1449 -static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len,
1450 -                        size_t *retlen, const u_char *buf)
1451 -{
1452 -       struct ps3vram_priv *priv = mtd->priv;
1453 -       unsigned int cached, count;
1454 -
1455 -       if (to >= mtd->size)
1456 -               return -EINVAL;
1457 -
1458 -       if (len > mtd->size - to)
1459 -               len = mtd->size - to;
1460 -
1461 -       /* Copy from buf to vram */
1462 -       count = len;
1463 -       while (count) {
1464 -               unsigned int offset, avail;
1465 -               unsigned int entry;
1466 -
1467 -               offset = (unsigned int) (to & (priv->cache.page_size - 1));
1468 -               avail  = priv->cache.page_size - offset;
1469 -
1470 -               mutex_lock(&priv->lock);
1471 -
1472 -               entry = ps3vram_cache_match(mtd, to);
1473 -               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
1474 -
1475 -               dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x "
1476 -                       "avail=%08x count=%08x\n", __func__, __LINE__,
1477 -                       (unsigned int)to, cached, offset, avail, count);
1478 -
1479 -               if (avail > count)
1480 -                       avail = count;
1481 -               memcpy(priv->xdr_buf + cached, buf, avail);
1482 -
1483 -               priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
1484 -
1485 -               mutex_unlock(&priv->lock);
1486 -
1487 -               buf += avail;
1488 -               count -= avail;
1489 -               to += avail;
1490 -       }
1491 -
1492 -       *retlen = len;
1493 -       return 0;
1494 -}
1495 -
1496 -static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
1497 -{
1498 -       struct ps3vram_priv *priv;
1499 -       int status;
1500 -       u64 ddr_lpar;
1501 -       u64 ctrl_lpar;
1502 -       u64 info_lpar;
1503 -       u64 reports_lpar;
1504 -       u64 ddr_size;
1505 -       u64 reports_size;
1506 -       int ret = -ENOMEM;
1507 -       char *rest;
1508 -
1509 -       ret = -EIO;
1510 -       ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL);
1511 -       if (!ps3vram_mtd.priv)
1512 -               goto out;
1513 -       priv = ps3vram_mtd.priv;
1514 -
1515 -       mutex_init(&priv->lock);
1516 -       priv->dev = &dev->core;
1517 -
1518 -       /* Allocate XDR buffer (1MiB aligned) */
1519 -       priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
1520 -               get_order(XDR_BUF_SIZE));
1521 -       if (priv->xdr_buf == NULL) {
1522 -               dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n",
1523 -                       __func__, __LINE__);
1524 -               ret = -ENOMEM;
1525 -               goto out_free_priv;
1526 -       }
1527 -
1528 -       /* Put FIFO at begginning of XDR buffer */
1529 -       priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
1530 -       priv->fifo_ptr = priv->fifo_base;
1531 -
1532 -       /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
1533 -       if (ps3_open_hv_device(dev)) {
1534 -               dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
1535 -                       __func__, __LINE__);
1536 -               ret = -EAGAIN;
1537 -               goto out_close_gpu;
1538 -       }
1539 -
1540 -       /* Request memory */
1541 -       status = -1;
1542 -       ddr_size = memparse(size, &rest);
1543 -       if (*rest == '-')
1544 -               ddr_size -= ps3fb_videomemory.size;
1545 -       ddr_size = ALIGN(ddr_size, 1024*1024);
1546 -       if (ddr_size <= 0) {
1547 -               dev_err(&dev->core, "%s:%d: specified size is too small\n",
1548 -                       __func__, __LINE__);
1549 -               ret = -EINVAL;
1550 -               goto out_close_gpu;
1551 -       }
1552 -
1553 -       while (ddr_size > 0) {
1554 -               status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
1555 -                                                &priv->memory_handle,
1556 -                                                &ddr_lpar);
1557 -               if (!status)
1558 -                       break;
1559 -               ddr_size -= 1024*1024;
1560 -       }
1561 -       if (status || ddr_size <= 0) {
1562 -               dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n",
1563 -                       __func__, __LINE__);
1564 -               ret = -ENOMEM;
1565 -               goto out_free_xdr_buf;
1566 -       }
1567 -
1568 -       /* Request context */
1569 -       status = lv1_gpu_context_allocate(priv->memory_handle,
1570 -                                         0,
1571 -                                         &priv->context_handle,
1572 -                                         &ctrl_lpar,
1573 -                                         &info_lpar,
1574 -                                         &reports_lpar,
1575 -                                         &reports_size);
1576 -       if (status) {
1577 -               dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n",
1578 -                       __func__, __LINE__);
1579 -               ret = -ENOMEM;
1580 -               goto out_free_memory;
1581 -       }
1582 -
1583 -       /* Map XDR buffer to RSX */
1584 -       status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
1585 -                                      ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
1586 -                                      XDR_BUF_SIZE, 0);
1587 -       if (status) {
1588 -               dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n",
1589 -                       __func__, __LINE__);
1590 -               ret = -ENOMEM;
1591 -               goto out_free_context;
1592 -       }
1593 -
1594 -       priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
1595 -
1596 -       if (!priv->ddr_base) {
1597 -               dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
1598 -                       __LINE__);
1599 -               ret = -ENOMEM;
1600 -               goto out_free_context;
1601 -       }
1602 -
1603 -       priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
1604 -       if (!priv->ctrl) {
1605 -               dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
1606 -                       __LINE__);
1607 -               ret = -ENOMEM;
1608 -               goto out_unmap_vram;
1609 -       }
1610 -
1611 -       priv->reports = ioremap(reports_lpar, reports_size);
1612 -       if (!priv->reports) {
1613 -               dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
1614 -                       __LINE__);
1615 -               ret = -ENOMEM;
1616 -               goto out_unmap_ctrl;
1617 -       }
1618 -
1619 -       mutex_lock(&ps3_gpu_mutex);
1620 -       ps3vram_init_ring(&ps3vram_mtd);
1621 -       mutex_unlock(&ps3_gpu_mutex);
1622 -
1623 -       ps3vram_mtd.name = "ps3vram";
1624 -       ps3vram_mtd.size = ddr_size;
1625 -       ps3vram_mtd.flags = MTD_CAP_RAM;
1626 -       ps3vram_mtd.erase = ps3vram_erase;
1627 -       ps3vram_mtd.point = NULL;
1628 -       ps3vram_mtd.unpoint = NULL;
1629 -       ps3vram_mtd.read = ps3vram_read;
1630 -       ps3vram_mtd.write = ps3vram_write;
1631 -       ps3vram_mtd.owner = THIS_MODULE;
1632 -       ps3vram_mtd.type = MTD_RAM;
1633 -       ps3vram_mtd.erasesize = CACHE_PAGE_SIZE;
1634 -       ps3vram_mtd.writesize = 1;
1635 -
1636 -       ps3vram_bind(&ps3vram_mtd);
1637 -
1638 -       mutex_lock(&ps3_gpu_mutex);
1639 -       ret = ps3vram_wait_ring(&ps3vram_mtd, 100);
1640 -       mutex_unlock(&ps3_gpu_mutex);
1641 -       if (ret < 0) {
1642 -               dev_err(&dev->core, "%s:%d: failed to initialize channels\n",
1643 -                       __func__, __LINE__);
1644 -               ret = -ETIMEDOUT;
1645 -               goto out_unmap_reports;
1646 -       }
1647 -
1648 -       ps3vram_cache_init(&ps3vram_mtd);
1649 -
1650 -       if (add_mtd_device(&ps3vram_mtd)) {
1651 -               dev_err(&dev->core, "%s:%d: add_mtd_device failed\n",
1652 -                       __func__, __LINE__);
1653 -               ret = -EAGAIN;
1654 -               goto out_cache_cleanup;
1655 -       }
1656 -
1657 -       dev_info(&dev->core, "reserved %u MiB of gpu memory\n",
1658 -               (unsigned int)(ddr_size / 1024 / 1024));
1659 -
1660 -       return 0;
1661 -
1662 -out_cache_cleanup:
1663 -       ps3vram_cache_cleanup(&ps3vram_mtd);
1664 -out_unmap_reports:
1665 -       iounmap(priv->reports);
1666 -out_unmap_ctrl:
1667 -       iounmap(priv->ctrl);
1668 -out_unmap_vram:
1669 -       iounmap(priv->ddr_base);
1670 -out_free_context:
1671 -       lv1_gpu_context_free(priv->context_handle);
1672 -out_free_memory:
1673 -       lv1_gpu_memory_free(priv->memory_handle);
1674 -out_close_gpu:
1675 -       ps3_close_hv_device(dev);
1676 -out_free_xdr_buf:
1677 -       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
1678 -out_free_priv:
1679 -       kfree(ps3vram_mtd.priv);
1680 -       ps3vram_mtd.priv = NULL;
1681 -out:
1682 -       return ret;
1683 -}
1684 -
1685 -static int ps3vram_shutdown(struct ps3_system_bus_device *dev)
1686 -{
1687 -       struct ps3vram_priv *priv;
1688 -
1689 -       priv = ps3vram_mtd.priv;
1690 -
1691 -       del_mtd_device(&ps3vram_mtd);
1692 -       ps3vram_cache_cleanup(&ps3vram_mtd);
1693 -       iounmap(priv->reports);
1694 -       iounmap(priv->ctrl);
1695 -       iounmap(priv->ddr_base);
1696 -       lv1_gpu_context_free(priv->context_handle);
1697 -       lv1_gpu_memory_free(priv->memory_handle);
1698 -       ps3_close_hv_device(dev);
1699 -       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
1700 -       kfree(priv);
1701 -       return 0;
1702 -}
1703 -
1704 -static struct ps3_system_bus_driver ps3vram_driver = {
1705 -       .match_id       = PS3_MATCH_ID_GPU,
1706 -       .match_sub_id   = PS3_MATCH_SUB_ID_GPU_RAMDISK,
1707 -       .core.name      = DEVICE_NAME,
1708 -       .core.owner     = THIS_MODULE,
1709 -       .probe          = ps3vram_probe,
1710 -       .remove         = ps3vram_shutdown,
1711 -       .shutdown       = ps3vram_shutdown,
1712 -};
1713 -
1714 -static int __init ps3vram_init(void)
1715 -{
1716 -       return ps3_system_bus_driver_register(&ps3vram_driver);
1717 -}
1718 -
1719 -static void __exit ps3vram_exit(void)
1720 -{
1721 -       ps3_system_bus_driver_unregister(&ps3vram_driver);
1722 -}
1723 -
1724 -module_init(ps3vram_init);
1725 -module_exit(ps3vram_exit);
1726 -
1727 -MODULE_LICENSE("GPL");
1728 -MODULE_AUTHOR("Jim Paris <jim@jtan.com>");
1729 -MODULE_DESCRIPTION("MTD driver for PS3 video RAM");
1730 -MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);
1731 -- 
1732 1.6.0.4
1733