USB: PS3: USB system-bus rework
authorGeoff Levand <geoffrey.levand@am.sony.com>
Wed, 6 Jun 2007 03:04:35 +0000 (20:04 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 12 Jul 2007 23:34:30 +0000 (16:34 -0700)
USB HCD glue updates to reflect the new PS3 unifed device support.
 - Fixed remove() routine.
 - Added shutdown() routine.
 - Added request_mem_region() call.
 - Fixed MODULE_ALIAS().
 - Made a proper fix for the hack done to support muti-platform in commit
   48fda45120a819ca40cadc50144b55bff1c4c78d.

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-ps3.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-ps3.c

index a205a53c61ff58ff6de0e0e30578537cbab01bc7..c4e15ed1405a96eaa85003ae796ba316b37f9714 100644 (file)
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
-#ifdef CONFIG_PPC_PS3
-#include <asm/firmware.h>
-#endif
-
 
 /*-------------------------------------------------------------------------*/
 
@@ -1012,7 +1008,7 @@ MODULE_LICENSE ("GPL");
 
 #ifdef CONFIG_PPC_PS3
 #include "ehci-ps3.c"
-#define        PS3_SYSTEM_BUS_DRIVER   ps3_ehci_sb_driver
+#define        PS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver
 #endif
 
 #ifdef CONFIG_440EPX
@@ -1051,18 +1047,15 @@ static int __init ehci_hcd_init(void)
 #endif
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
-               retval = ps3_system_bus_driver_register(
-                               &PS3_SYSTEM_BUS_DRIVER);
-               if (retval < 0) {
+       retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
+       if (retval < 0) {
 #ifdef PLATFORM_DRIVER
-                       platform_driver_unregister(&PLATFORM_DRIVER);
+               platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PCI_DRIVER
-                       pci_unregister_driver(&PCI_DRIVER);
+               pci_unregister_driver(&PCI_DRIVER);
 #endif
-                       return retval;
-               }
+               return retval;
        }
 #endif
 
@@ -1079,8 +1072,7 @@ static void __exit ehci_hcd_cleanup(void)
        pci_unregister_driver(&PCI_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
-               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ehci_hcd_cleanup);
index 37b83ba099695d7cc5dc51fb6ebb94ee8e26c8ec..829fe649a981fdc03ad6f5cb64df4f9f0b8e4024 100644 (file)
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <asm/firmware.h>
 #include <asm/ps3.h>
 
 static int ps3_ehci_hc_reset(struct usb_hcd *hcd)
@@ -73,7 +74,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
 #endif
 };
 
-static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
+static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
 {
        int result;
        struct usb_hcd *hcd;
@@ -85,13 +86,30 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
                goto fail_start;
        }
 
+       result = ps3_open_hv_device(dev);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
+                       __func__, __LINE__);
+               goto fail_open;
+       }
+
+       result = ps3_dma_region_create(dev->d_region);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+                       "(%d)\n", __func__, __LINE__, result);
+               BUG_ON("check region type");
+               goto fail_dma_region;
+       }
+
        result = ps3_mmio_region_create(dev->m_region);
 
        if (result) {
                dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
                        __func__, __LINE__);
                result = -EPERM;
-               goto fail_mmio;
+               goto fail_mmio_region;
        }
 
        dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -120,6 +138,11 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 
        hcd->rsrc_start = dev->m_region->lpar_addr;
        hcd->rsrc_len = dev->m_region->len;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+               dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+                       __func__, __LINE__);
+
        hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
        if (!hcd->regs) {
@@ -153,34 +176,73 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
        iounmap(hcd->regs);
 fail_ioremap:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
 fail_create_hcd:
        ps3_io_irq_destroy(virq);
 fail_irq:
        ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+       ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+       ps3_close_hv_device(dev);
+fail_open:
 fail_start:
        return result;
 }
 
-static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev)
+static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
 {
+       unsigned int tmp;
        struct usb_hcd *hcd =
                (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-       usb_put_hcd(hcd);
+       BUG_ON(!hcd);
+
+       dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+       dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+       tmp = hcd->irq;
+
+       usb_remove_hcd(hcd);
+
        ps3_system_bus_set_driver_data(dev, NULL);
 
+       BUG_ON(!hcd->regs);
+       iounmap(hcd->regs);
+
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+
+       ps3_io_irq_destroy(tmp);
+       ps3_free_mmio_region(dev->m_region);
+
+       ps3_dma_region_free(dev->d_region);
+       ps3_close_hv_device(dev);
+
        return 0;
 }
 
-MODULE_ALIAS("ps3-ehci");
+static int ps3_ehci_driver_register(struct ps3_system_bus_driver *drv)
+{
+       return firmware_has_feature(FW_FEATURE_PS3_LV1)
+               ? ps3_system_bus_driver_register(drv)
+               : 0;
+}
+
+static void ps3_ehci_driver_unregister(struct ps3_system_bus_driver *drv)
+{
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+               ps3_system_bus_driver_unregister(drv);
+}
+
+MODULE_ALIAS(PS3_MODULE_ALIAS_EHCI);
 
-static struct ps3_system_bus_driver ps3_ehci_sb_driver = {
+static struct ps3_system_bus_driver ps3_ehci_driver = {
+       .core.name = "ps3-ehci-driver",
+       .core.owner = THIS_MODULE,
        .match_id = PS3_MATCH_ID_EHCI,
-       .core = {
-               .name = "ps3-ehci-driver",
-       },
-       .probe = ps3_ehci_sb_probe,
-       .remove = ps3_ehci_sb_remove,
+       .probe = ps3_ehci_probe,
+       .remove = ps3_ehci_remove,
+       .shutdown = ps3_ehci_remove,
 };
index 44717fab7435cebe7afa684bdc044611b18507e7..2038125b7f8cf19143d0994b747220648a497282 100644 (file)
@@ -42,9 +42,6 @@
 #include <asm/system.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
-#ifdef CONFIG_PPC_PS3
-#include <asm/firmware.h>
-#endif
 
 #include "../core/hcd.h"
 
@@ -927,7 +924,7 @@ MODULE_LICENSE ("GPL");
 
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
-#define PS3_SYSTEM_BUS_DRIVER  ps3_ohci_sb_driver
+#define PS3_SYSTEM_BUS_DRIVER  ps3_ohci_driver
 #endif
 
 #if    !defined(PCI_DRIVER) &&         \
@@ -950,12 +947,9 @@ static int __init ohci_hcd_mod_init(void)
                sizeof (struct ed), sizeof (struct td));
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
-               retval = ps3_system_bus_driver_register(
-                               &PS3_SYSTEM_BUS_DRIVER);
-               if (retval < 0)
-                       goto error_ps3;
-       }
+       retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
+       if (retval < 0)
+               goto error_ps3;
 #endif
 
 #ifdef PLATFORM_DRIVER
