diff options
-rw-r--r-- | arch/powerpc/platforms/ps3/device-init.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 5695e00219e4..05c7c1c624dc 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c | |||
@@ -489,6 +489,38 @@ static int ps3_register_repository_device( | |||
489 | return result; | 489 | return result; |
490 | } | 490 | } |
491 | 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 | } | ||
492 | 524 | ||
493 | #define PS3_NOTIFICATION_DEV_ID ULONG_MAX | 525 | #define PS3_NOTIFICATION_DEV_ID ULONG_MAX |
494 | #define PS3_NOTIFICATION_INTERRUPT_ID 0 | 526 | #define PS3_NOTIFICATION_INTERRUPT_ID 0 |
@@ -600,7 +632,6 @@ static struct task_struct *probe_task; | |||
600 | static int ps3_probe_thread(void *data) | 632 | static int ps3_probe_thread(void *data) |
601 | { | 633 | { |
602 | struct ps3_notification_device dev; | 634 | struct ps3_notification_device dev; |
603 | struct ps3_repository_device repo; | ||
604 | int res; | 635 | int res; |
605 | unsigned int irq; | 636 | unsigned int irq; |
606 | u64 lpar; | 637 | u64 lpar; |
@@ -682,18 +713,7 @@ static int ps3_probe_thread(void *data) | |||
682 | continue; | 713 | continue; |
683 | } | 714 | } |
684 | 715 | ||
685 | res = ps3_repository_find_device_by_id(&repo, dev.sbd.bus_id, | 716 | ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id); |
686 | notify_event->dev_id); | ||
687 | if (res) { | ||
688 | pr_warning("%s:%u: device %lu:%lu not found\n", | ||
689 | __func__, __LINE__, dev.sbd.bus_id, | ||
690 | notify_event->dev_id); | ||
691 | continue; | ||
692 | } | ||
693 | |||
694 | pr_debug("%s:%u: device %lu:%lu found\n", __func__, __LINE__, | ||
695 | dev.sbd.bus_id, notify_event->dev_id); | ||
696 | ps3_register_repository_device(&repo); | ||
697 | 717 | ||
698 | } while (!kthread_should_stop()); | 718 | } while (!kthread_should_stop()); |
699 | 719 | ||