diff options
author | Geoff Levand <geoffrey.levand@am.sony.com> | 2007-06-06 07:04:35 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-13 03:34:30 +0400 |
commit | 7a4eb7fd50d4df99fc1f623e6d90680d9fca3d82 (patch) | |
tree | 6f5332d581e600a72a03e761128bd892c2097d48 /drivers/usb | |
parent | 59c2afa072506aae10ef93126aab651142e0c908 (diff) | |
download | linux-7a4eb7fd50d4df99fc1f623e6d90680d9fca3d82.tar.xz |
USB: PS3: USB system-bus rework
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 22 | ||||
-rw-r--r-- | drivers/usb/host/ehci-ps3.c | 86 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 20 | ||||
-rw-r--r-- | drivers/usb/host/ohci-ps3.c | 87 |
4 files changed, 162 insertions, 53 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index a205a53c61ff..c4e15ed1405a 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -41,10 +41,6 @@ #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); diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 37b83ba09969..829fe649a981 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -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, }; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 44717fab7435..2038125b7f8c 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -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); diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index d7cf07288b0b..01a0caeaa6bc 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c @@ -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, }; |