@@ -1001,8 +995,7 @@ static int __init ohci_hcd_mod_init(void)
  error_platform:
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
-               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
  error_ps3:
 #endif
        return retval;
@@ -1024,8 +1017,7 @@ static void __exit ohci_hcd_mod_exit(void)
        platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
 #ifdef PS3_SYSTEM_BUS_DRIVER
-       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
-               ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+       ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
 #endif
 }
 module_exit(ohci_hcd_mod_exit);
index d7cf07288b0bdbea54e444e9d7e862349eaf1b8d..01a0caeaa6bcc9345b74131baa03d3acfb956439 100644 (file)
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <asm/firmware.h>
 #include <asm/ps3.h>
 
 static int ps3_ohci_hc_reset(struct usb_hcd *hcd)
@@ -75,7 +76,7 @@ static const struct hc_driver ps3_ohci_hc_driver = {
 #endif
 };
 
-static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
+static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
 {
        int result;
        struct usb_hcd *hcd;
@@ -87,13 +88,31 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
                goto fail_start;
        }
 
+       result = ps3_open_hv_device(dev);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed: %s\n",
+                       __func__, __LINE__, ps3_result(result));
+               result = -EPERM;
+               goto fail_open;
+       }
+
+       result = ps3_dma_region_create(dev->d_region);
+
+       if (result) {
+               dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+                       "(%d)\n", __func__, __LINE__, result);
+               BUG_ON("check region type");
+               goto fail_dma_region;
+       }
+
        result = ps3_mmio_region_create(dev->m_region);
 
        if (result) {
                dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
                        __func__, __LINE__);
                result = -EPERM;
-               goto fail_mmio;
+               goto fail_mmio_region;
        }
 
        dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -122,6 +141,11 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 
        hcd->rsrc_start = dev->m_region->lpar_addr;
        hcd->rsrc_len = dev->m_region->len;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+               dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+                       __func__, __LINE__);
+
        hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
        if (!hcd->regs) {
@@ -155,34 +179,73 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
        iounmap(hcd->regs);
 fail_ioremap:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
 fail_create_hcd:
        ps3_io_irq_destroy(virq);
 fail_irq:
        ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+       ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+       ps3_close_hv_device(dev);
+fail_open:
 fail_start:
        return result;
 }
 
-static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev)
+static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
 {
+       unsigned int tmp;
        struct usb_hcd *hcd =
                (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-       usb_put_hcd(hcd);
+       BUG_ON(!hcd);
+
+       dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+       dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+       tmp = hcd->irq;
+
+       usb_remove_hcd(hcd);
+
        ps3_system_bus_set_driver_data(dev, NULL);
 
+       BUG_ON(!hcd->regs);
+       iounmap(hcd->regs);
+
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+
+       ps3_io_irq_destroy(tmp);
+       ps3_free_mmio_region(dev->m_region);
+
+       ps3_dma_region_free(dev->d_region);
+       ps3_close_hv_device(dev);
+
        return 0;
 }
 
-MODULE_ALIAS("ps3-ohci");
+static int ps3_ohci_driver_register(struct ps3_system_bus_driver *drv)
+{
+       return firmware_has_feature(FW_FEATURE_PS3_LV1)
+               ? ps3_system_bus_driver_register(drv)
+               : 0;
+}
+
+static void ps3_ohci_driver_unregister(struct ps3_system_bus_driver *drv)
+{
+       if (firmware_has_feature(FW_FEATURE_PS3_LV1))
+               ps3_system_bus_driver_unregister(drv);
+}
+
+MODULE_ALIAS(PS3_MODULE_ALIAS_OHCI);
 
-static struct ps3_system_bus_driver ps3_ohci_sb_driver = {
+static struct ps3_system_bus_driver ps3_ohci_driver = {
+       .core.name = "ps3-ohci-driver",
+       .core.owner = THIS_MODULE,
        .match_id = PS3_MATCH_ID_OHCI,
-       .core = {
-               .name = "ps3-ohci-driver",
-       },
-       .probe = ps3_ohci_sb_probe,
-       .remove = ps3_ohci_sb_remove,
+       .probe = ps3_ohci_probe,
+       .remove = ps3_ohci_remove,
+       .shutdown = ps3_ohci_remove,
 };