]> err.no Git - linux-2.6/blob - arch/powerpc/platforms/ps3/device-init.c
[POWERPC] PS3: Refactor ps3_repository_find_device()
[linux-2.6] / arch / powerpc / platforms / ps3 / device-init.c
1 /*
2  *  PS3 device registration routines.
3  *
4  *  Copyright (C) 2007 Sony Computer Entertainment Inc.
5  *  Copyright 2007 Sony Corp.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; version 2 of the License.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <linux/delay.h>
22 #include <linux/freezer.h>
23 #include <linux/kernel.h>
24 #include <linux/kthread.h>
25 #include <linux/init.h>
26 #include <linux/reboot.h>
27
28 #include <asm/firmware.h>
29 #include <asm/lv1call.h>
30 #include <asm/ps3stor.h>
31
32 #include "platform.h"
33
34 /**
35  * ps3_setup_gelic_device - Setup and register a gelic device instance.
36  *
37  * Allocates memory for a struct ps3_system_bus_device instance, initialises the
38  * structure members, and registers the device instance with the system bus.
39  */
40
41 static int __init ps3_setup_gelic_device(
42         const struct ps3_repository_device *repo)
43 {
44         int result;
45         struct layout {
46                 struct ps3_system_bus_device dev;
47                 struct ps3_dma_region d_region;
48         } *p;
49
50         pr_debug(" -> %s:%d\n", __func__, __LINE__);
51
52         BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
53         BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC);
54
55         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
56
57         if (!p) {
58                 result = -ENOMEM;
59                 goto fail_malloc;
60         }
61
62         p->dev.match_id = PS3_MATCH_ID_GELIC;
63         p->dev.dev_type = PS3_DEVICE_TYPE_SB;
64         p->dev.bus_id = repo->bus_id;
65         p->dev.dev_id = repo->dev_id;
66         p->dev.d_region = &p->d_region;
67
68         result = ps3_repository_find_interrupt(repo,
69                 PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id);
70
71         if (result) {
72                 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
73                         __func__, __LINE__);
74                 goto fail_find_interrupt;
75         }
76
77         BUG_ON(p->dev.interrupt_id != 0);
78
79         result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
80                 PS3_DMA_OTHER, NULL, 0);
81
82         if (result) {
83                 pr_debug("%s:%d ps3_dma_region_init failed\n",
84                         __func__, __LINE__);
85                 goto fail_dma_init;
86         }
87
88         result = ps3_system_bus_device_register(&p->dev);
89
90         if (result) {
91                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
92                         __func__, __LINE__);
93                 goto fail_device_register;
94         }
95
96         pr_debug(" <- %s:%d\n", __func__, __LINE__);
97         return result;
98
99 fail_device_register:
100 fail_dma_init:
101 fail_find_interrupt:
102         kfree(p);
103 fail_malloc:
104         pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
105         return result;
106 }
107
108 static int __init_refok ps3_setup_uhc_device(
109         const struct ps3_repository_device *repo, enum ps3_match_id match_id,
110         enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type)
111 {
112         int result;
113         struct layout {
114                 struct ps3_system_bus_device dev;
115                 struct ps3_dma_region d_region;
116                 struct ps3_mmio_region m_region;
117         } *p;
118         u64 bus_addr;
119         u64 len;
120
121         pr_debug(" -> %s:%d\n", __func__, __LINE__);
122
123         BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
124         BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB);
125
126         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
127
128         if (!p) {
129                 result = -ENOMEM;
130                 goto fail_malloc;
131         }
132
133         p->dev.match_id = match_id;
134         p->dev.dev_type = PS3_DEVICE_TYPE_SB;
135         p->dev.bus_id = repo->bus_id;
136         p->dev.dev_id = repo->dev_id;
137         p->dev.d_region = &p->d_region;
138         p->dev.m_region = &p->m_region;
139
140         result = ps3_repository_find_interrupt(repo,
141                 interrupt_type, &p->dev.interrupt_id);
142
143         if (result) {
144                 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
145                         __func__, __LINE__);
146                 goto fail_find_interrupt;
147         }
148
149         result = ps3_repository_find_reg(repo, reg_type,
150                 &bus_addr, &len);
151
152         if (result) {
153                 pr_debug("%s:%d ps3_repository_find_reg failed\n",
154                         __func__, __LINE__);
155                 goto fail_find_reg;
156         }
157
158         result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
159                 PS3_DMA_INTERNAL, NULL, 0);
160
161         if (result) {
162                 pr_debug("%s:%d ps3_dma_region_init failed\n",
163                         __func__, __LINE__);
164                 goto fail_dma_init;
165         }
166
167         result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len,
168                 PS3_MMIO_4K);
169
170         if (result) {
171                 pr_debug("%s:%d ps3_mmio_region_init failed\n",
172                         __func__, __LINE__);
173                 goto fail_mmio_init;
174         }
175
176         result = ps3_system_bus_device_register(&p->dev);
177
178         if (result) {
179                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
180                         __func__, __LINE__);
181                 goto fail_device_register;
182         }
183
184         pr_debug(" <- %s:%d\n", __func__, __LINE__);
185         return result;
186
187 fail_device_register:
188 fail_mmio_init:
189 fail_dma_init:
190 fail_find_reg:
191 fail_find_interrupt:
192         kfree(p);
193 fail_malloc:
194         pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
195         return result;
196 }
197
198 static int __init ps3_setup_ehci_device(
199         const struct ps3_repository_device *repo)
200 {
201         return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI,
202                 PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI);
203 }
204
205 static int __init ps3_setup_ohci_device(
206         const struct ps3_repository_device *repo)
207 {
208         return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI,
209                 PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI);
210 }
211
212 static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
213         unsigned int port_number)
214 {
215         int result;
216         struct layout {
217                 struct ps3_system_bus_device dev;
218         } *p;
219
220         pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__,
221                 match_id, port_number);
222
223         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
224
225         if (!p)
226                 return -ENOMEM;
227
228         p->dev.match_id = match_id;
229         p->dev.dev_type = PS3_DEVICE_TYPE_VUART;
230         p->dev.port_number = port_number;
231
232         result = ps3_system_bus_device_register(&p->dev);
233
234         if (result)
235                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
236                         __func__, __LINE__);
237
238         pr_debug(" <- %s:%d\n", __func__, __LINE__);
239         return result;
240 }
241
242 static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
243                                  enum ps3_match_id match_id)
244 {
245         int result;
246         struct ps3_storage_device *p;
247         u64 port, blk_size, num_blocks;
248         unsigned int num_regions, i;
249
250         pr_debug(" -> %s:%u: match_id %u\n", __func__, __LINE__, match_id);
251
252         result = ps3_repository_read_stor_dev_info(repo->bus_index,
253                                                    repo->dev_index, &port,
254                                                    &blk_size, &num_blocks,
255                                                    &num_regions);
256         if (result) {
257                 printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n",
258                        __func__, __LINE__, result);
259                 return -ENODEV;
260         }
261
262         pr_debug("%s:%u: (%u:%u:%u): port %lu blk_size %lu num_blocks %lu "
263                  "num_regions %u\n", __func__, __LINE__, repo->bus_index,
264                  repo->dev_index, repo->dev_type, port, blk_size, num_blocks,
265                  num_regions);
266
267         p = kzalloc(sizeof(struct ps3_storage_device) +
268                     num_regions * sizeof(struct ps3_storage_region),
269                     GFP_KERNEL);
270         if (!p) {
271                 result = -ENOMEM;
272                 goto fail_malloc;
273         }
274
275         p->sbd.match_id = match_id;
276         p->sbd.dev_type = PS3_DEVICE_TYPE_SB;
277         p->sbd.bus_id = repo->bus_id;
278         p->sbd.dev_id = repo->dev_id;
279         p->sbd.d_region = &p->dma_region;
280         p->blk_size = blk_size;
281         p->num_regions = num_regions;
282
283         result = ps3_repository_find_interrupt(repo,
284                                                PS3_INTERRUPT_TYPE_EVENT_PORT,
285                                                &p->sbd.interrupt_id);
286         if (result) {
287                 printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__,
288                        __LINE__, result);
289                 result = -ENODEV;
290                 goto fail_find_interrupt;
291         }
292
293         for (i = 0; i < num_regions; i++) {
294                 unsigned int id;
295                 u64 start, size;
296
297                 result = ps3_repository_read_stor_dev_region(repo->bus_index,
298                                                              repo->dev_index,
299                                                              i, &id, &start,
300                                                              &size);
301                 if (result) {
302                         printk(KERN_ERR
303                                "%s:%u: read_stor_dev_region failed %d\n",
304                                __func__, __LINE__, result);
305                         result = -ENODEV;
306                         goto fail_read_region;
307                 }
308                 pr_debug("%s:%u: region %u: id %u start %lu size %lu\n",
309                          __func__, __LINE__, i, id, start, size);
310
311                 p->regions[i].id = id;
312                 p->regions[i].start = start;
313                 p->regions[i].size = size;
314         }
315
316         result = ps3_system_bus_device_register(&p->sbd);
317         if (result) {
318                 pr_debug("%s:%u ps3_system_bus_device_register failed\n",
319                          __func__, __LINE__);
320                 goto fail_device_register;
321         }
322
323         pr_debug(" <- %s:%u\n", __func__, __LINE__);
324         return 0;
325
326 fail_device_register:
327 fail_read_region:
328 fail_find_interrupt:
329         kfree(p);
330 fail_malloc:
331         pr_debug(" <- %s:%u: fail.\n", __func__, __LINE__);
332         return result;
333 }
334
335 static int __init ps3_register_vuart_devices(void)
336 {
337         int result;
338         unsigned int port_number;
339
340         pr_debug(" -> %s:%d\n", __func__, __LINE__);
341
342         result = ps3_repository_read_vuart_av_port(&port_number);
343         if (result)
344                 port_number = 0; /* av default */
345
346         result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);
347         WARN_ON(result);
348
349         result = ps3_repository_read_vuart_sysmgr_port(&port_number);
350         if (result)
351                 port_number = 2; /* sysmgr default */
352
353         result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,
354                 port_number);
355         WARN_ON(result);
356
357         pr_debug(" <- %s:%d\n", __func__, __LINE__);
358         return result;
359 }
360
361 static int __init ps3_register_sound_devices(void)
362 {
363         int result;
364         struct layout {
365                 struct ps3_system_bus_device dev;
366                 struct ps3_dma_region d_region;
367                 struct ps3_mmio_region m_region;
368         } *p;
369
370         pr_debug(" -> %s:%d\n", __func__, __LINE__);
371
372         p = kzalloc(sizeof(*p), GFP_KERNEL);
373         if (!p)
374                 return -ENOMEM;
375
376         p->dev.match_id = PS3_MATCH_ID_SOUND;
377         p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
378         p->dev.d_region = &p->d_region;
379         p->dev.m_region = &p->m_region;
380
381         result = ps3_system_bus_device_register(&p->dev);
382
383         if (result)
384                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
385                         __func__, __LINE__);
386
387         pr_debug(" <- %s:%d\n", __func__, __LINE__);
388         return result;
389 }
390
391 static int __init ps3_register_graphics_devices(void)
392 {
393         int result;
394         struct layout {
395                 struct ps3_system_bus_device dev;
396         } *p;
397
398         pr_debug(" -> %s:%d\n", __func__, __LINE__);
399
400         p = kzalloc(sizeof(struct layout), GFP_KERNEL);
401
402         if (!p)
403                 return -ENOMEM;
404
405         p->dev.match_id = PS3_MATCH_ID_GRAPHICS;
406         p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
407
408         result = ps3_system_bus_device_register(&p->dev);
409
410         if (result)
411                 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
412                         __func__, __LINE__);
413
414         pr_debug(" <- %s:%d\n", __func__, __LINE__);
415         return result;
416 }
417
418 /**
419  * ps3_register_repository_device - Register a device from the repositiory info.
420  *
421  */
422
423 static int ps3_register_repository_device(
424         const struct ps3_repository_device *repo)
425 {
426         int result;
427
428         switch (repo->dev_type) {
429         case PS3_DEV_TYPE_SB_GELIC:
430                 result = ps3_setup_gelic_device(repo);
431                 if (result) {
432                         pr_debug("%s:%d ps3_setup_gelic_device failed\n",
433                                 __func__, __LINE__);
434                 }
435                 break;
436         case PS3_DEV_TYPE_SB_USB:
437
438                 /* Each USB device has both an EHCI and an OHCI HC */
439
440                 result = ps3_setup_ehci_device(repo);
441
442                 if (result) {
443                         pr_debug("%s:%d ps3_setup_ehci_device failed\n",
444                                 __func__, __LINE__);
445                 }
446
447                 result = ps3_setup_ohci_device(repo);
448
449                 if (result) {
450                         pr_debug("%s:%d ps3_setup_ohci_device failed\n",
451                                 __func__, __LINE__);
452                 }
453                 break;
454         case PS3_DEV_TYPE_STOR_DISK:
455                 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK);
456
457                 /* Some devices are not accessable from the Other OS lpar. */
458                 if (result == -ENODEV) {
459                         result = 0;
460                         pr_debug("%s:%u: not accessable\n", __func__,
461                                  __LINE__);
462                 }
463
464                 if (result)
465                         pr_debug("%s:%u ps3_setup_storage_dev failed\n",
466                                  __func__, __LINE__);
467                 break;
468
469         case PS3_DEV_TYPE_STOR_ROM:
470                 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM);
471                 if (result)
472                         pr_debug("%s:%u ps3_setup_storage_dev failed\n",
473                                  __func__, __LINE__);
474                 break;
475
476         case PS3_DEV_TYPE_STOR_FLASH:
477                 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH);
478                 if (result)
479                         pr_debug("%s:%u ps3_setup_storage_dev failed\n",
480                                  __func__, __LINE__);
481                 break;
482
483         default:
484                 result = 0;
485                 pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
486                         repo->dev_type);
487         }
488
489         return result;
490 }
491
492 static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
493 {
494         struct ps3_repository_device repo;
495         int res;
496         unsigned int retries;
497         unsigned long rem;
498
499         /*
500          * On some firmware versions (e.g. 1.90), the device may not show up
501          * in the repository immediately
502          */
503         for (retries = 0; retries < 10; retries++) {
504                 res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id);
505                 if (!res)
506                         goto found;
507
508                 rem = msleep_interruptible(100);
509                 if (rem)
510                         break;
511         }
512         pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__,
513                    bus_id, dev_id);
514         return;
515
516 found:
517         if (retries)
518                 pr_debug("%s:%u: device %lu:%lu found after %u retries\n",
519                          __func__, __LINE__, bus_id, dev_id, retries);
520
521         ps3_register_repository_device(&repo);
522         return;
523 }
524
525 #define PS3_NOTIFICATION_DEV_ID         ULONG_MAX
526 #define PS3_NOTIFICATION_INTERRUPT_ID   0
527
528 struct ps3_notification_device {
529         struct ps3_system_bus_device sbd;
530         spinlock_t lock;
531         u64 tag;
532         u64 lv1_status;
533         struct completion done;
534 };
535
536 enum ps3_notify_type {
537         notify_device_ready = 0,
538         notify_region_probe = 1,
539         notify_region_update = 2,
540 };
541
542 struct ps3_notify_cmd {
543         u64 operation_code;             /* must be zero */
544         u64 event_mask;                 /* OR of 1UL << enum ps3_notify_type */
545 };
546
547 struct ps3_notify_event {
548         u64 event_type;                 /* enum ps3_notify_type */
549         u64 bus_id;
550         u64 dev_id;
551         u64 dev_type;
552         u64 dev_port;
553 };
554
555 static irqreturn_t ps3_notification_interrupt(int irq, void *data)
556 {
557         struct ps3_notification_device *dev = data;
558         int res;
559         u64 tag, status;
560
561         spin_lock(&dev->lock);
562         res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag,
563                                            &status);
564         if (tag != dev->tag)
565                 pr_err("%s:%u: tag mismatch, got %lx, expected %lx\n",
566                        __func__, __LINE__, tag, dev->tag);
567
568         if (res) {
569                 pr_err("%s:%u: res %d status 0x%lx\n", __func__, __LINE__, res,
570                        status);
571         } else {
572                 pr_debug("%s:%u: completed, status 0x%lx\n", __func__,
573                          __LINE__, status);
574                 dev->lv1_status = status;
575                 complete(&dev->done);
576         }
577         spin_unlock(&dev->lock);
578         return IRQ_HANDLED;
579 }
580
581 static int ps3_notification_read_write(struct ps3_notification_device *dev,
582                                        u64 lpar, int write)
583 {
584         const char *op = write ? "write" : "read";
585         unsigned long flags;
586         int res;
587
588         init_completion(&dev->done);
589         spin_lock_irqsave(&dev->lock, flags);
590         res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
591                                         &dev->tag)
592                     : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
593                                        &dev->tag);
594         spin_unlock_irqrestore(&dev->lock, flags);
595         if (res) {
596                 pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res);
597                 return -EPERM;
598         }
599         pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op);
600
601         res = wait_event_interruptible(dev->done.wait,
602                                        dev->done.done || kthread_should_stop());
603         if (kthread_should_stop())
604                 res = -EINTR;
605         if (res) {
606                 pr_debug("%s:%u: interrupted %s\n", __func__, __LINE__, op);
607                 return res;
608         }
609
610         if (dev->lv1_status) {
611                 pr_err("%s:%u: %s not completed, status 0x%lx\n", __func__,
612                        __LINE__, op, dev->lv1_status);
613                 return -EIO;
614         }
615         pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op);
616
617         return 0;
618 }
619
620 static struct task_struct *probe_task;
621
622 /**
623  * ps3_probe_thread - Background repository probing at system startup.
624  *
625  * This implementation only supports background probing on a single bus.
626  * It uses the hypervisor's storage device notification mechanism to wait until
627  * a storage device is ready.  The device notification mechanism uses a
628  * pseudo device to asynchronously notify the guest when storage devices become
629  * ready.  The notification device has a block size of 512 bytes.
630  */
631
632 static int ps3_probe_thread(void *data)
633 {
634         struct ps3_notification_device dev;
635         int res;
636         unsigned int irq;
637         u64 lpar;
638         void *buf;
639         struct ps3_notify_cmd *notify_cmd;
640         struct ps3_notify_event *notify_event;
641
642         pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
643
644         buf = kzalloc(512, GFP_KERNEL);
645         if (!buf)
646                 return -ENOMEM;
647
648         lpar = ps3_mm_phys_to_lpar(__pa(buf));
649         notify_cmd = buf;
650         notify_event = buf;
651
652         /* dummy system bus device */
653         dev.sbd.bus_id = (u64)data;
654         dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
655         dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
656
657         res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0);
658         if (res) {
659                 pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
660                        __LINE__, ps3_result(res));
661                 goto fail_free;
662         }
663
664         res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY,
665                                               &irq);
666         if (res) {
667                 pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
668                        __func__, __LINE__, res);
669                goto fail_close_device;
670         }
671
672         spin_lock_init(&dev.lock);
673
674         res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED,
675                           "ps3_notification", &dev);
676         if (res) {
677                 pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
678                        res);
679                 goto fail_sb_event_receive_port_destroy;
680         }
681
682         /* Setup and write the request for device notification. */
683         notify_cmd->operation_code = 0; /* must be zero */
684         notify_cmd->event_mask = 1UL << notify_region_probe;
685
686         res = ps3_notification_read_write(&dev, lpar, 1);
687         if (res)
688                 goto fail_free_irq;
689
690         /* Loop here processing the requested notification events. */
691         do {
692                 try_to_freeze();
693
694                 memset(notify_event, 0, sizeof(*notify_event));
695
696                 res = ps3_notification_read_write(&dev, lpar, 0);
697                 if (res)
698                         break;
699
700                 pr_debug("%s:%u: notify event type 0x%lx bus id %lu dev id %lu"
701                          " type %lu port %lu\n", __func__, __LINE__,
702                          notify_event->event_type, notify_event->bus_id,
703                          notify_event->dev_id, notify_event->dev_type,
704                          notify_event->dev_port);
705
706                 if (notify_event->event_type != notify_region_probe ||
707                     notify_event->bus_id != dev.sbd.bus_id) {
708                         pr_warning("%s:%u: bad notify_event: event %lu, "
709                                    "dev_id %lu, dev_type %lu\n",
710                                    __func__, __LINE__, notify_event->event_type,
711                                    notify_event->dev_id,
712                                    notify_event->dev_type);
713                         continue;
714                 }
715
716                 ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
717
718         } while (!kthread_should_stop());
719
720 fail_free_irq:
721         free_irq(irq, &dev);
722 fail_sb_event_receive_port_destroy:
723         ps3_sb_event_receive_port_destroy(&dev.sbd, irq);
724 fail_close_device:
725         lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id);
726 fail_free:
727         kfree(buf);
728
729         probe_task = NULL;
730
731         pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
732
733         return 0;
734 }
735
736 /**
737  * ps3_stop_probe_thread - Stops the background probe thread.
738  *
739  */
740
741 static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code,
742                                  void *data)
743 {
744         if (probe_task)
745                 kthread_stop(probe_task);
746         return 0;
747 }
748
749 static struct notifier_block nb = {
750         .notifier_call = ps3_stop_probe_thread
751 };
752
753 /**
754  * ps3_start_probe_thread - Starts the background probe thread.
755  *
756  */
757
758 static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
759 {
760         int result;
761         struct task_struct *task;
762         struct ps3_repository_device repo;
763
764         pr_debug(" -> %s:%d\n", __func__, __LINE__);
765
766         memset(&repo, 0, sizeof(repo));
767
768         repo.bus_type = bus_type;
769
770         result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
771
772         if (result) {
773                 printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);
774                 return -ENODEV;
775         }
776
777         result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
778
779         if (result) {
780                 printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,
781                         result);
782                 return -ENODEV;
783         }
784
785         task = kthread_run(ps3_probe_thread, (void *)repo.bus_id,
786                            "ps3-probe-%u", bus_type);
787
788         if (IS_ERR(task)) {
789                 result = PTR_ERR(task);
790                 printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,
791                        result);
792                 return result;
793         }
794
795         probe_task = task;
796         register_reboot_notifier(&nb);
797
798         pr_debug(" <- %s:%d\n", __func__, __LINE__);
799         return 0;
800 }
801
802 /**
803  * ps3_register_devices - Probe the system and register devices found.
804  *
805  * A device_initcall() routine.
806  */
807
808 static int __init ps3_register_devices(void)
809 {
810         int result;
811
812         if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
813                 return -ENODEV;
814
815         pr_debug(" -> %s:%d\n", __func__, __LINE__);
816
817         /* ps3_repository_dump_bus_info(); */
818
819         result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
820
821         ps3_register_vuart_devices();
822
823         ps3_register_graphics_devices();
824
825         ps3_repository_find_devices(PS3_BUS_TYPE_SB,
826                 ps3_register_repository_device);
827
828         ps3_register_sound_devices();
829
830         pr_debug(" <- %s:%d\n", __func__, __LINE__);
831         return 0;
832 }
833
834 device_initcall(ps3_register_devices);