summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.com>2011-09-02 17:45:15 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:07 +0200
commitc5b0321065e36cde8cdc18e125901b2914369c05 (patch)
tree9b2a9f7f017476598fd574b6b165a775e157ac19
parent52b23ad5ede0668a07be02db0940bf16e82a635c (diff)
ux500: usb: core: USB Hub support musb host
USB Hub support musb host ST-Ericsson ID: CR 279072 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: NA Signed-off-by:<thirupathi.chippakurthy@stericsson.com> Change-Id: I22ded0d7cadc8d83996336cfe3917e345c48bd45 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30052 Reviewed-by: Praveena NADAHALLY <praveen.nadahally@stericsson.com>
-rw-r--r--drivers/usb/core/hub.c31
-rw-r--r--drivers/usb/core/notify.c7
-rw-r--r--drivers/usb/core/usb.h4
-rw-r--r--include/linux/usb.h8
4 files changed, 50 insertions, 0 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 98d9df0920f..87c938adbc7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -30,6 +30,12 @@
#include "usb.h"
+#ifdef CONFIG_ARCH_U8500
+#define MAX_TOPO_LEVEL_U8500 2
+#define MAX_USB_DEVICE_U8500 8
+int usb_device_count;
+#endif
+
/* if we are in debug mode, always announce new devices */
#ifdef DEBUG
#ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES
@@ -1326,11 +1332,20 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* Hubs have proper suspend/resume support. */
usb_enable_autosuspend(hdev);
+#ifdef CONFIG_ARCH_U8500
+ if (hdev->level > MAX_TOPO_LEVEL_U8500) {
+ dev_err(&intf->dev,
+ "Unsupported bus topology: > %d "
+ " hub nesting\n", MAX_TOPO_LEVEL_U8500);
+ return -E2BIG;
+ }
+#else
if (hdev->level == MAX_TOPO_LEVEL) {
dev_err(&intf->dev,
"Unsupported bus topology: hub nested too deep\n");
return -E2BIG;
}
+#endif
#ifdef CONFIG_USB_OTG_BLACKLIST_HUB
if (hdev->parent) {
@@ -3427,6 +3442,22 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
goto loop;
}
+#ifdef CONFIG_ARCH_U8500
+ if (hdev->parent == NULL)
+ usb_device_count = 1;
+
+ if (usb_device_count > MAX_USB_DEVICE_U8500) {
+
+ dev_err(&udev->dev,
+ "device connected is more than %d\n",
+ MAX_USB_DEVICE_U8500);
+
+ status = -ENOTCONN; /* Don't retry */
+ goto loop;
+ }
+#endif
+
+
/* reset (non-USB 3.0 devices) and get descriptor */
status = hub_port_init(hub, udev, port1, i);
if (status < 0)
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
index 7728c91dfa2..a5fdc3ac0d7 100644
--- a/drivers/usb/core/notify.c
+++ b/drivers/usb/core/notify.c
@@ -46,11 +46,18 @@ EXPORT_SYMBOL_GPL(usb_unregister_notify);
void usb_notify_add_device(struct usb_device *udev)
{
+#ifdef CONFIG_ARCH_U8500
+ usb_device_count++;
+#endif
+
blocking_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev);
}
void usb_notify_remove_device(struct usb_device *udev)
{
+#ifdef CONFIG_ARCH_U8500
+ usb_device_count--;
+#endif
/* Protect against simultaneous usbfs open */
mutex_lock(&usbfs_mutex);
blocking_notifier_call_chain(&usb_notifier_list,
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 71648dcbe43..5994cef4d2d 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -1,5 +1,9 @@
#include <linux/pm.h>
+#ifdef CONFIG_ARCH_U8500
+extern int usb_device_count;
+#endif
+
/* Functions local to drivers/usb/core/ */
extern int usb_create_sysfs_dev_files(struct usb_device *dev);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 73b68d1f2cb..33488200c17 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -372,7 +372,15 @@ struct usb_bus {
* limit. Because the arrays need to add a bit for hub status data, we
* do 31, so plus one evens out to four bytes.
*/
+
+#ifdef CONFIG_ARCH_U8500
+/**
+* On U8500 platform we support 16 ports only
+*/
+#define USB_MAXCHILDREN (16)
+#else
#define USB_MAXCHILDREN (31)
+#endif
struct usb_tt;