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>

diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index d7cf072..01a0cae 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 @@
 #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 @@
 		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 @@
 
 	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 @@
 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 struct ps3_system_bus_driver ps3_ohci_sb_driver = {
+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_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,
 };