diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 15:20:00 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 15:20:00 -0500 |
commit | 74e1a2a39355b2d3ae8c60c78d8add162c6d7183 (patch) | |
tree | 1ce09f285c505a774838a95cff7327a750dc85fc /drivers | |
parent | b5c78e04dd061b776978dad61dd85357081147b0 (diff) | |
parent | 6166805c3de539a41cfcae39026c5bc273d7c6aa (diff) |
Merge tag 'usb-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg Kroah-Hartman:
"Here's the big USB merge for 3.9-rc1
Nothing major, lots of gadget fixes, and of course, xhci stuff.
All of this has been in linux-next for a while, with the exception of
the last 3 patches, which were reverts of patches in the tree that
caused problems, they went in yesterday."
* tag 'usb-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (190 commits)
Revert "USB: EHCI: make ehci-vt8500 a separate driver"
Revert "USB: EHCI: make ehci-orion a separate driver"
Revert "USB: update host controller Kconfig entries"
USB: update host controller Kconfig entries
USB: EHCI: make ehci-orion a separate driver
USB: EHCI: make ehci-vt8500 a separate driver
USB: usb-storage: unusual_devs update for Super TOP SATA bridge
USB: ehci-omap: Fix autoloading of module
USB: ehci-omap: Don't free gpios that we didn't request
USB: option: add Huawei "ACM" devices using protocol = vendor
USB: serial: fix null-pointer dereferences on disconnect
USB: option: add Yota / Megafon M100-1 4g modem
drivers/usb: add missing GENERIC_HARDIRQS dependencies
USB: storage: properly handle the endian issues of idProduct
testusb: remove all mentions of 'usbfs'
usb: gadget: imx_udc: make it depend on BROKEN
usb: omap_control_usb: fix compile warning
ARM: OMAP: USB: Add phy binding information
ARM: OMAP2: MUSB: Specify omap4 has mailbox
ARM: OMAP: devices: create device for usb part of control module
...
Diffstat (limited to 'drivers')
137 files changed, 5784 insertions, 2464 deletions
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index d21349544ce5..3d4d1f8aac5c 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
@@ -91,6 +91,7 @@ enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask) | |||
91 | 91 | ||
92 | return ret; | 92 | return ret; |
93 | } | 93 | } |
94 | EXPORT_SYMBOL_GPL(dev_pm_qos_flags); | ||
94 | 95 | ||
95 | /** | 96 | /** |
96 | * __dev_pm_qos_read_value - Get PM QoS constraint for a given device. | 97 | * __dev_pm_qos_read_value - Get PM QoS constraint for a given device. |
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c index a9636f43bca2..3a1ca4dfc83a 100644 --- a/drivers/usb/c67x00/c67x00-ll-hpi.c +++ b/drivers/usb/c67x00/c67x00-ll-hpi.c | |||
@@ -237,7 +237,7 @@ void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie) | |||
237 | /* -------------------------------------------------------------------------- */ | 237 | /* -------------------------------------------------------------------------- */ |
238 | /* Transactions */ | 238 | /* Transactions */ |
239 | 239 | ||
240 | static inline u16 ll_recv_msg(struct c67x00_device *dev) | 240 | static inline int ll_recv_msg(struct c67x00_device *dev) |
241 | { | 241 | { |
242 | u16 res; | 242 | u16 res; |
243 | 243 | ||
diff --git a/drivers/usb/chipidea/ci13xxx_imx.h b/drivers/usb/chipidea/ci13xxx_imx.h index 2e88accb3d67..9cd2e910b1ca 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.h +++ b/drivers/usb/chipidea/ci13xxx_imx.h | |||
@@ -19,7 +19,7 @@ struct usbmisc_usb_device { | |||
19 | struct device *dev; /* usb controller device */ | 19 | struct device *dev; /* usb controller device */ |
20 | int index; | 20 | int index; |
21 | 21 | ||
22 | int disable_oc:1; /* over current detect disabled */ | 22 | unsigned int disable_oc:1; /* over current detect disabled */ |
23 | }; | 23 | }; |
24 | 24 | ||
25 | int usbmisc_set_ops(const struct usbmisc_ops *ops); | 25 | int usbmisc_set_ops(const struct usbmisc_ops *ops); |
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index aebf695a9344..57cae1f897b2 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -411,7 +411,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
411 | } | 411 | } |
412 | 412 | ||
413 | base = devm_request_and_ioremap(dev, res); | 413 | base = devm_request_and_ioremap(dev, res); |
414 | if (!res) { | 414 | if (!base) { |
415 | dev_err(dev, "can't request and ioremap resource\n"); | 415 | dev_err(dev, "can't request and ioremap resource\n"); |
416 | return -ENOMEM; | 416 | return -ENOMEM; |
417 | } | 417 | } |
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 26059b93dbf4..5e847ad2f58a 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
@@ -7,6 +7,7 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG | |||
7 | usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o | 7 | usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o |
8 | usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o | 8 | usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o |
9 | usbcore-y += devio.o notify.o generic.o quirks.o devices.o | 9 | usbcore-y += devio.o notify.o generic.o quirks.o devices.o |
10 | usbcore-y += port.o | ||
10 | 11 | ||
11 | usbcore-$(CONFIG_PCI) += hcd-pci.o | 12 | usbcore-$(CONFIG_PCI) += hcd-pci.o |
12 | usbcore-$(CONFIG_ACPI) += usb-acpi.o | 13 | usbcore-$(CONFIG_ACPI) += usb-acpi.o |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index cbacea933b18..e33224e23770 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -316,17 +316,23 @@ static char *usb_dump_iad_descriptor(char *start, char *end, | |||
316 | */ | 316 | */ |
317 | static char *usb_dump_config_descriptor(char *start, char *end, | 317 | static char *usb_dump_config_descriptor(char *start, char *end, |
318 | const struct usb_config_descriptor *desc, | 318 | const struct usb_config_descriptor *desc, |
319 | int active) | 319 | int active, int speed) |
320 | { | 320 | { |
321 | int mul; | ||
322 | |||
321 | if (start > end) | 323 | if (start > end) |
322 | return start; | 324 | return start; |
325 | if (speed == USB_SPEED_SUPER) | ||
326 | mul = 8; | ||
327 | else | ||
328 | mul = 2; | ||
323 | start += sprintf(start, format_config, | 329 | start += sprintf(start, format_config, |
324 | /* mark active/actual/current cfg. */ | 330 | /* mark active/actual/current cfg. */ |
325 | active ? '*' : ' ', | 331 | active ? '*' : ' ', |
326 | desc->bNumInterfaces, | 332 | desc->bNumInterfaces, |
327 | desc->bConfigurationValue, | 333 | desc->bConfigurationValue, |
328 | desc->bmAttributes, | 334 | desc->bmAttributes, |
329 | desc->bMaxPower * 2); | 335 | desc->bMaxPower * mul); |
330 | return start; | 336 | return start; |
331 | } | 337 | } |
332 | 338 | ||
@@ -342,7 +348,8 @@ static char *usb_dump_config(int speed, char *start, char *end, | |||
342 | if (!config) | 348 | if (!config) |
343 | /* getting these some in 2.3.7; none in 2.3.6 */ | 349 | /* getting these some in 2.3.7; none in 2.3.6 */ |
344 | return start + sprintf(start, "(null Cfg. desc.)\n"); | 350 | return start + sprintf(start, "(null Cfg. desc.)\n"); |
345 | start = usb_dump_config_descriptor(start, end, &config->desc, active); | 351 | start = usb_dump_config_descriptor(start, end, &config->desc, active, |
352 | speed); | ||
346 | for (i = 0; i < USB_MAXIADS; i++) { | 353 | for (i = 0; i < USB_MAXIADS; i++) { |
347 | if (config->intf_assoc[i] == NULL) | 354 | if (config->intf_assoc[i] == NULL) |
348 | break; | 355 | break; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index b78fbe222b72..4a863fdbdccd 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/signal.h> | 40 | #include <linux/signal.h> |
41 | #include <linux/poll.h> | 41 | #include <linux/poll.h> |
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/string.h> | ||
43 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
44 | #include <linux/usbdevice_fs.h> | 45 | #include <linux/usbdevice_fs.h> |
45 | #include <linux/usb/hcd.h> /* for usbcore internals */ | 46 | #include <linux/usb/hcd.h> /* for usbcore internals */ |
@@ -1077,7 +1078,7 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) | |||
1077 | if (!intf || !intf->dev.driver) | 1078 | if (!intf || !intf->dev.driver) |
1078 | ret = -ENODATA; | 1079 | ret = -ENODATA; |
1079 | else { | 1080 | else { |
1080 | strncpy(gd.driver, intf->dev.driver->name, | 1081 | strlcpy(gd.driver, intf->dev.driver->name, |
1081 | sizeof(gd.driver)); | 1082 | sizeof(gd.driver)); |
1082 | ret = (copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0); | 1083 | ret = (copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0); |
1083 | } | 1084 | } |
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index eff2010eb63f..271e761f563e 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -100,7 +100,7 @@ int usb_choose_configuration(struct usb_device *udev) | |||
100 | */ | 100 | */ |
101 | 101 | ||
102 | /* Rule out configs that draw too much bus current */ | 102 | /* Rule out configs that draw too much bus current */ |
103 | if (c->desc.bMaxPower * 2 > udev->bus_mA) { | 103 | if (usb_get_max_power(udev, c) > udev->bus_mA) { |
104 | insufficient_power++; | 104 | insufficient_power++; |
105 | continue; | 105 | continue; |
106 | } | 106 | } |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8e64adf8e4d5..99b34a30354f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -620,6 +620,10 @@ nongeneric: | |||
620 | status = hcd->driver->hub_control (hcd, | 620 | status = hcd->driver->hub_control (hcd, |
621 | typeReq, wValue, wIndex, | 621 | typeReq, wValue, wIndex, |
622 | tbuf, wLength); | 622 | tbuf, wLength); |
623 | |||
624 | if (typeReq == GetHubDescriptor) | ||
625 | usb_hub_adjust_deviceremovable(hcd->self.root_hub, | ||
626 | (struct usb_hub_descriptor *)tbuf); | ||
623 | break; | 627 | break; |
624 | error: | 628 | error: |
625 | /* "protocol stall" on error */ | 629 | /* "protocol stall" on error */ |
@@ -2550,7 +2554,6 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2550 | } | 2554 | } |
2551 | 2555 | ||
2552 | /* starting here, usbcore will pay attention to this root hub */ | 2556 | /* starting here, usbcore will pay attention to this root hub */ |
2553 | rhdev->bus_mA = min(500u, hcd->power_budget); | ||
2554 | if ((retval = register_root_hub(hcd)) != 0) | 2557 | if ((retval = register_root_hub(hcd)) != 0) |
2555 | goto err_register_root_hub; | 2558 | goto err_register_root_hub; |
2556 | 2559 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index cbf7168e3ce7..1775ad471edd 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -26,11 +26,12 @@ | |||
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/freezer.h> | 27 | #include <linux/freezer.h> |
28 | #include <linux/random.h> | 28 | #include <linux/random.h> |
29 | #include <linux/pm_qos.h> | ||
29 | 30 | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/byteorder.h> | 32 | #include <asm/byteorder.h> |
32 | 33 | ||
33 | #include "usb.h" | 34 | #include "hub.h" |
34 | 35 | ||
35 | /* if we are in debug mode, always announce new devices */ | 36 | /* if we are in debug mode, always announce new devices */ |
36 | #ifdef DEBUG | 37 | #ifdef DEBUG |
@@ -42,62 +43,6 @@ | |||
42 | #define USB_VENDOR_GENESYS_LOGIC 0x05e3 | 43 | #define USB_VENDOR_GENESYS_LOGIC 0x05e3 |
43 | #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 | 44 | #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 |
44 | 45 | ||
45 | struct usb_port { | ||
46 | struct usb_device *child; | ||
47 | struct device dev; | ||
48 | struct dev_state *port_owner; | ||
49 | enum usb_port_connect_type connect_type; | ||
50 | }; | ||
51 | |||
52 | struct usb_hub { | ||
53 | struct device *intfdev; /* the "interface" device */ | ||
54 | struct usb_device *hdev; | ||
55 | struct kref kref; | ||
56 | struct urb *urb; /* for interrupt polling pipe */ | ||
57 | |||
58 | /* buffer for urb ... with extra space in case of babble */ | ||
59 | char (*buffer)[8]; | ||
60 | union { | ||
61 | struct usb_hub_status hub; | ||
62 | struct usb_port_status port; | ||
63 | } *status; /* buffer for status reports */ | ||
64 | struct mutex status_mutex; /* for the status buffer */ | ||
65 | |||
66 | int error; /* last reported error */ | ||
67 | int nerrors; /* track consecutive errors */ | ||
68 | |||
69 | struct list_head event_list; /* hubs w/data or errs ready */ | ||
70 | unsigned long event_bits[1]; /* status change bitmask */ | ||
71 | unsigned long change_bits[1]; /* ports with logical connect | ||
72 | status change */ | ||
73 | unsigned long busy_bits[1]; /* ports being reset or | ||
74 | resumed */ | ||
75 | unsigned long removed_bits[1]; /* ports with a "removed" | ||
76 | device present */ | ||
77 | unsigned long wakeup_bits[1]; /* ports that have signaled | ||
78 | remote wakeup */ | ||
79 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ | ||
80 | #error event_bits[] is too short! | ||
81 | #endif | ||
82 | |||
83 | struct usb_hub_descriptor *descriptor; /* class descriptor */ | ||
84 | struct usb_tt tt; /* Transaction Translator */ | ||
85 | |||
86 | unsigned mA_per_port; /* current for each child */ | ||
87 | |||
88 | unsigned limited_power:1; | ||
89 | unsigned quiescing:1; | ||
90 | unsigned disconnected:1; | ||
91 | |||
92 | unsigned quirk_check_port_auto_suspend:1; | ||
93 | |||
94 | unsigned has_indicators:1; | ||
95 | u8 indicator[USB_MAXCHILDREN]; | ||
96 | struct delayed_work leds; | ||
97 | struct delayed_work init_work; | ||
98 | struct usb_port **ports; | ||
99 | }; | ||
100 | |||
101 | static inline int hub_is_superspeed(struct usb_device *hdev) | 46 | static inline int hub_is_superspeed(struct usb_device *hdev) |
102 | { | 47 | { |
103 | return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS); | 48 | return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS); |
@@ -164,13 +109,10 @@ MODULE_PARM_DESC(use_both_schemes, | |||
164 | DECLARE_RWSEM(ehci_cf_port_reset_rwsem); | 109 | DECLARE_RWSEM(ehci_cf_port_reset_rwsem); |
165 | EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); | 110 | EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); |
166 | 111 | ||
167 | #define HUB_DEBOUNCE_TIMEOUT 1500 | 112 | #define HUB_DEBOUNCE_TIMEOUT 2000 |
168 | #define HUB_DEBOUNCE_STEP 25 | 113 | #define HUB_DEBOUNCE_STEP 25 |
169 | #define HUB_DEBOUNCE_STABLE 100 | 114 | #define HUB_DEBOUNCE_STABLE 100 |
170 | 115 | ||
171 | #define to_usb_port(_dev) \ | ||
172 | container_of(_dev, struct usb_port, dev) | ||
173 | |||
174 | static int usb_reset_and_verify_device(struct usb_device *udev); | 116 | static int usb_reset_and_verify_device(struct usb_device *udev); |
175 | 117 | ||
176 | static inline char *portspeed(struct usb_hub *hub, int portstatus) | 118 | static inline char *portspeed(struct usb_hub *hub, int portstatus) |
@@ -186,7 +128,7 @@ static inline char *portspeed(struct usb_hub *hub, int portstatus) | |||
186 | } | 128 | } |
187 | 129 | ||
188 | /* Note that hdev or one of its children must be locked! */ | 130 | /* Note that hdev or one of its children must be locked! */ |
189 | static struct usb_hub *hdev_to_hub(struct usb_device *hdev) | 131 | struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev) |
190 | { | 132 | { |
191 | if (!hdev || !hdev->actconfig || !hdev->maxchild) | 133 | if (!hdev || !hdev->actconfig || !hdev->maxchild) |
192 | return NULL; | 134 | return NULL; |
@@ -360,7 +302,7 @@ static void usb_set_lpm_parameters(struct usb_device *udev) | |||
360 | if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER) | 302 | if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER) |
361 | return; | 303 | return; |
362 | 304 | ||
363 | hub = hdev_to_hub(udev->parent); | 305 | hub = usb_hub_to_struct_hub(udev->parent); |
364 | /* It doesn't take time to transition the roothub into U0, since it | 306 | /* It doesn't take time to transition the roothub into U0, since it |
365 | * doesn't have an upstream link. | 307 | * doesn't have an upstream link. |
366 | */ | 308 | */ |
@@ -452,7 +394,7 @@ static int clear_hub_feature(struct usb_device *hdev, int feature) | |||
452 | /* | 394 | /* |
453 | * USB 2.0 spec Section 11.24.2.2 | 395 | * USB 2.0 spec Section 11.24.2.2 |
454 | */ | 396 | */ |
455 | static int clear_port_feature(struct usb_device *hdev, int port1, int feature) | 397 | int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature) |
456 | { | 398 | { |
457 | return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), | 399 | return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), |
458 | USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1, | 400 | USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1, |
@@ -645,7 +587,7 @@ static void kick_khubd(struct usb_hub *hub) | |||
645 | 587 | ||
646 | void usb_kick_khubd(struct usb_device *hdev) | 588 | void usb_kick_khubd(struct usb_device *hdev) |
647 | { | 589 | { |
648 | struct usb_hub *hub = hdev_to_hub(hdev); | 590 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); |
649 | 591 | ||
650 | if (hub) | 592 | if (hub) |
651 | kick_khubd(hub); | 593 | kick_khubd(hub); |
@@ -667,7 +609,7 @@ void usb_wakeup_notification(struct usb_device *hdev, | |||
667 | if (!hdev) | 609 | if (!hdev) |
668 | return; | 610 | return; |
669 | 611 | ||
670 | hub = hdev_to_hub(hdev); | 612 | hub = usb_hub_to_struct_hub(hdev); |
671 | if (hub) { | 613 | if (hub) { |
672 | set_bit(portnum, hub->wakeup_bits); | 614 | set_bit(portnum, hub->wakeup_bits); |
673 | kick_khubd(hub); | 615 | kick_khubd(hub); |
@@ -774,6 +716,32 @@ static void hub_tt_work(struct work_struct *work) | |||
774 | } | 716 | } |
775 | 717 | ||
776 | /** | 718 | /** |
719 | * usb_hub_set_port_power - control hub port's power state | ||
720 | * @hdev: target hub | ||
721 | * @port1: port index | ||
722 | * @set: expected status | ||
723 | * | ||
724 | * call this function to control port's power via setting or | ||
725 | * clearing the port's PORT_POWER feature. | ||
726 | */ | ||
727 | int usb_hub_set_port_power(struct usb_device *hdev, int port1, | ||
728 | bool set) | ||
729 | { | ||
730 | int ret; | ||
731 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); | ||
732 | struct usb_port *port_dev = hub->ports[port1 - 1]; | ||
733 | |||
734 | if (set) | ||
735 | ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); | ||
736 | else | ||
737 | ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER); | ||
738 | |||
739 | if (!ret) | ||
740 | port_dev->power_is_on = set; | ||
741 | return ret; | ||
742 | } | ||
743 | |||
744 | /** | ||
777 | * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub | 745 | * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub |
778 | * @urb: an URB associated with the failed or incomplete split transaction | 746 | * @urb: an URB associated with the failed or incomplete split transaction |
779 | * | 747 | * |
@@ -849,7 +817,11 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay) | |||
849 | dev_dbg(hub->intfdev, "trying to enable port power on " | 817 | dev_dbg(hub->intfdev, "trying to enable port power on " |
850 | "non-switchable hub\n"); | 818 | "non-switchable hub\n"); |
851 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) | 819 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) |
852 | set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); | 820 | if (hub->ports[port1 - 1]->power_is_on) |
821 | set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); | ||
822 | else | ||
823 | usb_clear_port_feature(hub->hdev, port1, | ||
824 | USB_PORT_FEAT_POWER); | ||
853 | 825 | ||
854 | /* Wait at least 100 msec for power to become stable */ | 826 | /* Wait at least 100 msec for power to become stable */ |
855 | delay = max(pgood_delay, (unsigned) 100); | 827 | delay = max(pgood_delay, (unsigned) 100); |
@@ -943,7 +915,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) | |||
943 | if (hub_is_superspeed(hub->hdev)) | 915 | if (hub_is_superspeed(hub->hdev)) |
944 | ret = hub_usb3_port_disable(hub, port1); | 916 | ret = hub_usb3_port_disable(hub, port1); |
945 | else | 917 | else |
946 | ret = clear_port_feature(hdev, port1, | 918 | ret = usb_clear_port_feature(hdev, port1, |
947 | USB_PORT_FEAT_ENABLE); | 919 | USB_PORT_FEAT_ENABLE); |
948 | } | 920 | } |
949 | if (ret) | 921 | if (ret) |
@@ -992,7 +964,7 @@ int usb_remove_device(struct usb_device *udev) | |||
992 | 964 | ||
993 | if (!udev->parent) /* Can't remove a root hub */ | 965 | if (!udev->parent) /* Can't remove a root hub */ |
994 | return -EINVAL; | 966 | return -EINVAL; |
995 | hub = hdev_to_hub(udev->parent); | 967 | hub = usb_hub_to_struct_hub(udev->parent); |
996 | intf = to_usb_interface(hub->intfdev); | 968 | intf = to_usb_interface(hub->intfdev); |
997 | 969 | ||
998 | usb_autopm_get_interface(intf); | 970 | usb_autopm_get_interface(intf); |
@@ -1124,7 +1096,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1124 | * Do not disable USB3 protocol ports. | 1096 | * Do not disable USB3 protocol ports. |
1125 | */ | 1097 | */ |
1126 | if (!hub_is_superspeed(hdev)) { | 1098 | if (!hub_is_superspeed(hdev)) { |
1127 | clear_port_feature(hdev, port1, | 1099 | usb_clear_port_feature(hdev, port1, |
1128 | USB_PORT_FEAT_ENABLE); | 1100 | USB_PORT_FEAT_ENABLE); |
1129 | portstatus &= ~USB_PORT_STAT_ENABLE; | 1101 | portstatus &= ~USB_PORT_STAT_ENABLE; |
1130 | } else { | 1102 | } else { |
@@ -1136,18 +1108,18 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1136 | /* Clear status-change flags; we'll debounce later */ | 1108 | /* Clear status-change flags; we'll debounce later */ |
1137 | if (portchange & USB_PORT_STAT_C_CONNECTION) { | 1109 | if (portchange & USB_PORT_STAT_C_CONNECTION) { |
1138 | need_debounce_delay = true; | 1110 | need_debounce_delay = true; |
1139 | clear_port_feature(hub->hdev, port1, | 1111 | usb_clear_port_feature(hub->hdev, port1, |
1140 | USB_PORT_FEAT_C_CONNECTION); | 1112 | USB_PORT_FEAT_C_CONNECTION); |
1141 | } | 1113 | } |
1142 | if (portchange & USB_PORT_STAT_C_ENABLE) { | 1114 | if (portchange & USB_PORT_STAT_C_ENABLE) { |
1143 | need_debounce_delay = true; | 1115 | need_debounce_delay = true; |
1144 | clear_port_feature(hub->hdev, port1, | 1116 | usb_clear_port_feature(hub->hdev, port1, |
1145 | USB_PORT_FEAT_C_ENABLE); | 1117 | USB_PORT_FEAT_C_ENABLE); |
1146 | } | 1118 | } |
1147 | if ((portchange & USB_PORT_STAT_C_BH_RESET) && | 1119 | if ((portchange & USB_PORT_STAT_C_BH_RESET) && |
1148 | hub_is_superspeed(hub->hdev)) { | 1120 | hub_is_superspeed(hub->hdev)) { |
1149 | need_debounce_delay = true; | 1121 | need_debounce_delay = true; |
1150 | clear_port_feature(hub->hdev, port1, | 1122 | usb_clear_port_feature(hub->hdev, port1, |
1151 | USB_PORT_FEAT_C_BH_PORT_RESET); | 1123 | USB_PORT_FEAT_C_BH_PORT_RESET); |
1152 | } | 1124 | } |
1153 | /* We can forget about a "removed" device when there's a | 1125 | /* We can forget about a "removed" device when there's a |
@@ -1181,10 +1153,16 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1181 | set_bit(port1, hub->change_bits); | 1153 | set_bit(port1, hub->change_bits); |
1182 | 1154 | ||
1183 | } else if (udev->persist_enabled) { | 1155 | } else if (udev->persist_enabled) { |
1156 | struct usb_port *port_dev = hub->ports[port1 - 1]; | ||
1157 | |||
1184 | #ifdef CONFIG_PM | 1158 | #ifdef CONFIG_PM |
1185 | udev->reset_resume = 1; | 1159 | udev->reset_resume = 1; |
1186 | #endif | 1160 | #endif |
1187 | set_bit(port1, hub->change_bits); | 1161 | /* Don't set the change_bits when the device |
1162 | * was powered off. | ||
1163 | */ | ||
1164 | if (port_dev->power_is_on) | ||
1165 | set_bit(port1, hub->change_bits); | ||
1188 | 1166 | ||
1189 | } else { | 1167 | } else { |
1190 | /* The power session is gone; tell khubd */ | 1168 | /* The power session is gone; tell khubd */ |
@@ -1294,52 +1272,6 @@ static int hub_post_reset(struct usb_interface *intf) | |||
1294 | return 0; | 1272 | return 0; |
1295 | } | 1273 | } |
1296 | 1274 | ||
1297 | static void usb_port_device_release(struct device *dev) | ||
1298 | { | ||
1299 | struct usb_port *port_dev = to_usb_port(dev); | ||
1300 | |||
1301 | kfree(port_dev); | ||
1302 | } | ||
1303 | |||
1304 | static void usb_hub_remove_port_device(struct usb_hub *hub, | ||
1305 | int port1) | ||
1306 | { | ||
1307 | device_unregister(&hub->ports[port1 - 1]->dev); | ||
1308 | } | ||
1309 | |||
1310 | struct device_type usb_port_device_type = { | ||
1311 | .name = "usb_port", | ||
1312 | .release = usb_port_device_release, | ||
1313 | }; | ||
1314 | |||
1315 | static int usb_hub_create_port_device(struct usb_hub *hub, | ||
1316 | int port1) | ||
1317 | { | ||
1318 | struct usb_port *port_dev = NULL; | ||
1319 | int retval; | ||
1320 | |||
1321 | port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); | ||
1322 | if (!port_dev) { | ||
1323 | retval = -ENOMEM; | ||
1324 | goto exit; | ||
1325 | } | ||
1326 | |||
1327 | hub->ports[port1 - 1] = port_dev; | ||
1328 | port_dev->dev.parent = hub->intfdev; | ||
1329 | port_dev->dev.type = &usb_port_device_type; | ||
1330 | dev_set_name(&port_dev->dev, "port%d", port1); | ||
1331 | |||
1332 | retval = device_register(&port_dev->dev); | ||
1333 | if (retval) | ||
1334 | goto error_register; | ||
1335 | return 0; | ||
1336 | |||
1337 | error_register: | ||
1338 | put_device(&port_dev->dev); | ||
1339 | exit: | ||
1340 | return retval; | ||
1341 | } | ||
1342 | |||
1343 | static int hub_configure(struct usb_hub *hub, | 1275 | static int hub_configure(struct usb_hub *hub, |
1344 | struct usb_endpoint_descriptor *endpoint) | 1276 | struct usb_endpoint_descriptor *endpoint) |
1345 | { | 1277 | { |
@@ -1351,6 +1283,8 @@ static int hub_configure(struct usb_hub *hub, | |||
1351 | unsigned int pipe; | 1283 | unsigned int pipe; |
1352 | int maxp, ret, i; | 1284 | int maxp, ret, i; |
1353 | char *message = "out of memory"; | 1285 | char *message = "out of memory"; |
1286 | unsigned unit_load; | ||
1287 | unsigned full_load; | ||
1354 | 1288 | ||
1355 | hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL); | 1289 | hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL); |
1356 | if (!hub->buffer) { | 1290 | if (!hub->buffer) { |
@@ -1397,6 +1331,13 @@ static int hub_configure(struct usb_hub *hub, | |||
1397 | } | 1331 | } |
1398 | 1332 | ||
1399 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | 1333 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); |
1334 | if (hub_is_superspeed(hdev)) { | ||
1335 | unit_load = 150; | ||
1336 | full_load = 900; | ||
1337 | } else { | ||
1338 | unit_load = 100; | ||
1339 | full_load = 500; | ||
1340 | } | ||
1400 | 1341 | ||
1401 | /* FIXME for USB 3.0, skip for now */ | 1342 | /* FIXME for USB 3.0, skip for now */ |
1402 | if ((wHubCharacteristics & HUB_CHAR_COMPOUND) && | 1343 | if ((wHubCharacteristics & HUB_CHAR_COMPOUND) && |
@@ -1516,40 +1457,44 @@ static int hub_configure(struct usb_hub *hub, | |||
1516 | goto fail; | 1457 | goto fail; |
1517 | } | 1458 | } |
1518 | le16_to_cpus(&hubstatus); | 1459 | le16_to_cpus(&hubstatus); |
1460 | hcd = bus_to_hcd(hdev->bus); | ||
1519 | if (hdev == hdev->bus->root_hub) { | 1461 | if (hdev == hdev->bus->root_hub) { |
1520 | if (hdev->bus_mA == 0 || hdev->bus_mA >= 500) | 1462 | if (hcd->power_budget > 0) |
1521 | hub->mA_per_port = 500; | 1463 | hdev->bus_mA = hcd->power_budget; |
1464 | else | ||
1465 | hdev->bus_mA = full_load * hdev->maxchild; | ||
1466 | if (hdev->bus_mA >= full_load) | ||
1467 | hub->mA_per_port = full_load; | ||
1522 | else { | 1468 | else { |
1523 | hub->mA_per_port = hdev->bus_mA; | 1469 | hub->mA_per_port = hdev->bus_mA; |
1524 | hub->limited_power = 1; | 1470 | hub->limited_power = 1; |
1525 | } | 1471 | } |
1526 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 1472 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
1473 | int remaining = hdev->bus_mA - | ||
1474 | hub->descriptor->bHubContrCurrent; | ||
1475 | |||
1527 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", | 1476 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", |
1528 | hub->descriptor->bHubContrCurrent); | 1477 | hub->descriptor->bHubContrCurrent); |
1529 | hub->limited_power = 1; | 1478 | hub->limited_power = 1; |
1530 | if (hdev->maxchild > 0) { | ||
1531 | int remaining = hdev->bus_mA - | ||
1532 | hub->descriptor->bHubContrCurrent; | ||
1533 | 1479 | ||
1534 | if (remaining < hdev->maxchild * 100) | 1480 | if (remaining < hdev->maxchild * unit_load) |
1535 | dev_warn(hub_dev, | 1481 | dev_warn(hub_dev, |
1536 | "insufficient power available " | 1482 | "insufficient power available " |
1537 | "to use all downstream ports\n"); | 1483 | "to use all downstream ports\n"); |
1538 | hub->mA_per_port = 100; /* 7.2.1.1 */ | 1484 | hub->mA_per_port = unit_load; /* 7.2.1 */ |
1539 | } | 1485 | |
1540 | } else { /* Self-powered external hub */ | 1486 | } else { /* Self-powered external hub */ |
1541 | /* FIXME: What about battery-powered external hubs that | 1487 | /* FIXME: What about battery-powered external hubs that |
1542 | * provide less current per port? */ | 1488 | * provide less current per port? */ |
1543 | hub->mA_per_port = 500; | 1489 | hub->mA_per_port = full_load; |
1544 | } | 1490 | } |
1545 | if (hub->mA_per_port < 500) | 1491 | if (hub->mA_per_port < full_load) |
1546 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", | 1492 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", |
1547 | hub->mA_per_port); | 1493 | hub->mA_per_port); |
1548 | 1494 | ||
1549 | /* Update the HCD's internal representation of this hub before khubd | 1495 | /* Update the HCD's internal representation of this hub before khubd |
1550 | * starts getting port status changes for devices under the hub. | 1496 | * starts getting port status changes for devices under the hub. |
1551 | */ | 1497 | */ |
1552 | hcd = bus_to_hcd(hdev->bus); | ||
1553 | if (hcd->driver->update_hub_device) { | 1498 | if (hcd->driver->update_hub_device) { |
1554 | ret = hcd->driver->update_hub_device(hcd, hdev, | 1499 | ret = hcd->driver->update_hub_device(hcd, hdev, |
1555 | &hub->tt, GFP_KERNEL); | 1500 | &hub->tt, GFP_KERNEL); |
@@ -1605,6 +1550,8 @@ static int hub_configure(struct usb_hub *hub, | |||
1605 | dev_err(hub->intfdev, | 1550 | dev_err(hub->intfdev, |
1606 | "couldn't create port%d device.\n", i + 1); | 1551 | "couldn't create port%d device.\n", i + 1); |
1607 | 1552 | ||
1553 | usb_hub_adjust_deviceremovable(hdev, hub->descriptor); | ||
1554 | |||
1608 | hub_activate(hub, HUB_INIT); | 1555 | hub_activate(hub, HUB_INIT); |
1609 | return 0; | 1556 | return 0; |
1610 | 1557 | ||
@@ -1659,6 +1606,7 @@ static void hub_disconnect(struct usb_interface *intf) | |||
1659 | kfree(hub->status); | 1606 | kfree(hub->status); |
1660 | kfree(hub->buffer); | 1607 | kfree(hub->buffer); |
1661 | 1608 | ||
1609 | pm_suspend_ignore_children(&intf->dev, false); | ||
1662 | kref_put(&hub->kref, hub_release); | 1610 | kref_put(&hub->kref, hub_release); |
1663 | } | 1611 | } |
1664 | 1612 | ||
@@ -1761,6 +1709,7 @@ descriptor_error: | |||
1761 | 1709 | ||
1762 | usb_set_intfdata (intf, hub); | 1710 | usb_set_intfdata (intf, hub); |
1763 | intf->needs_remote_wakeup = 1; | 1711 | intf->needs_remote_wakeup = 1; |
1712 | pm_suspend_ignore_children(&intf->dev, true); | ||
1764 | 1713 | ||
1765 | if (hdev->speed == USB_SPEED_HIGH) | 1714 | if (hdev->speed == USB_SPEED_HIGH) |
1766 | highspeed_hubs++; | 1715 | highspeed_hubs++; |
@@ -1779,7 +1728,7 @@ static int | |||
1779 | hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) | 1728 | hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) |
1780 | { | 1729 | { |
1781 | struct usb_device *hdev = interface_to_usbdev (intf); | 1730 | struct usb_device *hdev = interface_to_usbdev (intf); |
1782 | struct usb_hub *hub = hdev_to_hub(hdev); | 1731 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); |
1783 | 1732 | ||
1784 | /* assert ifno == 0 (part of hub spec) */ | 1733 | /* assert ifno == 0 (part of hub spec) */ |
1785 | switch (code) { | 1734 | switch (code) { |
@@ -1825,7 +1774,7 @@ static int find_port_owner(struct usb_device *hdev, unsigned port1, | |||
1825 | /* This assumes that devices not managed by the hub driver | 1774 | /* This assumes that devices not managed by the hub driver |
1826 | * will always have maxchild equal to 0. | 1775 | * will always have maxchild equal to 0. |
1827 | */ | 1776 | */ |
1828 | *ppowner = &(hdev_to_hub(hdev)->ports[port1 - 1]->port_owner); | 1777 | *ppowner = &(usb_hub_to_struct_hub(hdev)->ports[port1 - 1]->port_owner); |
1829 | return 0; | 1778 | return 0; |
1830 | } | 1779 | } |
1831 | 1780 | ||
@@ -1862,7 +1811,7 @@ int usb_hub_release_port(struct usb_device *hdev, unsigned port1, | |||
1862 | 1811 | ||
1863 | void usb_hub_release_all_ports(struct usb_device *hdev, struct dev_state *owner) | 1812 | void usb_hub_release_all_ports(struct usb_device *hdev, struct dev_state *owner) |
1864 | { | 1813 | { |
1865 | struct usb_hub *hub = hdev_to_hub(hdev); | 1814 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); |
1866 | int n; | 1815 | int n; |
1867 | 1816 | ||
1868 | for (n = 0; n < hdev->maxchild; n++) { | 1817 | for (n = 0; n < hdev->maxchild; n++) { |
@@ -1879,13 +1828,13 @@ bool usb_device_is_owned(struct usb_device *udev) | |||
1879 | 1828 | ||
1880 | if (udev->state == USB_STATE_NOTATTACHED || !udev->parent) | 1829 | if (udev->state == USB_STATE_NOTATTACHED || !udev->parent) |
1881 | return false; | 1830 | return false; |
1882 | hub = hdev_to_hub(udev->parent); | 1831 | hub = usb_hub_to_struct_hub(udev->parent); |
1883 | return !!hub->ports[udev->portnum - 1]->port_owner; | 1832 | return !!hub->ports[udev->portnum - 1]->port_owner; |
1884 | } | 1833 | } |
1885 | 1834 | ||
1886 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) | 1835 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) |
1887 | { | 1836 | { |
1888 | struct usb_hub *hub = hdev_to_hub(udev); | 1837 | struct usb_hub *hub = usb_hub_to_struct_hub(udev); |
1889 | int i; | 1838 | int i; |
1890 | 1839 | ||
1891 | for (i = 0; i < udev->maxchild; ++i) { | 1840 | for (i = 0; i < udev->maxchild; ++i) { |
@@ -2054,7 +2003,7 @@ static void hub_free_dev(struct usb_device *udev) | |||
2054 | void usb_disconnect(struct usb_device **pdev) | 2003 | void usb_disconnect(struct usb_device **pdev) |
2055 | { | 2004 | { |
2056 | struct usb_device *udev = *pdev; | 2005 | struct usb_device *udev = *pdev; |
2057 | struct usb_hub *hub = hdev_to_hub(udev); | 2006 | struct usb_hub *hub = usb_hub_to_struct_hub(udev); |
2058 | int i; | 2007 | int i; |
2059 | 2008 | ||
2060 | /* mark the device as inactive, so any further urb submissions for | 2009 | /* mark the device as inactive, so any further urb submissions for |
@@ -2081,6 +2030,19 @@ void usb_disconnect(struct usb_device **pdev) | |||
2081 | usb_disable_device(udev, 0); | 2030 | usb_disable_device(udev, 0); |
2082 | usb_hcd_synchronize_unlinks(udev); | 2031 | usb_hcd_synchronize_unlinks(udev); |
2083 | 2032 | ||
2033 | if (udev->parent) { | ||
2034 | struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); | ||
2035 | struct usb_port *port_dev = hub->ports[udev->portnum - 1]; | ||
2036 | |||
2037 | sysfs_remove_link(&udev->dev.kobj, "port"); | ||
2038 | sysfs_remove_link(&port_dev->dev.kobj, "device"); | ||
2039 | |||
2040 | if (!port_dev->did_runtime_put) | ||
2041 | pm_runtime_put(&port_dev->dev); | ||
2042 | else | ||
2043 | port_dev->did_runtime_put = false; | ||
2044 | } | ||
2045 | |||
2084 | usb_remove_ep_devs(&udev->ep0); | 2046 | usb_remove_ep_devs(&udev->ep0); |
2085 | usb_unlock_device(udev); | 2047 | usb_unlock_device(udev); |
2086 | 2048 | ||
@@ -2267,7 +2229,7 @@ static void set_usb_port_removable(struct usb_device *udev) | |||
2267 | if (!hdev) | 2229 | if (!hdev) |
2268 | return; | 2230 | return; |
2269 | 2231 | ||
2270 | hub = hdev_to_hub(udev->parent); | 2232 | hub = usb_hub_to_struct_hub(udev->parent); |
2271 | 2233 | ||
2272 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | 2234 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); |
2273 | 2235 | ||
@@ -2373,6 +2335,26 @@ int usb_new_device(struct usb_device *udev) | |||
2373 | goto fail; | 2335 | goto fail; |
2374 | } | 2336 | } |
2375 | 2337 | ||
2338 | /* Create link files between child device and usb port device. */ | ||
2339 | if (udev->parent) { | ||
2340 | struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); | ||
2341 | struct usb_port *port_dev = hub->ports[udev->portnum - 1]; | ||
2342 | |||
2343 | err = sysfs_create_link(&udev->dev.kobj, | ||
2344 | &port_dev->dev.kobj, "port"); | ||
2345 | if (err) | ||
2346 | goto fail; | ||
2347 | |||
2348 | err = sysfs_create_link(&port_dev->dev.kobj, | ||
2349 | &udev->dev.kobj, "device"); | ||
2350 | if (err) { | ||
2351 | sysfs_remove_link(&udev->dev.kobj, "port"); | ||
2352 | goto fail; | ||
2353 | } | ||
2354 | |||
2355 | pm_runtime_get_sync(&port_dev->dev); | ||
2356 | } | ||
2357 | |||
2376 | (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); | 2358 | (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); |
2377 | usb_mark_last_busy(udev); | 2359 | usb_mark_last_busy(udev); |
2378 | pm_runtime_put_sync_autosuspend(&udev->dev); | 2360 | pm_runtime_put_sync_autosuspend(&udev->dev); |
@@ -2535,77 +2517,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, | |||
2535 | return ret; | 2517 | return ret; |
2536 | 2518 | ||
2537 | /* The port state is unknown until the reset completes. */ | 2519 | /* The port state is unknown until the reset completes. */ |
2538 | if ((portstatus & USB_PORT_STAT_RESET)) | 2520 | if (!(portstatus & USB_PORT_STAT_RESET)) |
2539 | goto delay; | 2521 | break; |
2540 | |||
2541 | /* | ||
2542 | * Some buggy devices require a warm reset to be issued even | ||
2543 | * when the port appears not to be connected. | ||
2544 | */ | ||
2545 | if (!warm) { | ||
2546 | /* | ||
2547 | * Some buggy devices can cause an NEC host controller | ||
2548 | * to transition to the "Error" state after a hot port | ||
2549 | * reset. This will show up as the port state in | ||
2550 | * "Inactive", and the port may also report a | ||
2551 | * disconnect. Forcing a warm port reset seems to make | ||
2552 | * the device work. | ||
2553 | * | ||
2554 | * See https://bugzilla.kernel.org/show_bug.cgi?id=41752 | ||
2555 | */ | ||
2556 | if (hub_port_warm_reset_required(hub, portstatus)) { | ||
2557 | int ret; | ||
2558 | |||
2559 | if ((portchange & USB_PORT_STAT_C_CONNECTION)) | ||
2560 | clear_port_feature(hub->hdev, port1, | ||
2561 | USB_PORT_FEAT_C_CONNECTION); | ||
2562 | if (portchange & USB_PORT_STAT_C_LINK_STATE) | ||
2563 | clear_port_feature(hub->hdev, port1, | ||
2564 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
2565 | if (portchange & USB_PORT_STAT_C_RESET) | ||
2566 | clear_port_feature(hub->hdev, port1, | ||
2567 | USB_PORT_FEAT_C_RESET); | ||
2568 | dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n", | ||
2569 | port1); | ||
2570 | ret = hub_port_reset(hub, port1, | ||
2571 | udev, HUB_BH_RESET_TIME, | ||
2572 | true); | ||
2573 | if ((portchange & USB_PORT_STAT_C_CONNECTION)) | ||
2574 | clear_port_feature(hub->hdev, port1, | ||
2575 | USB_PORT_FEAT_C_CONNECTION); | ||
2576 | return ret; | ||
2577 | } | ||
2578 | /* Device went away? */ | ||
2579 | if (!(portstatus & USB_PORT_STAT_CONNECTION)) | ||
2580 | return -ENOTCONN; | ||
2581 | |||
2582 | /* bomb out completely if the connection bounced */ | ||
2583 | if ((portchange & USB_PORT_STAT_C_CONNECTION)) | ||
2584 | return -ENOTCONN; | ||
2585 | |||
2586 | if ((portstatus & USB_PORT_STAT_ENABLE)) { | ||
2587 | if (hub_is_wusb(hub)) | ||
2588 | udev->speed = USB_SPEED_WIRELESS; | ||
2589 | else if (hub_is_superspeed(hub->hdev)) | ||
2590 | udev->speed = USB_SPEED_SUPER; | ||
2591 | else if (portstatus & USB_PORT_STAT_HIGH_SPEED) | ||
2592 | udev->speed = USB_SPEED_HIGH; | ||
2593 | else if (portstatus & USB_PORT_STAT_LOW_SPEED) | ||
2594 | udev->speed = USB_SPEED_LOW; | ||
2595 | else | ||
2596 | udev->speed = USB_SPEED_FULL; | ||
2597 | return 0; | ||
2598 | } | ||
2599 | } else { | ||
2600 | if (!(portstatus & USB_PORT_STAT_CONNECTION) || | ||
2601 | hub_port_warm_reset_required(hub, | ||
2602 | portstatus)) | ||
2603 | return -ENOTCONN; | ||
2604 | |||
2605 | return 0; | ||
2606 | } | ||
2607 | 2522 | ||
2608 | delay: | ||
2609 | /* switch to the long delay after two short delay failures */ | 2523 | /* switch to the long delay after two short delay failures */ |
2610 | if (delay_time >= 2 * HUB_SHORT_RESET_TIME) | 2524 | if (delay_time >= 2 * HUB_SHORT_RESET_TIME) |
2611 | delay = HUB_LONG_RESET_TIME; | 2525 | delay = HUB_LONG_RESET_TIME; |
@@ -2615,20 +2529,54 @@ delay: | |||
2615 | port1, warm ? "warm " : "", delay); | 2529 | port1, warm ? "warm " : "", delay); |
2616 | } | 2530 | } |
2617 | 2531 | ||
2618 | return -EBUSY; | 2532 | if ((portstatus & USB_PORT_STAT_RESET)) |
2533 | return -EBUSY; | ||
2534 | |||
2535 | if (hub_port_warm_reset_required(hub, portstatus)) | ||
2536 | return -ENOTCONN; | ||
2537 | |||
2538 | /* Device went away? */ | ||
2539 | if (!(portstatus & USB_PORT_STAT_CONNECTION)) | ||
2540 | return -ENOTCONN; | ||
2541 | |||
2542 | /* bomb out completely if the connection bounced. A USB 3.0 | ||
2543 | * connection may bounce if multiple warm resets were issued, | ||
2544 | * but the device may have successfully re-connected. Ignore it. | ||
2545 | */ | ||
2546 | if (!hub_is_superspeed(hub->hdev) && | ||
2547 | (portchange & USB_PORT_STAT_C_CONNECTION)) | ||
2548 | return -ENOTCONN; | ||
2549 | |||
2550 | if (!(portstatus & USB_PORT_STAT_ENABLE)) | ||
2551 | return -EBUSY; | ||
2552 | |||
2553 | if (!udev) | ||
2554 | return 0; | ||
2555 | |||
2556 | if (hub_is_wusb(hub)) | ||
2557 | udev->speed = USB_SPEED_WIRELESS; | ||
2558 | else if (hub_is_superspeed(hub->hdev)) | ||
2559 | udev->speed = USB_SPEED_SUPER; | ||
2560 | else if (portstatus & USB_PORT_STAT_HIGH_SPEED) | ||
2561 | udev->speed = USB_SPEED_HIGH; | ||
2562 | else if (portstatus & USB_PORT_STAT_LOW_SPEED) | ||
2563 | udev->speed = USB_SPEED_LOW; | ||
2564 | else | ||
2565 | udev->speed = USB_SPEED_FULL; | ||
2566 | return 0; | ||
2619 | } | 2567 | } |
2620 | 2568 | ||
2621 | static void hub_port_finish_reset(struct usb_hub *hub, int port1, | 2569 | static void hub_port_finish_reset(struct usb_hub *hub, int port1, |
2622 | struct usb_device *udev, int *status, bool warm) | 2570 | struct usb_device *udev, int *status) |
2623 | { | 2571 | { |
2624 | switch (*status) { | 2572 | switch (*status) { |
2625 | case 0: | 2573 | case 0: |
2626 | if (!warm) { | 2574 | /* TRSTRCY = 10 ms; plus some extra */ |
2627 | struct usb_hcd *hcd; | 2575 | msleep(10 + 40); |
2628 | /* TRSTRCY = 10 ms; plus some extra */ | 2576 | if (udev) { |
2629 | msleep(10 + 40); | 2577 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); |
2578 | |||
2630 | update_devnum(udev, 0); | 2579 | update_devnum(udev, 0); |
2631 | hcd = bus_to_hcd(udev->bus); | ||
2632 | /* The xHC may think the device is already reset, | 2580 | /* The xHC may think the device is already reset, |
2633 | * so ignore the status. | 2581 | * so ignore the status. |
2634 | */ | 2582 | */ |
@@ -2638,16 +2586,17 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1, | |||
2638 | /* FALL THROUGH */ | 2586 | /* FALL THROUGH */ |
2639 | case -ENOTCONN: | 2587 | case -ENOTCONN: |
2640 | case -ENODEV: | 2588 | case -ENODEV: |
2641 | clear_port_feature(hub->hdev, | 2589 | usb_clear_port_feature(hub->hdev, |
2642 | port1, USB_PORT_FEAT_C_RESET); | 2590 | port1, USB_PORT_FEAT_C_RESET); |
2643 | /* FIXME need disconnect() for NOTATTACHED device */ | ||
2644 | if (hub_is_superspeed(hub->hdev)) { | 2591 | if (hub_is_superspeed(hub->hdev)) { |
2645 | clear_port_feature(hub->hdev, port1, | 2592 | usb_clear_port_feature(hub->hdev, port1, |
2646 | USB_PORT_FEAT_C_BH_PORT_RESET); | 2593 | USB_PORT_FEAT_C_BH_PORT_RESET); |
2647 | clear_port_feature(hub->hdev, port1, | 2594 | usb_clear_port_feature(hub->hdev, port1, |
2648 | USB_PORT_FEAT_C_PORT_LINK_STATE); | 2595 | USB_PORT_FEAT_C_PORT_LINK_STATE); |
2596 | usb_clear_port_feature(hub->hdev, port1, | ||
2597 | USB_PORT_FEAT_C_CONNECTION); | ||
2649 | } | 2598 | } |
2650 | if (!warm) | 2599 | if (udev) |
2651 | usb_set_device_state(udev, *status | 2600 | usb_set_device_state(udev, *status |
2652 | ? USB_STATE_NOTATTACHED | 2601 | ? USB_STATE_NOTATTACHED |
2653 | : USB_STATE_DEFAULT); | 2602 | : USB_STATE_DEFAULT); |
@@ -2660,18 +2609,30 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2660 | struct usb_device *udev, unsigned int delay, bool warm) | 2609 | struct usb_device *udev, unsigned int delay, bool warm) |
2661 | { | 2610 | { |
2662 | int i, status; | 2611 | int i, status; |
2612 | u16 portchange, portstatus; | ||
2663 | 2613 | ||
2664 | if (!warm) { | 2614 | if (!hub_is_superspeed(hub->hdev)) { |
2665 | /* Block EHCI CF initialization during the port reset. | 2615 | if (warm) { |
2666 | * Some companion controllers don't like it when they mix. | ||
2667 | */ | ||
2668 | down_read(&ehci_cf_port_reset_rwsem); | ||
2669 | } else { | ||
2670 | if (!hub_is_superspeed(hub->hdev)) { | ||
2671 | dev_err(hub->intfdev, "only USB3 hub support " | 2616 | dev_err(hub->intfdev, "only USB3 hub support " |
2672 | "warm reset\n"); | 2617 | "warm reset\n"); |
2673 | return -EINVAL; | 2618 | return -EINVAL; |
2674 | } | 2619 | } |
2620 | /* Block EHCI CF initialization during the port reset. | ||
2621 | * Some companion controllers don't like it when they mix. | ||
2622 | */ | ||
2623 | down_read(&ehci_cf_port_reset_rwsem); | ||
2624 | } else if (!warm) { | ||
2625 | /* | ||
2626 | * If the caller hasn't explicitly requested a warm reset, | ||
2627 | * double check and see if one is needed. | ||
2628 | */ | ||
2629 | status = hub_port_status(hub, port1, | ||
2630 | &portstatus, &portchange); | ||
2631 | if (status < 0) | ||
2632 | goto done; | ||
2633 | |||
2634 | if (hub_port_warm_reset_required(hub, portstatus)) | ||
2635 | warm = true; | ||
2675 | } | 2636 | } |
2676 | 2637 | ||
2677 | /* Reset the port */ | 2638 | /* Reset the port */ |
@@ -2692,10 +2653,33 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2692 | status); | 2653 | status); |
2693 | } | 2654 | } |
2694 | 2655 | ||
2695 | /* return on disconnect or reset */ | 2656 | /* Check for disconnect or reset */ |
2696 | if (status == 0 || status == -ENOTCONN || status == -ENODEV) { | 2657 | if (status == 0 || status == -ENOTCONN || status == -ENODEV) { |
2697 | hub_port_finish_reset(hub, port1, udev, &status, warm); | 2658 | hub_port_finish_reset(hub, port1, udev, &status); |
2698 | goto done; | 2659 | |
2660 | if (!hub_is_superspeed(hub->hdev)) | ||
2661 | goto done; | ||
2662 | |||
2663 | /* | ||
2664 | * If a USB 3.0 device migrates from reset to an error | ||
2665 | * state, re-issue the warm reset. | ||
2666 | */ | ||
2667 | if (hub_port_status(hub, port1, | ||
2668 | &portstatus, &portchange) < 0) | ||
2669 | goto done; | ||
2670 | |||
2671 | if (!hub_port_warm_reset_required(hub, portstatus)) | ||
2672 | goto done; | ||
2673 | |||
2674 | /* | ||
2675 | * If the port is in SS.Inactive or Compliance Mode, the | ||
2676 | * hot or warm reset failed. Try another warm reset. | ||
2677 | */ | ||
2678 | if (!warm) { | ||
2679 | dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n", | ||
2680 | port1); | ||
2681 | warm = true; | ||
2682 | } | ||
2699 | } | 2683 | } |
2700 | 2684 | ||
2701 | dev_dbg (hub->intfdev, | 2685 | dev_dbg (hub->intfdev, |
@@ -2709,7 +2693,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2709 | port1); | 2693 | port1); |
2710 | 2694 | ||
2711 | done: | 2695 | done: |
2712 | if (!warm) | 2696 | if (!hub_is_superspeed(hub->hdev)) |
2713 | up_read(&ehci_cf_port_reset_rwsem); | 2697 | up_read(&ehci_cf_port_reset_rwsem); |
2714 | 2698 | ||
2715 | return status; | 2699 | return status; |
@@ -2783,10 +2767,10 @@ static int check_port_resume_type(struct usb_device *udev, | |||
2783 | 2767 | ||
2784 | /* Late port handoff can set status-change bits */ | 2768 | /* Late port handoff can set status-change bits */ |
2785 | if (portchange & USB_PORT_STAT_C_CONNECTION) | 2769 | if (portchange & USB_PORT_STAT_C_CONNECTION) |
2786 | clear_port_feature(hub->hdev, port1, | 2770 | usb_clear_port_feature(hub->hdev, port1, |
2787 | USB_PORT_FEAT_C_CONNECTION); | 2771 | USB_PORT_FEAT_C_CONNECTION); |
2788 | if (portchange & USB_PORT_STAT_C_ENABLE) | 2772 | if (portchange & USB_PORT_STAT_C_ENABLE) |
2789 | clear_port_feature(hub->hdev, port1, | 2773 | usb_clear_port_feature(hub->hdev, port1, |
2790 | USB_PORT_FEAT_C_ENABLE); | 2774 | USB_PORT_FEAT_C_ENABLE); |
2791 | } | 2775 | } |
2792 | 2776 | ||
@@ -2904,7 +2888,9 @@ static int usb_disable_function_remotewakeup(struct usb_device *udev) | |||
2904 | */ | 2888 | */ |
2905 | int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | 2889 | int usb_port_suspend(struct usb_device *udev, pm_message_t msg) |
2906 | { | 2890 | { |
2907 | struct usb_hub *hub = hdev_to_hub(udev->parent); | 2891 | struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); |
2892 | struct usb_port *port_dev = hub->ports[udev->portnum - 1]; | ||
2893 | enum pm_qos_flags_status pm_qos_stat; | ||
2908 | int port1 = udev->portnum; | 2894 | int port1 = udev->portnum; |
2909 | int status; | 2895 | int status; |
2910 | 2896 | ||
@@ -2962,9 +2948,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2962 | 2948 | ||
2963 | /* see 7.1.7.6 */ | 2949 | /* see 7.1.7.6 */ |
2964 | if (hub_is_superspeed(hub->hdev)) | 2950 | if (hub_is_superspeed(hub->hdev)) |
2965 | status = set_port_feature(hub->hdev, | 2951 | status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3); |
2966 | port1 | (USB_SS_PORT_LS_U3 << 3), | ||
2967 | USB_PORT_FEAT_LINK_STATE); | ||
2968 | else | 2952 | else |
2969 | status = set_port_feature(hub->hdev, port1, | 2953 | status = set_port_feature(hub->hdev, port1, |
2970 | USB_PORT_FEAT_SUSPEND); | 2954 | USB_PORT_FEAT_SUSPEND); |
@@ -3006,6 +2990,21 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
3006 | udev->port_is_suspended = 1; | 2990 | udev->port_is_suspended = 1; |
3007 | msleep(10); | 2991 | msleep(10); |
3008 | } | 2992 | } |
2993 | |||
2994 | /* | ||
2995 | * Check whether current status meets the requirement of | ||
2996 | * usb port power off mechanism | ||
2997 | */ | ||
2998 | pm_qos_stat = dev_pm_qos_flags(&port_dev->dev, | ||
2999 | PM_QOS_FLAG_NO_POWER_OFF); | ||
3000 | if (!udev->do_remote_wakeup | ||
3001 | && pm_qos_stat != PM_QOS_FLAGS_ALL | ||
3002 | && udev->persist_enabled | ||
3003 | && !status) { | ||
3004 | pm_runtime_put_sync(&port_dev->dev); | ||
3005 | port_dev->did_runtime_put = true; | ||
3006 | } | ||
3007 | |||
3009 | usb_mark_last_busy(hub->hdev); | 3008 | usb_mark_last_busy(hub->hdev); |
3010 | return status; | 3009 | return status; |
3011 | } | 3010 | } |
@@ -3141,11 +3140,22 @@ static int finish_port_resume(struct usb_device *udev) | |||
3141 | */ | 3140 | */ |
3142 | int usb_port_resume(struct usb_device *udev, pm_message_t msg) | 3141 | int usb_port_resume(struct usb_device *udev, pm_message_t msg) |
3143 | { | 3142 | { |
3144 | struct usb_hub *hub = hdev_to_hub(udev->parent); | 3143 | struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); |
3144 | struct usb_port *port_dev = hub->ports[udev->portnum - 1]; | ||
3145 | int port1 = udev->portnum; | 3145 | int port1 = udev->portnum; |
3146 | int status; | 3146 | int status; |
3147 | u16 portchange, portstatus; | 3147 | u16 portchange, portstatus; |
3148 | 3148 | ||
3149 | if (port_dev->did_runtime_put) { | ||
3150 | status = pm_runtime_get_sync(&port_dev->dev); | ||
3151 | port_dev->did_runtime_put = false; | ||
3152 | if (status < 0) { | ||
3153 | dev_dbg(&udev->dev, "can't resume usb port, status %d\n", | ||
3154 | status); | ||
3155 | return status; | ||
3156 | } | ||
3157 | } | ||
3158 | |||
3149 | /* Skip the initial Clear-Suspend step for a remote wakeup */ | 3159 | /* Skip the initial Clear-Suspend step for a remote wakeup */ |
3150 | status = hub_port_status(hub, port1, &portstatus, &portchange); | 3160 | status = hub_port_status(hub, port1, &portstatus, &portchange); |
3151 | if (status == 0 && !port_is_suspended(hub, portstatus)) | 3161 | if (status == 0 && !port_is_suspended(hub, portstatus)) |
@@ -3157,11 +3167,9 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
3157 | 3167 | ||
3158 | /* see 7.1.7.7; affects power usage, but not budgeting */ | 3168 | /* see 7.1.7.7; affects power usage, but not budgeting */ |
3159 | if (hub_is_superspeed(hub->hdev)) | 3169 | if (hub_is_superspeed(hub->hdev)) |
3160 | status = set_port_feature(hub->hdev, | 3170 | status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U0); |
3161 | port1 | (USB_SS_PORT_LS_U0 << 3), | ||
3162 | USB_PORT_FEAT_LINK_STATE); | ||
3163 | else | 3171 | else |
3164 | status = clear_port_feature(hub->hdev, | 3172 | status = usb_clear_port_feature(hub->hdev, |
3165 | port1, USB_PORT_FEAT_SUSPEND); | 3173 | port1, USB_PORT_FEAT_SUSPEND); |
3166 | if (status) { | 3174 | if (status) { |
3167 | dev_dbg(hub->intfdev, "can't resume port %d, status %d\n", | 3175 | dev_dbg(hub->intfdev, "can't resume port %d, status %d\n", |
@@ -3187,11 +3195,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
3187 | udev->port_is_suspended = 0; | 3195 | udev->port_is_suspended = 0; |
3188 | if (hub_is_superspeed(hub->hdev)) { | 3196 | if (hub_is_superspeed(hub->hdev)) { |
3189 | if (portchange & USB_PORT_STAT_C_LINK_STATE) | 3197 | if (portchange & USB_PORT_STAT_C_LINK_STATE) |
3190 | clear_port_feature(hub->hdev, port1, | 3198 | usb_clear_port_feature(hub->hdev, port1, |
3191 | USB_PORT_FEAT_C_PORT_LINK_STATE); | 3199 | USB_PORT_FEAT_C_PORT_LINK_STATE); |
3192 | } else { | 3200 | } else { |
3193 | if (portchange & USB_PORT_STAT_C_SUSPEND) | 3201 | if (portchange & USB_PORT_STAT_C_SUSPEND) |
3194 | clear_port_feature(hub->hdev, port1, | 3202 | usb_clear_port_feature(hub->hdev, port1, |
3195 | USB_PORT_FEAT_C_SUSPEND); | 3203 | USB_PORT_FEAT_C_SUSPEND); |
3196 | } | 3204 | } |
3197 | } | 3205 | } |
@@ -3247,7 +3255,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
3247 | 3255 | ||
3248 | int usb_port_resume(struct usb_device *udev, pm_message_t msg) | 3256 | int usb_port_resume(struct usb_device *udev, pm_message_t msg) |
3249 | { | 3257 | { |
3250 | struct usb_hub *hub = hdev_to_hub(udev->parent); | 3258 | struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); |
3251 | int port1 = udev->portnum; | 3259 | int port1 = udev->portnum; |
3252 | int status; | 3260 | int status; |
3253 | u16 portchange, portstatus; | 3261 | u16 portchange, portstatus; |
@@ -3826,7 +3834,7 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm); | |||
3826 | * every 25ms for transient disconnects. When the port status has been | 3834 | * every 25ms for transient disconnects. When the port status has been |
3827 | * unchanged for 100ms it returns the port status. | 3835 | * unchanged for 100ms it returns the port status. |
3828 | */ | 3836 | */ |
3829 | static int hub_port_debounce(struct usb_hub *hub, int port1) | 3837 | int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected) |
3830 | { | 3838 | { |
3831 | int ret; | 3839 | int ret; |
3832 | int total_time, stable_time = 0; | 3840 | int total_time, stable_time = 0; |
@@ -3840,7 +3848,9 @@ static int hub_port_debounce(struct usb_hub *hub, int port1) | |||
3840 | 3848 | ||
3841 | if (!(portchange & USB_PORT_STAT_C_CONNECTION) && | 3849 | if (!(portchange & USB_PORT_STAT_C_CONNECTION) && |
3842 | (portstatus & USB_PORT_STAT_CONNECTION) == connection) { | 3850 | (portstatus & USB_PORT_STAT_CONNECTION) == connection) { |
3843 | stable_time += HUB_DEBOUNCE_STEP; | 3851 | if (!must_be_connected || |
3852 | (connection == USB_PORT_STAT_CONNECTION)) | ||
3853 | stable_time += HUB_DEBOUNCE_STEP; | ||
3844 | if (stable_time >= HUB_DEBOUNCE_STABLE) | 3854 | if (stable_time >= HUB_DEBOUNCE_STABLE) |
3845 | break; | 3855 | break; |
3846 | } else { | 3856 | } else { |
@@ -3849,7 +3859,7 @@ static int hub_port_debounce(struct usb_hub *hub, int port1) | |||
3849 | } | 3859 | } |
3850 | 3860 | ||
3851 | if (portchange & USB_PORT_STAT_C_CONNECTION) { | 3861 | if (portchange & USB_PORT_STAT_C_CONNECTION) { |
3852 | clear_port_feature(hub->hdev, port1, | 3862 | usb_clear_port_feature(hub->hdev, port1, |
3853 | USB_PORT_FEAT_C_CONNECTION); | 3863 | USB_PORT_FEAT_C_CONNECTION); |
3854 | } | 3864 | } |
3855 | 3865 | ||
@@ -4246,16 +4256,23 @@ hub_power_remaining (struct usb_hub *hub) | |||
4246 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | 4256 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { |
4247 | struct usb_device *udev = hub->ports[port1 - 1]->child; | 4257 | struct usb_device *udev = hub->ports[port1 - 1]->child; |
4248 | int delta; | 4258 | int delta; |
4259 | unsigned unit_load; | ||
4249 | 4260 | ||
4250 | if (!udev) | 4261 | if (!udev) |
4251 | continue; | 4262 | continue; |
4263 | if (hub_is_superspeed(udev)) | ||
4264 | unit_load = 150; | ||
4265 | else | ||
4266 | unit_load = 100; | ||
4252 | 4267 | ||
4253 | /* Unconfigured devices may not use more than 100mA, | 4268 | /* |
4254 | * or 8mA for OTG ports */ | 4269 | * Unconfigured devices may not use more than one unit load, |
4270 | * or 8mA for OTG ports | ||
4271 | */ | ||
4255 | if (udev->actconfig) | 4272 | if (udev->actconfig) |
4256 | delta = udev->actconfig->desc.bMaxPower * 2; | 4273 | delta = usb_get_max_power(udev, udev->actconfig); |
4257 | else if (port1 != udev->bus->otg_port || hdev->parent) | 4274 | else if (port1 != udev->bus->otg_port || hdev->parent) |
4258 | delta = 100; | 4275 | delta = unit_load; |
4259 | else | 4276 | else |
4260 | delta = 8; | 4277 | delta = 8; |
4261 | if (delta > hub->mA_per_port) | 4278 | if (delta > hub->mA_per_port) |
@@ -4290,6 +4307,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4290 | le16_to_cpu(hub->descriptor->wHubCharacteristics); | 4307 | le16_to_cpu(hub->descriptor->wHubCharacteristics); |
4291 | struct usb_device *udev; | 4308 | struct usb_device *udev; |
4292 | int status, i; | 4309 | int status, i; |
4310 | unsigned unit_load; | ||
4293 | 4311 | ||
4294 | dev_dbg (hub_dev, | 4312 | dev_dbg (hub_dev, |
4295 | "port %d, status %04x, change %04x, %s\n", | 4313 | "port %d, status %04x, change %04x, %s\n", |
@@ -4353,7 +4371,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4353 | 4371 | ||
4354 | if (portchange & (USB_PORT_STAT_C_CONNECTION | | 4372 | if (portchange & (USB_PORT_STAT_C_CONNECTION | |
4355 | USB_PORT_STAT_C_ENABLE)) { | 4373 | USB_PORT_STAT_C_ENABLE)) { |
4356 | status = hub_port_debounce(hub, port1); | 4374 | status = hub_port_debounce_be_stable(hub, port1); |
4357 | if (status < 0) { | 4375 | if (status < 0) { |
4358 | if (printk_ratelimit()) | 4376 | if (printk_ratelimit()) |
4359 | dev_err(hub_dev, "connect-debounce failed, " | 4377 | dev_err(hub_dev, "connect-debounce failed, " |
@@ -4379,6 +4397,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4379 | goto done; | 4397 | goto done; |
4380 | return; | 4398 | return; |
4381 | } | 4399 | } |
4400 | if (hub_is_superspeed(hub->hdev)) | ||
4401 | unit_load = 150; | ||
4402 | else | ||
4403 | unit_load = 100; | ||
4382 | 4404 | ||
4383 | for (i = 0; i < SET_CONFIG_TRIES; i++) { | 4405 | for (i = 0; i < SET_CONFIG_TRIES; i++) { |
4384 | 4406 | ||
@@ -4426,7 +4448,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4426 | * on the parent. | 4448 | * on the parent. |
4427 | */ | 4449 | */ |
4428 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB | 4450 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB |
4429 | && udev->bus_mA <= 100) { | 4451 | && udev->bus_mA <= unit_load) { |
4430 | u16 devstat; | 4452 | u16 devstat; |
4431 | 4453 | ||
4432 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, | 4454 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, |
@@ -4528,7 +4550,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, | |||
4528 | if (!hub_is_superspeed(hdev)) { | 4550 | if (!hub_is_superspeed(hdev)) { |
4529 | if (!(portchange & USB_PORT_STAT_C_SUSPEND)) | 4551 | if (!(portchange & USB_PORT_STAT_C_SUSPEND)) |
4530 | return 0; | 4552 | return 0; |
4531 | clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); | 4553 | usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); |
4532 | } else { | 4554 | } else { |
4533 | if (!udev || udev->state != USB_STATE_SUSPENDED || | 4555 | if (!udev || udev->state != USB_STATE_SUSPENDED || |
4534 | (portstatus & USB_PORT_STAT_LINK_STATE) != | 4556 | (portstatus & USB_PORT_STAT_LINK_STATE) != |
@@ -4656,7 +4678,7 @@ static void hub_events(void) | |||
4656 | continue; | 4678 | continue; |
4657 | 4679 | ||
4658 | if (portchange & USB_PORT_STAT_C_CONNECTION) { | 4680 | if (portchange & USB_PORT_STAT_C_CONNECTION) { |
4659 | clear_port_feature(hdev, i, | 4681 | usb_clear_port_feature(hdev, i, |
4660 | USB_PORT_FEAT_C_CONNECTION); | 4682 | USB_PORT_FEAT_C_CONNECTION); |
4661 | connect_change = 1; | 4683 | connect_change = 1; |
4662 | } | 4684 | } |
@@ -4667,7 +4689,7 @@ static void hub_events(void) | |||
4667 | "port %d enable change, " | 4689 | "port %d enable change, " |
4668 | "status %08x\n", | 4690 | "status %08x\n", |
4669 | i, portstatus); | 4691 | i, portstatus); |
4670 | clear_port_feature(hdev, i, | 4692 | usb_clear_port_feature(hdev, i, |
4671 | USB_PORT_FEAT_C_ENABLE); | 4693 | USB_PORT_FEAT_C_ENABLE); |
4672 | 4694 | ||
4673 | /* | 4695 | /* |
@@ -4698,7 +4720,7 @@ static void hub_events(void) | |||
4698 | 4720 | ||
4699 | dev_dbg(hub_dev, "over-current change on port " | 4721 | dev_dbg(hub_dev, "over-current change on port " |
4700 | "%d\n", i); | 4722 | "%d\n", i); |
4701 | clear_port_feature(hdev, i, | 4723 | usb_clear_port_feature(hdev, i, |
4702 | USB_PORT_FEAT_C_OVER_CURRENT); | 4724 | USB_PORT_FEAT_C_OVER_CURRENT); |
4703 | msleep(100); /* Cool down */ | 4725 | msleep(100); /* Cool down */ |
4704 | hub_power_on(hub, true); | 4726 | hub_power_on(hub, true); |
@@ -4712,7 +4734,7 @@ static void hub_events(void) | |||
4712 | dev_dbg (hub_dev, | 4734 | dev_dbg (hub_dev, |
4713 | "reset change on port %d\n", | 4735 | "reset change on port %d\n", |
4714 | i); | 4736 | i); |
4715 | clear_port_feature(hdev, i, | 4737 | usb_clear_port_feature(hdev, i, |
4716 | USB_PORT_FEAT_C_RESET); | 4738 | USB_PORT_FEAT_C_RESET); |
4717 | } | 4739 | } |
4718 | if ((portchange & USB_PORT_STAT_C_BH_RESET) && | 4740 | if ((portchange & USB_PORT_STAT_C_BH_RESET) && |
@@ -4720,18 +4742,18 @@ static void hub_events(void) | |||
4720 | dev_dbg(hub_dev, | 4742 | dev_dbg(hub_dev, |
4721 | "warm reset change on port %d\n", | 4743 | "warm reset change on port %d\n", |
4722 | i); | 4744 | i); |
4723 | clear_port_feature(hdev, i, | 4745 | usb_clear_port_feature(hdev, i, |
4724 | USB_PORT_FEAT_C_BH_PORT_RESET); | 4746 | USB_PORT_FEAT_C_BH_PORT_RESET); |
4725 | } | 4747 | } |
4726 | if (portchange & USB_PORT_STAT_C_LINK_STATE) { | 4748 | if (portchange & USB_PORT_STAT_C_LINK_STATE) { |
4727 | clear_port_feature(hub->hdev, i, | 4749 | usb_clear_port_feature(hub->hdev, i, |
4728 | USB_PORT_FEAT_C_PORT_LINK_STATE); | 4750 | USB_PORT_FEAT_C_PORT_LINK_STATE); |
4729 | } | 4751 | } |
4730 | if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) { | 4752 | if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) { |
4731 | dev_warn(hub_dev, | 4753 | dev_warn(hub_dev, |
4732 | "config error on port %d\n", | 4754 | "config error on port %d\n", |
4733 | i); | 4755 | i); |
4734 | clear_port_feature(hub->hdev, i, | 4756 | usb_clear_port_feature(hub->hdev, i, |
4735 | USB_PORT_FEAT_C_PORT_CONFIG_ERROR); | 4757 | USB_PORT_FEAT_C_PORT_CONFIG_ERROR); |
4736 | } | 4758 | } |
4737 | 4759 | ||
@@ -4740,12 +4762,21 @@ static void hub_events(void) | |||
4740 | */ | 4762 | */ |
4741 | if (hub_port_warm_reset_required(hub, portstatus)) { | 4763 | if (hub_port_warm_reset_required(hub, portstatus)) { |
4742 | int status; | 4764 | int status; |
4765 | struct usb_device *udev = | ||
4766 | hub->ports[i - 1]->child; | ||
4743 | 4767 | ||
4744 | dev_dbg(hub_dev, "warm reset port %d\n", i); | 4768 | dev_dbg(hub_dev, "warm reset port %d\n", i); |
4745 | status = hub_port_reset(hub, i, NULL, | 4769 | if (!udev) { |
4746 | HUB_BH_RESET_TIME, true); | 4770 | status = hub_port_reset(hub, i, |
4747 | if (status < 0) | 4771 | NULL, HUB_BH_RESET_TIME, |
4748 | hub_port_disable(hub, i, 1); | 4772 | true); |
4773 | if (status < 0) | ||
4774 | hub_port_disable(hub, i, 1); | ||
4775 | } else { | ||
4776 | usb_lock_device(udev); | ||
4777 | status = usb_reset_device(udev); | ||
4778 | usb_unlock_device(udev); | ||
4779 | } | ||
4749 | connect_change = 0; | 4780 | connect_change = 0; |
4750 | } | 4781 | } |
4751 | 4782 | ||
@@ -5006,7 +5037,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
5006 | dev_dbg(&udev->dev, "%s for root hub!\n", __func__); | 5037 | dev_dbg(&udev->dev, "%s for root hub!\n", __func__); |
5007 | return -EISDIR; | 5038 | return -EISDIR; |
5008 | } | 5039 | } |
5009 | parent_hub = hdev_to_hub(parent_hdev); | 5040 | parent_hub = usb_hub_to_struct_hub(parent_hdev); |
5010 | 5041 | ||
5011 | /* Disable LPM and LTM while we reset the device and reinstall the alt | 5042 | /* Disable LPM and LTM while we reset the device and reinstall the alt |
5012 | * settings. Device-initiated LPM settings, and system exit latency | 5043 | * settings. Device-initiated LPM settings, and system exit latency |
@@ -5262,7 +5293,7 @@ EXPORT_SYMBOL_GPL(usb_queue_reset_device); | |||
5262 | struct usb_device *usb_hub_find_child(struct usb_device *hdev, | 5293 | struct usb_device *usb_hub_find_child(struct usb_device *hdev, |
5263 | int port1) | 5294 | int port1) |
5264 | { | 5295 | { |
5265 | struct usb_hub *hub = hdev_to_hub(hdev); | 5296 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); |
5266 | 5297 | ||
5267 | if (port1 < 1 || port1 > hdev->maxchild) | 5298 | if (port1 < 1 || port1 > hdev->maxchild) |
5268 | return NULL; | 5299 | return NULL; |
@@ -5279,7 +5310,7 @@ EXPORT_SYMBOL_GPL(usb_hub_find_child); | |||
5279 | void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1, | 5310 | void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1, |
5280 | enum usb_port_connect_type type) | 5311 | enum usb_port_connect_type type) |
5281 | { | 5312 | { |
5282 | struct usb_hub *hub = hdev_to_hub(hdev); | 5313 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); |
5283 | 5314 | ||
5284 | hub->ports[port1 - 1]->connect_type = type; | 5315 | hub->ports[port1 - 1]->connect_type = type; |
5285 | } | 5316 | } |
@@ -5295,11 +5326,52 @@ void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1, | |||
5295 | enum usb_port_connect_type | 5326 | enum usb_port_connect_type |
5296 | usb_get_hub_port_connect_type(struct usb_device *hdev, int port1) | 5327 | usb_get_hub_port_connect_type(struct usb_device *hdev, int port1) |
5297 | { | 5328 | { |
5298 | struct usb_hub *hub = hdev_to_hub(hdev); | 5329 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); |
5299 | 5330 | ||
5300 | return hub->ports[port1 - 1]->connect_type; | 5331 | return hub->ports[port1 - 1]->connect_type; |
5301 | } | 5332 | } |
5302 | 5333 | ||
5334 | void usb_hub_adjust_deviceremovable(struct usb_device *hdev, | ||
5335 | struct usb_hub_descriptor *desc) | ||
5336 | { | ||
5337 | enum usb_port_connect_type connect_type; | ||
5338 | int i; | ||
5339 | |||
5340 | if (!hub_is_superspeed(hdev)) { | ||
5341 | for (i = 1; i <= hdev->maxchild; i++) { | ||
5342 | connect_type = usb_get_hub_port_connect_type(hdev, i); | ||
5343 | |||
5344 | if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { | ||
5345 | u8 mask = 1 << (i%8); | ||
5346 | |||
5347 | if (!(desc->u.hs.DeviceRemovable[i/8] & mask)) { | ||
5348 | dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n", | ||
5349 | i); | ||
5350 | desc->u.hs.DeviceRemovable[i/8] |= mask; | ||
5351 | } | ||
5352 | } | ||
5353 | } | ||
5354 | } else { | ||
5355 | u16 port_removable = le16_to_cpu(desc->u.ss.DeviceRemovable); | ||
5356 | |||
5357 | for (i = 1; i <= hdev->maxchild; i++) { | ||
5358 | connect_type = usb_get_hub_port_connect_type(hdev, i); | ||
5359 | |||
5360 | if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { | ||
5361 | u16 mask = 1 << i; | ||
5362 | |||
5363 | if (!(port_removable & mask)) { | ||
5364 | dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n", | ||
5365 | i); | ||
5366 | port_removable |= mask; | ||
5367 | } | ||
5368 | } | ||
5369 | } | ||
5370 | |||
5371 | desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable); | ||
5372 | } | ||
5373 | } | ||
5374 | |||
5303 | #ifdef CONFIG_ACPI | 5375 | #ifdef CONFIG_ACPI |
5304 | /** | 5376 | /** |
5305 | * usb_get_hub_port_acpi_handle - Get the usb port's acpi handle | 5377 | * usb_get_hub_port_acpi_handle - Get the usb port's acpi handle |
@@ -5312,7 +5384,7 @@ usb_get_hub_port_connect_type(struct usb_device *hdev, int port1) | |||
5312 | acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev, | 5384 | acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev, |
5313 | int port1) | 5385 | int port1) |
5314 | { | 5386 | { |
5315 | struct usb_hub *hub = hdev_to_hub(hdev); | 5387 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); |
5316 | 5388 | ||
5317 | return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev); | 5389 | return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev); |
5318 | } | 5390 | } |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h new file mode 100644 index 000000000000..80ab9ee07017 --- /dev/null +++ b/drivers/usb/core/hub.h | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * usb hub driver head file | ||
3 | * | ||
4 | * Copyright (C) 1999 Linus Torvalds | ||
5 | * Copyright (C) 1999 Johannes Erdfelt | ||
6 | * Copyright (C) 1999 Gregory P. Smith | ||
7 | * Copyright (C) 2001 Brad Hards (bhards@bigpond.net.au) | ||
8 | * Copyright (C) 2012 Intel Corp (tianyu.lan@intel.com) | ||
9 | * | ||
10 | * move struct usb_hub to this file. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but | ||
17 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
18 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
19 | * for more details. | ||
20 | */ | ||
21 | |||
22 | #include <linux/usb.h> | ||
23 | #include <linux/usb/ch11.h> | ||
24 | #include <linux/usb/hcd.h> | ||
25 | #include "usb.h" | ||
26 | |||
27 | struct usb_hub { | ||
28 | struct device *intfdev; /* the "interface" device */ | ||
29 | struct usb_device *hdev; | ||
30 | struct kref kref; | ||
31 | struct urb *urb; /* for interrupt polling pipe */ | ||
32 | |||
33 | /* buffer for urb ... with extra space in case of babble */ | ||
34 | u8 (*buffer)[8]; | ||
35 | union { | ||
36 | struct usb_hub_status hub; | ||
37 | struct usb_port_status port; | ||
38 | } *status; /* buffer for status reports */ | ||
39 | struct mutex status_mutex; /* for the status buffer */ | ||
40 | |||
41 | int error; /* last reported error */ | ||
42 | int nerrors; /* track consecutive errors */ | ||
43 | |||
44 | struct list_head event_list; /* hubs w/data or errs ready */ | ||
45 | unsigned long event_bits[1]; /* status change bitmask */ | ||
46 | unsigned long change_bits[1]; /* ports with logical connect | ||
47 | status change */ | ||
48 | unsigned long busy_bits[1]; /* ports being reset or | ||
49 | resumed */ | ||
50 | unsigned long removed_bits[1]; /* ports with a "removed" | ||
51 | device present */ | ||
52 | unsigned long wakeup_bits[1]; /* ports that have signaled | ||
53 | remote wakeup */ | ||
54 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ | ||
55 | #error event_bits[] is too short! | ||
56 | #endif | ||
57 | |||
58 | struct usb_hub_descriptor *descriptor; /* class descriptor */ | ||
59 | struct usb_tt tt; /* Transaction Translator */ | ||
60 | |||
61 | unsigned mA_per_port; /* current for each child */ | ||
62 | |||
63 | unsigned limited_power:1; | ||
64 | unsigned quiescing:1; | ||
65 | unsigned disconnected:1; | ||
66 | |||
67 | unsigned quirk_check_port_auto_suspend:1; | ||
68 | |||
69 | unsigned has_indicators:1; | ||
70 | u8 indicator[USB_MAXCHILDREN]; | ||
71 | struct delayed_work leds; | ||
72 | struct delayed_work init_work; | ||
73 | struct usb_port **ports; | ||
74 | }; | ||
75 | |||
76 | /** | ||
77 | * struct usb port - kernel's representation of a usb port | ||
78 | * @child: usb device attatched to the port | ||
79 | * @dev: generic device interface | ||
80 | * @port_owner: port's owner | ||
81 | * @connect_type: port's connect type | ||
82 | * @portnum: port index num based one | ||
83 | * @power_is_on: port's power state | ||
84 | * @did_runtime_put: port has done pm_runtime_put(). | ||
85 | */ | ||
86 | struct usb_port { | ||
87 | struct usb_device *child; | ||
88 | struct device dev; | ||
89 | struct dev_state *port_owner; | ||
90 | enum usb_port_connect_type connect_type; | ||
91 | u8 portnum; | ||
92 | unsigned power_is_on:1; | ||
93 | unsigned did_runtime_put:1; | ||
94 | }; | ||
95 | |||
96 | #define to_usb_port(_dev) \ | ||
97 | container_of(_dev, struct usb_port, dev) | ||
98 | |||
99 | extern int usb_hub_create_port_device(struct usb_hub *hub, | ||
100 | int port1); | ||
101 | extern void usb_hub_remove_port_device(struct usb_hub *hub, | ||
102 | int port1); | ||
103 | extern int usb_hub_set_port_power(struct usb_device *hdev, | ||
104 | int port1, bool set); | ||
105 | extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev); | ||
106 | extern int hub_port_debounce(struct usb_hub *hub, int port1, | ||
107 | bool must_be_connected); | ||
108 | extern int usb_clear_port_feature(struct usb_device *hdev, | ||
109 | int port1, int feature); | ||
110 | |||
111 | static inline int hub_port_debounce_be_connected(struct usb_hub *hub, | ||
112 | int port1) | ||
113 | { | ||
114 | return hub_port_debounce(hub, port1, true); | ||
115 | } | ||
116 | |||
117 | static inline int hub_port_debounce_be_stable(struct usb_hub *hub, | ||
118 | int port1) | ||
119 | { | ||
120 | return hub_port_debounce(hub, port1, false); | ||
121 | } | ||
122 | |||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 131f73649b60..444d30e3a78b 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1751,7 +1751,7 @@ free_interfaces: | |||
1751 | } | 1751 | } |
1752 | } | 1752 | } |
1753 | 1753 | ||
1754 | i = dev->bus_mA - cp->desc.bMaxPower * 2; | 1754 | i = dev->bus_mA - usb_get_max_power(dev, cp); |
1755 | if (i < 0) | 1755 | if (i < 0) |
1756 | dev_warn(&dev->dev, "new config #%d exceeds power " | 1756 | dev_warn(&dev->dev, "new config #%d exceeds power " |
1757 | "limit by %dmA\n", | 1757 | "limit by %dmA\n", |
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c new file mode 100644 index 000000000000..797f9d514732 --- /dev/null +++ b/drivers/usb/core/port.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * usb port device code | ||
3 | * | ||
4 | * Copyright (C) 2012 Intel Corp | ||
5 | * | ||
6 | * Author: Lan Tianyu <tianyu.lan@intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
15 | * for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/slab.h> | ||
20 | #include <linux/pm_qos.h> | ||
21 | |||
22 | #include "hub.h" | ||
23 | |||
24 | static const struct attribute_group *port_dev_group[]; | ||
25 | |||
26 | static ssize_t show_port_connect_type(struct device *dev, | ||
27 | struct device_attribute *attr, char *buf) | ||
28 | { | ||
29 | struct usb_port *port_dev = to_usb_port(dev); | ||
30 | char *result; | ||
31 | |||
32 | switch (port_dev->connect_type) { | ||
33 | case USB_PORT_CONNECT_TYPE_HOT_PLUG: | ||
34 | result = "hotplug"; | ||
35 | break; | ||
36 | case USB_PORT_CONNECT_TYPE_HARD_WIRED: | ||
37 | result = "hardwired"; | ||
38 | break; | ||
39 | case USB_PORT_NOT_USED: | ||
40 | result = "not used"; | ||
41 | break; | ||
42 | default: | ||
43 | result = "unknown"; | ||
44 | break; | ||
45 | } | ||
46 | |||
47 | return sprintf(buf, "%s\n", result); | ||
48 | } | ||
49 | static DEVICE_ATTR(connect_type, S_IRUGO, show_port_connect_type, | ||
50 | NULL); | ||
51 | |||
52 | static struct attribute *port_dev_attrs[] = { | ||
53 | &dev_attr_connect_type.attr, | ||
54 | NULL, | ||
55 | }; | ||
56 | |||
57 | static struct attribute_group port_dev_attr_grp = { | ||
58 | .attrs = port_dev_attrs, | ||
59 | }; | ||
60 | |||
61 | static const struct attribute_group *port_dev_group[] = { | ||
62 | &port_dev_attr_grp, | ||
63 | NULL, | ||
64 | }; | ||
65 | |||
66 | static void usb_port_device_release(struct device *dev) | ||
67 | { | ||
68 | struct usb_port *port_dev = to_usb_port(dev); | ||
69 | |||
70 | dev_pm_qos_hide_flags(dev); | ||
71 | kfree(port_dev); | ||
72 | } | ||
73 | |||
74 | #ifdef CONFIG_USB_SUSPEND | ||
75 | static int usb_port_runtime_resume(struct device *dev) | ||
76 | { | ||
77 | struct usb_port *port_dev = to_usb_port(dev); | ||
78 | struct usb_device *hdev = to_usb_device(dev->parent->parent); | ||
79 | struct usb_interface *intf = to_usb_interface(dev->parent); | ||
80 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); | ||
81 | int port1 = port_dev->portnum; | ||
82 | int retval; | ||
83 | |||
84 | if (!hub) | ||
85 | return -EINVAL; | ||
86 | |||
87 | usb_autopm_get_interface(intf); | ||
88 | set_bit(port1, hub->busy_bits); | ||
89 | |||
90 | retval = usb_hub_set_port_power(hdev, port1, true); | ||
91 | if (port_dev->child && !retval) { | ||
92 | /* | ||
93 | * Wait for usb hub port to be reconnected in order to make | ||
94 | * the resume procedure successful. | ||
95 | */ | ||
96 | retval = hub_port_debounce_be_connected(hub, port1); | ||
97 | if (retval < 0) { | ||
98 | dev_dbg(&port_dev->dev, "can't get reconnection after setting port power on, status %d\n", | ||
99 | retval); | ||
100 | goto out; | ||
101 | } | ||
102 | usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); | ||
103 | |||
104 | /* Set return value to 0 if debounce successful */ | ||
105 | retval = 0; | ||
106 | } | ||
107 | |||
108 | out: | ||
109 | clear_bit(port1, hub->busy_bits); | ||
110 | usb_autopm_put_interface(intf); | ||
111 | return retval; | ||
112 | } | ||
113 | |||
114 | static int usb_port_runtime_suspend(struct device *dev) | ||
115 | { | ||
116 | struct usb_port *port_dev = to_usb_port(dev); | ||
117 | struct usb_device *hdev = to_usb_device(dev->parent->parent); | ||
118 | struct usb_interface *intf = to_usb_interface(dev->parent); | ||
119 | struct usb_hub *hub = usb_hub_to_struct_hub(hdev); | ||
120 | int port1 = port_dev->portnum; | ||
121 | int retval; | ||
122 | |||
123 | if (!hub) | ||
124 | return -EINVAL; | ||
125 | |||
126 | if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) | ||
127 | == PM_QOS_FLAGS_ALL) | ||
128 | return -EAGAIN; | ||
129 | |||
130 | usb_autopm_get_interface(intf); | ||
131 | set_bit(port1, hub->busy_bits); | ||
132 | retval = usb_hub_set_port_power(hdev, port1, false); | ||
133 | usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); | ||
134 | usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); | ||
135 | clear_bit(port1, hub->busy_bits); | ||
136 | usb_autopm_put_interface(intf); | ||
137 | return retval; | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | static const struct dev_pm_ops usb_port_pm_ops = { | ||
142 | #ifdef CONFIG_USB_SUSPEND | ||
143 | .runtime_suspend = usb_port_runtime_suspend, | ||
144 | .runtime_resume = usb_port_runtime_resume, | ||
145 | .runtime_idle = pm_generic_runtime_idle, | ||
146 | #endif | ||
147 | }; | ||
148 | |||
149 | struct device_type usb_port_device_type = { | ||
150 | .name = "usb_port", | ||
151 | .release = usb_port_device_release, | ||
152 | .pm = &usb_port_pm_ops, | ||
153 | }; | ||
154 | |||
155 | int usb_hub_create_port_device(struct usb_hub *hub, int port1) | ||
156 | { | ||
157 | struct usb_port *port_dev = NULL; | ||
158 | int retval; | ||
159 | |||
160 | port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); | ||
161 | if (!port_dev) { | ||
162 | retval = -ENOMEM; | ||
163 | goto exit; | ||
164 | } | ||
165 | |||
166 | hub->ports[port1 - 1] = port_dev; | ||
167 | port_dev->portnum = port1; | ||
168 | port_dev->power_is_on = true; | ||
169 | port_dev->dev.parent = hub->intfdev; | ||
170 | port_dev->dev.groups = port_dev_group; | ||
171 | port_dev->dev.type = &usb_port_device_type; | ||
172 | dev_set_name(&port_dev->dev, "port%d", port1); | ||
173 | |||
174 | retval = device_register(&port_dev->dev); | ||
175 | if (retval) | ||
176 | goto error_register; | ||
177 | |||
178 | pm_runtime_set_active(&port_dev->dev); | ||
179 | |||
180 | /* It would be dangerous if user space couldn't | ||
181 | * prevent usb device from being powered off. So don't | ||
182 | * enable port runtime pm if failed to expose port's pm qos. | ||
183 | */ | ||
184 | if (!dev_pm_qos_expose_flags(&port_dev->dev, | ||
185 | PM_QOS_FLAG_NO_POWER_OFF)) | ||
186 | pm_runtime_enable(&port_dev->dev); | ||
187 | |||
188 | device_enable_async_suspend(&port_dev->dev); | ||
189 | return 0; | ||
190 | |||
191 | error_register: | ||
192 | put_device(&port_dev->dev); | ||
193 | exit: | ||
194 | return retval; | ||
195 | } | ||
196 | |||
197 | void usb_hub_remove_port_device(struct usb_hub *hub, | ||
198 | int port1) | ||
199 | { | ||
200 | device_unregister(&hub->ports[port1 - 1]->dev); | ||
201 | } | ||
202 | |||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 818e4a024d0d..3f81a3dc6867 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include "usb.h" | 17 | #include "usb.h" |
18 | 18 | ||
19 | /* Active configuration fields */ | 19 | /* Active configuration fields */ |
20 | #define usb_actconfig_show(field, multiplier, format_string) \ | 20 | #define usb_actconfig_show(field, format_string) \ |
21 | static ssize_t show_##field(struct device *dev, \ | 21 | static ssize_t show_##field(struct device *dev, \ |
22 | struct device_attribute *attr, char *buf) \ | 22 | struct device_attribute *attr, char *buf) \ |
23 | { \ | 23 | { \ |
@@ -28,18 +28,31 @@ static ssize_t show_##field(struct device *dev, \ | |||
28 | actconfig = udev->actconfig; \ | 28 | actconfig = udev->actconfig; \ |
29 | if (actconfig) \ | 29 | if (actconfig) \ |
30 | return sprintf(buf, format_string, \ | 30 | return sprintf(buf, format_string, \ |
31 | actconfig->desc.field * multiplier); \ | 31 | actconfig->desc.field); \ |
32 | else \ | 32 | else \ |
33 | return 0; \ | 33 | return 0; \ |
34 | } \ | 34 | } \ |
35 | 35 | ||
36 | #define usb_actconfig_attr(field, multiplier, format_string) \ | 36 | #define usb_actconfig_attr(field, format_string) \ |
37 | usb_actconfig_show(field, multiplier, format_string) \ | 37 | usb_actconfig_show(field, format_string) \ |
38 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 38 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
39 | |||
40 | usb_actconfig_attr(bNumInterfaces, "%2d\n") | ||
41 | usb_actconfig_attr(bmAttributes, "%2x\n") | ||
39 | 42 | ||
40 | usb_actconfig_attr(bNumInterfaces, 1, "%2d\n") | 43 | static ssize_t show_bMaxPower(struct device *dev, |
41 | usb_actconfig_attr(bmAttributes, 1, "%2x\n") | 44 | struct device_attribute *attr, char *buf) |
42 | usb_actconfig_attr(bMaxPower, 2, "%3dmA\n") | 45 | { |
46 | struct usb_device *udev; | ||
47 | struct usb_host_config *actconfig; | ||
48 | |||
49 | udev = to_usb_device(dev); | ||
50 | actconfig = udev->actconfig; | ||
51 | if (!actconfig) | ||
52 | return 0; | ||
53 | return sprintf(buf, "%dmA\n", usb_get_max_power(udev, actconfig)); | ||
54 | } | ||
55 | static DEVICE_ATTR(bMaxPower, S_IRUGO, show_bMaxPower, NULL); | ||
43 | 56 | ||
44 | static ssize_t show_configuration_string(struct device *dev, | 57 | static ssize_t show_configuration_string(struct device *dev, |
45 | struct device_attribute *attr, char *buf) | 58 | struct device_attribute *attr, char *buf) |
@@ -56,7 +69,7 @@ static ssize_t show_configuration_string(struct device *dev, | |||
56 | static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); | 69 | static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); |
57 | 70 | ||
58 | /* configuration value is always present, and r/w */ | 71 | /* configuration value is always present, and r/w */ |
59 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); | 72 | usb_actconfig_show(bConfigurationValue, "%u\n"); |
60 | 73 | ||
61 | static ssize_t | 74 | static ssize_t |
62 | set_bConfigurationValue(struct device *dev, struct device_attribute *attr, | 75 | set_bConfigurationValue(struct device *dev, struct device_attribute *attr, |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 1c528c1bf0be..a7f20bde0e5e 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/pm.h> | 1 | #include <linux/pm.h> |
2 | #include <linux/acpi.h> | 2 | #include <linux/acpi.h> |
3 | 3 | ||
4 | struct usb_hub_descriptor; | ||
4 | struct dev_state; | 5 | struct dev_state; |
5 | 6 | ||
6 | /* Functions local to drivers/usb/core/ */ | 7 | /* Functions local to drivers/usb/core/ */ |
@@ -38,6 +39,15 @@ extern char *usb_cache_string(struct usb_device *udev, int index); | |||
38 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 39 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
39 | extern int usb_choose_configuration(struct usb_device *udev); | 40 | extern int usb_choose_configuration(struct usb_device *udev); |
40 | 41 | ||
42 | static inline unsigned usb_get_max_power(struct usb_device *udev, | ||
43 | struct usb_host_config *c) | ||
44 | { | ||
45 | /* SuperSpeed power is in 8 mA units; others are in 2 mA units */ | ||
46 | unsigned mul = (udev->speed == USB_SPEED_SUPER ? 8 : 2); | ||
47 | |||
48 | return c->desc.bMaxPower * mul; | ||
49 | } | ||
50 | |||
41 | extern void usb_kick_khubd(struct usb_device *dev); | 51 | extern void usb_kick_khubd(struct usb_device *dev); |
42 | extern int usb_match_one_id_intf(struct usb_device *dev, | 52 | extern int usb_match_one_id_intf(struct usb_device *dev, |
43 | struct usb_host_interface *intf, | 53 | struct usb_host_interface *intf, |
@@ -173,6 +183,8 @@ extern enum usb_port_connect_type | |||
173 | usb_get_hub_port_connect_type(struct usb_device *hdev, int port1); | 183 | usb_get_hub_port_connect_type(struct usb_device *hdev, int port1); |
174 | extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1, | 184 | extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1, |
175 | enum usb_port_connect_type type); | 185 | enum usb_port_connect_type type); |
186 | extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev, | ||
187 | struct usb_hub_descriptor *desc); | ||
176 | 188 | ||
177 | #ifdef CONFIG_ACPI | 189 | #ifdef CONFIG_ACPI |
178 | extern int usb_acpi_register(void); | 190 | extern int usb_acpi_register(void); |
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index f6a6e070c2ac..68e9a2c5a01a 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config USB_DWC3 | 1 | config USB_DWC3 |
2 | tristate "DesignWare USB3 DRD Core Support" | 2 | tristate "DesignWare USB3 DRD Core Support" |
3 | depends on (USB && USB_GADGET) | 3 | depends on (USB || USB_GADGET) && GENERIC_HARDIRQS |
4 | select USB_OTG_UTILS | 4 | select USB_OTG_UTILS |
5 | select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD | 5 | select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD |
6 | help | 6 | help |
@@ -12,6 +12,35 @@ config USB_DWC3 | |||
12 | 12 | ||
13 | if USB_DWC3 | 13 | if USB_DWC3 |
14 | 14 | ||
15 | choice | ||
16 | bool "DWC3 Mode Selection" | ||
17 | default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET) | ||
18 | default USB_DWC3_HOST if (USB && !USB_GADGET) | ||
19 | default USB_DWC3_GADGET if (!USB && USB_GADGET) | ||
20 | |||
21 | config USB_DWC3_HOST | ||
22 | bool "Host only mode" | ||
23 | depends on USB | ||
24 | help | ||
25 | Select this when you want to use DWC3 in host mode only, | ||
26 | thereby the gadget feature will be regressed. | ||
27 | |||
28 | config USB_DWC3_GADGET | ||
29 | bool "Gadget only mode" | ||
30 | depends on USB_GADGET | ||
31 | help | ||
32 | Select this when you want to use DWC3 in gadget mode only, | ||
33 | thereby the host feature will be regressed. | ||
34 | |||
35 | config USB_DWC3_DUAL_ROLE | ||
36 | bool "Dual Role mode" | ||
37 | depends on (USB && USB_GADGET) | ||
38 | help | ||
39 | This is the default mode of working of DWC3 controller where | ||
40 | both host and gadget features are enabled. | ||
41 | |||
42 | endchoice | ||
43 | |||
15 | config USB_DWC3_DEBUG | 44 | config USB_DWC3_DEBUG |
16 | bool "Enable Debugging Messages" | 45 | bool "Enable Debugging Messages" |
17 | help | 46 | help |
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 4502648b8171..0c7ac92582be 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile | |||
@@ -4,8 +4,14 @@ ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG | |||
4 | obj-$(CONFIG_USB_DWC3) += dwc3.o | 4 | obj-$(CONFIG_USB_DWC3) += dwc3.o |
5 | 5 | ||
6 | dwc3-y := core.o | 6 | dwc3-y := core.o |
7 | dwc3-y += host.o | 7 | |
8 | dwc3-y += gadget.o ep0.o | 8 | ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),) |
9 | dwc3-y += host.o | ||
10 | endif | ||
11 | |||
12 | ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),) | ||
13 | dwc3-y += gadget.o ep0.o | ||
14 | endif | ||
9 | 15 | ||
10 | ifneq ($(CONFIG_DEBUG_FS),) | 16 | ifneq ($(CONFIG_DEBUG_FS),) |
11 | dwc3-y += debugfs.o | 17 | dwc3-y += debugfs.o |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 3a4004a620ad..999909451e37 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -420,18 +420,27 @@ static int dwc3_probe(struct platform_device *pdev) | |||
420 | return -ENOMEM; | 420 | return -ENOMEM; |
421 | } | 421 | } |
422 | 422 | ||
423 | dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | 423 | if (node) { |
424 | dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); | ||
425 | dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); | ||
426 | } else { | ||
427 | dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
428 | dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); | ||
429 | } | ||
430 | |||
424 | if (IS_ERR_OR_NULL(dwc->usb2_phy)) { | 431 | if (IS_ERR_OR_NULL(dwc->usb2_phy)) { |
425 | dev_err(dev, "no usb2 phy configured\n"); | 432 | dev_err(dev, "no usb2 phy configured\n"); |
426 | return -EPROBE_DEFER; | 433 | return -EPROBE_DEFER; |
427 | } | 434 | } |
428 | 435 | ||
429 | dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); | ||
430 | if (IS_ERR_OR_NULL(dwc->usb3_phy)) { | 436 | if (IS_ERR_OR_NULL(dwc->usb3_phy)) { |
431 | dev_err(dev, "no usb3 phy configured\n"); | 437 | dev_err(dev, "no usb3 phy configured\n"); |
432 | return -EPROBE_DEFER; | 438 | return -EPROBE_DEFER; |
433 | } | 439 | } |
434 | 440 | ||
441 | usb_phy_set_suspend(dwc->usb2_phy, 0); | ||
442 | usb_phy_set_suspend(dwc->usb3_phy, 0); | ||
443 | |||
435 | spin_lock_init(&dwc->lock); | 444 | spin_lock_init(&dwc->lock); |
436 | platform_set_drvdata(pdev, dwc); | 445 | platform_set_drvdata(pdev, dwc); |
437 | 446 | ||
@@ -450,8 +459,7 @@ static int dwc3_probe(struct platform_device *pdev) | |||
450 | else | 459 | else |
451 | dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; | 460 | dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; |
452 | 461 | ||
453 | if (of_get_property(node, "tx-fifo-resize", NULL)) | 462 | dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); |
454 | dwc->needs_fifo_resize = true; | ||
455 | 463 | ||
456 | pm_runtime_enable(dev); | 464 | pm_runtime_enable(dev); |
457 | pm_runtime_get_sync(dev); | 465 | pm_runtime_get_sync(dev); |
@@ -550,9 +558,9 @@ err0: | |||
550 | static int dwc3_remove(struct platform_device *pdev) | 558 | static int dwc3_remove(struct platform_device *pdev) |
551 | { | 559 | { |
552 | struct dwc3 *dwc = platform_get_drvdata(pdev); | 560 | struct dwc3 *dwc = platform_get_drvdata(pdev); |
553 | struct resource *res; | ||
554 | 561 | ||
555 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 562 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
563 | usb_phy_set_suspend(dwc->usb3_phy, 1); | ||
556 | 564 | ||
557 | pm_runtime_put(&pdev->dev); | 565 | pm_runtime_put(&pdev->dev); |
558 | pm_runtime_disable(&pdev->dev); | 566 | pm_runtime_disable(&pdev->dev); |
@@ -580,11 +588,22 @@ static int dwc3_remove(struct platform_device *pdev) | |||
580 | return 0; | 588 | return 0; |
581 | } | 589 | } |
582 | 590 | ||
591 | #ifdef CONFIG_OF | ||
592 | static const struct of_device_id of_dwc3_match[] = { | ||
593 | { | ||
594 | .compatible = "synopsys,dwc3" | ||
595 | }, | ||
596 | { }, | ||
597 | }; | ||
598 | MODULE_DEVICE_TABLE(of, of_dwc3_match); | ||
599 | #endif | ||
600 | |||
583 | static struct platform_driver dwc3_driver = { | 601 | static struct platform_driver dwc3_driver = { |
584 | .probe = dwc3_probe, | 602 | .probe = dwc3_probe, |
585 | .remove = dwc3_remove, | 603 | .remove = dwc3_remove, |
586 | .driver = { | 604 | .driver = { |
587 | .name = "dwc3", | 605 | .name = "dwc3", |
606 | .of_match_table = of_match_ptr(of_dwc3_match), | ||
588 | }, | 607 | }, |
589 | }; | 608 | }; |
590 | 609 | ||
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 499956344262..b41750660235 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -55,7 +55,9 @@ | |||
55 | #define DWC3_ENDPOINTS_NUM 32 | 55 | #define DWC3_ENDPOINTS_NUM 32 |
56 | #define DWC3_XHCI_RESOURCES_NUM 2 | 56 | #define DWC3_XHCI_RESOURCES_NUM 2 |
57 | 57 | ||
58 | #define DWC3_EVENT_BUFFERS_SIZE PAGE_SIZE | 58 | #define DWC3_EVENT_SIZE 4 /* bytes */ |
59 | #define DWC3_EVENT_MAX_NUM 64 /* 2 events/endpoint */ | ||
60 | #define DWC3_EVENT_BUFFERS_SIZE (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM) | ||
59 | #define DWC3_EVENT_TYPE_MASK 0xfe | 61 | #define DWC3_EVENT_TYPE_MASK 0xfe |
60 | 62 | ||
61 | #define DWC3_EVENT_TYPE_DEV 0 | 63 | #define DWC3_EVENT_TYPE_DEV 0 |
@@ -405,7 +407,6 @@ struct dwc3_event_buffer { | |||
405 | * @number: endpoint number (1 - 15) | 407 | * @number: endpoint number (1 - 15) |
406 | * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK | 408 | * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK |
407 | * @resource_index: Resource transfer index | 409 | * @resource_index: Resource transfer index |
408 | * @current_uf: Current uf received through last event parameter | ||
409 | * @interval: the intervall on which the ISOC transfer is started | 410 | * @interval: the intervall on which the ISOC transfer is started |
410 | * @name: a human readable name e.g. ep1out-bulk | 411 | * @name: a human readable name e.g. ep1out-bulk |
411 | * @direction: true for TX, false for RX | 412 | * @direction: true for TX, false for RX |
@@ -439,7 +440,6 @@ struct dwc3_ep { | |||
439 | u8 number; | 440 | u8 number; |
440 | u8 type; | 441 | u8 type; |
441 | u8 resource_index; | 442 | u8 resource_index; |
442 | u16 current_uf; | ||
443 | u32 interval; | 443 | u32 interval; |
444 | 444 | ||
445 | char name[20]; | 445 | char name[20]; |
@@ -581,6 +581,7 @@ struct dwc3_request { | |||
581 | struct usb_request request; | 581 | struct usb_request request; |
582 | struct list_head list; | 582 | struct list_head list; |
583 | struct dwc3_ep *dep; | 583 | struct dwc3_ep *dep; |
584 | u32 start_slot; | ||
584 | 585 | ||
585 | u8 epnum; | 586 | u8 epnum; |
586 | struct dwc3_trb *trb; | 587 | struct dwc3_trb *trb; |
@@ -721,6 +722,7 @@ struct dwc3 { | |||
721 | 722 | ||
722 | struct dwc3_hwparams hwparams; | 723 | struct dwc3_hwparams hwparams; |
723 | struct dentry *root; | 724 | struct dentry *root; |
725 | struct debugfs_regset32 *regset; | ||
724 | 726 | ||
725 | u8 test_mode; | 727 | u8 test_mode; |
726 | u8 test_mode_nr; | 728 | u8 test_mode_nr; |
@@ -862,10 +864,24 @@ union dwc3_event { | |||
862 | void dwc3_set_mode(struct dwc3 *dwc, u32 mode); | 864 | void dwc3_set_mode(struct dwc3 *dwc, u32 mode); |
863 | int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); | 865 | int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); |
864 | 866 | ||
867 | #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) | ||
865 | int dwc3_host_init(struct dwc3 *dwc); | 868 | int dwc3_host_init(struct dwc3 *dwc); |
866 | void dwc3_host_exit(struct dwc3 *dwc); | 869 | void dwc3_host_exit(struct dwc3 *dwc); |
867 | 870 | #else | |
871 | static inline int dwc3_host_init(struct dwc3 *dwc) | ||
872 | { return 0; } | ||
873 | static inline void dwc3_host_exit(struct dwc3 *dwc) | ||
874 | { } | ||
875 | #endif | ||
876 | |||
877 | #if IS_ENABLED(CONFIG_USB_DWC3_GADGET) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) | ||
868 | int dwc3_gadget_init(struct dwc3 *dwc); | 878 | int dwc3_gadget_init(struct dwc3 *dwc); |
869 | void dwc3_gadget_exit(struct dwc3 *dwc); | 879 | void dwc3_gadget_exit(struct dwc3 *dwc); |
880 | #else | ||
881 | static inline int dwc3_gadget_init(struct dwc3 *dwc) | ||
882 | { return 0; } | ||
883 | static inline void dwc3_gadget_exit(struct dwc3 *dwc) | ||
884 | { } | ||
885 | #endif | ||
870 | 886 | ||
871 | #endif /* __DRIVERS_USB_DWC3_CORE_H */ | 887 | #endif /* __DRIVERS_USB_DWC3_CORE_H */ |
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 5945aadaa1c9..4a752e730c5f 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c | |||
@@ -59,7 +59,7 @@ | |||
59 | .offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \ | 59 | .offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \ |
60 | } | 60 | } |
61 | 61 | ||
62 | static const struct debugfs_reg32 dwc3_regs[] = { | 62 | static struct debugfs_reg32 dwc3_regs[] = { |
63 | dump_register(GSBUSCFG0), | 63 | dump_register(GSBUSCFG0), |
64 | dump_register(GSBUSCFG1), | 64 | dump_register(GSBUSCFG1), |
65 | dump_register(GTXTHRCFG), | 65 | dump_register(GTXTHRCFG), |
@@ -376,27 +376,6 @@ static const struct debugfs_reg32 dwc3_regs[] = { | |||
376 | dump_register(OSTS), | 376 | dump_register(OSTS), |
377 | }; | 377 | }; |
378 | 378 | ||
379 | static int dwc3_regdump_show(struct seq_file *s, void *unused) | ||
380 | { | ||
381 | struct dwc3 *dwc = s->private; | ||
382 | |||
383 | seq_printf(s, "DesignWare USB3 Core Register Dump\n"); | ||
384 | debugfs_print_regs32(s, dwc3_regs, ARRAY_SIZE(dwc3_regs), | ||
385 | dwc->regs, ""); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int dwc3_regdump_open(struct inode *inode, struct file *file) | ||
390 | { | ||
391 | return single_open(file, dwc3_regdump_show, inode->i_private); | ||
392 | } | ||
393 | |||
394 | static const struct file_operations dwc3_regdump_fops = { | ||
395 | .open = dwc3_regdump_open, | ||
396 | .read = seq_read, | ||
397 | .release = single_release, | ||
398 | }; | ||
399 | |||
400 | static int dwc3_mode_show(struct seq_file *s, void *unused) | 379 | static int dwc3_mode_show(struct seq_file *s, void *unused) |
401 | { | 380 | { |
402 | struct dwc3 *dwc = s->private; | 381 | struct dwc3 *dwc = s->private; |
@@ -666,13 +645,23 @@ int dwc3_debugfs_init(struct dwc3 *dwc) | |||
666 | 645 | ||
667 | dwc->root = root; | 646 | dwc->root = root; |
668 | 647 | ||
669 | file = debugfs_create_file("regdump", S_IRUGO, root, dwc, | 648 | dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL); |
670 | &dwc3_regdump_fops); | 649 | if (!dwc->regset) { |
650 | ret = -ENOMEM; | ||
651 | goto err1; | ||
652 | } | ||
653 | |||
654 | dwc->regset->regs = dwc3_regs; | ||
655 | dwc->regset->nregs = ARRAY_SIZE(dwc3_regs); | ||
656 | dwc->regset->base = dwc->regs; | ||
657 | |||
658 | file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset); | ||
671 | if (!file) { | 659 | if (!file) { |
672 | ret = -ENOMEM; | 660 | ret = -ENOMEM; |
673 | goto err1; | 661 | goto err1; |
674 | } | 662 | } |
675 | 663 | ||
664 | #if IS_ENABLED(CONFIG_USB_DWC3_GADGET) | ||
676 | file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, | 665 | file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, |
677 | dwc, &dwc3_mode_fops); | 666 | dwc, &dwc3_mode_fops); |
678 | if (!file) { | 667 | if (!file) { |
@@ -693,6 +682,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc) | |||
693 | ret = -ENOMEM; | 682 | ret = -ENOMEM; |
694 | goto err1; | 683 | goto err1; |
695 | } | 684 | } |
685 | #endif | ||
696 | 686 | ||
697 | return 0; | 687 | return 0; |
698 | 688 | ||
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index aae5328ac771..b50da53e9a52 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c | |||
@@ -42,7 +42,7 @@ static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) | |||
42 | 42 | ||
43 | memset(&pdata, 0x00, sizeof(pdata)); | 43 | memset(&pdata, 0x00, sizeof(pdata)); |
44 | 44 | ||
45 | pdev = platform_device_alloc("nop_usb_xceiv", 0); | 45 | pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO); |
46 | if (!pdev) | 46 | if (!pdev) |
47 | return -ENOMEM; | 47 | return -ENOMEM; |
48 | 48 | ||
@@ -53,7 +53,7 @@ static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) | |||
53 | if (ret) | 53 | if (ret) |
54 | goto err1; | 54 | goto err1; |
55 | 55 | ||
56 | pdev = platform_device_alloc("nop_usb_xceiv", 1); | 56 | pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO); |
57 | if (!pdev) { | 57 | if (!pdev) { |
58 | ret = -ENOMEM; | 58 | ret = -ENOMEM; |
59 | goto err1; | 59 | goto err1; |
@@ -95,13 +95,14 @@ static int dwc3_exynos_probe(struct platform_device *pdev) | |||
95 | struct platform_device *dwc3; | 95 | struct platform_device *dwc3; |
96 | struct dwc3_exynos *exynos; | 96 | struct dwc3_exynos *exynos; |
97 | struct clk *clk; | 97 | struct clk *clk; |
98 | struct device *dev = &pdev->dev; | ||
98 | 99 | ||
99 | int ret = -ENOMEM; | 100 | int ret = -ENOMEM; |
100 | 101 | ||
101 | exynos = kzalloc(sizeof(*exynos), GFP_KERNEL); | 102 | exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL); |
102 | if (!exynos) { | 103 | if (!exynos) { |
103 | dev_err(&pdev->dev, "not enough memory\n"); | 104 | dev_err(dev, "not enough memory\n"); |
104 | goto err0; | 105 | return -ENOMEM; |
105 | } | 106 | } |
106 | 107 | ||
107 | /* | 108 | /* |
@@ -116,30 +117,30 @@ static int dwc3_exynos_probe(struct platform_device *pdev) | |||
116 | 117 | ||
117 | ret = dwc3_exynos_register_phys(exynos); | 118 | ret = dwc3_exynos_register_phys(exynos); |
118 | if (ret) { | 119 | if (ret) { |
119 | dev_err(&pdev->dev, "couldn't register PHYs\n"); | 120 | dev_err(dev, "couldn't register PHYs\n"); |
120 | goto err1; | 121 | return ret; |
121 | } | 122 | } |
122 | 123 | ||
123 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); | 124 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); |
124 | if (!dwc3) { | 125 | if (!dwc3) { |
125 | dev_err(&pdev->dev, "couldn't allocate dwc3 device\n"); | 126 | dev_err(dev, "couldn't allocate dwc3 device\n"); |
126 | goto err1; | 127 | return -ENOMEM; |
127 | } | 128 | } |
128 | 129 | ||
129 | clk = clk_get(&pdev->dev, "usbdrd30"); | 130 | clk = devm_clk_get(dev, "usbdrd30"); |
130 | if (IS_ERR(clk)) { | 131 | if (IS_ERR(clk)) { |
131 | dev_err(&pdev->dev, "couldn't get clock\n"); | 132 | dev_err(dev, "couldn't get clock\n"); |
132 | ret = -EINVAL; | 133 | ret = -EINVAL; |
133 | goto err3; | 134 | goto err1; |
134 | } | 135 | } |
135 | 136 | ||
136 | dma_set_coherent_mask(&dwc3->dev, pdev->dev.coherent_dma_mask); | 137 | dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); |
137 | 138 | ||
138 | dwc3->dev.parent = &pdev->dev; | 139 | dwc3->dev.parent = dev; |
139 | dwc3->dev.dma_mask = pdev->dev.dma_mask; | 140 | dwc3->dev.dma_mask = dev->dma_mask; |
140 | dwc3->dev.dma_parms = pdev->dev.dma_parms; | 141 | dwc3->dev.dma_parms = dev->dma_parms; |
141 | exynos->dwc3 = dwc3; | 142 | exynos->dwc3 = dwc3; |
142 | exynos->dev = &pdev->dev; | 143 | exynos->dev = dev; |
143 | exynos->clk = clk; | 144 | exynos->clk = clk; |
144 | 145 | ||
145 | clk_enable(exynos->clk); | 146 | clk_enable(exynos->clk); |
@@ -147,26 +148,23 @@ static int dwc3_exynos_probe(struct platform_device *pdev) | |||
147 | ret = platform_device_add_resources(dwc3, pdev->resource, | 148 | ret = platform_device_add_resources(dwc3, pdev->resource, |
148 | pdev->num_resources); | 149 | pdev->num_resources); |
149 | if (ret) { | 150 | if (ret) { |
150 | dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n"); | 151 | dev_err(dev, "couldn't add resources to dwc3 device\n"); |
151 | goto err4; | 152 | goto err2; |
152 | } | 153 | } |
153 | 154 | ||
154 | ret = platform_device_add(dwc3); | 155 | ret = platform_device_add(dwc3); |
155 | if (ret) { | 156 | if (ret) { |
156 | dev_err(&pdev->dev, "failed to register dwc3 device\n"); | 157 | dev_err(dev, "failed to register dwc3 device\n"); |
157 | goto err4; | 158 | goto err2; |
158 | } | 159 | } |
159 | 160 | ||
160 | return 0; | 161 | return 0; |
161 | 162 | ||
162 | err4: | 163 | err2: |
163 | clk_disable(clk); | 164 | clk_disable(clk); |
164 | clk_put(clk); | ||
165 | err3: | ||
166 | platform_device_put(dwc3); | ||
167 | err1: | 165 | err1: |
168 | kfree(exynos); | 166 | platform_device_put(dwc3); |
169 | err0: | 167 | |
170 | return ret; | 168 | return ret; |
171 | } | 169 | } |
172 | 170 | ||
@@ -179,16 +177,13 @@ static int dwc3_exynos_remove(struct platform_device *pdev) | |||
179 | platform_device_unregister(exynos->usb3_phy); | 177 | platform_device_unregister(exynos->usb3_phy); |
180 | 178 | ||
181 | clk_disable(exynos->clk); | 179 | clk_disable(exynos->clk); |
182 | clk_put(exynos->clk); | ||
183 | |||
184 | kfree(exynos); | ||
185 | 180 | ||
186 | return 0; | 181 | return 0; |
187 | } | 182 | } |
188 | 183 | ||
189 | #ifdef CONFIG_OF | 184 | #ifdef CONFIG_OF |
190 | static const struct of_device_id exynos_dwc3_match[] = { | 185 | static const struct of_device_id exynos_dwc3_match[] = { |
191 | { .compatible = "samsung,exynos-dwc3" }, | 186 | { .compatible = "samsung,exynos5250-dwusb3" }, |
192 | {}, | 187 | {}, |
193 | }; | 188 | }; |
194 | MODULE_DEVICE_TABLE(of, exynos_dwc3_match); | 189 | MODULE_DEVICE_TABLE(of, exynos_dwc3_match); |
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index f31867fd2574..22f337f57219 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
@@ -43,10 +43,13 @@ | |||
43 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
44 | #include <linux/platform_device.h> | 44 | #include <linux/platform_device.h> |
45 | #include <linux/platform_data/dwc3-omap.h> | 45 | #include <linux/platform_data/dwc3-omap.h> |
46 | #include <linux/usb/dwc3-omap.h> | ||
47 | #include <linux/pm_runtime.h> | ||
46 | #include <linux/dma-mapping.h> | 48 | #include <linux/dma-mapping.h> |
47 | #include <linux/ioport.h> | 49 | #include <linux/ioport.h> |
48 | #include <linux/io.h> | 50 | #include <linux/io.h> |
49 | #include <linux/of.h> | 51 | #include <linux/of.h> |
52 | #include <linux/of_platform.h> | ||
50 | 53 | ||
51 | #include <linux/usb/otg.h> | 54 | #include <linux/usb/otg.h> |
52 | #include <linux/usb/nop-usb-xceiv.h> | 55 | #include <linux/usb/nop-usb-xceiv.h> |
@@ -78,23 +81,6 @@ | |||
78 | 81 | ||
79 | /* SYSCONFIG REGISTER */ | 82 | /* SYSCONFIG REGISTER */ |
80 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) | 83 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) |
81 | #define USBOTGSS_SYSCONFIG_STANDBYMODE(x) ((x) << 4) | ||
82 | |||
83 | #define USBOTGSS_STANDBYMODE_FORCE_STANDBY 0 | ||
84 | #define USBOTGSS_STANDBYMODE_NO_STANDBY 1 | ||
85 | #define USBOTGSS_STANDBYMODE_SMART_STANDBY 2 | ||
86 | #define USBOTGSS_STANDBYMODE_SMART_WAKEUP 3 | ||
87 | |||
88 | #define USBOTGSS_STANDBYMODE_MASK (0x03 << 4) | ||
89 | |||
90 | #define USBOTGSS_SYSCONFIG_IDLEMODE(x) ((x) << 2) | ||
91 | |||
92 | #define USBOTGSS_IDLEMODE_FORCE_IDLE 0 | ||
93 | #define USBOTGSS_IDLEMODE_NO_IDLE 1 | ||
94 | #define USBOTGSS_IDLEMODE_SMART_IDLE 2 | ||
95 | #define USBOTGSS_IDLEMODE_SMART_WAKEUP 3 | ||
96 | |||
97 | #define USBOTGSS_IDLEMODE_MASK (0x03 << 2) | ||
98 | 84 | ||
99 | /* IRQ_EOI REGISTER */ | 85 | /* IRQ_EOI REGISTER */ |
100 | #define USBOTGSS_IRQ_EOI_LINE_NUMBER (1 << 0) | 86 | #define USBOTGSS_IRQ_EOI_LINE_NUMBER (1 << 0) |
@@ -133,7 +119,6 @@ struct dwc3_omap { | |||
133 | /* device lock */ | 119 | /* device lock */ |
134 | spinlock_t lock; | 120 | spinlock_t lock; |
135 | 121 | ||
136 | struct platform_device *dwc3; | ||
137 | struct platform_device *usb2_phy; | 122 | struct platform_device *usb2_phy; |
138 | struct platform_device *usb3_phy; | 123 | struct platform_device *usb3_phy; |
139 | struct device *dev; | 124 | struct device *dev; |
@@ -147,6 +132,8 @@ struct dwc3_omap { | |||
147 | u32 dma_status:1; | 132 | u32 dma_status:1; |
148 | }; | 133 | }; |
149 | 134 | ||
135 | struct dwc3_omap *_omap; | ||
136 | |||
150 | static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) | 137 | static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) |
151 | { | 138 | { |
152 | return readl(base + offset); | 139 | return readl(base + offset); |
@@ -157,6 +144,57 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value) | |||
157 | writel(value, base + offset); | 144 | writel(value, base + offset); |
158 | } | 145 | } |
159 | 146 | ||
147 | void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) | ||
148 | { | ||
149 | u32 val; | ||
150 | struct dwc3_omap *omap = _omap; | ||
151 | |||
152 | switch (status) { | ||
153 | case OMAP_DWC3_ID_GROUND: | ||
154 | dev_dbg(omap->dev, "ID GND\n"); | ||
155 | |||
156 | val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | ||
157 | val &= ~(USBOTGSS_UTMI_OTG_STATUS_IDDIG | ||
158 | | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID | ||
159 | | USBOTGSS_UTMI_OTG_STATUS_SESSEND); | ||
160 | val |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID | ||
161 | | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; | ||
162 | dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val); | ||
163 | break; | ||
164 | |||
165 | case OMAP_DWC3_VBUS_VALID: | ||
166 | dev_dbg(omap->dev, "VBUS Connect\n"); | ||
167 | |||
168 | val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | ||
169 | val &= ~USBOTGSS_UTMI_OTG_STATUS_SESSEND; | ||
170 | val |= USBOTGSS_UTMI_OTG_STATUS_IDDIG | ||
171 | | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID | ||
172 | | USBOTGSS_UTMI_OTG_STATUS_SESSVALID | ||
173 | | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; | ||
174 | dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val); | ||
175 | break; | ||
176 | |||
177 | case OMAP_DWC3_ID_FLOAT: | ||
178 | case OMAP_DWC3_VBUS_OFF: | ||
179 | dev_dbg(omap->dev, "VBUS Disconnect\n"); | ||
180 | |||
181 | val = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | ||
182 | val &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSVALID | ||
183 | | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID | ||
184 | | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT); | ||
185 | val |= USBOTGSS_UTMI_OTG_STATUS_SESSEND | ||
186 | | USBOTGSS_UTMI_OTG_STATUS_IDDIG; | ||
187 | dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, val); | ||
188 | break; | ||
189 | |||
190 | default: | ||
191 | dev_dbg(omap->dev, "ID float\n"); | ||
192 | } | ||
193 | |||
194 | return; | ||
195 | } | ||
196 | EXPORT_SYMBOL_GPL(dwc3_omap_mailbox); | ||
197 | |||
160 | static int dwc3_omap_register_phys(struct dwc3_omap *omap) | 198 | static int dwc3_omap_register_phys(struct dwc3_omap *omap) |
161 | { | 199 | { |
162 | struct nop_usb_xceiv_platform_data pdata; | 200 | struct nop_usb_xceiv_platform_data pdata; |
@@ -165,7 +203,7 @@ static int dwc3_omap_register_phys(struct dwc3_omap *omap) | |||
165 | 203 | ||
166 | memset(&pdata, 0x00, sizeof(pdata)); | 204 | memset(&pdata, 0x00, sizeof(pdata)); |
167 | 205 | ||
168 | pdev = platform_device_alloc("nop_usb_xceiv", 0); | 206 | pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO); |
169 | if (!pdev) | 207 | if (!pdev) |
170 | return -ENOMEM; | 208 | return -ENOMEM; |
171 | 209 | ||
@@ -176,7 +214,7 @@ static int dwc3_omap_register_phys(struct dwc3_omap *omap) | |||
176 | if (ret) | 214 | if (ret) |
177 | goto err1; | 215 | goto err1; |
178 | 216 | ||
179 | pdev = platform_device_alloc("nop_usb_xceiv", 1); | 217 | pdev = platform_device_alloc("nop_usb_xceiv", PLATFORM_DEVID_AUTO); |
180 | if (!pdev) { | 218 | if (!pdev) { |
181 | ret = -ENOMEM; | 219 | ret = -ENOMEM; |
182 | goto err1; | 220 | goto err1; |
@@ -262,12 +300,20 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) | |||
262 | return IRQ_HANDLED; | 300 | return IRQ_HANDLED; |
263 | } | 301 | } |
264 | 302 | ||
303 | static int dwc3_omap_remove_core(struct device *dev, void *c) | ||
304 | { | ||
305 | struct platform_device *pdev = to_platform_device(dev); | ||
306 | |||
307 | platform_device_unregister(pdev); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
265 | static int dwc3_omap_probe(struct platform_device *pdev) | 312 | static int dwc3_omap_probe(struct platform_device *pdev) |
266 | { | 313 | { |
267 | struct dwc3_omap_data *pdata = pdev->dev.platform_data; | 314 | struct dwc3_omap_data *pdata = pdev->dev.platform_data; |
268 | struct device_node *node = pdev->dev.of_node; | 315 | struct device_node *node = pdev->dev.of_node; |
269 | 316 | ||
270 | struct platform_device *dwc3; | ||
271 | struct dwc3_omap *omap; | 317 | struct dwc3_omap *omap; |
272 | struct resource *res; | 318 | struct resource *res; |
273 | struct device *dev = &pdev->dev; | 319 | struct device *dev = &pdev->dev; |
@@ -314,30 +360,32 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
314 | return ret; | 360 | return ret; |
315 | } | 361 | } |
316 | 362 | ||
317 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); | ||
318 | if (!dwc3) { | ||
319 | dev_err(dev, "couldn't allocate dwc3 device\n"); | ||
320 | return -ENOMEM; | ||
321 | } | ||
322 | |||
323 | context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL); | 363 | context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL); |
324 | if (!context) { | 364 | if (!context) { |
325 | dev_err(dev, "couldn't allocate dwc3 context memory\n"); | 365 | dev_err(dev, "couldn't allocate dwc3 context memory\n"); |
326 | goto err2; | 366 | return -ENOMEM; |
327 | } | 367 | } |
328 | 368 | ||
329 | spin_lock_init(&omap->lock); | 369 | spin_lock_init(&omap->lock); |
330 | dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); | ||
331 | 370 | ||
332 | dwc3->dev.parent = dev; | ||
333 | dwc3->dev.dma_mask = dev->dma_mask; | ||
334 | dwc3->dev.dma_parms = dev->dma_parms; | ||
335 | omap->resource_size = resource_size(res); | 371 | omap->resource_size = resource_size(res); |
336 | omap->context = context; | 372 | omap->context = context; |
337 | omap->dev = dev; | 373 | omap->dev = dev; |
338 | omap->irq = irq; | 374 | omap->irq = irq; |
339 | omap->base = base; | 375 | omap->base = base; |
340 | omap->dwc3 = dwc3; | 376 | |
377 | /* | ||
378 | * REVISIT if we ever have two instances of the wrapper, we will be | ||
379 | * in big trouble | ||
380 | */ | ||
381 | _omap = omap; | ||
382 | |||
383 | pm_runtime_enable(dev); | ||
384 | ret = pm_runtime_get_sync(dev); | ||
385 | if (ret < 0) { | ||
386 | dev_err(dev, "get_sync failed with err %d\n", ret); | ||
387 | return ret; | ||
388 | } | ||
341 | 389 | ||
342 | reg = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); | 390 | reg = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); |
343 | 391 | ||
@@ -368,21 +416,12 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
368 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); | 416 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); |
369 | omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE); | 417 | omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE); |
370 | 418 | ||
371 | /* Set No-Idle and No-Standby */ | ||
372 | reg &= ~(USBOTGSS_STANDBYMODE_MASK | ||
373 | | USBOTGSS_IDLEMODE_MASK); | ||
374 | |||
375 | reg |= (USBOTGSS_SYSCONFIG_STANDBYMODE(USBOTGSS_STANDBYMODE_NO_STANDBY) | ||
376 | | USBOTGSS_SYSCONFIG_IDLEMODE(USBOTGSS_IDLEMODE_NO_IDLE)); | ||
377 | |||
378 | dwc3_omap_writel(omap->base, USBOTGSS_SYSCONFIG, reg); | ||
379 | |||
380 | ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0, | 419 | ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0, |
381 | "dwc3-omap", omap); | 420 | "dwc3-omap", omap); |
382 | if (ret) { | 421 | if (ret) { |
383 | dev_err(dev, "failed to request IRQ #%d --> %d\n", | 422 | dev_err(dev, "failed to request IRQ #%d --> %d\n", |
384 | omap->irq, ret); | 423 | omap->irq, ret); |
385 | goto err2; | 424 | return ret; |
386 | } | 425 | } |
387 | 426 | ||
388 | /* enable all IRQs */ | 427 | /* enable all IRQs */ |
@@ -401,33 +440,28 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
401 | 440 | ||
402 | dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); | 441 | dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); |
403 | 442 | ||
404 | ret = platform_device_add_resources(dwc3, pdev->resource, | 443 | if (node) { |
405 | pdev->num_resources); | 444 | ret = of_platform_populate(node, NULL, NULL, dev); |
406 | if (ret) { | 445 | if (ret) { |
407 | dev_err(dev, "couldn't add resources to dwc3 device\n"); | 446 | dev_err(&pdev->dev, |
408 | goto err2; | 447 | "failed to add create dwc3 core\n"); |
409 | } | 448 | return ret; |
410 | 449 | } | |
411 | ret = platform_device_add(dwc3); | ||
412 | if (ret) { | ||
413 | dev_err(dev, "failed to register dwc3 device\n"); | ||
414 | goto err2; | ||
415 | } | 450 | } |
416 | 451 | ||
417 | return 0; | 452 | return 0; |
418 | |||
419 | err2: | ||
420 | platform_device_put(dwc3); | ||
421 | return ret; | ||
422 | } | 453 | } |
423 | 454 | ||
424 | static int dwc3_omap_remove(struct platform_device *pdev) | 455 | static int dwc3_omap_remove(struct platform_device *pdev) |
425 | { | 456 | { |
426 | struct dwc3_omap *omap = platform_get_drvdata(pdev); | 457 | struct dwc3_omap *omap = platform_get_drvdata(pdev); |
427 | 458 | ||
428 | platform_device_unregister(omap->dwc3); | ||
429 | platform_device_unregister(omap->usb2_phy); | 459 | platform_device_unregister(omap->usb2_phy); |
430 | platform_device_unregister(omap->usb3_phy); | 460 | platform_device_unregister(omap->usb3_phy); |
461 | pm_runtime_put_sync(&pdev->dev); | ||
462 | pm_runtime_disable(&pdev->dev); | ||
463 | device_for_each_child(&pdev->dev, NULL, dwc3_omap_remove_core); | ||
464 | |||
431 | return 0; | 465 | return 0; |
432 | } | 466 | } |
433 | 467 | ||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2fdd767f8fe8..a04342f6cbfa 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -241,21 +241,23 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
241 | int status) | 241 | int status) |
242 | { | 242 | { |
243 | struct dwc3 *dwc = dep->dwc; | 243 | struct dwc3 *dwc = dep->dwc; |
244 | int i; | ||
244 | 245 | ||
245 | if (req->queued) { | 246 | if (req->queued) { |
246 | if (req->request.num_mapped_sgs) | 247 | i = 0; |
247 | dep->busy_slot += req->request.num_mapped_sgs; | 248 | do { |
248 | else | ||
249 | dep->busy_slot++; | 249 | dep->busy_slot++; |
250 | 250 | /* | |
251 | /* | 251 | * Skip LINK TRB. We can't use req->trb and check for |
252 | * Skip LINK TRB. We can't use req->trb and check for | 252 | * DWC3_TRBCTL_LINK_TRB because it points the TRB we |
253 | * DWC3_TRBCTL_LINK_TRB because it points the TRB we just | 253 | * just completed (not the LINK TRB). |
254 | * completed (not the LINK TRB). | 254 | */ |
255 | */ | 255 | if (((dep->busy_slot & DWC3_TRB_MASK) == |
256 | if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && | 256 | DWC3_TRB_NUM- 1) && |
257 | usb_endpoint_xfer_isoc(dep->endpoint.desc)) | 257 | usb_endpoint_xfer_isoc(dep->endpoint.desc)) |
258 | dep->busy_slot++; | 258 | dep->busy_slot++; |
259 | } while(++i < req->request.num_mapped_sgs); | ||
260 | req->queued = false; | ||
259 | } | 261 | } |
260 | list_del(&req->list); | 262 | list_del(&req->list); |
261 | req->trb = NULL; | 263 | req->trb = NULL; |
@@ -749,33 +751,32 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, | |||
749 | */ | 751 | */ |
750 | static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | 752 | static void dwc3_prepare_one_trb(struct dwc3_ep *dep, |
751 | struct dwc3_request *req, dma_addr_t dma, | 753 | struct dwc3_request *req, dma_addr_t dma, |
752 | unsigned length, unsigned last, unsigned chain) | 754 | unsigned length, unsigned last, unsigned chain, unsigned node) |
753 | { | 755 | { |
754 | struct dwc3 *dwc = dep->dwc; | 756 | struct dwc3 *dwc = dep->dwc; |
755 | struct dwc3_trb *trb; | 757 | struct dwc3_trb *trb; |
756 | 758 | ||
757 | unsigned int cur_slot; | ||
758 | |||
759 | dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n", | 759 | dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n", |
760 | dep->name, req, (unsigned long long) dma, | 760 | dep->name, req, (unsigned long long) dma, |
761 | length, last ? " last" : "", | 761 | length, last ? " last" : "", |
762 | chain ? " chain" : ""); | 762 | chain ? " chain" : ""); |
763 | 763 | ||
764 | trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; | ||
765 | cur_slot = dep->free_slot; | ||
766 | dep->free_slot++; | ||
767 | |||
768 | /* Skip the LINK-TRB on ISOC */ | 764 | /* Skip the LINK-TRB on ISOC */ |
769 | if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && | 765 | if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && |
770 | usb_endpoint_xfer_isoc(dep->endpoint.desc)) | 766 | usb_endpoint_xfer_isoc(dep->endpoint.desc)) |
771 | return; | 767 | dep->free_slot++; |
768 | |||
769 | trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; | ||
772 | 770 | ||
773 | if (!req->trb) { | 771 | if (!req->trb) { |
774 | dwc3_gadget_move_request_queued(req); | 772 | dwc3_gadget_move_request_queued(req); |
775 | req->trb = trb; | 773 | req->trb = trb; |
776 | req->trb_dma = dwc3_trb_dma_offset(dep, trb); | 774 | req->trb_dma = dwc3_trb_dma_offset(dep, trb); |
775 | req->start_slot = dep->free_slot & DWC3_TRB_MASK; | ||
777 | } | 776 | } |
778 | 777 | ||
778 | dep->free_slot++; | ||
779 | |||
779 | trb->size = DWC3_TRB_SIZE_LENGTH(length); | 780 | trb->size = DWC3_TRB_SIZE_LENGTH(length); |
780 | trb->bpl = lower_32_bits(dma); | 781 | trb->bpl = lower_32_bits(dma); |
781 | trb->bph = upper_32_bits(dma); | 782 | trb->bph = upper_32_bits(dma); |
@@ -786,9 +787,12 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
786 | break; | 787 | break; |
787 | 788 | ||
788 | case USB_ENDPOINT_XFER_ISOC: | 789 | case USB_ENDPOINT_XFER_ISOC: |
789 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; | 790 | if (!node) |
791 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; | ||
792 | else | ||
793 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; | ||
790 | 794 | ||
791 | if (!req->request.no_interrupt) | 795 | if (!req->request.no_interrupt && !chain) |
792 | trb->ctrl |= DWC3_TRB_CTRL_IOC; | 796 | trb->ctrl |= DWC3_TRB_CTRL_IOC; |
793 | break; | 797 | break; |
794 | 798 | ||
@@ -807,14 +811,13 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
807 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 811 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
808 | trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; | 812 | trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; |
809 | trb->ctrl |= DWC3_TRB_CTRL_CSP; | 813 | trb->ctrl |= DWC3_TRB_CTRL_CSP; |
810 | } else { | 814 | } else if (last) { |
811 | if (chain) | 815 | trb->ctrl |= DWC3_TRB_CTRL_LST; |
812 | trb->ctrl |= DWC3_TRB_CTRL_CHN; | ||
813 | |||
814 | if (last) | ||
815 | trb->ctrl |= DWC3_TRB_CTRL_LST; | ||
816 | } | 816 | } |
817 | 817 | ||
818 | if (chain) | ||
819 | trb->ctrl |= DWC3_TRB_CTRL_CHN; | ||
820 | |||
818 | if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable) | 821 | if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable) |
819 | trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id); | 822 | trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id); |
820 | 823 | ||
@@ -885,6 +888,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) | |||
885 | list_for_each_entry_safe(req, n, &dep->request_list, list) { | 888 | list_for_each_entry_safe(req, n, &dep->request_list, list) { |
886 | unsigned length; | 889 | unsigned length; |
887 | dma_addr_t dma; | 890 | dma_addr_t dma; |
891 | last_one = false; | ||
888 | 892 | ||
889 | if (req->request.num_mapped_sgs > 0) { | 893 | if (req->request.num_mapped_sgs > 0) { |
890 | struct usb_request *request = &req->request; | 894 | struct usb_request *request = &req->request; |
@@ -900,7 +904,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) | |||
900 | 904 | ||
901 | if (i == (request->num_mapped_sgs - 1) || | 905 | if (i == (request->num_mapped_sgs - 1) || |
902 | sg_is_last(s)) { | 906 | sg_is_last(s)) { |
903 | last_one = true; | 907 | if (list_is_last(&req->list, |
908 | &dep->request_list)) | ||
909 | last_one = true; | ||
904 | chain = false; | 910 | chain = false; |
905 | } | 911 | } |
906 | 912 | ||
@@ -912,7 +918,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) | |||
912 | chain = false; | 918 | chain = false; |
913 | 919 | ||
914 | dwc3_prepare_one_trb(dep, req, dma, length, | 920 | dwc3_prepare_one_trb(dep, req, dma, length, |
915 | last_one, chain); | 921 | last_one, chain, i); |
916 | 922 | ||
917 | if (last_one) | 923 | if (last_one) |
918 | break; | 924 | break; |
@@ -930,7 +936,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) | |||
930 | last_one = 1; | 936 | last_one = 1; |
931 | 937 | ||
932 | dwc3_prepare_one_trb(dep, req, dma, length, | 938 | dwc3_prepare_one_trb(dep, req, dma, length, |
933 | last_one, false); | 939 | last_one, false, 0); |
934 | 940 | ||
935 | if (last_one) | 941 | if (last_one) |
936 | break; | 942 | break; |
@@ -977,13 +983,14 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | |||
977 | } | 983 | } |
978 | 984 | ||
979 | memset(¶ms, 0, sizeof(params)); | 985 | memset(¶ms, 0, sizeof(params)); |
980 | params.param0 = upper_32_bits(req->trb_dma); | ||
981 | params.param1 = lower_32_bits(req->trb_dma); | ||
982 | 986 | ||
983 | if (start_new) | 987 | if (start_new) { |
988 | params.param0 = upper_32_bits(req->trb_dma); | ||
989 | params.param1 = lower_32_bits(req->trb_dma); | ||
984 | cmd = DWC3_DEPCMD_STARTTRANSFER; | 990 | cmd = DWC3_DEPCMD_STARTTRANSFER; |
985 | else | 991 | } else { |
986 | cmd = DWC3_DEPCMD_UPDATETRANSFER; | 992 | cmd = DWC3_DEPCMD_UPDATETRANSFER; |
993 | } | ||
987 | 994 | ||
988 | cmd |= DWC3_DEPCMD_PARAM(cmd_param); | 995 | cmd |= DWC3_DEPCMD_PARAM(cmd_param); |
989 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | 996 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); |
@@ -1082,8 +1089,6 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1082 | * | 1089 | * |
1083 | */ | 1090 | */ |
1084 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | 1091 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { |
1085 | int ret; | ||
1086 | |||
1087 | /* | 1092 | /* |
1088 | * If xfernotready is already elapsed and it is a case | 1093 | * If xfernotready is already elapsed and it is a case |
1089 | * of isoc transfer, then issue END TRANSFER, so that | 1094 | * of isoc transfer, then issue END TRANSFER, so that |
@@ -1091,7 +1096,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1091 | * notion of current microframe. | 1096 | * notion of current microframe. |
1092 | */ | 1097 | */ |
1093 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 1098 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
1094 | dwc3_stop_active_transfer(dwc, dep->number); | 1099 | if (list_empty(&dep->req_queued)) { |
1100 | dwc3_stop_active_transfer(dwc, dep->number); | ||
1101 | dep->flags = DWC3_EP_ENABLED; | ||
1102 | } | ||
1095 | return 0; | 1103 | return 0; |
1096 | } | 1104 | } |
1097 | 1105 | ||
@@ -1099,6 +1107,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1099 | if (ret && ret != -EBUSY) | 1107 | if (ret && ret != -EBUSY) |
1100 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | 1108 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", |
1101 | dep->name); | 1109 | dep->name); |
1110 | return ret; | ||
1102 | } | 1111 | } |
1103 | 1112 | ||
1104 | /* | 1113 | /* |
@@ -1115,16 +1124,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1115 | if (ret && ret != -EBUSY) | 1124 | if (ret && ret != -EBUSY) |
1116 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | 1125 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", |
1117 | dep->name); | 1126 | dep->name); |
1118 | } | 1127 | return ret; |
1119 | |||
1120 | /* | ||
1121 | * 3. Missed ISOC Handling. We need to start isoc transfer on the saved | ||
1122 | * uframe number. | ||
1123 | */ | ||
1124 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | ||
1125 | (dep->flags & DWC3_EP_MISSED_ISOC)) { | ||
1126 | __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf); | ||
1127 | dep->flags &= ~DWC3_EP_MISSED_ISOC; | ||
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | return 0; | 1130 | return 0; |
@@ -1652,76 +1652,134 @@ static void dwc3_gadget_release(struct device *dev) | |||
1652 | } | 1652 | } |
1653 | 1653 | ||
1654 | /* -------------------------------------------------------------------------- */ | 1654 | /* -------------------------------------------------------------------------- */ |
1655 | static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | 1655 | static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, |
1656 | struct dwc3_request *req, struct dwc3_trb *trb, | ||
1656 | const struct dwc3_event_depevt *event, int status) | 1657 | const struct dwc3_event_depevt *event, int status) |
1657 | { | 1658 | { |
1658 | struct dwc3_request *req; | ||
1659 | struct dwc3_trb *trb; | ||
1660 | unsigned int count; | 1659 | unsigned int count; |
1661 | unsigned int s_pkt = 0; | 1660 | unsigned int s_pkt = 0; |
1662 | unsigned int trb_status; | 1661 | unsigned int trb_status; |
1663 | 1662 | ||
1663 | if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN) | ||
1664 | /* | ||
1665 | * We continue despite the error. There is not much we | ||
1666 | * can do. If we don't clean it up we loop forever. If | ||
1667 | * we skip the TRB then it gets overwritten after a | ||
1668 | * while since we use them in a ring buffer. A BUG() | ||
1669 | * would help. Lets hope that if this occurs, someone | ||
1670 | * fixes the root cause instead of looking away :) | ||
1671 | */ | ||
1672 | dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", | ||
1673 | dep->name, trb); | ||
1674 | count = trb->size & DWC3_TRB_SIZE_MASK; | ||
1675 | |||
1676 | if (dep->direction) { | ||
1677 | if (count) { | ||
1678 | trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); | ||
1679 | if (trb_status == DWC3_TRBSTS_MISSED_ISOC) { | ||
1680 | dev_dbg(dwc->dev, "incomplete IN transfer %s\n", | ||
1681 | dep->name); | ||
1682 | /* | ||
1683 | * If missed isoc occurred and there is | ||
1684 | * no request queued then issue END | ||
1685 | * TRANSFER, so that core generates | ||
1686 | * next xfernotready and we will issue | ||
1687 | * a fresh START TRANSFER. | ||
1688 | * If there are still queued request | ||
1689 | * then wait, do not issue either END | ||
1690 | * or UPDATE TRANSFER, just attach next | ||
1691 | * request in request_list during | ||
1692 | * giveback.If any future queued request | ||
1693 | * is successfully transferred then we | ||
1694 | * will issue UPDATE TRANSFER for all | ||
1695 | * request in the request_list. | ||
1696 | */ | ||
1697 | dep->flags |= DWC3_EP_MISSED_ISOC; | ||
1698 | } else { | ||
1699 | dev_err(dwc->dev, "incomplete IN transfer %s\n", | ||
1700 | dep->name); | ||
1701 | status = -ECONNRESET; | ||
1702 | } | ||
1703 | } else { | ||
1704 | dep->flags &= ~DWC3_EP_MISSED_ISOC; | ||
1705 | } | ||
1706 | } else { | ||
1707 | if (count && (event->status & DEPEVT_STATUS_SHORT)) | ||
1708 | s_pkt = 1; | ||
1709 | } | ||
1710 | |||
1711 | /* | ||
1712 | * We assume here we will always receive the entire data block | ||
1713 | * which we should receive. Meaning, if we program RX to | ||
1714 | * receive 4K but we receive only 2K, we assume that's all we | ||
1715 | * should receive and we simply bounce the request back to the | ||
1716 | * gadget driver for further processing. | ||
1717 | */ | ||
1718 | req->request.actual += req->request.length - count; | ||
1719 | if (s_pkt) | ||
1720 | return 1; | ||
1721 | if ((event->status & DEPEVT_STATUS_LST) && | ||
1722 | (trb->ctrl & (DWC3_TRB_CTRL_LST | | ||
1723 | DWC3_TRB_CTRL_HWO))) | ||
1724 | return 1; | ||
1725 | if ((event->status & DEPEVT_STATUS_IOC) && | ||
1726 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | ||
1727 | return 1; | ||
1728 | return 0; | ||
1729 | } | ||
1730 | |||
1731 | static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | ||
1732 | const struct dwc3_event_depevt *event, int status) | ||
1733 | { | ||
1734 | struct dwc3_request *req; | ||
1735 | struct dwc3_trb *trb; | ||
1736 | unsigned int slot; | ||
1737 | unsigned int i; | ||
1738 | int ret; | ||
1739 | |||
1664 | do { | 1740 | do { |
1665 | req = next_request(&dep->req_queued); | 1741 | req = next_request(&dep->req_queued); |
1666 | if (!req) { | 1742 | if (!req) { |
1667 | WARN_ON_ONCE(1); | 1743 | WARN_ON_ONCE(1); |
1668 | return 1; | 1744 | return 1; |
1669 | } | 1745 | } |
1746 | i = 0; | ||
1747 | do { | ||
1748 | slot = req->start_slot + i; | ||
1749 | if ((slot == DWC3_TRB_NUM - 1) && | ||
1750 | usb_endpoint_xfer_isoc(dep->endpoint.desc)) | ||
1751 | slot++; | ||
1752 | slot %= DWC3_TRB_NUM; | ||
1753 | trb = &dep->trb_pool[slot]; | ||
1670 | 1754 | ||
1671 | trb = req->trb; | 1755 | ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, |
1756 | event, status); | ||
1757 | if (ret) | ||
1758 | break; | ||
1759 | }while (++i < req->request.num_mapped_sgs); | ||
1672 | 1760 | ||
1673 | if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN) | 1761 | dwc3_gadget_giveback(dep, req, status); |
1762 | |||
1763 | if (ret) | ||
1764 | break; | ||
1765 | } while (1); | ||
1766 | |||
1767 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | ||
1768 | list_empty(&dep->req_queued)) { | ||
1769 | if (list_empty(&dep->request_list)) { | ||
1674 | /* | 1770 | /* |
1675 | * We continue despite the error. There is not much we | 1771 | * If there is no entry in request list then do |
1676 | * can do. If we don't clean it up we loop forever. If | 1772 | * not issue END TRANSFER now. Just set PENDING |
1677 | * we skip the TRB then it gets overwritten after a | 1773 | * flag, so that END TRANSFER is issued when an |
1678 | * while since we use them in a ring buffer. A BUG() | 1774 | * entry is added into request list. |
1679 | * would help. Lets hope that if this occurs, someone | ||
1680 | * fixes the root cause instead of looking away :) | ||
1681 | */ | 1775 | */ |
1682 | dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", | 1776 | dep->flags = DWC3_EP_PENDING_REQUEST; |
1683 | dep->name, req->trb); | ||
1684 | count = trb->size & DWC3_TRB_SIZE_MASK; | ||
1685 | |||
1686 | if (dep->direction) { | ||
1687 | if (count) { | ||
1688 | trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); | ||
1689 | if (trb_status == DWC3_TRBSTS_MISSED_ISOC) { | ||
1690 | dev_dbg(dwc->dev, "incomplete IN transfer %s\n", | ||
1691 | dep->name); | ||
1692 | dep->current_uf = event->parameters & | ||
1693 | ~(dep->interval - 1); | ||
1694 | dep->flags |= DWC3_EP_MISSED_ISOC; | ||
1695 | } else { | ||
1696 | dev_err(dwc->dev, "incomplete IN transfer %s\n", | ||
1697 | dep->name); | ||
1698 | status = -ECONNRESET; | ||
1699 | } | ||
1700 | } | ||
1701 | } else { | 1777 | } else { |
1702 | if (count && (event->status & DEPEVT_STATUS_SHORT)) | 1778 | dwc3_stop_active_transfer(dwc, dep->number); |
1703 | s_pkt = 1; | 1779 | dep->flags = DWC3_EP_ENABLED; |
1704 | } | 1780 | } |
1705 | 1781 | return 1; | |
1706 | /* | 1782 | } |
1707 | * We assume here we will always receive the entire data block | ||
1708 | * which we should receive. Meaning, if we program RX to | ||
1709 | * receive 4K but we receive only 2K, we assume that's all we | ||
1710 | * should receive and we simply bounce the request back to the | ||
1711 | * gadget driver for further processing. | ||
1712 | */ | ||
1713 | req->request.actual += req->request.length - count; | ||
1714 | dwc3_gadget_giveback(dep, req, status); | ||
1715 | if (s_pkt) | ||
1716 | break; | ||
1717 | if ((event->status & DEPEVT_STATUS_LST) && | ||
1718 | (trb->ctrl & (DWC3_TRB_CTRL_LST | | ||
1719 | DWC3_TRB_CTRL_HWO))) | ||
1720 | break; | ||
1721 | if ((event->status & DEPEVT_STATUS_IOC) && | ||
1722 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | ||
1723 | break; | ||
1724 | } while (1); | ||
1725 | 1783 | ||
1726 | if ((event->status & DEPEVT_STATUS_IOC) && | 1784 | if ((event->status & DEPEVT_STATUS_IOC) && |
1727 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | 1785 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) |
@@ -2157,6 +2215,26 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) | |||
2157 | break; | 2215 | break; |
2158 | } | 2216 | } |
2159 | 2217 | ||
2218 | /* Enable USB2 LPM Capability */ | ||
2219 | |||
2220 | if ((dwc->revision > DWC3_REVISION_194A) | ||
2221 | && (speed != DWC3_DCFG_SUPERSPEED)) { | ||
2222 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | ||
2223 | reg |= DWC3_DCFG_LPM_CAP; | ||
2224 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | ||
2225 | |||
2226 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
2227 | reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); | ||
2228 | |||
2229 | /* | ||
2230 | * TODO: This should be configurable. For now using | ||
2231 | * maximum allowed HIRD threshold value of 0b1100 | ||
2232 | */ | ||
2233 | reg |= DWC3_DCTL_HIRD_THRES(12); | ||
2234 | |||
2235 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
2236 | } | ||
2237 | |||
2160 | /* Recent versions support automatic phy suspend and don't need this */ | 2238 | /* Recent versions support automatic phy suspend and don't need this */ |
2161 | if (dwc->revision < DWC3_REVISION_194A) { | 2239 | if (dwc->revision < DWC3_REVISION_194A) { |
2162 | /* Suspend unneeded PHY */ | 2240 | /* Suspend unneeded PHY */ |
@@ -2463,20 +2541,8 @@ int dwc3_gadget_init(struct dwc3 *dwc) | |||
2463 | DWC3_DEVTEN_DISCONNEVTEN); | 2541 | DWC3_DEVTEN_DISCONNEVTEN); |
2464 | dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); | 2542 | dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); |
2465 | 2543 | ||
2466 | /* Enable USB2 LPM and automatic phy suspend only on recent versions */ | 2544 | /* automatic phy suspend only on recent versions */ |
2467 | if (dwc->revision >= DWC3_REVISION_194A) { | 2545 | if (dwc->revision >= DWC3_REVISION_194A) { |
2468 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | ||
2469 | reg |= DWC3_DCFG_LPM_CAP; | ||
2470 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | ||
2471 | |||
2472 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
2473 | reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); | ||
2474 | |||
2475 | /* TODO: This should be configurable */ | ||
2476 | reg |= DWC3_DCTL_HIRD_THRES(28); | ||
2477 | |||
2478 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
2479 | |||
2480 | dwc3_gadget_usb2_phy_suspend(dwc, false); | 2546 | dwc3_gadget_usb2_phy_suspend(dwc, false); |
2481 | dwc3_gadget_usb3_phy_suspend(dwc, false); | 2547 | dwc3_gadget_usb3_phy_suspend(dwc, false); |
2482 | } | 2548 | } |
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index 56a62342884d..0fa1846eda4c 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c | |||
@@ -44,7 +44,7 @@ int dwc3_host_init(struct dwc3 *dwc) | |||
44 | struct platform_device *xhci; | 44 | struct platform_device *xhci; |
45 | int ret; | 45 | int ret; |
46 | 46 | ||
47 | xhci = platform_device_alloc("xhci-hcd", -1); | 47 | xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); |
48 | if (!xhci) { | 48 | if (!xhci) { |
49 | dev_err(dwc->dev, "couldn't allocate xHCI device\n"); | 49 | dev_err(dwc->dev, "couldn't allocate xHCI device\n"); |
50 | ret = -ENOMEM; | 50 | ret = -ENOMEM; |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 14625fd2cecd..c5c6fa60910d 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -281,6 +281,7 @@ config USB_S3C_HSOTG | |||
281 | config USB_IMX | 281 | config USB_IMX |
282 | tristate "Freescale i.MX1 USB Peripheral Controller" | 282 | tristate "Freescale i.MX1 USB Peripheral Controller" |
283 | depends on ARCH_MXC | 283 | depends on ARCH_MXC |
284 | depends on BROKEN | ||
284 | help | 285 | help |
285 | Freescale's i.MX1 includes an integrated full speed | 286 | Freescale's i.MX1 includes an integrated full speed |
286 | USB 1.1 device controller. | 287 | USB 1.1 device controller. |
@@ -319,6 +320,7 @@ config USB_S3C_HSUDC | |||
319 | 320 | ||
320 | config USB_MV_UDC | 321 | config USB_MV_UDC |
321 | tristate "Marvell USB2.0 Device Controller" | 322 | tristate "Marvell USB2.0 Device Controller" |
323 | depends on GENERIC_HARDIRQS | ||
322 | help | 324 | help |
323 | Marvell Socs (including PXA and MMP series) include a high speed | 325 | Marvell Socs (including PXA and MMP series) include a high speed |
324 | USB2.0 OTG controller, which can be configured as high speed or | 326 | USB2.0 OTG controller, which can be configured as high speed or |
@@ -440,7 +442,7 @@ config USB_GOKU | |||
440 | 442 | ||
441 | config USB_EG20T | 443 | config USB_EG20T |
442 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" | 444 | tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" |
443 | depends on PCI | 445 | depends on PCI && GENERIC_HARDIRQS |
444 | help | 446 | help |
445 | This is a USB device driver for EG20T PCH. | 447 | This is a USB device driver for EG20T PCH. |
446 | EG20T PCH is the platform controller hub that is used in Intel's | 448 | EG20T PCH is the platform controller hub that is used in Intel's |
@@ -500,6 +502,15 @@ config USB_LIBCOMPOSITE | |||
500 | tristate | 502 | tristate |
501 | depends on USB_GADGET | 503 | depends on USB_GADGET |
502 | 504 | ||
505 | config USB_F_ACM | ||
506 | tristate | ||
507 | |||
508 | config USB_F_SS_LB | ||
509 | tristate | ||
510 | |||
511 | config USB_U_SERIAL | ||
512 | tristate | ||
513 | |||
503 | choice | 514 | choice |
504 | tristate "USB Gadget Drivers" | 515 | tristate "USB Gadget Drivers" |
505 | default USB_ETH | 516 | default USB_ETH |
@@ -524,6 +535,7 @@ choice | |||
524 | config USB_ZERO | 535 | config USB_ZERO |
525 | tristate "Gadget Zero (DEVELOPMENT)" | 536 | tristate "Gadget Zero (DEVELOPMENT)" |
526 | select USB_LIBCOMPOSITE | 537 | select USB_LIBCOMPOSITE |
538 | select USB_F_SS_LB | ||
527 | help | 539 | help |
528 | Gadget Zero is a two-configuration device. It either sinks and | 540 | Gadget Zero is a two-configuration device. It either sinks and |
529 | sources bulk data; or it loops back a configurable number of | 541 | sources bulk data; or it loops back a configurable number of |
@@ -750,6 +762,8 @@ config USB_GADGET_TARGET | |||
750 | 762 | ||
751 | config USB_G_SERIAL | 763 | config USB_G_SERIAL |
752 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | 764 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" |
765 | select USB_U_SERIAL | ||
766 | select USB_F_ACM | ||
753 | select USB_LIBCOMPOSITE | 767 | select USB_LIBCOMPOSITE |
754 | help | 768 | help |
755 | The Serial Gadget talks to the Linux-USB generic serial driver. | 769 | The Serial Gadget talks to the Linux-USB generic serial driver. |
@@ -803,6 +817,8 @@ config USB_CDC_COMPOSITE | |||
803 | tristate "CDC Composite Device (Ethernet and ACM)" | 817 | tristate "CDC Composite Device (Ethernet and ACM)" |
804 | depends on NET | 818 | depends on NET |
805 | select USB_LIBCOMPOSITE | 819 | select USB_LIBCOMPOSITE |
820 | select USB_U_SERIAL | ||
821 | select USB_F_ACM | ||
806 | help | 822 | help |
807 | This driver provides two functions in one configuration: | 823 | This driver provides two functions in one configuration: |
808 | a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. | 824 | a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. |
@@ -818,6 +834,7 @@ config USB_G_NOKIA | |||
818 | tristate "Nokia composite gadget" | 834 | tristate "Nokia composite gadget" |
819 | depends on PHONET | 835 | depends on PHONET |
820 | select USB_LIBCOMPOSITE | 836 | select USB_LIBCOMPOSITE |
837 | select USB_U_SERIAL | ||
821 | help | 838 | help |
822 | The Nokia composite gadget provides support for acm, obex | 839 | The Nokia composite gadget provides support for acm, obex |
823 | and phonet in only one composite gadget driver. | 840 | and phonet in only one composite gadget driver. |
@@ -829,6 +846,8 @@ config USB_G_ACM_MS | |||
829 | tristate "CDC Composite Device (ACM and mass storage)" | 846 | tristate "CDC Composite Device (ACM and mass storage)" |
830 | depends on BLOCK | 847 | depends on BLOCK |
831 | select USB_LIBCOMPOSITE | 848 | select USB_LIBCOMPOSITE |
849 | select USB_U_SERIAL | ||
850 | select USB_F_ACM | ||
832 | help | 851 | help |
833 | This driver provides two functions in one configuration: | 852 | This driver provides two functions in one configuration: |
834 | a mass storage, and a CDC ACM (serial port) link. | 853 | a mass storage, and a CDC ACM (serial port) link. |
@@ -841,6 +860,8 @@ config USB_G_MULTI | |||
841 | depends on BLOCK && NET | 860 | depends on BLOCK && NET |
842 | select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS | 861 | select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS |
843 | select USB_LIBCOMPOSITE | 862 | select USB_LIBCOMPOSITE |
863 | select USB_U_SERIAL | ||
864 | select USB_F_ACM | ||
844 | help | 865 | help |
845 | The Multifunction Composite Gadget provides Ethernet (RNDIS | 866 | The Multifunction Composite Gadget provides Ethernet (RNDIS |
846 | and/or CDC Ethernet), mass storage and ACM serial link | 867 | and/or CDC Ethernet), mass storage and ACM serial link |
@@ -916,6 +937,7 @@ config USB_G_DBGP_PRINTK | |||
916 | 937 | ||
917 | config USB_G_DBGP_SERIAL | 938 | config USB_G_DBGP_SERIAL |
918 | depends on USB_G_DBGP | 939 | depends on USB_G_DBGP |
940 | select USB_U_SERIAL | ||
919 | bool "serial" | 941 | bool "serial" |
920 | help | 942 | help |
921 | Userland can interact using /dev/ttyGSxxx. | 943 | Userland can interact using /dev/ttyGSxxx. |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 8b4acfd92aa3..97a13c349cc5 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG | |||
6 | obj-$(CONFIG_USB_GADGET) += udc-core.o | 6 | obj-$(CONFIG_USB_GADGET) += udc-core.o |
7 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o | 7 | obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o |
8 | libcomposite-y := usbstring.o config.o epautoconf.o | 8 | libcomposite-y := usbstring.o config.o epautoconf.o |
9 | libcomposite-y += composite.o | 9 | libcomposite-y += composite.o functions.o |
10 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | 10 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o |
11 | obj-$(CONFIG_USB_NET2272) += net2272.o | 11 | obj-$(CONFIG_USB_NET2272) += net2272.o |
12 | obj-$(CONFIG_USB_NET2280) += net2280.o | 12 | obj-$(CONFIG_USB_NET2280) += net2280.o |
@@ -74,3 +74,9 @@ obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o | |||
74 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o | 74 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o |
75 | obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o | 75 | obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o |
76 | obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o | 76 | obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o |
77 | |||
78 | # USB Functions | ||
79 | obj-$(CONFIG_USB_F_ACM) += f_acm.o | ||
80 | f_ss_lb-y := f_loopback.o f_sourcesink.o | ||
81 | obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o | ||
82 | obj-$(CONFIG_USB_U_SERIAL) += u_serial.o | ||
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 5a7f289805ff..8f2b0e391534 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c | |||
@@ -40,9 +40,6 @@ | |||
40 | * the runtime footprint, and giving us at least some parts of what | 40 | * the runtime footprint, and giving us at least some parts of what |
41 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | 41 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. |
42 | */ | 42 | */ |
43 | |||
44 | #include "u_serial.c" | ||
45 | #include "f_acm.c" | ||
46 | #include "f_mass_storage.c" | 43 | #include "f_mass_storage.c" |
47 | 44 | ||
48 | /*-------------------------------------------------------------------------*/ | 45 | /*-------------------------------------------------------------------------*/ |
@@ -112,12 +109,15 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); | |||
112 | static struct fsg_common fsg_common; | 109 | static struct fsg_common fsg_common; |
113 | 110 | ||
114 | /*-------------------------------------------------------------------------*/ | 111 | /*-------------------------------------------------------------------------*/ |
115 | 112 | static unsigned char tty_line; | |
113 | static struct usb_function *f_acm; | ||
114 | static struct usb_function_instance *f_acm_inst; | ||
116 | /* | 115 | /* |
117 | * We _always_ have both ACM and mass storage functions. | 116 | * We _always_ have both ACM and mass storage functions. |
118 | */ | 117 | */ |
119 | static int __init acm_ms_do_config(struct usb_configuration *c) | 118 | static int __init acm_ms_do_config(struct usb_configuration *c) |
120 | { | 119 | { |
120 | struct f_serial_opts *opts; | ||
121 | int status; | 121 | int status; |
122 | 122 | ||
123 | if (gadget_is_otg(c->cdev->gadget)) { | 123 | if (gadget_is_otg(c->cdev->gadget)) { |
@@ -125,16 +125,35 @@ static int __init acm_ms_do_config(struct usb_configuration *c) | |||
125 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 125 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
126 | } | 126 | } |
127 | 127 | ||
128 | f_acm_inst = usb_get_function_instance("acm"); | ||
129 | if (IS_ERR(f_acm_inst)) | ||
130 | return PTR_ERR(f_acm_inst); | ||
131 | |||
132 | opts = container_of(f_acm_inst, struct f_serial_opts, func_inst); | ||
133 | opts->port_num = tty_line; | ||
134 | |||
135 | f_acm = usb_get_function(f_acm_inst); | ||
136 | if (IS_ERR(f_acm)) { | ||
137 | status = PTR_ERR(f_acm); | ||
138 | goto err_func; | ||
139 | } | ||
128 | 140 | ||
129 | status = acm_bind_config(c, 0); | 141 | status = usb_add_function(c, f_acm); |
130 | if (status < 0) | 142 | if (status < 0) |
131 | return status; | 143 | goto err_conf; |
132 | 144 | ||
133 | status = fsg_bind_config(c->cdev, c, &fsg_common); | 145 | status = fsg_bind_config(c->cdev, c, &fsg_common); |
134 | if (status < 0) | 146 | if (status < 0) |
135 | return status; | 147 | goto err_fsg; |
136 | 148 | ||
137 | return 0; | 149 | return 0; |
150 | err_fsg: | ||
151 | usb_remove_function(c, f_acm); | ||
152 | err_conf: | ||
153 | usb_put_function(f_acm); | ||
154 | err_func: | ||
155 | usb_put_function_instance(f_acm_inst); | ||
156 | return status; | ||
138 | } | 157 | } |
139 | 158 | ||
140 | static struct usb_configuration acm_ms_config_driver = { | 159 | static struct usb_configuration acm_ms_config_driver = { |
@@ -153,7 +172,7 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) | |||
153 | void *retp; | 172 | void *retp; |
154 | 173 | ||
155 | /* set up serial link layer */ | 174 | /* set up serial link layer */ |
156 | status = gserial_setup(cdev->gadget, 1); | 175 | status = gserial_alloc_line(&tty_line); |
157 | if (status < 0) | 176 | if (status < 0) |
158 | return status; | 177 | return status; |
159 | 178 | ||
@@ -189,14 +208,15 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) | |||
189 | fail1: | 208 | fail1: |
190 | fsg_common_put(&fsg_common); | 209 | fsg_common_put(&fsg_common); |
191 | fail0: | 210 | fail0: |
192 | gserial_cleanup(); | 211 | gserial_free_line(tty_line); |
193 | return status; | 212 | return status; |
194 | } | 213 | } |
195 | 214 | ||
196 | static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) | 215 | static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) |
197 | { | 216 | { |
198 | gserial_cleanup(); | 217 | usb_put_function(f_acm); |
199 | 218 | usb_put_function_instance(f_acm_inst); | |
219 | gserial_free_line(tty_line); | ||
200 | return 0; | 220 | return 0; |
201 | } | 221 | } |
202 | 222 | ||
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index d9f6b9372491..75973f33a4c8 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -1400,15 +1400,16 @@ static int udc_wakeup(struct usb_gadget *gadget) | |||
1400 | return 0; | 1400 | return 0; |
1401 | } | 1401 | } |
1402 | 1402 | ||
1403 | static int amd5536_start(struct usb_gadget_driver *driver, | 1403 | static int amd5536_udc_start(struct usb_gadget *g, |
1404 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1404 | struct usb_gadget_driver *driver); |
1405 | static int amd5536_stop(struct usb_gadget_driver *driver); | 1405 | static int amd5536_udc_stop(struct usb_gadget *g, |
1406 | struct usb_gadget_driver *driver); | ||
1406 | /* gadget operations */ | 1407 | /* gadget operations */ |
1407 | static const struct usb_gadget_ops udc_ops = { | 1408 | static const struct usb_gadget_ops udc_ops = { |
1408 | .wakeup = udc_wakeup, | 1409 | .wakeup = udc_wakeup, |
1409 | .get_frame = udc_get_frame, | 1410 | .get_frame = udc_get_frame, |
1410 | .start = amd5536_start, | 1411 | .udc_start = amd5536_udc_start, |
1411 | .stop = amd5536_stop, | 1412 | .udc_stop = amd5536_udc_stop, |
1412 | }; | 1413 | }; |
1413 | 1414 | ||
1414 | /* Setups endpoint parameters, adds endpoints to linked list */ | 1415 | /* Setups endpoint parameters, adds endpoints to linked list */ |
@@ -1913,41 +1914,22 @@ static int setup_ep0(struct udc *dev) | |||
1913 | } | 1914 | } |
1914 | 1915 | ||
1915 | /* Called by gadget driver to register itself */ | 1916 | /* Called by gadget driver to register itself */ |
1916 | static int amd5536_start(struct usb_gadget_driver *driver, | 1917 | static int amd5536_udc_start(struct usb_gadget *g, |
1917 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1918 | struct usb_gadget_driver *driver) |
1918 | { | 1919 | { |
1919 | struct udc *dev = udc; | 1920 | struct udc *dev = to_amd5536_udc(g); |
1920 | int retval; | ||
1921 | u32 tmp; | 1921 | u32 tmp; |
1922 | 1922 | ||
1923 | if (!driver || !bind || !driver->setup | ||
1924 | || driver->max_speed < USB_SPEED_HIGH) | ||
1925 | return -EINVAL; | ||
1926 | if (!dev) | ||
1927 | return -ENODEV; | ||
1928 | if (dev->driver) | ||
1929 | return -EBUSY; | ||
1930 | |||
1931 | driver->driver.bus = NULL; | 1923 | driver->driver.bus = NULL; |
1932 | dev->driver = driver; | 1924 | dev->driver = driver; |
1933 | dev->gadget.dev.driver = &driver->driver; | 1925 | dev->gadget.dev.driver = &driver->driver; |
1934 | 1926 | ||
1935 | retval = bind(&dev->gadget, driver); | ||
1936 | |||
1937 | /* Some gadget drivers use both ep0 directions. | 1927 | /* Some gadget drivers use both ep0 directions. |
1938 | * NOTE: to gadget driver, ep0 is just one endpoint... | 1928 | * NOTE: to gadget driver, ep0 is just one endpoint... |
1939 | */ | 1929 | */ |
1940 | dev->ep[UDC_EP0OUT_IX].ep.driver_data = | 1930 | dev->ep[UDC_EP0OUT_IX].ep.driver_data = |
1941 | dev->ep[UDC_EP0IN_IX].ep.driver_data; | 1931 | dev->ep[UDC_EP0IN_IX].ep.driver_data; |
1942 | 1932 | ||
1943 | if (retval) { | ||
1944 | DBG(dev, "binding to %s returning %d\n", | ||
1945 | driver->driver.name, retval); | ||
1946 | dev->driver = NULL; | ||
1947 | dev->gadget.dev.driver = NULL; | ||
1948 | return retval; | ||
1949 | } | ||
1950 | |||
1951 | /* get ready for ep0 traffic */ | 1933 | /* get ready for ep0 traffic */ |
1952 | setup_ep0(dev); | 1934 | setup_ep0(dev); |
1953 | 1935 | ||
@@ -1969,14 +1951,9 @@ __acquires(dev->lock) | |||
1969 | { | 1951 | { |
1970 | int tmp; | 1952 | int tmp; |
1971 | 1953 | ||
1972 | if (dev->gadget.speed != USB_SPEED_UNKNOWN) { | ||
1973 | spin_unlock(&dev->lock); | ||
1974 | driver->disconnect(&dev->gadget); | ||
1975 | spin_lock(&dev->lock); | ||
1976 | } | ||
1977 | |||
1978 | /* empty queues and init hardware */ | 1954 | /* empty queues and init hardware */ |
1979 | udc_basic_init(dev); | 1955 | udc_basic_init(dev); |
1956 | |||
1980 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) | 1957 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) |
1981 | empty_req_queue(&dev->ep[tmp]); | 1958 | empty_req_queue(&dev->ep[tmp]); |
1982 | 1959 | ||
@@ -1984,23 +1961,18 @@ __acquires(dev->lock) | |||
1984 | } | 1961 | } |
1985 | 1962 | ||
1986 | /* Called by gadget driver to unregister itself */ | 1963 | /* Called by gadget driver to unregister itself */ |
1987 | static int amd5536_stop(struct usb_gadget_driver *driver) | 1964 | static int amd5536_udc_stop(struct usb_gadget *g, |
1965 | struct usb_gadget_driver *driver) | ||
1988 | { | 1966 | { |
1989 | struct udc *dev = udc; | 1967 | struct udc *dev = to_amd5536_udc(g); |
1990 | unsigned long flags; | 1968 | unsigned long flags; |
1991 | u32 tmp; | 1969 | u32 tmp; |
1992 | 1970 | ||
1993 | if (!dev) | ||
1994 | return -ENODEV; | ||
1995 | if (!driver || driver != dev->driver || !driver->unbind) | ||
1996 | return -EINVAL; | ||
1997 | |||
1998 | spin_lock_irqsave(&dev->lock, flags); | 1971 | spin_lock_irqsave(&dev->lock, flags); |
1999 | udc_mask_unused_interrupts(dev); | 1972 | udc_mask_unused_interrupts(dev); |
2000 | shutdown(dev, driver); | 1973 | shutdown(dev, driver); |
2001 | spin_unlock_irqrestore(&dev->lock, flags); | 1974 | spin_unlock_irqrestore(&dev->lock, flags); |
2002 | 1975 | ||
2003 | driver->unbind(&dev->gadget); | ||
2004 | dev->gadget.dev.driver = NULL; | 1976 | dev->gadget.dev.driver = NULL; |
2005 | dev->driver = NULL; | 1977 | dev->driver = NULL; |
2006 | 1978 | ||
@@ -2009,9 +1981,6 @@ static int amd5536_stop(struct usb_gadget_driver *driver) | |||
2009 | tmp |= AMD_BIT(UDC_DEVCTL_SD); | 1981 | tmp |= AMD_BIT(UDC_DEVCTL_SD); |
2010 | writel(tmp, &dev->regs->ctl); | 1982 | writel(tmp, &dev->regs->ctl); |
2011 | 1983 | ||
2012 | |||
2013 | DBG(dev, "%s: unregistered\n", driver->driver.name); | ||
2014 | |||
2015 | return 0; | 1984 | return 0; |
2016 | } | 1985 | } |
2017 | 1986 | ||
diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h index 14af87d65caa..f1bf32e6b8d8 100644 --- a/drivers/usb/gadget/amd5536udc.h +++ b/drivers/usb/gadget/amd5536udc.h | |||
@@ -563,6 +563,8 @@ struct udc { | |||
563 | u16 cur_alt; | 563 | u16 cur_alt; |
564 | }; | 564 | }; |
565 | 565 | ||
566 | #define to_amd5536_udc(g) (container_of((g), struct udc, gadget)) | ||
567 | |||
566 | /* setup request data */ | 568 | /* setup request data */ |
567 | union udc_setup_data { | 569 | union udc_setup_data { |
568 | u32 data[2]; | 570 | u32 data[2]; |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 0143ffa4e409..45dd2929a671 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1621,8 +1621,7 @@ static void at91_vbus_timer(unsigned long data) | |||
1621 | * bus such as i2c or spi which may sleep, so schedule some work | 1621 | * bus such as i2c or spi which may sleep, so schedule some work |
1622 | * to read the vbus gpio | 1622 | * to read the vbus gpio |
1623 | */ | 1623 | */ |
1624 | if (!work_pending(&udc->vbus_timer_work)) | 1624 | schedule_work(&udc->vbus_timer_work); |
1625 | schedule_work(&udc->vbus_timer_work); | ||
1626 | } | 1625 | } |
1627 | 1626 | ||
1628 | static int at91_start(struct usb_gadget *gadget, | 1627 | static int at91_start(struct usb_gadget *gadget, |
@@ -1739,7 +1738,7 @@ static int at91udc_probe(struct platform_device *pdev) | |||
1739 | 1738 | ||
1740 | /* rm9200 needs manual D+ pullup; off by default */ | 1739 | /* rm9200 needs manual D+ pullup; off by default */ |
1741 | if (cpu_is_at91rm9200()) { | 1740 | if (cpu_is_at91rm9200()) { |
1742 | if (gpio_is_valid(udc->board.pullup_pin)) { | 1741 | if (!gpio_is_valid(udc->board.pullup_pin)) { |
1743 | DBG("no D+ pullup?\n"); | 1742 | DBG("no D+ pullup?\n"); |
1744 | retval = -ENODEV; | 1743 | retval = -ENODEV; |
1745 | goto fail0; | 1744 | goto fail0; |
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 1e4bb77f00bb..a7d6f7026757 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c | |||
@@ -42,9 +42,6 @@ USB_GADGET_COMPOSITE_OPTIONS(); | |||
42 | * the runtime footprint, and giving us at least some parts of what | 42 | * the runtime footprint, and giving us at least some parts of what |
43 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | 43 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. |
44 | */ | 44 | */ |
45 | |||
46 | #include "u_serial.c" | ||
47 | #include "f_acm.c" | ||
48 | #include "f_ecm.c" | 45 | #include "f_ecm.c" |
49 | #include "u_ether.c" | 46 | #include "u_ether.c" |
50 | 47 | ||
@@ -108,12 +105,16 @@ static struct usb_gadget_strings *dev_strings[] = { | |||
108 | static u8 hostaddr[ETH_ALEN]; | 105 | static u8 hostaddr[ETH_ALEN]; |
109 | 106 | ||
110 | /*-------------------------------------------------------------------------*/ | 107 | /*-------------------------------------------------------------------------*/ |
108 | static struct usb_function *f_acm; | ||
109 | static struct usb_function_instance *fi_serial; | ||
111 | 110 | ||
111 | static unsigned char tty_line; | ||
112 | /* | 112 | /* |
113 | * We _always_ have both CDC ECM and CDC ACM functions. | 113 | * We _always_ have both CDC ECM and CDC ACM functions. |
114 | */ | 114 | */ |
115 | static int __init cdc_do_config(struct usb_configuration *c) | 115 | static int __init cdc_do_config(struct usb_configuration *c) |
116 | { | 116 | { |
117 | struct f_serial_opts *opts; | ||
117 | int status; | 118 | int status; |
118 | 119 | ||
119 | if (gadget_is_otg(c->cdev->gadget)) { | 120 | if (gadget_is_otg(c->cdev->gadget)) { |
@@ -125,11 +126,26 @@ static int __init cdc_do_config(struct usb_configuration *c) | |||
125 | if (status < 0) | 126 | if (status < 0) |
126 | return status; | 127 | return status; |
127 | 128 | ||
128 | status = acm_bind_config(c, 0); | 129 | fi_serial = usb_get_function_instance("acm"); |
129 | if (status < 0) | 130 | if (IS_ERR(fi_serial)) |
130 | return status; | 131 | return PTR_ERR(fi_serial); |
131 | 132 | ||
133 | opts = container_of(fi_serial, struct f_serial_opts, func_inst); | ||
134 | opts->port_num = tty_line; | ||
135 | |||
136 | f_acm = usb_get_function(fi_serial); | ||
137 | if (IS_ERR(f_acm)) | ||
138 | goto err_func_acm; | ||
139 | |||
140 | status = usb_add_function(c, f_acm); | ||
141 | if (status) | ||
142 | goto err_conf; | ||
132 | return 0; | 143 | return 0; |
144 | err_conf: | ||
145 | usb_put_function(f_acm); | ||
146 | err_func_acm: | ||
147 | usb_put_function_instance(fi_serial); | ||
148 | return status; | ||
133 | } | 149 | } |
134 | 150 | ||
135 | static struct usb_configuration cdc_config_driver = { | 151 | static struct usb_configuration cdc_config_driver = { |
@@ -158,7 +174,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) | |||
158 | return status; | 174 | return status; |
159 | 175 | ||
160 | /* set up serial link layer */ | 176 | /* set up serial link layer */ |
161 | status = gserial_setup(cdev->gadget, 1); | 177 | status = gserial_alloc_line(&tty_line); |
162 | if (status < 0) | 178 | if (status < 0) |
163 | goto fail0; | 179 | goto fail0; |
164 | 180 | ||
@@ -184,7 +200,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) | |||
184 | return 0; | 200 | return 0; |
185 | 201 | ||
186 | fail1: | 202 | fail1: |
187 | gserial_cleanup(); | 203 | gserial_free_line(tty_line); |
188 | fail0: | 204 | fail0: |
189 | gether_cleanup(); | 205 | gether_cleanup(); |
190 | return status; | 206 | return status; |
@@ -192,7 +208,9 @@ fail0: | |||
192 | 208 | ||
193 | static int __exit cdc_unbind(struct usb_composite_dev *cdev) | 209 | static int __exit cdc_unbind(struct usb_composite_dev *cdev) |
194 | { | 210 | { |
195 | gserial_cleanup(); | 211 | usb_put_function(f_acm); |
212 | usb_put_function_instance(fi_serial); | ||
213 | gserial_free_line(tty_line); | ||
196 | gether_cleanup(); | 214 | gether_cleanup(); |
197 | return 0; | 215 | return 0; |
198 | } | 216 | } |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 2a6bfe759c29..7c821de8ce3d 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -28,6 +28,12 @@ | |||
28 | * with the relevant device-wide data. | 28 | * with the relevant device-wide data. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | static struct usb_gadget_strings **get_containers_gs( | ||
32 | struct usb_gadget_string_container *uc) | ||
33 | { | ||
34 | return (struct usb_gadget_strings **)uc->stash; | ||
35 | } | ||
36 | |||
31 | /** | 37 | /** |
32 | * next_ep_desc() - advance to the next EP descriptor | 38 | * next_ep_desc() - advance to the next EP descriptor |
33 | * @t: currect pointer within descriptor array | 39 | * @t: currect pointer within descriptor array |
@@ -215,6 +221,18 @@ done: | |||
215 | } | 221 | } |
216 | EXPORT_SYMBOL_GPL(usb_add_function); | 222 | EXPORT_SYMBOL_GPL(usb_add_function); |
217 | 223 | ||
224 | void usb_remove_function(struct usb_configuration *c, struct usb_function *f) | ||
225 | { | ||
226 | if (f->disable) | ||
227 | f->disable(f); | ||
228 | |||
229 | bitmap_zero(f->endpoints, 32); | ||
230 | list_del(&f->list); | ||
231 | if (f->unbind) | ||
232 | f->unbind(c, f); | ||
233 | } | ||
234 | EXPORT_SYMBOL_GPL(usb_remove_function); | ||
235 | |||
218 | /** | 236 | /** |
219 | * usb_function_deactivate - prevent function and gadget enumeration | 237 | * usb_function_deactivate - prevent function and gadget enumeration |
220 | * @function: the function that isn't yet ready to respond | 238 | * @function: the function that isn't yet ready to respond |
@@ -320,6 +338,25 @@ int usb_interface_id(struct usb_configuration *config, | |||
320 | } | 338 | } |
321 | EXPORT_SYMBOL_GPL(usb_interface_id); | 339 | EXPORT_SYMBOL_GPL(usb_interface_id); |
322 | 340 | ||
341 | static u8 encode_bMaxPower(enum usb_device_speed speed, | ||
342 | struct usb_configuration *c) | ||
343 | { | ||
344 | unsigned val; | ||
345 | |||
346 | if (c->MaxPower) | ||
347 | val = c->MaxPower; | ||
348 | else | ||
349 | val = CONFIG_USB_GADGET_VBUS_DRAW; | ||
350 | if (!val) | ||
351 | return 0; | ||
352 | switch (speed) { | ||
353 | case USB_SPEED_SUPER: | ||
354 | return DIV_ROUND_UP(val, 8); | ||
355 | default: | ||
356 | return DIV_ROUND_UP(val, 2); | ||
357 | }; | ||
358 | } | ||
359 | |||
323 | static int config_buf(struct usb_configuration *config, | 360 | static int config_buf(struct usb_configuration *config, |
324 | enum usb_device_speed speed, void *buf, u8 type) | 361 | enum usb_device_speed speed, void *buf, u8 type) |
325 | { | 362 | { |
@@ -339,7 +376,7 @@ static int config_buf(struct usb_configuration *config, | |||
339 | c->bConfigurationValue = config->bConfigurationValue; | 376 | c->bConfigurationValue = config->bConfigurationValue; |
340 | c->iConfiguration = config->iConfiguration; | 377 | c->iConfiguration = config->iConfiguration; |
341 | c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; | 378 | c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; |
342 | c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2); | 379 | c->bMaxPower = encode_bMaxPower(speed, config); |
343 | 380 | ||
344 | /* There may be e.g. OTG descriptors */ | 381 | /* There may be e.g. OTG descriptors */ |
345 | if (config->descriptors) { | 382 | if (config->descriptors) { |
@@ -656,7 +693,7 @@ static int set_config(struct usb_composite_dev *cdev, | |||
656 | } | 693 | } |
657 | 694 | ||
658 | /* when we return, be sure our power usage is valid */ | 695 | /* when we return, be sure our power usage is valid */ |
659 | power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; | 696 | power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; |
660 | done: | 697 | done: |
661 | usb_gadget_vbus_draw(gadget, power); | 698 | usb_gadget_vbus_draw(gadget, power); |
662 | if (result >= 0 && cdev->delayed_status) | 699 | if (result >= 0 && cdev->delayed_status) |
@@ -664,6 +701,31 @@ done: | |||
664 | return result; | 701 | return result; |
665 | } | 702 | } |
666 | 703 | ||
704 | int usb_add_config_only(struct usb_composite_dev *cdev, | ||
705 | struct usb_configuration *config) | ||
706 | { | ||
707 | struct usb_configuration *c; | ||
708 | |||
709 | if (!config->bConfigurationValue) | ||
710 | return -EINVAL; | ||
711 | |||
712 | /* Prevent duplicate configuration identifiers */ | ||
713 | list_for_each_entry(c, &cdev->configs, list) { | ||
714 | if (c->bConfigurationValue == config->bConfigurationValue) | ||
715 | return -EBUSY; | ||
716 | } | ||
717 | |||
718 | config->cdev = cdev; | ||
719 | list_add_tail(&config->list, &cdev->configs); | ||
720 | |||
721 | INIT_LIST_HEAD(&config->functions); | ||
722 | config->next_interface_id = 0; | ||
723 | memset(config->interface, 0, sizeof(config->interface)); | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | EXPORT_SYMBOL_GPL(usb_add_config_only); | ||
728 | |||
667 | /** | 729 | /** |
668 | * usb_add_config() - add a configuration to a device. | 730 | * usb_add_config() - add a configuration to a device. |
669 | * @cdev: wraps the USB gadget | 731 | * @cdev: wraps the USB gadget |
@@ -684,30 +746,18 @@ int usb_add_config(struct usb_composite_dev *cdev, | |||
684 | int (*bind)(struct usb_configuration *)) | 746 | int (*bind)(struct usb_configuration *)) |
685 | { | 747 | { |
686 | int status = -EINVAL; | 748 | int status = -EINVAL; |
687 | struct usb_configuration *c; | 749 | |
750 | if (!bind) | ||
751 | goto done; | ||
688 | 752 | ||
689 | DBG(cdev, "adding config #%u '%s'/%p\n", | 753 | DBG(cdev, "adding config #%u '%s'/%p\n", |
690 | config->bConfigurationValue, | 754 | config->bConfigurationValue, |
691 | config->label, config); | 755 | config->label, config); |
692 | 756 | ||
693 | if (!config->bConfigurationValue || !bind) | 757 | status = usb_add_config_only(cdev, config); |
758 | if (status) | ||
694 | goto done; | 759 | goto done; |
695 | 760 | ||
696 | /* Prevent duplicate configuration identifiers */ | ||
697 | list_for_each_entry(c, &cdev->configs, list) { | ||
698 | if (c->bConfigurationValue == config->bConfigurationValue) { | ||
699 | status = -EBUSY; | ||
700 | goto done; | ||
701 | } | ||
702 | } | ||
703 | |||
704 | config->cdev = cdev; | ||
705 | list_add_tail(&config->list, &cdev->configs); | ||
706 | |||
707 | INIT_LIST_HEAD(&config->functions); | ||
708 | config->next_interface_id = 0; | ||
709 | memset(config->interface, 0, sizeof(config->interface)); | ||
710 | |||
711 | status = bind(config); | 761 | status = bind(config); |
712 | if (status < 0) { | 762 | if (status < 0) { |
713 | while (!list_empty(&config->functions)) { | 763 | while (!list_empty(&config->functions)) { |
@@ -860,6 +910,7 @@ static int get_string(struct usb_composite_dev *cdev, | |||
860 | void *buf, u16 language, int id) | 910 | void *buf, u16 language, int id) |
861 | { | 911 | { |
862 | struct usb_composite_driver *composite = cdev->driver; | 912 | struct usb_composite_driver *composite = cdev->driver; |
913 | struct usb_gadget_string_container *uc; | ||
863 | struct usb_configuration *c; | 914 | struct usb_configuration *c; |
864 | struct usb_function *f; | 915 | struct usb_function *f; |
865 | int len; | 916 | int len; |
@@ -892,6 +943,12 @@ static int get_string(struct usb_composite_dev *cdev, | |||
892 | collect_langs(sp, s->wData); | 943 | collect_langs(sp, s->wData); |
893 | } | 944 | } |
894 | } | 945 | } |
946 | list_for_each_entry(uc, &cdev->gstrings, list) { | ||
947 | struct usb_gadget_strings **sp; | ||
948 | |||
949 | sp = get_containers_gs(uc); | ||
950 | collect_langs(sp, s->wData); | ||
951 | } | ||
895 | 952 | ||
896 | for (len = 0; len <= 126 && s->wData[len]; len++) | 953 | for (len = 0; len <= 126 && s->wData[len]; len++) |
897 | continue; | 954 | continue; |
@@ -902,6 +959,15 @@ static int get_string(struct usb_composite_dev *cdev, | |||
902 | return s->bLength; | 959 | return s->bLength; |
903 | } | 960 | } |
904 | 961 | ||
962 | list_for_each_entry(uc, &cdev->gstrings, list) { | ||
963 | struct usb_gadget_strings **sp; | ||
964 | |||
965 | sp = get_containers_gs(uc); | ||
966 | len = lookup_string(sp, buf, language, id); | ||
967 | if (len > 0) | ||
968 | return len; | ||
969 | } | ||
970 | |||
905 | /* String IDs are device-scoped, so we look up each string | 971 | /* String IDs are device-scoped, so we look up each string |
906 | * table we're told about. These lookups are infrequent; | 972 | * table we're told about. These lookups are infrequent; |
907 | * simpler-is-better here. | 973 | * simpler-is-better here. |
@@ -987,6 +1053,119 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str) | |||
987 | } | 1053 | } |
988 | EXPORT_SYMBOL_GPL(usb_string_ids_tab); | 1054 | EXPORT_SYMBOL_GPL(usb_string_ids_tab); |
989 | 1055 | ||
1056 | static struct usb_gadget_string_container *copy_gadget_strings( | ||
1057 | struct usb_gadget_strings **sp, unsigned n_gstrings, | ||
1058 | unsigned n_strings) | ||
1059 | { | ||
1060 | struct usb_gadget_string_container *uc; | ||
1061 | struct usb_gadget_strings **gs_array; | ||
1062 | struct usb_gadget_strings *gs; | ||
1063 | struct usb_string *s; | ||
1064 | unsigned mem; | ||
1065 | unsigned n_gs; | ||
1066 | unsigned n_s; | ||
1067 | void *stash; | ||
1068 | |||
1069 | mem = sizeof(*uc); | ||
1070 | mem += sizeof(void *) * (n_gstrings + 1); | ||
1071 | mem += sizeof(struct usb_gadget_strings) * n_gstrings; | ||
1072 | mem += sizeof(struct usb_string) * (n_strings + 1) * (n_gstrings); | ||
1073 | uc = kmalloc(mem, GFP_KERNEL); | ||
1074 | if (!uc) | ||
1075 | return ERR_PTR(-ENOMEM); | ||
1076 | gs_array = get_containers_gs(uc); | ||
1077 | stash = uc->stash; | ||
1078 | stash += sizeof(void *) * (n_gstrings + 1); | ||
1079 | for (n_gs = 0; n_gs < n_gstrings; n_gs++) { | ||
1080 | struct usb_string *org_s; | ||
1081 | |||
1082 | gs_array[n_gs] = stash; | ||
1083 | gs = gs_array[n_gs]; | ||
1084 | stash += sizeof(struct usb_gadget_strings); | ||
1085 | gs->language = sp[n_gs]->language; | ||
1086 | gs->strings = stash; | ||
1087 | org_s = sp[n_gs]->strings; | ||
1088 | |||
1089 | for (n_s = 0; n_s < n_strings; n_s++) { | ||
1090 | s = stash; | ||
1091 | stash += sizeof(struct usb_string); | ||
1092 | if (org_s->s) | ||
1093 | s->s = org_s->s; | ||
1094 | else | ||
1095 | s->s = ""; | ||
1096 | org_s++; | ||
1097 | } | ||
1098 | s = stash; | ||
1099 | s->s = NULL; | ||
1100 | stash += sizeof(struct usb_string); | ||
1101 | |||
1102 | } | ||
1103 | gs_array[n_gs] = NULL; | ||
1104 | return uc; | ||
1105 | } | ||
1106 | |||
1107 | /** | ||
1108 | * usb_gstrings_attach() - attach gadget strings to a cdev and assign ids | ||
1109 | * @cdev: the device whose string descriptor IDs are being allocated | ||
1110 | * and attached. | ||
1111 | * @sp: an array of usb_gadget_strings to attach. | ||
1112 | * @n_strings: number of entries in each usb_strings array (sp[]->strings) | ||
1113 | * | ||
1114 | * This function will create a deep copy of usb_gadget_strings and usb_string | ||
1115 | * and attach it to the cdev. The actual string (usb_string.s) will not be | ||
1116 | * copied but only a referenced will be made. The struct usb_gadget_strings | ||
1117 | * array may contain multiple languges and should be NULL terminated. | ||
1118 | * The ->language pointer of each struct usb_gadget_strings has to contain the | ||
1119 | * same amount of entries. | ||
1120 | * For instance: sp[0] is en-US, sp[1] is es-ES. It is expected that the first | ||
1121 | * usb_string entry of es-ES containts the translation of the first usb_string | ||
1122 | * entry of en-US. Therefore both entries become the same id assign. | ||
1123 | */ | ||
1124 | struct usb_string *usb_gstrings_attach(struct usb_composite_dev *cdev, | ||
1125 | struct usb_gadget_strings **sp, unsigned n_strings) | ||
1126 | { | ||
1127 | struct usb_gadget_string_container *uc; | ||
1128 | struct usb_gadget_strings **n_gs; | ||
1129 | unsigned n_gstrings = 0; | ||
1130 | unsigned i; | ||
1131 | int ret; | ||
1132 | |||
1133 | for (i = 0; sp[i]; i++) | ||
1134 | n_gstrings++; | ||
1135 | |||
1136 | if (!n_gstrings) | ||
1137 | return ERR_PTR(-EINVAL); | ||
1138 | |||
1139 | uc = copy_gadget_strings(sp, n_gstrings, n_strings); | ||
1140 | if (IS_ERR(uc)) | ||
1141 | return ERR_PTR(PTR_ERR(uc)); | ||
1142 | |||
1143 | n_gs = get_containers_gs(uc); | ||
1144 | ret = usb_string_ids_tab(cdev, n_gs[0]->strings); | ||
1145 | if (ret) | ||
1146 | goto err; | ||
1147 | |||
1148 | for (i = 1; i < n_gstrings; i++) { | ||
1149 | struct usb_string *m_s; | ||
1150 | struct usb_string *s; | ||
1151 | unsigned n; | ||
1152 | |||
1153 | m_s = n_gs[0]->strings; | ||
1154 | s = n_gs[i]->strings; | ||
1155 | for (n = 0; n < n_strings; n++) { | ||
1156 | s->id = m_s->id; | ||
1157 | s++; | ||
1158 | m_s++; | ||
1159 | } | ||
1160 | } | ||
1161 | list_add_tail(&uc->list, &cdev->gstrings); | ||
1162 | return n_gs[0]->strings; | ||
1163 | err: | ||
1164 | kfree(uc); | ||
1165 | return ERR_PTR(ret); | ||
1166 | } | ||
1167 | EXPORT_SYMBOL_GPL(usb_gstrings_attach); | ||
1168 | |||
990 | /** | 1169 | /** |
991 | * usb_string_ids_n() - allocate unused string IDs in batch | 1170 | * usb_string_ids_n() - allocate unused string IDs in batch |
992 | * @c: the device whose string descriptor IDs are being allocated | 1171 | * @c: the device whose string descriptor IDs are being allocated |
@@ -1033,7 +1212,7 @@ static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) | |||
1033 | * housekeeping for the gadget function we're implementing. Most of | 1212 | * housekeeping for the gadget function we're implementing. Most of |
1034 | * the work is in config and function specific setup. | 1213 | * the work is in config and function specific setup. |
1035 | */ | 1214 | */ |
1036 | static int | 1215 | int |
1037 | composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | 1216 | composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) |
1038 | { | 1217 | { |
1039 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1218 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
@@ -1300,7 +1479,7 @@ done: | |||
1300 | return value; | 1479 | return value; |
1301 | } | 1480 | } |
1302 | 1481 | ||
1303 | static void composite_disconnect(struct usb_gadget *gadget) | 1482 | void composite_disconnect(struct usb_gadget *gadget) |
1304 | { | 1483 | { |
1305 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1484 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
1306 | unsigned long flags; | 1485 | unsigned long flags; |
@@ -1330,8 +1509,7 @@ static ssize_t composite_show_suspended(struct device *dev, | |||
1330 | 1509 | ||
1331 | static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL); | 1510 | static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL); |
1332 | 1511 | ||
1333 | static void | 1512 | static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) |
1334 | composite_unbind(struct usb_gadget *gadget) | ||
1335 | { | 1513 | { |
1336 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1514 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
1337 | 1515 | ||
@@ -1348,19 +1526,21 @@ composite_unbind(struct usb_gadget *gadget) | |||
1348 | struct usb_configuration, list); | 1526 | struct usb_configuration, list); |
1349 | remove_config(cdev, c); | 1527 | remove_config(cdev, c); |
1350 | } | 1528 | } |
1351 | if (cdev->driver->unbind) | 1529 | if (cdev->driver->unbind && unbind_driver) |
1352 | cdev->driver->unbind(cdev); | 1530 | cdev->driver->unbind(cdev); |
1353 | 1531 | ||
1354 | if (cdev->req) { | 1532 | composite_dev_cleanup(cdev); |
1355 | kfree(cdev->req->buf); | 1533 | |
1356 | usb_ep_free_request(gadget->ep0, cdev->req); | ||
1357 | } | ||
1358 | device_remove_file(&gadget->dev, &dev_attr_suspended); | ||
1359 | kfree(cdev->def_manufacturer); | 1534 | kfree(cdev->def_manufacturer); |
1360 | kfree(cdev); | 1535 | kfree(cdev); |
1361 | set_gadget_data(gadget, NULL); | 1536 | set_gadget_data(gadget, NULL); |
1362 | } | 1537 | } |
1363 | 1538 | ||
1539 | static void composite_unbind(struct usb_gadget *gadget) | ||
1540 | { | ||
1541 | __composite_unbind(gadget, true); | ||
1542 | } | ||
1543 | |||
1364 | static void update_unchanged_dev_desc(struct usb_device_descriptor *new, | 1544 | static void update_unchanged_dev_desc(struct usb_device_descriptor *new, |
1365 | const struct usb_device_descriptor *old) | 1545 | const struct usb_device_descriptor *old) |
1366 | { | 1546 | { |
@@ -1399,34 +1579,25 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, | |||
1399 | new->iProduct = iProduct; | 1579 | new->iProduct = iProduct; |
1400 | } | 1580 | } |
1401 | 1581 | ||
1402 | static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) | 1582 | int composite_dev_prepare(struct usb_composite_driver *composite, |
1403 | { | 1583 | struct usb_composite_dev *cdev) |
1404 | return container_of(gdrv, struct usb_composite_driver, gadget_driver); | ||
1405 | } | ||
1406 | |||
1407 | static int composite_bind(struct usb_gadget *gadget, | ||
1408 | struct usb_gadget_driver *gdriver) | ||
1409 | { | 1584 | { |
1410 | struct usb_composite_dev *cdev; | 1585 | struct usb_gadget *gadget = cdev->gadget; |
1411 | struct usb_composite_driver *composite = to_cdriver(gdriver); | 1586 | int ret = -ENOMEM; |
1412 | int status = -ENOMEM; | ||
1413 | |||
1414 | cdev = kzalloc(sizeof *cdev, GFP_KERNEL); | ||
1415 | if (!cdev) | ||
1416 | return status; | ||
1417 | |||
1418 | spin_lock_init(&cdev->lock); | ||
1419 | cdev->gadget = gadget; | ||
1420 | set_gadget_data(gadget, cdev); | ||
1421 | INIT_LIST_HEAD(&cdev->configs); | ||
1422 | 1587 | ||
1423 | /* preallocate control response and buffer */ | 1588 | /* preallocate control response and buffer */ |
1424 | cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); | 1589 | cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); |
1425 | if (!cdev->req) | 1590 | if (!cdev->req) |
1426 | goto fail; | 1591 | return -ENOMEM; |
1592 | |||
1427 | cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); | 1593 | cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); |
1428 | if (!cdev->req->buf) | 1594 | if (!cdev->req->buf) |
1429 | goto fail; | 1595 | goto fail; |
1596 | |||
1597 | ret = device_create_file(&gadget->dev, &dev_attr_suspended); | ||
1598 | if (ret) | ||
1599 | goto fail_dev; | ||
1600 | |||
1430 | cdev->req->complete = composite_setup_complete; | 1601 | cdev->req->complete = composite_setup_complete; |
1431 | gadget->ep0->driver_data = cdev; | 1602 | gadget->ep0->driver_data = cdev; |
1432 | 1603 | ||
@@ -1444,7 +1615,51 @@ static int composite_bind(struct usb_gadget *gadget, | |||
1444 | * we force endpoints to start unassigned; few controller | 1615 | * we force endpoints to start unassigned; few controller |
1445 | * drivers will zero ep->driver_data. | 1616 | * drivers will zero ep->driver_data. |
1446 | */ | 1617 | */ |
1447 | usb_ep_autoconfig_reset(cdev->gadget); | 1618 | usb_ep_autoconfig_reset(gadget); |
1619 | return 0; | ||
1620 | fail_dev: | ||
1621 | kfree(cdev->req->buf); | ||
1622 | fail: | ||
1623 | usb_ep_free_request(gadget->ep0, cdev->req); | ||
1624 | cdev->req = NULL; | ||
1625 | return ret; | ||
1626 | } | ||
1627 | |||
1628 | void composite_dev_cleanup(struct usb_composite_dev *cdev) | ||
1629 | { | ||
1630 | struct usb_gadget_string_container *uc, *tmp; | ||
1631 | |||
1632 | list_for_each_entry_safe(uc, tmp, &cdev->gstrings, list) { | ||
1633 | list_del(&uc->list); | ||
1634 | kfree(uc); | ||
1635 | } | ||
1636 | if (cdev->req) { | ||
1637 | kfree(cdev->req->buf); | ||
1638 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); | ||
1639 | } | ||
1640 | device_remove_file(&cdev->gadget->dev, &dev_attr_suspended); | ||
1641 | } | ||
1642 | |||
1643 | static int composite_bind(struct usb_gadget *gadget, | ||
1644 | struct usb_gadget_driver *gdriver) | ||
1645 | { | ||
1646 | struct usb_composite_dev *cdev; | ||
1647 | struct usb_composite_driver *composite = to_cdriver(gdriver); | ||
1648 | int status = -ENOMEM; | ||
1649 | |||
1650 | cdev = kzalloc(sizeof *cdev, GFP_KERNEL); | ||
1651 | if (!cdev) | ||
1652 | return status; | ||
1653 | |||
1654 | spin_lock_init(&cdev->lock); | ||
1655 | cdev->gadget = gadget; | ||
1656 | set_gadget_data(gadget, cdev); | ||
1657 | INIT_LIST_HEAD(&cdev->configs); | ||
1658 | INIT_LIST_HEAD(&cdev->gstrings); | ||
1659 | |||
1660 | status = composite_dev_prepare(composite, cdev); | ||
1661 | if (status) | ||
1662 | goto fail; | ||
1448 | 1663 | ||
1449 | /* composite gadget needs to assign strings for whole device (like | 1664 | /* composite gadget needs to assign strings for whole device (like |
1450 | * serial number), register function drivers, potentially update | 1665 | * serial number), register function drivers, potentially update |
@@ -1460,16 +1675,11 @@ static int composite_bind(struct usb_gadget *gadget, | |||
1460 | if (composite->needs_serial && !cdev->desc.iSerialNumber) | 1675 | if (composite->needs_serial && !cdev->desc.iSerialNumber) |
1461 | WARNING(cdev, "userspace failed to provide iSerialNumber\n"); | 1676 | WARNING(cdev, "userspace failed to provide iSerialNumber\n"); |
1462 | 1677 | ||
1463 | /* finish up */ | ||
1464 | status = device_create_file(&gadget->dev, &dev_attr_suspended); | ||
1465 | if (status) | ||
1466 | goto fail; | ||
1467 | |||
1468 | INFO(cdev, "%s ready\n", composite->name); | 1678 | INFO(cdev, "%s ready\n", composite->name); |
1469 | return 0; | 1679 | return 0; |
1470 | 1680 | ||
1471 | fail: | 1681 | fail: |
1472 | composite_unbind(gadget); | 1682 | __composite_unbind(gadget, false); |
1473 | return status; | 1683 | return status; |
1474 | } | 1684 | } |
1475 | 1685 | ||
@@ -1518,10 +1728,10 @@ composite_resume(struct usb_gadget *gadget) | |||
1518 | f->resume(f); | 1728 | f->resume(f); |
1519 | } | 1729 | } |
1520 | 1730 | ||
1521 | maxpower = cdev->config->bMaxPower; | 1731 | maxpower = cdev->config->MaxPower; |
1522 | 1732 | ||
1523 | usb_gadget_vbus_draw(gadget, maxpower ? | 1733 | usb_gadget_vbus_draw(gadget, maxpower ? |
1524 | (2 * maxpower) : CONFIG_USB_GADGET_VBUS_DRAW); | 1734 | maxpower : CONFIG_USB_GADGET_VBUS_DRAW); |
1525 | } | 1735 | } |
1526 | 1736 | ||
1527 | cdev->suspended = 0; | 1737 | cdev->suspended = 0; |
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 87d165028162..986fc511a2ed 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c | |||
@@ -13,9 +13,7 @@ | |||
13 | #include <linux/usb/ch9.h> | 13 | #include <linux/usb/ch9.h> |
14 | #include <linux/usb/gadget.h> | 14 | #include <linux/usb/gadget.h> |
15 | 15 | ||
16 | #ifdef CONFIG_USB_G_DBGP_SERIAL | 16 | #include "u_serial.h" |
17 | #include "u_serial.c" | ||
18 | #endif | ||
19 | 17 | ||
20 | #define DRIVER_VENDOR_ID 0x0525 /* NetChip */ | 18 | #define DRIVER_VENDOR_ID 0x0525 /* NetChip */ |
21 | #define DRIVER_PRODUCT_ID 0xc0de /* undefined */ | 19 | #define DRIVER_PRODUCT_ID 0xc0de /* undefined */ |
@@ -233,6 +231,10 @@ static void dbgp_unbind(struct usb_gadget *gadget) | |||
233 | gadget->ep0->driver_data = NULL; | 231 | gadget->ep0->driver_data = NULL; |
234 | } | 232 | } |
235 | 233 | ||
234 | #ifdef CONFIG_USB_G_DBGP_SERIAL | ||
235 | static unsigned char tty_line; | ||
236 | #endif | ||
237 | |||
236 | static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) | 238 | static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) |
237 | { | 239 | { |
238 | int stp; | 240 | int stp; |
@@ -270,7 +272,7 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) | |||
270 | dbgp.serial->in->desc = &i_desc; | 272 | dbgp.serial->in->desc = &i_desc; |
271 | dbgp.serial->out->desc = &o_desc; | 273 | dbgp.serial->out->desc = &o_desc; |
272 | 274 | ||
273 | if (gserial_setup(gadget, 1) < 0) { | 275 | if (gserial_alloc_line(&tty_line)) { |
274 | stp = 3; | 276 | stp = 3; |
275 | goto fail_3; | 277 | goto fail_3; |
276 | } | 278 | } |
@@ -379,7 +381,7 @@ static int dbgp_setup(struct usb_gadget *gadget, | |||
379 | #ifdef CONFIG_USB_G_DBGP_PRINTK | 381 | #ifdef CONFIG_USB_G_DBGP_PRINTK |
380 | err = dbgp_enable_ep(); | 382 | err = dbgp_enable_ep(); |
381 | #else | 383 | #else |
382 | err = gserial_connect(dbgp.serial, 0); | 384 | err = gserial_connect(dbgp.serial, tty_line); |
383 | #endif | 385 | #endif |
384 | if (err < 0) | 386 | if (err < 0) |
385 | goto fail; | 387 | goto fail; |
@@ -422,7 +424,7 @@ static void __exit dbgp_exit(void) | |||
422 | { | 424 | { |
423 | usb_gadget_unregister_driver(&dbgp_driver); | 425 | usb_gadget_unregister_driver(&dbgp_driver); |
424 | #ifdef CONFIG_USB_G_DBGP_SERIAL | 426 | #ifdef CONFIG_USB_G_DBGP_SERIAL |
425 | gserial_cleanup(); | 427 | gserial_free_line(tty_line); |
426 | #endif | 428 | #endif |
427 | } | 429 | } |
428 | 430 | ||
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 549174466c21..1ae180baa597 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
@@ -16,7 +16,9 @@ | |||
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | ||
19 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/err.h> | ||
20 | 22 | ||
21 | #include "u_serial.h" | 23 | #include "u_serial.h" |
22 | #include "gadget_chips.h" | 24 | #include "gadget_chips.h" |
@@ -283,7 +285,6 @@ static struct usb_string acm_string_defs[] = { | |||
283 | [ACM_CTRL_IDX].s = "CDC Abstract Control Model (ACM)", | 285 | [ACM_CTRL_IDX].s = "CDC Abstract Control Model (ACM)", |
284 | [ACM_DATA_IDX].s = "CDC ACM Data", | 286 | [ACM_DATA_IDX].s = "CDC ACM Data", |
285 | [ACM_IAD_IDX ].s = "CDC Serial", | 287 | [ACM_IAD_IDX ].s = "CDC Serial", |
286 | { /* ZEROES END LIST */ }, | ||
287 | }; | 288 | }; |
288 | 289 | ||
289 | static struct usb_gadget_strings acm_string_table = { | 290 | static struct usb_gadget_strings acm_string_table = { |
@@ -605,9 +606,23 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) | |||
605 | { | 606 | { |
606 | struct usb_composite_dev *cdev = c->cdev; | 607 | struct usb_composite_dev *cdev = c->cdev; |
607 | struct f_acm *acm = func_to_acm(f); | 608 | struct f_acm *acm = func_to_acm(f); |
609 | struct usb_string *us; | ||
608 | int status; | 610 | int status; |
609 | struct usb_ep *ep; | 611 | struct usb_ep *ep; |
610 | 612 | ||
613 | /* REVISIT might want instance-specific strings to help | ||
614 | * distinguish instances ... | ||
615 | */ | ||
616 | |||
617 | /* maybe allocate device-global string IDs, and patch descriptors */ | ||
618 | us = usb_gstrings_attach(cdev, acm_strings, | ||
619 | ARRAY_SIZE(acm_string_defs)); | ||
620 | if (IS_ERR(us)) | ||
621 | return PTR_ERR(us); | ||
622 | acm_control_interface_desc.iInterface = us[ACM_CTRL_IDX].id; | ||
623 | acm_data_interface_desc.iInterface = us[ACM_DATA_IDX].id; | ||
624 | acm_iad_descriptor.iFunction = us[ACM_IAD_IDX].id; | ||
625 | |||
611 | /* allocate instance-specific interface IDs, and patch descriptors */ | 626 | /* allocate instance-specific interface IDs, and patch descriptors */ |
612 | status = usb_interface_id(c, f); | 627 | status = usb_interface_id(c, f); |
613 | if (status < 0) | 628 | if (status < 0) |
@@ -700,24 +715,42 @@ fail: | |||
700 | return status; | 715 | return status; |
701 | } | 716 | } |
702 | 717 | ||
718 | static struct f_acm *acm_alloc_basic_func(void) | ||
719 | { | ||
720 | struct f_acm *acm; | ||
721 | |||
722 | acm = kzalloc(sizeof(*acm), GFP_KERNEL); | ||
723 | if (!acm) | ||
724 | return NULL; | ||
725 | |||
726 | spin_lock_init(&acm->lock); | ||
727 | |||
728 | acm->port.connect = acm_connect; | ||
729 | acm->port.disconnect = acm_disconnect; | ||
730 | acm->port.send_break = acm_send_break; | ||
731 | |||
732 | acm->port.func.name = "acm"; | ||
733 | /* descriptors are per-instance copies */ | ||
734 | acm->port.func.bind = acm_bind; | ||
735 | acm->port.func.set_alt = acm_set_alt; | ||
736 | acm->port.func.setup = acm_setup; | ||
737 | acm->port.func.disable = acm_disable; | ||
738 | |||
739 | return acm; | ||
740 | } | ||
741 | |||
742 | #ifdef USB_FACM_INCLUDED | ||
703 | static void | 743 | static void |
704 | acm_unbind(struct usb_configuration *c, struct usb_function *f) | 744 | acm_old_unbind(struct usb_configuration *c, struct usb_function *f) |
705 | { | 745 | { |
706 | struct f_acm *acm = func_to_acm(f); | 746 | struct f_acm *acm = func_to_acm(f); |
707 | 747 | ||
708 | acm_string_defs[0].id = 0; | ||
709 | usb_free_all_descriptors(f); | 748 | usb_free_all_descriptors(f); |
710 | gs_free_req(acm->notify, acm->notify_req); | 749 | if (acm->notify_req) |
750 | gs_free_req(acm->notify, acm->notify_req); | ||
711 | kfree(acm); | 751 | kfree(acm); |
712 | } | 752 | } |
713 | 753 | ||
714 | /* Some controllers can't support CDC ACM ... */ | ||
715 | static inline bool can_support_cdc(struct usb_configuration *c) | ||
716 | { | ||
717 | /* everything else is *probably* fine ... */ | ||
718 | return true; | ||
719 | } | ||
720 | |||
721 | /** | 754 | /** |
722 | * acm_bind_config - add a CDC ACM function to a configuration | 755 | * acm_bind_config - add a CDC ACM function to a configuration |
723 | * @c: the configuration to support the CDC ACM instance | 756 | * @c: the configuration to support the CDC ACM instance |
@@ -726,58 +759,80 @@ static inline bool can_support_cdc(struct usb_configuration *c) | |||
726 | * | 759 | * |
727 | * Returns zero on success, else negative errno. | 760 | * Returns zero on success, else negative errno. |
728 | * | 761 | * |
729 | * Caller must have called @gserial_setup() with enough ports to | ||
730 | * handle all the ones it binds. Caller is also responsible | ||
731 | * for calling @gserial_cleanup() before module unload. | ||
732 | */ | 762 | */ |
733 | int acm_bind_config(struct usb_configuration *c, u8 port_num) | 763 | int acm_bind_config(struct usb_configuration *c, u8 port_num) |
734 | { | 764 | { |
735 | struct f_acm *acm; | 765 | struct f_acm *acm; |
736 | int status; | 766 | int status; |
737 | 767 | ||
738 | if (!can_support_cdc(c)) | ||
739 | return -EINVAL; | ||
740 | |||
741 | /* REVISIT might want instance-specific strings to help | ||
742 | * distinguish instances ... | ||
743 | */ | ||
744 | |||
745 | /* maybe allocate device-global string IDs, and patch descriptors */ | ||
746 | if (acm_string_defs[0].id == 0) { | ||
747 | status = usb_string_ids_tab(c->cdev, acm_string_defs); | ||
748 | if (status < 0) | ||
749 | return status; | ||
750 | acm_control_interface_desc.iInterface = | ||
751 | acm_string_defs[ACM_CTRL_IDX].id; | ||
752 | acm_data_interface_desc.iInterface = | ||
753 | acm_string_defs[ACM_DATA_IDX].id; | ||
754 | acm_iad_descriptor.iFunction = acm_string_defs[ACM_IAD_IDX].id; | ||
755 | } | ||
756 | |||
757 | /* allocate and initialize one new instance */ | 768 | /* allocate and initialize one new instance */ |
758 | acm = kzalloc(sizeof *acm, GFP_KERNEL); | 769 | acm = acm_alloc_basic_func(); |
759 | if (!acm) | 770 | if (!acm) |
760 | return -ENOMEM; | 771 | return -ENOMEM; |
761 | 772 | ||
762 | spin_lock_init(&acm->lock); | ||
763 | |||
764 | acm->port_num = port_num; | 773 | acm->port_num = port_num; |
765 | 774 | acm->port.func.unbind = acm_old_unbind; | |
766 | acm->port.connect = acm_connect; | ||
767 | acm->port.disconnect = acm_disconnect; | ||
768 | acm->port.send_break = acm_send_break; | ||
769 | |||
770 | acm->port.func.name = "acm"; | ||
771 | acm->port.func.strings = acm_strings; | ||
772 | /* descriptors are per-instance copies */ | ||
773 | acm->port.func.bind = acm_bind; | ||
774 | acm->port.func.unbind = acm_unbind; | ||
775 | acm->port.func.set_alt = acm_set_alt; | ||
776 | acm->port.func.setup = acm_setup; | ||
777 | acm->port.func.disable = acm_disable; | ||
778 | 775 | ||
779 | status = usb_add_function(c, &acm->port.func); | 776 | status = usb_add_function(c, &acm->port.func); |
780 | if (status) | 777 | if (status) |
781 | kfree(acm); | 778 | kfree(acm); |
782 | return status; | 779 | return status; |
783 | } | 780 | } |
781 | |||
782 | #else | ||
783 | |||
784 | static void acm_unbind(struct usb_configuration *c, struct usb_function *f) | ||
785 | { | ||
786 | struct f_acm *acm = func_to_acm(f); | ||
787 | |||
788 | acm_string_defs[0].id = 0; | ||
789 | usb_free_all_descriptors(f); | ||
790 | if (acm->notify_req) | ||
791 | gs_free_req(acm->notify, acm->notify_req); | ||
792 | } | ||
793 | |||
794 | static void acm_free_func(struct usb_function *f) | ||
795 | { | ||
796 | struct f_acm *acm = func_to_acm(f); | ||
797 | |||
798 | kfree(acm); | ||
799 | } | ||
800 | |||
801 | static struct usb_function *acm_alloc_func(struct usb_function_instance *fi) | ||
802 | { | ||
803 | struct f_serial_opts *opts; | ||
804 | struct f_acm *acm; | ||
805 | |||
806 | acm = acm_alloc_basic_func(); | ||
807 | if (!acm) | ||
808 | return ERR_PTR(-ENOMEM); | ||
809 | |||
810 | opts = container_of(fi, struct f_serial_opts, func_inst); | ||
811 | acm->port_num = opts->port_num; | ||
812 | acm->port.func.unbind = acm_unbind; | ||
813 | acm->port.func.free_func = acm_free_func; | ||
814 | |||
815 | return &acm->port.func; | ||
816 | } | ||
817 | |||
818 | static void acm_free_instance(struct usb_function_instance *fi) | ||
819 | { | ||
820 | struct f_serial_opts *opts; | ||
821 | |||
822 | opts = container_of(fi, struct f_serial_opts, func_inst); | ||
823 | kfree(opts); | ||
824 | } | ||
825 | |||
826 | static struct usb_function_instance *acm_alloc_instance(void) | ||
827 | { | ||
828 | struct f_serial_opts *opts; | ||
829 | |||
830 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | ||
831 | if (!opts) | ||
832 | return ERR_PTR(-ENOMEM); | ||
833 | opts->func_inst.free_func_inst = acm_free_instance; | ||
834 | return &opts->func_inst; | ||
835 | } | ||
836 | DECLARE_USB_FUNCTION_INIT(acm, acm_alloc_instance, acm_alloc_func); | ||
837 | MODULE_LICENSE("GPL"); | ||
838 | #endif | ||
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 8c2f25121149..38388d7844fc 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -1103,8 +1103,8 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | |||
1103 | return 0; | 1103 | return 0; |
1104 | 1104 | ||
1105 | for (;;) { | 1105 | for (;;) { |
1106 | char *end, *eq, *comma; | ||
1107 | unsigned long value; | 1106 | unsigned long value; |
1107 | char *eq, *comma; | ||
1108 | 1108 | ||
1109 | /* Option limit */ | 1109 | /* Option limit */ |
1110 | comma = strchr(opts, ','); | 1110 | comma = strchr(opts, ','); |
@@ -1120,8 +1120,7 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | |||
1120 | *eq = 0; | 1120 | *eq = 0; |
1121 | 1121 | ||
1122 | /* Parse value */ | 1122 | /* Parse value */ |
1123 | value = simple_strtoul(eq + 1, &end, 0); | 1123 | if (kstrtoul(eq + 1, 0, &value)) { |
1124 | if (unlikely(*end != ',' && *end != 0)) { | ||
1125 | pr_err("%s: invalid value: %s\n", opts, eq + 1); | 1124 | pr_err("%s: invalid value: %s\n", opts, eq + 1); |
1126 | return -EINVAL; | 1125 | return -EINVAL; |
1127 | } | 1126 | } |
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index bb39cb2bb3a3..4a3873a0f2d0 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c | |||
@@ -15,10 +15,11 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/module.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/usb/composite.h> | ||
18 | 21 | ||
19 | #include "g_zero.h" | 22 | #include "g_zero.h" |
20 | #include "gadget_chips.h" | ||
21 | |||
22 | 23 | ||
23 | /* | 24 | /* |
24 | * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals, | 25 | * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals, |
@@ -44,9 +45,8 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f) | |||
44 | return container_of(f, struct f_loopback, function); | 45 | return container_of(f, struct f_loopback, function); |
45 | } | 46 | } |
46 | 47 | ||
47 | static unsigned qlen = 32; | 48 | static unsigned qlen; |
48 | module_param(qlen, uint, 0); | 49 | static unsigned buflen; |
49 | MODULE_PARM_DESC(qlenn, "depth of loopback queue"); | ||
50 | 50 | ||
51 | /*-------------------------------------------------------------------------*/ | 51 | /*-------------------------------------------------------------------------*/ |
52 | 52 | ||
@@ -171,8 +171,7 @@ static struct usb_gadget_strings *loopback_strings[] = { | |||
171 | 171 | ||
172 | /*-------------------------------------------------------------------------*/ | 172 | /*-------------------------------------------------------------------------*/ |
173 | 173 | ||
174 | static int __init | 174 | static int loopback_bind(struct usb_configuration *c, struct usb_function *f) |
175 | loopback_bind(struct usb_configuration *c, struct usb_function *f) | ||
176 | { | 175 | { |
177 | struct usb_composite_dev *cdev = c->cdev; | 176 | struct usb_composite_dev *cdev = c->cdev; |
178 | struct f_loopback *loop = func_to_loop(f); | 177 | struct f_loopback *loop = func_to_loop(f); |
@@ -185,6 +184,12 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f) | |||
185 | return id; | 184 | return id; |
186 | loopback_intf.bInterfaceNumber = id; | 185 | loopback_intf.bInterfaceNumber = id; |
187 | 186 | ||
187 | id = usb_string_id(cdev); | ||
188 | if (id < 0) | ||
189 | return id; | ||
190 | strings_loopback[0].id = id; | ||
191 | loopback_intf.iInterface = id; | ||
192 | |||
188 | /* allocate endpoints */ | 193 | /* allocate endpoints */ |
189 | 194 | ||
190 | loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc); | 195 | loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc); |
@@ -223,8 +228,7 @@ autoconf_fail: | |||
223 | return 0; | 228 | return 0; |
224 | } | 229 | } |
225 | 230 | ||
226 | static void | 231 | static void lb_free_func(struct usb_function *f) |
227 | loopback_unbind(struct usb_configuration *c, struct usb_function *f) | ||
228 | { | 232 | { |
229 | usb_free_all_descriptors(f); | 233 | usb_free_all_descriptors(f); |
230 | kfree(func_to_loop(f)); | 234 | kfree(func_to_loop(f)); |
@@ -366,63 +370,64 @@ static void loopback_disable(struct usb_function *f) | |||
366 | disable_loopback(loop); | 370 | disable_loopback(loop); |
367 | } | 371 | } |
368 | 372 | ||
369 | /*-------------------------------------------------------------------------*/ | 373 | static struct usb_function *loopback_alloc(struct usb_function_instance *fi) |
370 | |||
371 | static int __init loopback_bind_config(struct usb_configuration *c) | ||
372 | { | 374 | { |
373 | struct f_loopback *loop; | 375 | struct f_loopback *loop; |
374 | int status; | 376 | struct f_lb_opts *lb_opts; |
375 | 377 | ||
376 | loop = kzalloc(sizeof *loop, GFP_KERNEL); | 378 | loop = kzalloc(sizeof *loop, GFP_KERNEL); |
377 | if (!loop) | 379 | if (!loop) |
378 | return -ENOMEM; | 380 | return ERR_PTR(-ENOMEM); |
381 | |||
382 | lb_opts = container_of(fi, struct f_lb_opts, func_inst); | ||
383 | buflen = lb_opts->bulk_buflen; | ||
384 | qlen = lb_opts->qlen; | ||
385 | if (!qlen) | ||
386 | qlen = 32; | ||
379 | 387 | ||
380 | loop->function.name = "loopback"; | 388 | loop->function.name = "loopback"; |
381 | loop->function.bind = loopback_bind; | 389 | loop->function.bind = loopback_bind; |
382 | loop->function.unbind = loopback_unbind; | ||
383 | loop->function.set_alt = loopback_set_alt; | 390 | loop->function.set_alt = loopback_set_alt; |
384 | loop->function.disable = loopback_disable; | 391 | loop->function.disable = loopback_disable; |
392 | loop->function.strings = loopback_strings; | ||
385 | 393 | ||
386 | status = usb_add_function(c, &loop->function); | 394 | loop->function.free_func = lb_free_func; |
387 | if (status) | ||
388 | kfree(loop); | ||
389 | return status; | ||
390 | } | ||
391 | 395 | ||
392 | static struct usb_configuration loopback_driver = { | 396 | return &loop->function; |
393 | .label = "loopback", | 397 | } |
394 | .strings = loopback_strings, | ||
395 | .bConfigurationValue = 2, | ||
396 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | ||
397 | /* .iConfiguration = DYNAMIC */ | ||
398 | }; | ||
399 | 398 | ||
400 | /** | 399 | static void lb_free_instance(struct usb_function_instance *fi) |
401 | * loopback_add - add a loopback testing configuration to a device | ||
402 | * @cdev: the device to support the loopback configuration | ||
403 | */ | ||
404 | int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume) | ||
405 | { | 400 | { |
406 | int id; | 401 | struct f_lb_opts *lb_opts; |
407 | 402 | ||
408 | /* allocate string ID(s) */ | 403 | lb_opts = container_of(fi, struct f_lb_opts, func_inst); |
409 | id = usb_string_id(cdev); | 404 | kfree(lb_opts); |
410 | if (id < 0) | 405 | } |
411 | return id; | ||
412 | strings_loopback[0].id = id; | ||
413 | 406 | ||
414 | loopback_intf.iInterface = id; | 407 | static struct usb_function_instance *loopback_alloc_instance(void) |
415 | loopback_driver.iConfiguration = id; | 408 | { |
409 | struct f_lb_opts *lb_opts; | ||
416 | 410 | ||
417 | /* support autoresume for remote wakeup testing */ | 411 | lb_opts = kzalloc(sizeof(*lb_opts), GFP_KERNEL); |
418 | if (autoresume) | 412 | if (!lb_opts) |
419 | loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 413 | return ERR_PTR(-ENOMEM); |
414 | lb_opts->func_inst.free_func_inst = lb_free_instance; | ||
415 | return &lb_opts->func_inst; | ||
416 | } | ||
417 | DECLARE_USB_FUNCTION(Loopback, loopback_alloc_instance, loopback_alloc); | ||
420 | 418 | ||
421 | /* support OTG systems */ | 419 | int __init lb_modinit(void) |
422 | if (gadget_is_otg(cdev->gadget)) { | 420 | { |
423 | loopback_driver.descriptors = otg_desc; | 421 | int ret; |
424 | loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
425 | } | ||
426 | 422 | ||
427 | return usb_add_config(cdev, &loopback_driver, loopback_bind_config); | 423 | ret = usb_function_register(&Loopbackusb_func); |
424 | if (ret) | ||
425 | return ret; | ||
426 | return ret; | ||
428 | } | 427 | } |
428 | void __exit lb_modexit(void) | ||
429 | { | ||
430 | usb_function_unregister(&Loopbackusb_func); | ||
431 | } | ||
432 | |||
433 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 5d027b3e1ef0..fc5c16ca5e0a 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -246,20 +246,6 @@ struct fsg_operations { | |||
246 | * set). | 246 | * set). |
247 | */ | 247 | */ |
248 | int (*thread_exits)(struct fsg_common *common); | 248 | int (*thread_exits)(struct fsg_common *common); |
249 | |||
250 | /* | ||
251 | * Called prior to ejection. Negative return means error, | ||
252 | * zero means to continue with ejection, positive means not to | ||
253 | * eject. | ||
254 | */ | ||
255 | int (*pre_eject)(struct fsg_common *common, | ||
256 | struct fsg_lun *lun, int num); | ||
257 | /* | ||
258 | * Called after ejection. Negative return means error, zero | ||
259 | * or positive is just a success. | ||
260 | */ | ||
261 | int (*post_eject)(struct fsg_common *common, | ||
262 | struct fsg_lun *lun, int num); | ||
263 | }; | 249 | }; |
264 | 250 | ||
265 | /* Data shared by all the FSG instances. */ | 251 | /* Data shared by all the FSG instances. */ |
@@ -1374,26 +1360,13 @@ static int do_start_stop(struct fsg_common *common) | |||
1374 | if (!loej) | 1360 | if (!loej) |
1375 | return 0; | 1361 | return 0; |
1376 | 1362 | ||
1377 | /* Simulate an unload/eject */ | ||
1378 | if (common->ops && common->ops->pre_eject) { | ||
1379 | int r = common->ops->pre_eject(common, curlun, | ||
1380 | curlun - common->luns); | ||
1381 | if (unlikely(r < 0)) | ||
1382 | return r; | ||
1383 | else if (r) | ||
1384 | return 0; | ||
1385 | } | ||
1386 | |||
1387 | up_read(&common->filesem); | 1363 | up_read(&common->filesem); |
1388 | down_write(&common->filesem); | 1364 | down_write(&common->filesem); |
1389 | fsg_lun_close(curlun); | 1365 | fsg_lun_close(curlun); |
1390 | up_write(&common->filesem); | 1366 | up_write(&common->filesem); |
1391 | down_read(&common->filesem); | 1367 | down_read(&common->filesem); |
1392 | 1368 | ||
1393 | return common->ops && common->ops->post_eject | 1369 | return 0; |
1394 | ? min(0, common->ops->post_eject(common, curlun, | ||
1395 | curlun - common->luns)) | ||
1396 | : 0; | ||
1397 | } | 1370 | } |
1398 | 1371 | ||
1399 | static int do_prevent_allow(struct fsg_common *common) | 1372 | static int do_prevent_allow(struct fsg_common *common) |
@@ -1718,7 +1691,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1718 | int needs_medium, const char *name) | 1691 | int needs_medium, const char *name) |
1719 | { | 1692 | { |
1720 | int i; | 1693 | int i; |
1721 | int lun = common->cmnd[1] >> 5; | 1694 | unsigned int lun = common->cmnd[1] >> 5; |
1722 | static const char dirletter[4] = {'u', 'o', 'i', 'n'}; | 1695 | static const char dirletter[4] = {'u', 'o', 'i', 'n'}; |
1723 | char hdlen[20]; | 1696 | char hdlen[20]; |
1724 | struct fsg_lun *curlun; | 1697 | struct fsg_lun *curlun; |
@@ -1784,7 +1757,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1784 | 1757 | ||
1785 | /* Check that the LUN values are consistent */ | 1758 | /* Check that the LUN values are consistent */ |
1786 | if (common->lun != lun) | 1759 | if (common->lun != lun) |
1787 | DBG(common, "using LUN %d from CBW, not LUN %d from CDB\n", | 1760 | DBG(common, "using LUN %u from CBW, not LUN %u from CDB\n", |
1788 | common->lun, lun); | 1761 | common->lun, lun); |
1789 | 1762 | ||
1790 | /* Check the LUN */ | 1763 | /* Check the LUN */ |
@@ -1804,7 +1777,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1804 | */ | 1777 | */ |
1805 | if (common->cmnd[0] != INQUIRY && | 1778 | if (common->cmnd[0] != INQUIRY && |
1806 | common->cmnd[0] != REQUEST_SENSE) { | 1779 | common->cmnd[0] != REQUEST_SENSE) { |
1807 | DBG(common, "unsupported LUN %d\n", common->lun); | 1780 | DBG(common, "unsupported LUN %u\n", common->lun); |
1808 | return -EINVAL; | 1781 | return -EINVAL; |
1809 | } | 1782 | } |
1810 | } | 1783 | } |
@@ -2196,7 +2169,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2196 | if (common->data_size == 0) | 2169 | if (common->data_size == 0) |
2197 | common->data_dir = DATA_DIR_NONE; | 2170 | common->data_dir = DATA_DIR_NONE; |
2198 | common->lun = cbw->Lun; | 2171 | common->lun = cbw->Lun; |
2199 | if (common->lun >= 0 && common->lun < common->nluns) | 2172 | if (common->lun < common->nluns) |
2200 | common->curlun = &common->luns[common->lun]; | 2173 | common->curlun = &common->luns[common->lun]; |
2201 | else | 2174 | else |
2202 | common->curlun = NULL; | 2175 | common->curlun = NULL; |
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index 6c8362f937be..5e7557e23ecc 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c | |||
@@ -56,8 +56,9 @@ struct f_ncm { | |||
56 | u8 notify_state; | 56 | u8 notify_state; |
57 | bool is_open; | 57 | bool is_open; |
58 | 58 | ||
59 | struct ndp_parser_opts *parser_opts; | 59 | const struct ndp_parser_opts *parser_opts; |
60 | bool is_crc; | 60 | bool is_crc; |
61 | u32 ndp_sign; | ||
61 | 62 | ||
62 | /* | 63 | /* |
63 | * for notification, it is accessed from both | 64 | * for notification, it is accessed from both |
@@ -390,8 +391,8 @@ struct ndp_parser_opts { | |||
390 | .next_fp_index = 2, \ | 391 | .next_fp_index = 2, \ |
391 | } | 392 | } |
392 | 393 | ||
393 | static struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS; | 394 | static const struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS; |
394 | static struct ndp_parser_opts ndp32_opts = INIT_NDP32_OPTS; | 395 | static const struct ndp_parser_opts ndp32_opts = INIT_NDP32_OPTS; |
395 | 396 | ||
396 | static inline void put_ncm(__le16 **p, unsigned size, unsigned val) | 397 | static inline void put_ncm(__le16 **p, unsigned size, unsigned val) |
397 | { | 398 | { |
@@ -732,8 +733,7 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | |||
732 | default: | 733 | default: |
733 | goto invalid; | 734 | goto invalid; |
734 | } | 735 | } |
735 | ncm->parser_opts->ndp_sign &= ~NCM_NDP_HDR_CRC_MASK; | 736 | ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc; |
736 | ncm->parser_opts->ndp_sign |= ndp_hdr_crc; | ||
737 | value = 0; | 737 | value = 0; |
738 | break; | 738 | break; |
739 | } | 739 | } |
@@ -875,7 +875,7 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port, | |||
875 | int ndp_align; | 875 | int ndp_align; |
876 | int ndp_pad; | 876 | int ndp_pad; |
877 | unsigned max_size = ncm->port.fixed_in_len; | 877 | unsigned max_size = ncm->port.fixed_in_len; |
878 | struct ndp_parser_opts *opts = ncm->parser_opts; | 878 | const struct ndp_parser_opts *opts = ncm->parser_opts; |
879 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; | 879 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; |
880 | 880 | ||
881 | div = le16_to_cpu(ntb_parameters.wNdpInDivisor); | 881 | div = le16_to_cpu(ntb_parameters.wNdpInDivisor); |
@@ -921,7 +921,7 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port, | |||
921 | tmp = (void *)tmp + ndp_pad; | 921 | tmp = (void *)tmp + ndp_pad; |
922 | 922 | ||
923 | /* NDP */ | 923 | /* NDP */ |
924 | put_unaligned_le32(opts->ndp_sign, tmp); /* dwSignature */ | 924 | put_unaligned_le32(ncm->ndp_sign, tmp); /* dwSignature */ |
925 | tmp += 2; | 925 | tmp += 2; |
926 | /* wLength */ | 926 | /* wLength */ |
927 | put_unaligned_le16(ncb_len - opts->nth_size - pad, tmp++); | 927 | put_unaligned_le16(ncb_len - opts->nth_size - pad, tmp++); |
@@ -965,7 +965,7 @@ static int ncm_unwrap_ntb(struct gether *port, | |||
965 | struct sk_buff *skb2; | 965 | struct sk_buff *skb2; |
966 | int ret = -EINVAL; | 966 | int ret = -EINVAL; |
967 | unsigned max_size = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize); | 967 | unsigned max_size = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize); |
968 | struct ndp_parser_opts *opts = ncm->parser_opts; | 968 | const struct ndp_parser_opts *opts = ncm->parser_opts; |
969 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; | 969 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; |
970 | int dgram_counter; | 970 | int dgram_counter; |
971 | 971 | ||
@@ -1002,7 +1002,7 @@ static int ncm_unwrap_ntb(struct gether *port, | |||
1002 | 1002 | ||
1003 | /* walk through NDP */ | 1003 | /* walk through NDP */ |
1004 | tmp = ((void *)skb->data) + index; | 1004 | tmp = ((void *)skb->data) + index; |
1005 | if (get_unaligned_le32(tmp) != opts->ndp_sign) { | 1005 | if (get_unaligned_le32(tmp) != ncm->ndp_sign) { |
1006 | INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); | 1006 | INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); |
1007 | goto err; | 1007 | goto err; |
1008 | } | 1008 | } |
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index d8dd8782768c..36a004563b82 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c | |||
@@ -406,10 +406,6 @@ static inline bool can_support_obex(struct usb_configuration *c) | |||
406 | * Context: single threaded during gadget setup | 406 | * Context: single threaded during gadget setup |
407 | * | 407 | * |
408 | * Returns zero on success, else negative errno. | 408 | * Returns zero on success, else negative errno. |
409 | * | ||
410 | * Caller must have called @gserial_setup() with enough ports to | ||
411 | * handle all the ones it binds. Caller is also responsible | ||
412 | * for calling @gserial_cleanup() before module unload. | ||
413 | */ | 409 | */ |
414 | int __init obex_bind_config(struct usb_configuration *c, u8 port_num) | 410 | int __init obex_bind_config(struct usb_configuration *c, u8 port_num) |
415 | { | 411 | { |
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index 98fa7795df5f..da33cfb3031d 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c | |||
@@ -260,10 +260,6 @@ gser_unbind(struct usb_configuration *c, struct usb_function *f) | |||
260 | * Context: single threaded during gadget setup | 260 | * Context: single threaded during gadget setup |
261 | * | 261 | * |
262 | * Returns zero on success, else negative errno. | 262 | * Returns zero on success, else negative errno. |
263 | * | ||
264 | * Caller must have called @gserial_setup() with enough ports to | ||
265 | * handle all the ones it binds. Caller is also responsible | ||
266 | * for calling @gserial_cleanup() before module unload. | ||
267 | */ | 263 | */ |
268 | int __init gser_bind_config(struct usb_configuration *c, u8 port_num) | 264 | int __init gser_bind_config(struct usb_configuration *c, u8 port_num) |
269 | { | 265 | { |
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 102d49beb9df..41adf3ef96c2 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c | |||
@@ -16,11 +16,12 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/usb/composite.h> | ||
20 | #include <linux/err.h> | ||
19 | 21 | ||
20 | #include "g_zero.h" | 22 | #include "g_zero.h" |
21 | #include "gadget_chips.h" | 23 | #include "gadget_chips.h" |
22 | 24 | ||
23 | |||
24 | /* | 25 | /* |
25 | * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral | 26 | * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral |
26 | * controller drivers. | 27 | * controller drivers. |
@@ -62,24 +63,11 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f) | |||
62 | } | 63 | } |
63 | 64 | ||
64 | static unsigned pattern; | 65 | static unsigned pattern; |
65 | module_param(pattern, uint, S_IRUGO|S_IWUSR); | 66 | static unsigned isoc_interval; |
66 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63, 2 = none"); | 67 | static unsigned isoc_maxpacket; |
67 | |||
68 | static unsigned isoc_interval = 4; | ||
69 | module_param(isoc_interval, uint, S_IRUGO|S_IWUSR); | ||
70 | MODULE_PARM_DESC(isoc_interval, "1 - 16"); | ||
71 | |||
72 | static unsigned isoc_maxpacket = 1024; | ||
73 | module_param(isoc_maxpacket, uint, S_IRUGO|S_IWUSR); | ||
74 | MODULE_PARM_DESC(isoc_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); | ||
75 | |||
76 | static unsigned isoc_mult; | 68 | static unsigned isoc_mult; |
77 | module_param(isoc_mult, uint, S_IRUGO|S_IWUSR); | ||
78 | MODULE_PARM_DESC(isoc_mult, "0 - 2 (hs/ss only)"); | ||
79 | |||
80 | static unsigned isoc_maxburst; | 69 | static unsigned isoc_maxburst; |
81 | module_param(isoc_maxburst, uint, S_IRUGO|S_IWUSR); | 70 | static unsigned buflen; |
82 | MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)"); | ||
83 | 71 | ||
84 | /*-------------------------------------------------------------------------*/ | 72 | /*-------------------------------------------------------------------------*/ |
85 | 73 | ||
@@ -313,7 +301,57 @@ static struct usb_gadget_strings *sourcesink_strings[] = { | |||
313 | 301 | ||
314 | /*-------------------------------------------------------------------------*/ | 302 | /*-------------------------------------------------------------------------*/ |
315 | 303 | ||
316 | static int __init | 304 | struct usb_request *alloc_ep_req(struct usb_ep *ep, int len) |
305 | { | ||
306 | struct usb_request *req; | ||
307 | |||
308 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); | ||
309 | if (req) { | ||
310 | if (len) | ||
311 | req->length = len; | ||
312 | else | ||
313 | req->length = buflen; | ||
314 | req->buf = kmalloc(req->length, GFP_ATOMIC); | ||
315 | if (!req->buf) { | ||
316 | usb_ep_free_request(ep, req); | ||
317 | req = NULL; | ||
318 | } | ||
319 | } | ||
320 | return req; | ||
321 | } | ||
322 | |||
323 | void free_ep_req(struct usb_ep *ep, struct usb_request *req) | ||
324 | { | ||
325 | kfree(req->buf); | ||
326 | usb_ep_free_request(ep, req); | ||
327 | } | ||
328 | |||
329 | static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) | ||
330 | { | ||
331 | int value; | ||
332 | |||
333 | if (ep->driver_data) { | ||
334 | value = usb_ep_disable(ep); | ||
335 | if (value < 0) | ||
336 | DBG(cdev, "disable %s --> %d\n", | ||
337 | ep->name, value); | ||
338 | ep->driver_data = NULL; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | void disable_endpoints(struct usb_composite_dev *cdev, | ||
343 | struct usb_ep *in, struct usb_ep *out, | ||
344 | struct usb_ep *iso_in, struct usb_ep *iso_out) | ||
345 | { | ||
346 | disable_ep(cdev, in); | ||
347 | disable_ep(cdev, out); | ||
348 | if (iso_in) | ||
349 | disable_ep(cdev, iso_in); | ||
350 | if (iso_out) | ||
351 | disable_ep(cdev, iso_out); | ||
352 | } | ||
353 | |||
354 | static int | ||
317 | sourcesink_bind(struct usb_configuration *c, struct usb_function *f) | 355 | sourcesink_bind(struct usb_configuration *c, struct usb_function *f) |
318 | { | 356 | { |
319 | struct usb_composite_dev *cdev = c->cdev; | 357 | struct usb_composite_dev *cdev = c->cdev; |
@@ -450,7 +488,7 @@ no_iso: | |||
450 | } | 488 | } |
451 | 489 | ||
452 | static void | 490 | static void |
453 | sourcesink_unbind(struct usb_configuration *c, struct usb_function *f) | 491 | sourcesink_free_func(struct usb_function *f) |
454 | { | 492 | { |
455 | usb_free_all_descriptors(f); | 493 | usb_free_all_descriptors(f); |
456 | kfree(func_to_ss(f)); | 494 | kfree(func_to_ss(f)); |
@@ -531,8 +569,7 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) | |||
531 | check_read_data(ss, req); | 569 | check_read_data(ss, req); |
532 | if (pattern != 2) | 570 | if (pattern != 2) |
533 | memset(req->buf, 0x55, req->length); | 571 | memset(req->buf, 0x55, req->length); |
534 | } else | 572 | } |
535 | reinit_write_data(ep, req); | ||
536 | break; | 573 | break; |
537 | 574 | ||
538 | /* this endpoint is normally active while we're configured */ | 575 | /* this endpoint is normally active while we're configured */ |
@@ -758,31 +795,10 @@ static void sourcesink_disable(struct usb_function *f) | |||
758 | 795 | ||
759 | /*-------------------------------------------------------------------------*/ | 796 | /*-------------------------------------------------------------------------*/ |
760 | 797 | ||
761 | static int __init sourcesink_bind_config(struct usb_configuration *c) | 798 | static int sourcesink_setup(struct usb_function *f, |
762 | { | ||
763 | struct f_sourcesink *ss; | ||
764 | int status; | ||
765 | |||
766 | ss = kzalloc(sizeof *ss, GFP_KERNEL); | ||
767 | if (!ss) | ||
768 | return -ENOMEM; | ||
769 | |||
770 | ss->function.name = "source/sink"; | ||
771 | ss->function.bind = sourcesink_bind; | ||
772 | ss->function.unbind = sourcesink_unbind; | ||
773 | ss->function.set_alt = sourcesink_set_alt; | ||
774 | ss->function.get_alt = sourcesink_get_alt; | ||
775 | ss->function.disable = sourcesink_disable; | ||
776 | |||
777 | status = usb_add_function(c, &ss->function); | ||
778 | if (status) | ||
779 | kfree(ss); | ||
780 | return status; | ||
781 | } | ||
782 | |||
783 | static int sourcesink_setup(struct usb_configuration *c, | ||
784 | const struct usb_ctrlrequest *ctrl) | 799 | const struct usb_ctrlrequest *ctrl) |
785 | { | 800 | { |
801 | struct usb_configuration *c = f->config; | ||
786 | struct usb_request *req = c->cdev->req; | 802 | struct usb_request *req = c->cdev->req; |
787 | int value = -EOPNOTSUPP; | 803 | int value = -EOPNOTSUPP; |
788 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 804 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
@@ -851,42 +867,76 @@ unknown: | |||
851 | return value; | 867 | return value; |
852 | } | 868 | } |
853 | 869 | ||
854 | static struct usb_configuration sourcesink_driver = { | 870 | static struct usb_function *source_sink_alloc_func( |
855 | .label = "source/sink", | 871 | struct usb_function_instance *fi) |
856 | .strings = sourcesink_strings, | 872 | { |
857 | .setup = sourcesink_setup, | 873 | struct f_sourcesink *ss; |
858 | .bConfigurationValue = 3, | 874 | struct f_ss_opts *ss_opts; |
859 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | ||
860 | /* .iConfiguration = DYNAMIC */ | ||
861 | }; | ||
862 | 875 | ||
863 | /** | 876 | ss = kzalloc(sizeof(*ss), GFP_KERNEL); |
864 | * sourcesink_add - add a source/sink testing configuration to a device | 877 | if (!ss) |
865 | * @cdev: the device to support the configuration | 878 | return NULL; |
866 | */ | 879 | |
867 | int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume) | 880 | ss_opts = container_of(fi, struct f_ss_opts, func_inst); |
881 | pattern = ss_opts->pattern; | ||
882 | isoc_interval = ss_opts->isoc_interval; | ||
883 | isoc_maxpacket = ss_opts->isoc_maxpacket; | ||
884 | isoc_mult = ss_opts->isoc_mult; | ||
885 | isoc_maxburst = ss_opts->isoc_maxburst; | ||
886 | buflen = ss_opts->bulk_buflen; | ||
887 | |||
888 | ss->function.name = "source/sink"; | ||
889 | ss->function.bind = sourcesink_bind; | ||
890 | ss->function.set_alt = sourcesink_set_alt; | ||
891 | ss->function.get_alt = sourcesink_get_alt; | ||
892 | ss->function.disable = sourcesink_disable; | ||
893 | ss->function.setup = sourcesink_setup; | ||
894 | ss->function.strings = sourcesink_strings; | ||
895 | |||
896 | ss->function.free_func = sourcesink_free_func; | ||
897 | |||
898 | return &ss->function; | ||
899 | } | ||
900 | |||
901 | static void acm_free_instance(struct usb_function_instance *fi) | ||
868 | { | 902 | { |
869 | int id; | 903 | struct f_ss_opts *ss_opts; |
870 | 904 | ||
871 | /* allocate string ID(s) */ | 905 | ss_opts = container_of(fi, struct f_ss_opts, func_inst); |
872 | id = usb_string_id(cdev); | 906 | kfree(ss_opts); |
873 | if (id < 0) | 907 | } |
874 | return id; | ||
875 | strings_sourcesink[0].id = id; | ||
876 | 908 | ||
877 | source_sink_intf_alt0.iInterface = id; | 909 | static struct usb_function_instance *source_sink_alloc_inst(void) |
878 | source_sink_intf_alt1.iInterface = id; | 910 | { |
879 | sourcesink_driver.iConfiguration = id; | 911 | struct f_ss_opts *ss_opts; |
880 | 912 | ||
881 | /* support autoresume for remote wakeup testing */ | 913 | ss_opts = kzalloc(sizeof(*ss_opts), GFP_KERNEL); |
882 | if (autoresume) | 914 | if (!ss_opts) |
883 | sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 915 | return ERR_PTR(-ENOMEM); |
916 | ss_opts->func_inst.free_func_inst = acm_free_instance; | ||
917 | return &ss_opts->func_inst; | ||
918 | } | ||
919 | DECLARE_USB_FUNCTION(SourceSink, source_sink_alloc_inst, | ||
920 | source_sink_alloc_func); | ||
884 | 921 | ||
885 | /* support OTG systems */ | 922 | static int __init sslb_modinit(void) |
886 | if (gadget_is_otg(cdev->gadget)) { | 923 | { |
887 | sourcesink_driver.descriptors = otg_desc; | 924 | int ret; |
888 | sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
889 | } | ||
890 | 925 | ||
891 | return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config); | 926 | ret = usb_function_register(&SourceSinkusb_func); |
927 | if (ret) | ||
928 | return ret; | ||
929 | ret = lb_modinit(); | ||
930 | if (ret) | ||
931 | usb_function_unregister(&SourceSinkusb_func); | ||
932 | return ret; | ||
933 | } | ||
934 | static void __exit sslb_modexit(void) | ||
935 | { | ||
936 | usb_function_unregister(&SourceSinkusb_func); | ||
937 | lb_modexit(); | ||
892 | } | 938 | } |
939 | module_init(sslb_modinit); | ||
940 | module_exit(sslb_modexit); | ||
941 | |||
942 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index d7da258fa3f6..c7468b6c07b0 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c | |||
@@ -260,19 +260,14 @@ static int | |||
260 | uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 260 | uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
261 | { | 261 | { |
262 | struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); | 262 | struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); |
263 | struct audio_dev *agdev = uac2_to_agdev(uac2); | ||
264 | struct uac2_rtd_params *prm; | 263 | struct uac2_rtd_params *prm; |
265 | unsigned long flags; | 264 | unsigned long flags; |
266 | struct usb_ep *ep; | ||
267 | int err = 0; | 265 | int err = 0; |
268 | 266 | ||
269 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 267 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
270 | ep = agdev->in_ep; | ||
271 | prm = &uac2->p_prm; | 268 | prm = &uac2->p_prm; |
272 | } else { | 269 | else |
273 | ep = agdev->out_ep; | ||
274 | prm = &uac2->c_prm; | 270 | prm = &uac2->c_prm; |
275 | } | ||
276 | 271 | ||
277 | spin_lock_irqsave(&prm->lock, flags); | 272 | spin_lock_irqsave(&prm->lock, flags); |
278 | 273 | ||
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 5b629876941b..92efd6ec48af 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
19 | #include <linux/string.h> | ||
19 | #include <linux/usb/ch9.h> | 20 | #include <linux/usb/ch9.h> |
20 | #include <linux/usb/gadget.h> | 21 | #include <linux/usb/gadget.h> |
21 | #include <linux/usb/video.h> | 22 | #include <linux/usb/video.h> |
@@ -419,7 +420,7 @@ uvc_register_video(struct uvc_device *uvc) | |||
419 | video->parent = &cdev->gadget->dev; | 420 | video->parent = &cdev->gadget->dev; |
420 | video->fops = &uvc_v4l2_fops; | 421 | video->fops = &uvc_v4l2_fops; |
421 | video->release = video_device_release; | 422 | video->release = video_device_release; |
422 | strncpy(video->name, cdev->gadget->name, sizeof(video->name)); | 423 | strlcpy(video->name, cdev->gadget->name, sizeof(video->name)); |
423 | 424 | ||
424 | uvc->vdev = video; | 425 | uvc->vdev = video; |
425 | video_set_drvdata(video, uvc); | 426 | video_set_drvdata(video, uvc); |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index ec50f18c8890..034477ce77c6 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -1894,7 +1894,7 @@ static int fsl_qe_stop(struct usb_gadget *gadget, | |||
1894 | struct usb_gadget_driver *driver); | 1894 | struct usb_gadget_driver *driver); |
1895 | 1895 | ||
1896 | /* defined in usb_gadget.h */ | 1896 | /* defined in usb_gadget.h */ |
1897 | static struct usb_gadget_ops qe_gadget_ops = { | 1897 | static const struct usb_gadget_ops qe_gadget_ops = { |
1898 | .get_frame = qe_get_frame, | 1898 | .get_frame = qe_get_frame, |
1899 | .udc_start = fsl_qe_start, | 1899 | .udc_start = fsl_qe_start, |
1900 | .udc_stop = fsl_qe_stop, | 1900 | .udc_stop = fsl_qe_stop, |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 667275cb7bad..04d5fef1440c 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -1255,19 +1255,20 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) | |||
1255 | return 0; | 1255 | return 0; |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | static int fsl_start(struct usb_gadget_driver *driver, | 1258 | static int fsl_udc_start(struct usb_gadget *g, |
1259 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1259 | struct usb_gadget_driver *driver); |
1260 | static int fsl_stop(struct usb_gadget_driver *driver); | 1260 | static int fsl_udc_stop(struct usb_gadget *g, |
1261 | struct usb_gadget_driver *driver); | ||
1261 | /* defined in gadget.h */ | 1262 | /* defined in gadget.h */ |
1262 | static struct usb_gadget_ops fsl_gadget_ops = { | 1263 | static const struct usb_gadget_ops fsl_gadget_ops = { |
1263 | .get_frame = fsl_get_frame, | 1264 | .get_frame = fsl_get_frame, |
1264 | .wakeup = fsl_wakeup, | 1265 | .wakeup = fsl_wakeup, |
1265 | /* .set_selfpowered = fsl_set_selfpowered, */ /* Always selfpowered */ | 1266 | /* .set_selfpowered = fsl_set_selfpowered, */ /* Always selfpowered */ |
1266 | .vbus_session = fsl_vbus_session, | 1267 | .vbus_session = fsl_vbus_session, |
1267 | .vbus_draw = fsl_vbus_draw, | 1268 | .vbus_draw = fsl_vbus_draw, |
1268 | .pullup = fsl_pullup, | 1269 | .pullup = fsl_pullup, |
1269 | .start = fsl_start, | 1270 | .udc_start = fsl_udc_start, |
1270 | .stop = fsl_stop, | 1271 | .udc_stop = fsl_udc_stop, |
1271 | }; | 1272 | }; |
1272 | 1273 | ||
1273 | /* Set protocol stall on ep0, protocol stall will automatically be cleared | 1274 | /* Set protocol stall on ep0, protocol stall will automatically be cleared |
@@ -1951,22 +1952,12 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) | |||
1951 | * Hook to gadget drivers | 1952 | * Hook to gadget drivers |
1952 | * Called by initialization code of gadget drivers | 1953 | * Called by initialization code of gadget drivers |
1953 | *----------------------------------------------------------------*/ | 1954 | *----------------------------------------------------------------*/ |
1954 | static int fsl_start(struct usb_gadget_driver *driver, | 1955 | static int fsl_udc_start(struct usb_gadget *g, |
1955 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1956 | struct usb_gadget_driver *driver) |
1956 | { | 1957 | { |
1957 | int retval = -ENODEV; | 1958 | int retval = 0; |
1958 | unsigned long flags = 0; | 1959 | unsigned long flags = 0; |
1959 | 1960 | ||
1960 | if (!udc_controller) | ||
1961 | return -ENODEV; | ||
1962 | |||
1963 | if (!driver || driver->max_speed < USB_SPEED_FULL | ||
1964 | || !bind || !driver->disconnect || !driver->setup) | ||
1965 | return -EINVAL; | ||
1966 | |||
1967 | if (udc_controller->driver) | ||
1968 | return -EBUSY; | ||
1969 | |||
1970 | /* lock is needed but whether should use this lock or another */ | 1961 | /* lock is needed but whether should use this lock or another */ |
1971 | spin_lock_irqsave(&udc_controller->lock, flags); | 1962 | spin_lock_irqsave(&udc_controller->lock, flags); |
1972 | 1963 | ||
@@ -1976,15 +1967,6 @@ static int fsl_start(struct usb_gadget_driver *driver, | |||
1976 | udc_controller->gadget.dev.driver = &driver->driver; | 1967 | udc_controller->gadget.dev.driver = &driver->driver; |
1977 | spin_unlock_irqrestore(&udc_controller->lock, flags); | 1968 | spin_unlock_irqrestore(&udc_controller->lock, flags); |
1978 | 1969 | ||
1979 | /* bind udc driver to gadget driver */ | ||
1980 | retval = bind(&udc_controller->gadget, driver); | ||
1981 | if (retval) { | ||
1982 | VDBG("bind to %s --> %d", driver->driver.name, retval); | ||
1983 | udc_controller->gadget.dev.driver = NULL; | ||
1984 | udc_controller->driver = NULL; | ||
1985 | goto out; | ||
1986 | } | ||
1987 | |||
1988 | if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { | 1970 | if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { |
1989 | /* Suspend the controller until OTG enable it */ | 1971 | /* Suspend the controller until OTG enable it */ |
1990 | udc_controller->stopped = 1; | 1972 | udc_controller->stopped = 1; |
@@ -2010,28 +1992,17 @@ static int fsl_start(struct usb_gadget_driver *driver, | |||
2010 | udc_controller->ep0_state = WAIT_FOR_SETUP; | 1992 | udc_controller->ep0_state = WAIT_FOR_SETUP; |
2011 | udc_controller->ep0_dir = 0; | 1993 | udc_controller->ep0_dir = 0; |
2012 | } | 1994 | } |
2013 | printk(KERN_INFO "%s: bind to driver %s\n", | ||
2014 | udc_controller->gadget.name, driver->driver.name); | ||
2015 | 1995 | ||
2016 | out: | ||
2017 | if (retval) | ||
2018 | printk(KERN_WARNING "gadget driver register failed %d\n", | ||
2019 | retval); | ||
2020 | return retval; | 1996 | return retval; |
2021 | } | 1997 | } |
2022 | 1998 | ||
2023 | /* Disconnect from gadget driver */ | 1999 | /* Disconnect from gadget driver */ |
2024 | static int fsl_stop(struct usb_gadget_driver *driver) | 2000 | static int fsl_udc_stop(struct usb_gadget *g, |
2001 | struct usb_gadget_driver *driver) | ||
2025 | { | 2002 | { |
2026 | struct fsl_ep *loop_ep; | 2003 | struct fsl_ep *loop_ep; |
2027 | unsigned long flags; | 2004 | unsigned long flags; |
2028 | 2005 | ||
2029 | if (!udc_controller) | ||
2030 | return -ENODEV; | ||
2031 | |||
2032 | if (!driver || driver != udc_controller->driver || !driver->unbind) | ||
2033 | return -EINVAL; | ||
2034 | |||
2035 | if (!IS_ERR_OR_NULL(udc_controller->transceiver)) | 2006 | if (!IS_ERR_OR_NULL(udc_controller->transceiver)) |
2036 | otg_set_peripheral(udc_controller->transceiver->otg, NULL); | 2007 | otg_set_peripheral(udc_controller->transceiver->otg, NULL); |
2037 | 2008 | ||
@@ -2052,16 +2023,9 @@ static int fsl_stop(struct usb_gadget_driver *driver) | |||
2052 | nuke(loop_ep, -ESHUTDOWN); | 2023 | nuke(loop_ep, -ESHUTDOWN); |
2053 | spin_unlock_irqrestore(&udc_controller->lock, flags); | 2024 | spin_unlock_irqrestore(&udc_controller->lock, flags); |
2054 | 2025 | ||
2055 | /* report disconnect; the controller is already quiesced */ | ||
2056 | driver->disconnect(&udc_controller->gadget); | ||
2057 | |||
2058 | /* unbind gadget and unhook driver. */ | ||
2059 | driver->unbind(&udc_controller->gadget); | ||
2060 | udc_controller->gadget.dev.driver = NULL; | 2026 | udc_controller->gadget.dev.driver = NULL; |
2061 | udc_controller->driver = NULL; | 2027 | udc_controller->driver = NULL; |
2062 | 2028 | ||
2063 | printk(KERN_WARNING "unregistered gadget driver '%s'\n", | ||
2064 | driver->driver.name); | ||
2065 | return 0; | 2029 | return 0; |
2066 | } | 2030 | } |
2067 | 2031 | ||
diff --git a/drivers/usb/gadget/functions.c b/drivers/usb/gadget/functions.c new file mode 100644 index 000000000000..b13f839e7368 --- /dev/null +++ b/drivers/usb/gadget/functions.c | |||
@@ -0,0 +1,116 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/slab.h> | ||
3 | #include <linux/module.h> | ||
4 | #include <linux/err.h> | ||
5 | |||
6 | #include <linux/usb/composite.h> | ||
7 | |||
8 | static LIST_HEAD(func_list); | ||
9 | static DEFINE_MUTEX(func_lock); | ||
10 | |||
11 | static struct usb_function_instance *try_get_usb_function_instance(const char *name) | ||
12 | { | ||
13 | struct usb_function_driver *fd; | ||
14 | struct usb_function_instance *fi; | ||
15 | |||
16 | fi = ERR_PTR(-ENOENT); | ||
17 | mutex_lock(&func_lock); | ||
18 | list_for_each_entry(fd, &func_list, list) { | ||
19 | |||
20 | if (strcmp(name, fd->name)) | ||
21 | continue; | ||
22 | |||
23 | if (!try_module_get(fd->mod)) { | ||
24 | fi = ERR_PTR(-EBUSY); | ||
25 | break; | ||
26 | } | ||
27 | fi = fd->alloc_inst(); | ||
28 | if (IS_ERR(fi)) | ||
29 | module_put(fd->mod); | ||
30 | else | ||
31 | fi->fd = fd; | ||
32 | break; | ||
33 | } | ||
34 | mutex_unlock(&func_lock); | ||
35 | return fi; | ||
36 | } | ||
37 | |||
38 | struct usb_function_instance *usb_get_function_instance(const char *name) | ||
39 | { | ||
40 | struct usb_function_instance *fi; | ||
41 | int ret; | ||
42 | |||
43 | fi = try_get_usb_function_instance(name); | ||
44 | if (!IS_ERR(fi)) | ||
45 | return fi; | ||
46 | ret = PTR_ERR(fi); | ||
47 | if (ret != -ENOENT) | ||
48 | return fi; | ||
49 | ret = request_module("usbfunc:%s", name); | ||
50 | if (ret < 0) | ||
51 | return ERR_PTR(ret); | ||
52 | return try_get_usb_function_instance(name); | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(usb_get_function_instance); | ||
55 | |||
56 | struct usb_function *usb_get_function(struct usb_function_instance *fi) | ||
57 | { | ||
58 | struct usb_function *f; | ||
59 | |||
60 | f = fi->fd->alloc_func(fi); | ||
61 | if (IS_ERR(f)) | ||
62 | return f; | ||
63 | f->fi = fi; | ||
64 | return f; | ||
65 | } | ||
66 | EXPORT_SYMBOL_GPL(usb_get_function); | ||
67 | |||
68 | void usb_put_function_instance(struct usb_function_instance *fi) | ||
69 | { | ||
70 | struct module *mod; | ||
71 | |||
72 | if (!fi) | ||
73 | return; | ||
74 | |||
75 | mod = fi->fd->mod; | ||
76 | fi->free_func_inst(fi); | ||
77 | module_put(mod); | ||
78 | } | ||
79 | EXPORT_SYMBOL_GPL(usb_put_function_instance); | ||
80 | |||
81 | void usb_put_function(struct usb_function *f) | ||
82 | { | ||
83 | if (!f) | ||
84 | return; | ||
85 | |||
86 | f->free_func(f); | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(usb_put_function); | ||
89 | |||
90 | int usb_function_register(struct usb_function_driver *newf) | ||
91 | { | ||
92 | struct usb_function_driver *fd; | ||
93 | int ret; | ||
94 | |||
95 | ret = -EEXIST; | ||
96 | |||
97 | mutex_lock(&func_lock); | ||
98 | list_for_each_entry(fd, &func_list, list) { | ||
99 | if (!strcmp(fd->name, newf->name)) | ||
100 | goto out; | ||
101 | } | ||
102 | ret = 0; | ||
103 | list_add_tail(&newf->list, &func_list); | ||
104 | out: | ||
105 | mutex_unlock(&func_lock); | ||
106 | return ret; | ||
107 | } | ||
108 | EXPORT_SYMBOL_GPL(usb_function_register); | ||
109 | |||
110 | void usb_function_unregister(struct usb_function_driver *fd) | ||
111 | { | ||
112 | mutex_lock(&func_lock); | ||
113 | list_del(&fd->list); | ||
114 | mutex_unlock(&func_lock); | ||
115 | } | ||
116 | EXPORT_SYMBOL_GPL(usb_function_unregister); | ||
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index fc7cb09ab52b..066cb89376de 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c | |||
@@ -1308,65 +1308,28 @@ static void init_controller(struct fusb300 *fusb300) | |||
1308 | iowrite32(0xcfffff9f, fusb300->reg + FUSB300_OFFSET_IGER1); | 1308 | iowrite32(0xcfffff9f, fusb300->reg + FUSB300_OFFSET_IGER1); |
1309 | } | 1309 | } |
1310 | /*------------------------------------------------------------------------*/ | 1310 | /*------------------------------------------------------------------------*/ |
1311 | static struct fusb300 *the_controller; | 1311 | static int fusb300_udc_start(struct usb_gadget *g, |
1312 | 1312 | struct usb_gadget_driver *driver) | |
1313 | static int fusb300_udc_start(struct usb_gadget_driver *driver, | ||
1314 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | ||
1315 | { | 1313 | { |
1316 | struct fusb300 *fusb300 = the_controller; | 1314 | struct fusb300 *fusb300 = to_fusb300(g); |
1317 | int retval; | ||
1318 | |||
1319 | if (!driver | ||
1320 | || driver->max_speed < USB_SPEED_FULL | ||
1321 | || !bind | ||
1322 | || !driver->setup) | ||
1323 | return -EINVAL; | ||
1324 | |||
1325 | if (!fusb300) | ||
1326 | return -ENODEV; | ||
1327 | |||
1328 | if (fusb300->driver) | ||
1329 | return -EBUSY; | ||
1330 | 1315 | ||
1331 | /* hook up the driver */ | 1316 | /* hook up the driver */ |
1332 | driver->driver.bus = NULL; | 1317 | driver->driver.bus = NULL; |
1333 | fusb300->driver = driver; | 1318 | fusb300->driver = driver; |
1334 | fusb300->gadget.dev.driver = &driver->driver; | 1319 | fusb300->gadget.dev.driver = &driver->driver; |
1335 | 1320 | ||
1336 | retval = device_add(&fusb300->gadget.dev); | ||
1337 | if (retval) { | ||
1338 | pr_err("device_add error (%d)\n", retval); | ||
1339 | goto error; | ||
1340 | } | ||
1341 | |||
1342 | retval = bind(&fusb300->gadget, driver); | ||
1343 | if (retval) { | ||
1344 | pr_err("bind to driver error (%d)\n", retval); | ||
1345 | device_del(&fusb300->gadget.dev); | ||
1346 | goto error; | ||
1347 | } | ||
1348 | |||
1349 | return 0; | 1321 | return 0; |
1350 | |||
1351 | error: | ||
1352 | fusb300->driver = NULL; | ||
1353 | fusb300->gadget.dev.driver = NULL; | ||
1354 | |||
1355 | return retval; | ||
1356 | } | 1322 | } |
1357 | 1323 | ||
1358 | static int fusb300_udc_stop(struct usb_gadget_driver *driver) | 1324 | static int fusb300_udc_stop(struct usb_gadget *g, |
1325 | struct usb_gadget_driver *driver) | ||
1359 | { | 1326 | { |
1360 | struct fusb300 *fusb300 = the_controller; | 1327 | struct fusb300 *fusb300 = to_fusb300(g); |
1361 | |||
1362 | if (driver != fusb300->driver || !driver->unbind) | ||
1363 | return -EINVAL; | ||
1364 | 1328 | ||
1365 | driver->unbind(&fusb300->gadget); | 1329 | driver->unbind(&fusb300->gadget); |
1366 | fusb300->gadget.dev.driver = NULL; | 1330 | fusb300->gadget.dev.driver = NULL; |
1367 | 1331 | ||
1368 | init_controller(fusb300); | 1332 | init_controller(fusb300); |
1369 | device_del(&fusb300->gadget.dev); | ||
1370 | fusb300->driver = NULL; | 1333 | fusb300->driver = NULL; |
1371 | 1334 | ||
1372 | return 0; | 1335 | return 0; |
@@ -1378,10 +1341,10 @@ static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
1378 | return 0; | 1341 | return 0; |
1379 | } | 1342 | } |
1380 | 1343 | ||
1381 | static struct usb_gadget_ops fusb300_gadget_ops = { | 1344 | static const struct usb_gadget_ops fusb300_gadget_ops = { |
1382 | .pullup = fusb300_udc_pullup, | 1345 | .pullup = fusb300_udc_pullup, |
1383 | .start = fusb300_udc_start, | 1346 | .udc_start = fusb300_udc_start, |
1384 | .stop = fusb300_udc_stop, | 1347 | .udc_stop = fusb300_udc_stop, |
1385 | }; | 1348 | }; |
1386 | 1349 | ||
1387 | static int __exit fusb300_remove(struct platform_device *pdev) | 1350 | static int __exit fusb300_remove(struct platform_device *pdev) |
@@ -1505,8 +1468,6 @@ static int __init fusb300_probe(struct platform_device *pdev) | |||
1505 | fusb300->gadget.ep0 = &fusb300->ep[0]->ep; | 1468 | fusb300->gadget.ep0 = &fusb300->ep[0]->ep; |
1506 | INIT_LIST_HEAD(&fusb300->gadget.ep0->ep_list); | 1469 | INIT_LIST_HEAD(&fusb300->gadget.ep0->ep_list); |
1507 | 1470 | ||
1508 | the_controller = fusb300; | ||
1509 | |||
1510 | fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep, | 1471 | fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep, |
1511 | GFP_KERNEL); | 1472 | GFP_KERNEL); |
1512 | if (fusb300->ep0_req == NULL) | 1473 | if (fusb300->ep0_req == NULL) |
@@ -1517,9 +1478,19 @@ static int __init fusb300_probe(struct platform_device *pdev) | |||
1517 | if (ret) | 1478 | if (ret) |
1518 | goto err_add_udc; | 1479 | goto err_add_udc; |
1519 | 1480 | ||
1481 | ret = device_add(&fusb300->gadget.dev); | ||
1482 | if (ret) { | ||
1483 | pr_err("device_add error (%d)\n", ret); | ||
1484 | goto err_add_device; | ||
1485 | } | ||
1486 | |||
1520 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); | 1487 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); |
1521 | 1488 | ||
1522 | return 0; | 1489 | return 0; |
1490 | |||
1491 | err_add_device: | ||
1492 | usb_del_gadget_udc(&fusb300->gadget); | ||
1493 | |||
1523 | err_add_udc: | 1494 | err_add_udc: |
1524 | fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); | 1495 | fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); |
1525 | 1496 | ||
diff --git a/drivers/usb/gadget/fusb300_udc.h b/drivers/usb/gadget/fusb300_udc.h index 542cd83cc806..6ba444ae8dd5 100644 --- a/drivers/usb/gadget/fusb300_udc.h +++ b/drivers/usb/gadget/fusb300_udc.h | |||
@@ -673,4 +673,6 @@ struct fusb300 { | |||
673 | u8 reenum; /* if re-enumeration */ | 673 | u8 reenum; /* if re-enumeration */ |
674 | }; | 674 | }; |
675 | 675 | ||
676 | #define to_fusb300(g) (container_of((g), struct fusb300, gadget)) | ||
677 | |||
676 | #endif | 678 | #endif |
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h index 71ca193358b8..ef3e8515272b 100644 --- a/drivers/usb/gadget/g_zero.h +++ b/drivers/usb/gadget/g_zero.h | |||
@@ -6,11 +6,34 @@ | |||
6 | #ifndef __G_ZERO_H | 6 | #ifndef __G_ZERO_H |
7 | #define __G_ZERO_H | 7 | #define __G_ZERO_H |
8 | 8 | ||
9 | #include <linux/usb/composite.h> | 9 | struct usb_zero_options { |
10 | unsigned pattern; | ||
11 | unsigned isoc_interval; | ||
12 | unsigned isoc_maxpacket; | ||
13 | unsigned isoc_mult; | ||
14 | unsigned isoc_maxburst; | ||
15 | unsigned bulk_buflen; | ||
16 | unsigned qlen; | ||
17 | }; | ||
10 | 18 | ||
11 | /* global state */ | 19 | struct f_ss_opts { |
12 | extern unsigned buflen; | 20 | struct usb_function_instance func_inst; |
13 | extern const struct usb_descriptor_header *otg_desc[]; | 21 | unsigned pattern; |
22 | unsigned isoc_interval; | ||
23 | unsigned isoc_maxpacket; | ||
24 | unsigned isoc_mult; | ||
25 | unsigned isoc_maxburst; | ||
26 | unsigned bulk_buflen; | ||
27 | }; | ||
28 | |||
29 | struct f_lb_opts { | ||
30 | struct usb_function_instance func_inst; | ||
31 | unsigned bulk_buflen; | ||
32 | unsigned qlen; | ||
33 | }; | ||
34 | |||
35 | void lb_modexit(void); | ||
36 | int lb_modinit(void); | ||
14 | 37 | ||
15 | /* common utilities */ | 38 | /* common utilities */ |
16 | struct usb_request *alloc_ep_req(struct usb_ep *ep, int len); | 39 | struct usb_request *alloc_ep_req(struct usb_ep *ep, int len); |
@@ -19,8 +42,4 @@ void disable_endpoints(struct usb_composite_dev *cdev, | |||
19 | struct usb_ep *in, struct usb_ep *out, | 42 | struct usb_ep *in, struct usb_ep *out, |
20 | struct usb_ep *iso_in, struct usb_ep *iso_out); | 43 | struct usb_ep *iso_in, struct usb_ep *iso_out); |
21 | 44 | ||
22 | /* configuration-specific linkup */ | ||
23 | int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume); | ||
24 | int loopback_add(struct usb_composite_dev *cdev, bool autoresume); | ||
25 | |||
26 | #endif /* __G_ZERO_H */ | 45 | #endif /* __G_ZERO_H */ |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 881aab86ae99..e879e2c9f461 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -125,7 +125,7 @@ static struct usb_configuration midi_config = { | |||
125 | .bConfigurationValue = 1, | 125 | .bConfigurationValue = 1, |
126 | /* .iConfiguration = DYNAMIC */ | 126 | /* .iConfiguration = DYNAMIC */ |
127 | .bmAttributes = USB_CONFIG_ATT_ONE, | 127 | .bmAttributes = USB_CONFIG_ATT_ONE, |
128 | .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, | 128 | .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW, |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static int __init midi_bind_config(struct usb_configuration *c) | 131 | static int __init midi_bind_config(struct usb_configuration *c) |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 51037cb78604..85742d4c67df 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -993,14 +993,15 @@ static int goku_get_frame(struct usb_gadget *_gadget) | |||
993 | return -EOPNOTSUPP; | 993 | return -EOPNOTSUPP; |
994 | } | 994 | } |
995 | 995 | ||
996 | static int goku_start(struct usb_gadget_driver *driver, | 996 | static int goku_udc_start(struct usb_gadget *g, |
997 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 997 | struct usb_gadget_driver *driver); |
998 | static int goku_stop(struct usb_gadget_driver *driver); | 998 | static int goku_udc_stop(struct usb_gadget *g, |
999 | struct usb_gadget_driver *driver); | ||
999 | 1000 | ||
1000 | static const struct usb_gadget_ops goku_ops = { | 1001 | static const struct usb_gadget_ops goku_ops = { |
1001 | .get_frame = goku_get_frame, | 1002 | .get_frame = goku_get_frame, |
1002 | .start = goku_start, | 1003 | .udc_start = goku_udc_start, |
1003 | .stop = goku_stop, | 1004 | .udc_stop = goku_udc_stop, |
1004 | // no remote wakeup | 1005 | // no remote wakeup |
1005 | // not selfpowered | 1006 | // not selfpowered |
1006 | }; | 1007 | }; |
@@ -1339,50 +1340,28 @@ static void udc_enable(struct goku_udc *dev) | |||
1339 | * - one function driver, initted second | 1340 | * - one function driver, initted second |
1340 | */ | 1341 | */ |
1341 | 1342 | ||
1342 | static struct goku_udc *the_controller; | ||
1343 | |||
1344 | /* when a driver is successfully registered, it will receive | 1343 | /* when a driver is successfully registered, it will receive |
1345 | * control requests including set_configuration(), which enables | 1344 | * control requests including set_configuration(), which enables |
1346 | * non-control requests. then usb traffic follows until a | 1345 | * non-control requests. then usb traffic follows until a |
1347 | * disconnect is reported. then a host may connect again, or | 1346 | * disconnect is reported. then a host may connect again, or |
1348 | * the driver might get unbound. | 1347 | * the driver might get unbound. |
1349 | */ | 1348 | */ |
1350 | static int goku_start(struct usb_gadget_driver *driver, | 1349 | static int goku_udc_start(struct usb_gadget *g, |
1351 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1350 | struct usb_gadget_driver *driver) |
1352 | { | 1351 | { |
1353 | struct goku_udc *dev = the_controller; | 1352 | struct goku_udc *dev = to_goku_udc(g); |
1354 | int retval; | ||
1355 | |||
1356 | if (!driver | ||
1357 | || driver->max_speed < USB_SPEED_FULL | ||
1358 | || !bind | ||
1359 | || !driver->disconnect | ||
1360 | || !driver->setup) | ||
1361 | return -EINVAL; | ||
1362 | if (!dev) | ||
1363 | return -ENODEV; | ||
1364 | if (dev->driver) | ||
1365 | return -EBUSY; | ||
1366 | 1353 | ||
1367 | /* hook up the driver */ | 1354 | /* hook up the driver */ |
1368 | driver->driver.bus = NULL; | 1355 | driver->driver.bus = NULL; |
1369 | dev->driver = driver; | 1356 | dev->driver = driver; |
1370 | dev->gadget.dev.driver = &driver->driver; | 1357 | dev->gadget.dev.driver = &driver->driver; |
1371 | retval = bind(&dev->gadget, driver); | ||
1372 | if (retval) { | ||
1373 | DBG(dev, "bind to driver %s --> error %d\n", | ||
1374 | driver->driver.name, retval); | ||
1375 | dev->driver = NULL; | ||
1376 | dev->gadget.dev.driver = NULL; | ||
1377 | return retval; | ||
1378 | } | ||
1379 | 1358 | ||
1380 | /* then enable host detection and ep0; and we're ready | 1359 | /* |
1360 | * then enable host detection and ep0; and we're ready | ||
1381 | * for set_configuration as well as eventual disconnect. | 1361 | * for set_configuration as well as eventual disconnect. |
1382 | */ | 1362 | */ |
1383 | udc_enable(dev); | 1363 | udc_enable(dev); |
1384 | 1364 | ||
1385 | DBG(dev, "registered gadget driver '%s'\n", driver->driver.name); | ||
1386 | return 0; | 1365 | return 0; |
1387 | } | 1366 | } |
1388 | 1367 | ||
@@ -1400,35 +1379,23 @@ stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver) | |||
1400 | udc_reset (dev); | 1379 | udc_reset (dev); |
1401 | for (i = 0; i < 4; i++) | 1380 | for (i = 0; i < 4; i++) |
1402 | nuke(&dev->ep [i], -ESHUTDOWN); | 1381 | nuke(&dev->ep [i], -ESHUTDOWN); |
1403 | if (driver) { | ||
1404 | spin_unlock(&dev->lock); | ||
1405 | driver->disconnect(&dev->gadget); | ||
1406 | spin_lock(&dev->lock); | ||
1407 | } | ||
1408 | 1382 | ||
1409 | if (dev->driver) | 1383 | if (dev->driver) |
1410 | udc_enable(dev); | 1384 | udc_enable(dev); |
1411 | } | 1385 | } |
1412 | 1386 | ||
1413 | static int goku_stop(struct usb_gadget_driver *driver) | 1387 | static int goku_udc_stop(struct usb_gadget *g, |
1388 | struct usb_gadget_driver *driver) | ||
1414 | { | 1389 | { |
1415 | struct goku_udc *dev = the_controller; | 1390 | struct goku_udc *dev = to_goku_udc(g); |
1416 | unsigned long flags; | 1391 | unsigned long flags; |
1417 | 1392 | ||
1418 | if (!dev) | ||
1419 | return -ENODEV; | ||
1420 | if (!driver || driver != dev->driver || !driver->unbind) | ||
1421 | return -EINVAL; | ||
1422 | |||
1423 | spin_lock_irqsave(&dev->lock, flags); | 1393 | spin_lock_irqsave(&dev->lock, flags); |
1424 | dev->driver = NULL; | 1394 | dev->driver = NULL; |
1425 | stop_activity(dev, driver); | 1395 | stop_activity(dev, driver); |
1426 | spin_unlock_irqrestore(&dev->lock, flags); | 1396 | spin_unlock_irqrestore(&dev->lock, flags); |
1427 | |||
1428 | driver->unbind(&dev->gadget); | ||
1429 | dev->gadget.dev.driver = NULL; | 1397 | dev->gadget.dev.driver = NULL; |
1430 | 1398 | ||
1431 | DBG(dev, "unregistered driver '%s'\n", driver->driver.name); | ||
1432 | return 0; | 1399 | return 0; |
1433 | } | 1400 | } |
1434 | 1401 | ||
@@ -1754,7 +1721,6 @@ static void goku_remove(struct pci_dev *pdev) | |||
1754 | 1721 | ||
1755 | pci_set_drvdata(pdev, NULL); | 1722 | pci_set_drvdata(pdev, NULL); |
1756 | dev->regs = NULL; | 1723 | dev->regs = NULL; |
1757 | the_controller = NULL; | ||
1758 | 1724 | ||
1759 | INFO(dev, "unbind\n"); | 1725 | INFO(dev, "unbind\n"); |
1760 | } | 1726 | } |
@@ -1770,13 +1736,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1770 | void __iomem *base = NULL; | 1736 | void __iomem *base = NULL; |
1771 | int retval; | 1737 | int retval; |
1772 | 1738 | ||
1773 | /* if you want to support more than one controller in a system, | ||
1774 | * usb_gadget_driver_{register,unregister}() must change. | ||
1775 | */ | ||
1776 | if (the_controller) { | ||
1777 | pr_warning("ignoring %s\n", pci_name(pdev)); | ||
1778 | return -EBUSY; | ||
1779 | } | ||
1780 | if (!pdev->irq) { | 1739 | if (!pdev->irq) { |
1781 | printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev)); | 1740 | printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev)); |
1782 | retval = -ENODEV; | 1741 | retval = -ENODEV; |
@@ -1851,7 +1810,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1851 | create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); | 1810 | create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); |
1852 | #endif | 1811 | #endif |
1853 | 1812 | ||
1854 | the_controller = dev; | ||
1855 | retval = device_register(&dev->gadget.dev); | 1813 | retval = device_register(&dev->gadget.dev); |
1856 | if (retval) { | 1814 | if (retval) { |
1857 | put_device(&dev->gadget.dev); | 1815 | put_device(&dev->gadget.dev); |
diff --git a/drivers/usb/gadget/goku_udc.h b/drivers/usb/gadget/goku_udc.h index 85cdce0d1901..b4470d2b1d86 100644 --- a/drivers/usb/gadget/goku_udc.h +++ b/drivers/usb/gadget/goku_udc.h | |||
@@ -261,6 +261,7 @@ struct goku_udc { | |||
261 | /* statistics... */ | 261 | /* statistics... */ |
262 | unsigned long irqs; | 262 | unsigned long irqs; |
263 | }; | 263 | }; |
264 | #define to_goku_udc(g) (container_of((g), struct goku_udc, gadget)) | ||
264 | 265 | ||
265 | /*-------------------------------------------------------------------------*/ | 266 | /*-------------------------------------------------------------------------*/ |
266 | 267 | ||
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index dfce0cfe4e6f..c1b8c2dd808d 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1463,42 +1463,16 @@ static struct usb_ep_ops m66592_ep_ops = { | |||
1463 | }; | 1463 | }; |
1464 | 1464 | ||
1465 | /*-------------------------------------------------------------------------*/ | 1465 | /*-------------------------------------------------------------------------*/ |
1466 | static struct m66592 *the_controller; | 1466 | static int m66592_udc_start(struct usb_gadget *g, |
1467 | 1467 | struct usb_gadget_driver *driver) | |
1468 | static int m66592_start(struct usb_gadget_driver *driver, | ||
1469 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | ||
1470 | { | 1468 | { |
1471 | struct m66592 *m66592 = the_controller; | 1469 | struct m66592 *m66592 = to_m66592(g); |
1472 | int retval; | ||
1473 | |||
1474 | if (!driver | ||
1475 | || driver->max_speed < USB_SPEED_HIGH | ||
1476 | || !bind | ||
1477 | || !driver->setup) | ||
1478 | return -EINVAL; | ||
1479 | if (!m66592) | ||
1480 | return -ENODEV; | ||
1481 | if (m66592->driver) | ||
1482 | return -EBUSY; | ||
1483 | 1470 | ||
1484 | /* hook up the driver */ | 1471 | /* hook up the driver */ |
1485 | driver->driver.bus = NULL; | 1472 | driver->driver.bus = NULL; |
1486 | m66592->driver = driver; | 1473 | m66592->driver = driver; |
1487 | m66592->gadget.dev.driver = &driver->driver; | 1474 | m66592->gadget.dev.driver = &driver->driver; |
1488 | 1475 | ||
1489 | retval = device_add(&m66592->gadget.dev); | ||
1490 | if (retval) { | ||
1491 | pr_err("device_add error (%d)\n", retval); | ||
1492 | goto error; | ||
1493 | } | ||
1494 | |||
1495 | retval = bind(&m66592->gadget, driver); | ||
1496 | if (retval) { | ||
1497 | pr_err("bind to driver error (%d)\n", retval); | ||
1498 | device_del(&m66592->gadget.dev); | ||
1499 | goto error; | ||
1500 | } | ||
1501 | |||
1502 | m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); | 1476 | m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); |
1503 | if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) { | 1477 | if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) { |
1504 | m66592_start_xclock(m66592); | 1478 | m66592_start_xclock(m66592); |
@@ -1510,26 +1484,12 @@ static int m66592_start(struct usb_gadget_driver *driver, | |||
1510 | } | 1484 | } |
1511 | 1485 | ||
1512 | return 0; | 1486 | return 0; |
1513 | |||
1514 | error: | ||
1515 | m66592->driver = NULL; | ||
1516 | m66592->gadget.dev.driver = NULL; | ||
1517 | |||
1518 | return retval; | ||
1519 | } | 1487 | } |
1520 | 1488 | ||
1521 | static int m66592_stop(struct usb_gadget_driver *driver) | 1489 | static int m66592_udc_stop(struct usb_gadget *g, |
1490 | struct usb_gadget_driver *driver) | ||
1522 | { | 1491 | { |
1523 | struct m66592 *m66592 = the_controller; | 1492 | struct m66592 *m66592 = to_m66592(g); |
1524 | unsigned long flags; | ||
1525 | |||
1526 | if (driver != m66592->driver || !driver->unbind) | ||
1527 | return -EINVAL; | ||
1528 | |||
1529 | spin_lock_irqsave(&m66592->lock, flags); | ||
1530 | if (m66592->gadget.speed != USB_SPEED_UNKNOWN) | ||
1531 | m66592_usb_disconnect(m66592); | ||
1532 | spin_unlock_irqrestore(&m66592->lock, flags); | ||
1533 | 1493 | ||
1534 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); | 1494 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); |
1535 | 1495 | ||
@@ -1539,8 +1499,8 @@ static int m66592_stop(struct usb_gadget_driver *driver) | |||
1539 | init_controller(m66592); | 1499 | init_controller(m66592); |
1540 | disable_controller(m66592); | 1500 | disable_controller(m66592); |
1541 | 1501 | ||
1542 | device_del(&m66592->gadget.dev); | ||
1543 | m66592->driver = NULL; | 1502 | m66592->driver = NULL; |
1503 | |||
1544 | return 0; | 1504 | return 0; |
1545 | } | 1505 | } |
1546 | 1506 | ||
@@ -1566,10 +1526,10 @@ static int m66592_pullup(struct usb_gadget *gadget, int is_on) | |||
1566 | return 0; | 1526 | return 0; |
1567 | } | 1527 | } |
1568 | 1528 | ||
1569 | static struct usb_gadget_ops m66592_gadget_ops = { | 1529 | static const struct usb_gadget_ops m66592_gadget_ops = { |
1570 | .get_frame = m66592_get_frame, | 1530 | .get_frame = m66592_get_frame, |
1571 | .start = m66592_start, | 1531 | .udc_start = m66592_udc_start, |
1572 | .stop = m66592_stop, | 1532 | .udc_stop = m66592_udc_stop, |
1573 | .pullup = m66592_pullup, | 1533 | .pullup = m66592_pullup, |
1574 | }; | 1534 | }; |
1575 | 1535 | ||
@@ -1578,6 +1538,7 @@ static int __exit m66592_remove(struct platform_device *pdev) | |||
1578 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); | 1538 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); |
1579 | 1539 | ||
1580 | usb_del_gadget_udc(&m66592->gadget); | 1540 | usb_del_gadget_udc(&m66592->gadget); |
1541 | device_del(&m66592->gadget.dev); | ||
1581 | 1542 | ||
1582 | del_timer_sync(&m66592->timer); | 1543 | del_timer_sync(&m66592->timer); |
1583 | iounmap(m66592->reg); | 1544 | iounmap(m66592->reg); |
@@ -1706,8 +1667,6 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1706 | m66592->pipenum2ep[0] = &m66592->ep[0]; | 1667 | m66592->pipenum2ep[0] = &m66592->ep[0]; |
1707 | m66592->epaddr2ep[0] = &m66592->ep[0]; | 1668 | m66592->epaddr2ep[0] = &m66592->ep[0]; |
1708 | 1669 | ||
1709 | the_controller = m66592; | ||
1710 | |||
1711 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); | 1670 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); |
1712 | if (m66592->ep0_req == NULL) | 1671 | if (m66592->ep0_req == NULL) |
1713 | goto clean_up3; | 1672 | goto clean_up3; |
@@ -1715,6 +1674,12 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1715 | 1674 | ||
1716 | init_controller(m66592); | 1675 | init_controller(m66592); |
1717 | 1676 | ||
1677 | ret = device_add(&m66592->gadget.dev); | ||
1678 | if (ret) { | ||
1679 | pr_err("device_add error (%d)\n", ret); | ||
1680 | goto err_device_add; | ||
1681 | } | ||
1682 | |||
1718 | ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget); | 1683 | ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget); |
1719 | if (ret) | 1684 | if (ret) |
1720 | goto err_add_udc; | 1685 | goto err_add_udc; |
@@ -1723,6 +1688,9 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1723 | return 0; | 1688 | return 0; |
1724 | 1689 | ||
1725 | err_add_udc: | 1690 | err_add_udc: |
1691 | device_del(&m66592->gadget.dev); | ||
1692 | |||
1693 | err_device_add: | ||
1726 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); | 1694 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); |
1727 | 1695 | ||
1728 | clean_up3: | 1696 | clean_up3: |
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index 16c7e14678b8..96d49d7bfb6b 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h | |||
@@ -492,6 +492,7 @@ struct m66592 { | |||
492 | int isochronous; | 492 | int isochronous; |
493 | int num_dma; | 493 | int num_dma; |
494 | }; | 494 | }; |
495 | #define to_m66592(g) (container_of((g), struct m66592, gadget)) | ||
495 | 496 | ||
496 | #define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget) | 497 | #define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget) |
497 | #define m66592_to_gadget(m66592) (&m66592->gadget) | 498 | #define m66592_to_gadget(m66592) (&m66592->gadget) |
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 88472bf7dbb7..20bbbf917fc2 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | #include "u_serial.h" | ||
19 | #if defined USB_ETH_RNDIS | 20 | #if defined USB_ETH_RNDIS |
20 | # undef USB_ETH_RNDIS | 21 | # undef USB_ETH_RNDIS |
21 | #endif | 22 | #endif |
@@ -42,9 +43,6 @@ MODULE_LICENSE("GPL"); | |||
42 | */ | 43 | */ |
43 | #include "f_mass_storage.c" | 44 | #include "f_mass_storage.c" |
44 | 45 | ||
45 | #include "u_serial.c" | ||
46 | #include "f_acm.c" | ||
47 | |||
48 | #include "f_ecm.c" | 46 | #include "f_ecm.c" |
49 | #include "f_subset.c" | 47 | #include "f_subset.c" |
50 | #ifdef USB_ETH_RNDIS | 48 | #ifdef USB_ETH_RNDIS |
@@ -137,10 +135,13 @@ static struct fsg_common fsg_common; | |||
137 | 135 | ||
138 | static u8 hostaddr[ETH_ALEN]; | 136 | static u8 hostaddr[ETH_ALEN]; |
139 | 137 | ||
138 | static unsigned char tty_line; | ||
139 | static struct usb_function_instance *fi_acm; | ||
140 | 140 | ||
141 | /********** RNDIS **********/ | 141 | /********** RNDIS **********/ |
142 | 142 | ||
143 | #ifdef USB_ETH_RNDIS | 143 | #ifdef USB_ETH_RNDIS |
144 | static struct usb_function *f_acm_rndis; | ||
144 | 145 | ||
145 | static __init int rndis_do_config(struct usb_configuration *c) | 146 | static __init int rndis_do_config(struct usb_configuration *c) |
146 | { | 147 | { |
@@ -155,15 +156,25 @@ static __init int rndis_do_config(struct usb_configuration *c) | |||
155 | if (ret < 0) | 156 | if (ret < 0) |
156 | return ret; | 157 | return ret; |
157 | 158 | ||
158 | ret = acm_bind_config(c, 0); | 159 | f_acm_rndis = usb_get_function(fi_acm); |
159 | if (ret < 0) | 160 | if (IS_ERR(f_acm_rndis)) |
160 | return ret; | 161 | goto err_func_acm; |
162 | |||
163 | ret = usb_add_function(c, f_acm_rndis); | ||
164 | if (ret) | ||
165 | goto err_conf; | ||
161 | 166 | ||
162 | ret = fsg_bind_config(c->cdev, c, &fsg_common); | 167 | ret = fsg_bind_config(c->cdev, c, &fsg_common); |
163 | if (ret < 0) | 168 | if (ret < 0) |
164 | return ret; | 169 | goto err_fsg; |
165 | 170 | ||
166 | return 0; | 171 | return 0; |
172 | err_fsg: | ||
173 | usb_remove_function(c, f_acm_rndis); | ||
174 | err_conf: | ||
175 | usb_put_function(f_acm_rndis); | ||
176 | err_func_acm: | ||
177 | return ret; | ||
167 | } | 178 | } |
168 | 179 | ||
169 | static int rndis_config_register(struct usb_composite_dev *cdev) | 180 | static int rndis_config_register(struct usb_composite_dev *cdev) |
@@ -192,6 +203,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev) | |||
192 | /********** CDC ECM **********/ | 203 | /********** CDC ECM **********/ |
193 | 204 | ||
194 | #ifdef CONFIG_USB_G_MULTI_CDC | 205 | #ifdef CONFIG_USB_G_MULTI_CDC |
206 | static struct usb_function *f_acm_multi; | ||
195 | 207 | ||
196 | static __init int cdc_do_config(struct usb_configuration *c) | 208 | static __init int cdc_do_config(struct usb_configuration *c) |
197 | { | 209 | { |
@@ -206,15 +218,26 @@ static __init int cdc_do_config(struct usb_configuration *c) | |||
206 | if (ret < 0) | 218 | if (ret < 0) |
207 | return ret; | 219 | return ret; |
208 | 220 | ||
209 | ret = acm_bind_config(c, 0); | 221 | /* implicit port_num is zero */ |
210 | if (ret < 0) | 222 | f_acm_multi = usb_get_function(fi_acm); |
211 | return ret; | 223 | if (IS_ERR(f_acm_multi)) |
224 | goto err_func_acm; | ||
225 | |||
226 | ret = usb_add_function(c, f_acm_multi); | ||
227 | if (ret) | ||
228 | goto err_conf; | ||
212 | 229 | ||
213 | ret = fsg_bind_config(c->cdev, c, &fsg_common); | 230 | ret = fsg_bind_config(c->cdev, c, &fsg_common); |
214 | if (ret < 0) | 231 | if (ret < 0) |
215 | return ret; | 232 | goto err_fsg; |
216 | 233 | ||
217 | return 0; | 234 | return 0; |
235 | err_fsg: | ||
236 | usb_remove_function(c, f_acm_multi); | ||
237 | err_conf: | ||
238 | usb_put_function(f_acm_multi); | ||
239 | err_func_acm: | ||
240 | return ret; | ||
218 | } | 241 | } |
219 | 242 | ||
220 | static int cdc_config_register(struct usb_composite_dev *cdev) | 243 | static int cdc_config_register(struct usb_composite_dev *cdev) |
@@ -243,10 +266,10 @@ static int cdc_config_register(struct usb_composite_dev *cdev) | |||
243 | 266 | ||
244 | /****************************** Gadget Bind ******************************/ | 267 | /****************************** Gadget Bind ******************************/ |
245 | 268 | ||
246 | |||
247 | static int __ref multi_bind(struct usb_composite_dev *cdev) | 269 | static int __ref multi_bind(struct usb_composite_dev *cdev) |
248 | { | 270 | { |
249 | struct usb_gadget *gadget = cdev->gadget; | 271 | struct usb_gadget *gadget = cdev->gadget; |
272 | struct f_serial_opts *opts; | ||
250 | int status; | 273 | int status; |
251 | 274 | ||
252 | if (!can_support_ecm(cdev->gadget)) { | 275 | if (!can_support_ecm(cdev->gadget)) { |
@@ -261,10 +284,19 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) | |||
261 | return status; | 284 | return status; |
262 | 285 | ||
263 | /* set up serial link layer */ | 286 | /* set up serial link layer */ |
264 | status = gserial_setup(cdev->gadget, 1); | 287 | status = gserial_alloc_line(&tty_line); |
265 | if (status < 0) | 288 | if (status < 0) |
266 | goto fail0; | 289 | goto fail0; |
267 | 290 | ||
291 | fi_acm = usb_get_function_instance("acm"); | ||
292 | if (IS_ERR(fi_acm)) { | ||
293 | status = PTR_ERR(fi_acm); | ||
294 | goto fail0dot5; | ||
295 | } | ||
296 | |||
297 | opts = container_of(fi_acm, struct f_serial_opts, func_inst); | ||
298 | opts->port_num = tty_line; | ||
299 | |||
268 | /* set up mass storage function */ | 300 | /* set up mass storage function */ |
269 | { | 301 | { |
270 | void *retp; | 302 | void *retp; |
@@ -301,7 +333,9 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) | |||
301 | fail2: | 333 | fail2: |
302 | fsg_common_put(&fsg_common); | 334 | fsg_common_put(&fsg_common); |
303 | fail1: | 335 | fail1: |
304 | gserial_cleanup(); | 336 | usb_put_function_instance(fi_acm); |
337 | fail0dot5: | ||
338 | gserial_free_line(tty_line); | ||
305 | fail0: | 339 | fail0: |
306 | gether_cleanup(); | 340 | gether_cleanup(); |
307 | return status; | 341 | return status; |
@@ -309,7 +343,14 @@ fail0: | |||
309 | 343 | ||
310 | static int __exit multi_unbind(struct usb_composite_dev *cdev) | 344 | static int __exit multi_unbind(struct usb_composite_dev *cdev) |
311 | { | 345 | { |
312 | gserial_cleanup(); | 346 | #ifdef CONFIG_USB_G_MULTI_CDC |
347 | usb_put_function(f_acm_multi); | ||
348 | #endif | ||
349 | #ifdef USB_ETH_RNDIS | ||
350 | usb_put_function(f_acm_rndis); | ||
351 | #endif | ||
352 | usb_put_function_instance(fi_acm); | ||
353 | gserial_free_line(tty_line); | ||
313 | gether_cleanup(); | 354 | gether_cleanup(); |
314 | return 0; | 355 | return 0; |
315 | } | 356 | } |
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 6e8b1272ebce..c8cf959057fe 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c | |||
@@ -61,9 +61,6 @@ static DECLARE_COMPLETION(release_done); | |||
61 | static const char driver_name[] = "mv_udc"; | 61 | static const char driver_name[] = "mv_udc"; |
62 | static const char driver_desc[] = DRIVER_DESC; | 62 | static const char driver_desc[] = DRIVER_DESC; |
63 | 63 | ||
64 | /* controller device global variable */ | ||
65 | static struct mv_udc *the_controller; | ||
66 | |||
67 | static void nuke(struct mv_ep *ep, int status); | 64 | static void nuke(struct mv_ep *ep, int status); |
68 | static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver); | 65 | static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver); |
69 | 66 | ||
@@ -1268,9 +1265,8 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) | |||
1268 | return retval; | 1265 | return retval; |
1269 | } | 1266 | } |
1270 | 1267 | ||
1271 | static int mv_udc_start(struct usb_gadget_driver *driver, | 1268 | static int mv_udc_start(struct usb_gadget *, struct usb_gadget_driver *); |
1272 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1269 | static int mv_udc_stop(struct usb_gadget *, struct usb_gadget_driver *); |
1273 | static int mv_udc_stop(struct usb_gadget_driver *driver); | ||
1274 | /* device controller usb_gadget_ops structure */ | 1270 | /* device controller usb_gadget_ops structure */ |
1275 | static const struct usb_gadget_ops mv_ops = { | 1271 | static const struct usb_gadget_ops mv_ops = { |
1276 | 1272 | ||
@@ -1285,8 +1281,8 @@ static const struct usb_gadget_ops mv_ops = { | |||
1285 | 1281 | ||
1286 | /* D+ pullup, software-controlled connect/disconnect to USB host */ | 1282 | /* D+ pullup, software-controlled connect/disconnect to USB host */ |
1287 | .pullup = mv_udc_pullup, | 1283 | .pullup = mv_udc_pullup, |
1288 | .start = mv_udc_start, | 1284 | .udc_start = mv_udc_start, |
1289 | .stop = mv_udc_stop, | 1285 | .udc_stop = mv_udc_stop, |
1290 | }; | 1286 | }; |
1291 | 1287 | ||
1292 | static int eps_init(struct mv_udc *udc) | 1288 | static int eps_init(struct mv_udc *udc) |
@@ -1373,15 +1369,14 @@ static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver) | |||
1373 | } | 1369 | } |
1374 | } | 1370 | } |
1375 | 1371 | ||
1376 | static int mv_udc_start(struct usb_gadget_driver *driver, | 1372 | static int mv_udc_start(struct usb_gadget *gadget, |
1377 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1373 | struct usb_gadget_driver *driver) |
1378 | { | 1374 | { |
1379 | struct mv_udc *udc = the_controller; | 1375 | struct mv_udc *udc; |
1380 | int retval = 0; | 1376 | int retval = 0; |
1381 | unsigned long flags; | 1377 | unsigned long flags; |
1382 | 1378 | ||
1383 | if (!udc) | 1379 | udc = container_of(gadget, struct mv_udc, gadget); |
1384 | return -ENODEV; | ||
1385 | 1380 | ||
1386 | if (udc->driver) | 1381 | if (udc->driver) |
1387 | return -EBUSY; | 1382 | return -EBUSY; |
@@ -1399,26 +1394,14 @@ static int mv_udc_start(struct usb_gadget_driver *driver, | |||
1399 | 1394 | ||
1400 | spin_unlock_irqrestore(&udc->lock, flags); | 1395 | spin_unlock_irqrestore(&udc->lock, flags); |
1401 | 1396 | ||
1402 | retval = bind(&udc->gadget, driver); | 1397 | if (udc->transceiver) { |
1403 | if (retval) { | ||
1404 | dev_err(&udc->dev->dev, "bind to driver %s --> %d\n", | ||
1405 | driver->driver.name, retval); | ||
1406 | udc->driver = NULL; | ||
1407 | udc->gadget.dev.driver = NULL; | ||
1408 | return retval; | ||
1409 | } | ||
1410 | |||
1411 | if (!IS_ERR_OR_NULL(udc->transceiver)) { | ||
1412 | retval = otg_set_peripheral(udc->transceiver->otg, | 1398 | retval = otg_set_peripheral(udc->transceiver->otg, |
1413 | &udc->gadget); | 1399 | &udc->gadget); |
1414 | if (retval) { | 1400 | if (retval) { |
1415 | dev_err(&udc->dev->dev, | 1401 | dev_err(&udc->dev->dev, |
1416 | "unable to register peripheral to otg\n"); | 1402 | "unable to register peripheral to otg\n"); |
1417 | if (driver->unbind) { | 1403 | udc->driver = NULL; |
1418 | driver->unbind(&udc->gadget); | 1404 | udc->gadget.dev.driver = NULL; |
1419 | udc->gadget.dev.driver = NULL; | ||
1420 | udc->driver = NULL; | ||
1421 | } | ||
1422 | return retval; | 1405 | return retval; |
1423 | } | 1406 | } |
1424 | } | 1407 | } |
@@ -1433,13 +1416,13 @@ static int mv_udc_start(struct usb_gadget_driver *driver, | |||
1433 | return 0; | 1416 | return 0; |
1434 | } | 1417 | } |
1435 | 1418 | ||
1436 | static int mv_udc_stop(struct usb_gadget_driver *driver) | 1419 | static int mv_udc_stop(struct usb_gadget *gadget, |
1420 | struct usb_gadget_driver *driver) | ||
1437 | { | 1421 | { |
1438 | struct mv_udc *udc = the_controller; | 1422 | struct mv_udc *udc; |
1439 | unsigned long flags; | 1423 | unsigned long flags; |
1440 | 1424 | ||
1441 | if (!udc) | 1425 | udc = container_of(gadget, struct mv_udc, gadget); |
1442 | return -ENODEV; | ||
1443 | 1426 | ||
1444 | spin_lock_irqsave(&udc->lock, flags); | 1427 | spin_lock_irqsave(&udc->lock, flags); |
1445 | 1428 | ||
@@ -1454,7 +1437,6 @@ static int mv_udc_stop(struct usb_gadget_driver *driver) | |||
1454 | spin_unlock_irqrestore(&udc->lock, flags); | 1437 | spin_unlock_irqrestore(&udc->lock, flags); |
1455 | 1438 | ||
1456 | /* unbind gadget driver */ | 1439 | /* unbind gadget driver */ |
1457 | driver->unbind(&udc->gadget); | ||
1458 | udc->gadget.dev.driver = NULL; | 1440 | udc->gadget.dev.driver = NULL; |
1459 | udc->driver = NULL; | 1441 | udc->driver = NULL; |
1460 | 1442 | ||
@@ -1472,10 +1454,13 @@ static void mv_set_ptc(struct mv_udc *udc, u32 mode) | |||
1472 | 1454 | ||
1473 | static void prime_status_complete(struct usb_ep *ep, struct usb_request *_req) | 1455 | static void prime_status_complete(struct usb_ep *ep, struct usb_request *_req) |
1474 | { | 1456 | { |
1475 | struct mv_udc *udc = the_controller; | 1457 | struct mv_ep *mvep = container_of(ep, struct mv_ep, ep); |
1476 | struct mv_req *req = container_of(_req, struct mv_req, req); | 1458 | struct mv_req *req = container_of(_req, struct mv_req, req); |
1459 | struct mv_udc *udc; | ||
1477 | unsigned long flags; | 1460 | unsigned long flags; |
1478 | 1461 | ||
1462 | udc = mvep->udc; | ||
1463 | |||
1479 | dev_info(&udc->dev->dev, "switch to test mode %d\n", req->test_mode); | 1464 | dev_info(&udc->dev->dev, "switch to test mode %d\n", req->test_mode); |
1480 | 1465 | ||
1481 | spin_lock_irqsave(&udc->lock, flags); | 1466 | spin_lock_irqsave(&udc->lock, flags); |
@@ -2123,15 +2108,18 @@ static void mv_udc_vbus_work(struct work_struct *work) | |||
2123 | /* release device structure */ | 2108 | /* release device structure */ |
2124 | static void gadget_release(struct device *_dev) | 2109 | static void gadget_release(struct device *_dev) |
2125 | { | 2110 | { |
2126 | struct mv_udc *udc = the_controller; | 2111 | struct mv_udc *udc; |
2112 | |||
2113 | udc = dev_get_drvdata(_dev); | ||
2127 | 2114 | ||
2128 | complete(udc->done); | 2115 | complete(udc->done); |
2129 | } | 2116 | } |
2130 | 2117 | ||
2131 | static int mv_udc_remove(struct platform_device *dev) | 2118 | static int mv_udc_remove(struct platform_device *pdev) |
2132 | { | 2119 | { |
2133 | struct mv_udc *udc = the_controller; | 2120 | struct mv_udc *udc; |
2134 | int clk_i; | 2121 | |
2122 | udc = platform_get_drvdata(pdev); | ||
2135 | 2123 | ||
2136 | usb_del_gadget_udc(&udc->gadget); | 2124 | usb_del_gadget_udc(&udc->gadget); |
2137 | 2125 | ||
@@ -2140,57 +2128,27 @@ static int mv_udc_remove(struct platform_device *dev) | |||
2140 | destroy_workqueue(udc->qwork); | 2128 | destroy_workqueue(udc->qwork); |
2141 | } | 2129 | } |
2142 | 2130 | ||
2143 | /* | ||
2144 | * If we have transceiver inited, | ||
2145 | * then vbus irq will not be requested in udc driver. | ||
2146 | */ | ||
2147 | if (udc->pdata && udc->pdata->vbus | ||
2148 | && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver)) | ||
2149 | free_irq(udc->pdata->vbus->irq, &dev->dev); | ||
2150 | |||
2151 | /* free memory allocated in probe */ | 2131 | /* free memory allocated in probe */ |
2152 | if (udc->dtd_pool) | 2132 | if (udc->dtd_pool) |
2153 | dma_pool_destroy(udc->dtd_pool); | 2133 | dma_pool_destroy(udc->dtd_pool); |
2154 | 2134 | ||
2155 | if (udc->ep_dqh) | 2135 | if (udc->ep_dqh) |
2156 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, | 2136 | dma_free_coherent(&pdev->dev, udc->ep_dqh_size, |
2157 | udc->ep_dqh, udc->ep_dqh_dma); | 2137 | udc->ep_dqh, udc->ep_dqh_dma); |
2158 | 2138 | ||
2159 | kfree(udc->eps); | ||
2160 | |||
2161 | if (udc->irq) | ||
2162 | free_irq(udc->irq, &dev->dev); | ||
2163 | |||
2164 | mv_udc_disable(udc); | 2139 | mv_udc_disable(udc); |
2165 | 2140 | ||
2166 | if (udc->cap_regs) | ||
2167 | iounmap(udc->cap_regs); | ||
2168 | |||
2169 | if (udc->phy_regs) | ||
2170 | iounmap(udc->phy_regs); | ||
2171 | |||
2172 | if (udc->status_req) { | ||
2173 | kfree(udc->status_req->req.buf); | ||
2174 | kfree(udc->status_req); | ||
2175 | } | ||
2176 | |||
2177 | for (clk_i = 0; clk_i <= udc->clknum; clk_i++) | ||
2178 | clk_put(udc->clk[clk_i]); | ||
2179 | |||
2180 | device_unregister(&udc->gadget.dev); | 2141 | device_unregister(&udc->gadget.dev); |
2181 | 2142 | ||
2182 | /* free dev, wait for the release() finished */ | 2143 | /* free dev, wait for the release() finished */ |
2183 | wait_for_completion(udc->done); | 2144 | wait_for_completion(udc->done); |
2184 | kfree(udc); | ||
2185 | |||
2186 | the_controller = NULL; | ||
2187 | 2145 | ||
2188 | return 0; | 2146 | return 0; |
2189 | } | 2147 | } |
2190 | 2148 | ||
2191 | static int mv_udc_probe(struct platform_device *dev) | 2149 | static int mv_udc_probe(struct platform_device *pdev) |
2192 | { | 2150 | { |
2193 | struct mv_usb_platform_data *pdata = dev->dev.platform_data; | 2151 | struct mv_usb_platform_data *pdata = pdev->dev.platform_data; |
2194 | struct mv_udc *udc; | 2152 | struct mv_udc *udc; |
2195 | int retval = 0; | 2153 | int retval = 0; |
2196 | int clk_i = 0; | 2154 | int clk_i = 0; |
@@ -2198,71 +2156,73 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2198 | size_t size; | 2156 | size_t size; |
2199 | 2157 | ||
2200 | if (pdata == NULL) { | 2158 | if (pdata == NULL) { |
2201 | dev_err(&dev->dev, "missing platform_data\n"); | 2159 | dev_err(&pdev->dev, "missing platform_data\n"); |
2202 | return -ENODEV; | 2160 | return -ENODEV; |
2203 | } | 2161 | } |
2204 | 2162 | ||
2205 | size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum; | 2163 | size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum; |
2206 | udc = kzalloc(size, GFP_KERNEL); | 2164 | udc = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
2207 | if (udc == NULL) { | 2165 | if (udc == NULL) { |
2208 | dev_err(&dev->dev, "failed to allocate memory for udc\n"); | 2166 | dev_err(&pdev->dev, "failed to allocate memory for udc\n"); |
2209 | return -ENOMEM; | 2167 | return -ENOMEM; |
2210 | } | 2168 | } |
2211 | 2169 | ||
2212 | the_controller = udc; | ||
2213 | udc->done = &release_done; | 2170 | udc->done = &release_done; |
2214 | udc->pdata = dev->dev.platform_data; | 2171 | udc->pdata = pdev->dev.platform_data; |
2215 | spin_lock_init(&udc->lock); | 2172 | spin_lock_init(&udc->lock); |
2216 | 2173 | ||
2217 | udc->dev = dev; | 2174 | udc->dev = pdev; |
2218 | 2175 | ||
2219 | #ifdef CONFIG_USB_OTG_UTILS | 2176 | #ifdef CONFIG_USB_OTG_UTILS |
2220 | if (pdata->mode == MV_USB_MODE_OTG) | 2177 | if (pdata->mode == MV_USB_MODE_OTG) { |
2221 | udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | 2178 | udc->transceiver = devm_usb_get_phy(&pdev->dev, |
2179 | USB_PHY_TYPE_USB2); | ||
2180 | if (IS_ERR_OR_NULL(udc->transceiver)) { | ||
2181 | udc->transceiver = NULL; | ||
2182 | return -ENODEV; | ||
2183 | } | ||
2184 | } | ||
2222 | #endif | 2185 | #endif |
2223 | 2186 | ||
2224 | udc->clknum = pdata->clknum; | 2187 | udc->clknum = pdata->clknum; |
2225 | for (clk_i = 0; clk_i < udc->clknum; clk_i++) { | 2188 | for (clk_i = 0; clk_i < udc->clknum; clk_i++) { |
2226 | udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]); | 2189 | udc->clk[clk_i] = devm_clk_get(&pdev->dev, |
2190 | pdata->clkname[clk_i]); | ||
2227 | if (IS_ERR(udc->clk[clk_i])) { | 2191 | if (IS_ERR(udc->clk[clk_i])) { |
2228 | retval = PTR_ERR(udc->clk[clk_i]); | 2192 | retval = PTR_ERR(udc->clk[clk_i]); |
2229 | goto err_put_clk; | 2193 | return retval; |
2230 | } | 2194 | } |
2231 | } | 2195 | } |
2232 | 2196 | ||
2233 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs"); | 2197 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs"); |
2234 | if (r == NULL) { | 2198 | if (r == NULL) { |
2235 | dev_err(&dev->dev, "no I/O memory resource defined\n"); | 2199 | dev_err(&pdev->dev, "no I/O memory resource defined\n"); |
2236 | retval = -ENODEV; | 2200 | return -ENODEV; |
2237 | goto err_put_clk; | ||
2238 | } | 2201 | } |
2239 | 2202 | ||
2240 | udc->cap_regs = (struct mv_cap_regs __iomem *) | 2203 | udc->cap_regs = (struct mv_cap_regs __iomem *) |
2241 | ioremap(r->start, resource_size(r)); | 2204 | devm_ioremap(&pdev->dev, r->start, resource_size(r)); |
2242 | if (udc->cap_regs == NULL) { | 2205 | if (udc->cap_regs == NULL) { |
2243 | dev_err(&dev->dev, "failed to map I/O memory\n"); | 2206 | dev_err(&pdev->dev, "failed to map I/O memory\n"); |
2244 | retval = -EBUSY; | 2207 | return -EBUSY; |
2245 | goto err_put_clk; | ||
2246 | } | 2208 | } |
2247 | 2209 | ||
2248 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs"); | 2210 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs"); |
2249 | if (r == NULL) { | 2211 | if (r == NULL) { |
2250 | dev_err(&dev->dev, "no phy I/O memory resource defined\n"); | 2212 | dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); |
2251 | retval = -ENODEV; | 2213 | return -ENODEV; |
2252 | goto err_iounmap_capreg; | ||
2253 | } | 2214 | } |
2254 | 2215 | ||
2255 | udc->phy_regs = ioremap(r->start, resource_size(r)); | 2216 | udc->phy_regs = ioremap(r->start, resource_size(r)); |
2256 | if (udc->phy_regs == NULL) { | 2217 | if (udc->phy_regs == NULL) { |
2257 | dev_err(&dev->dev, "failed to map phy I/O memory\n"); | 2218 | dev_err(&pdev->dev, "failed to map phy I/O memory\n"); |
2258 | retval = -EBUSY; | 2219 | return -EBUSY; |
2259 | goto err_iounmap_capreg; | ||
2260 | } | 2220 | } |
2261 | 2221 | ||
2262 | /* we will acces controller register, so enable the clk */ | 2222 | /* we will acces controller register, so enable the clk */ |
2263 | retval = mv_udc_enable_internal(udc); | 2223 | retval = mv_udc_enable_internal(udc); |
2264 | if (retval) | 2224 | if (retval) |
2265 | goto err_iounmap_phyreg; | 2225 | return retval; |
2266 | 2226 | ||
2267 | udc->op_regs = | 2227 | udc->op_regs = |
2268 | (struct mv_op_regs __iomem *)((unsigned long)udc->cap_regs | 2228 | (struct mv_op_regs __iomem *)((unsigned long)udc->cap_regs |
@@ -2279,11 +2239,11 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2279 | 2239 | ||
2280 | size = udc->max_eps * sizeof(struct mv_dqh) *2; | 2240 | size = udc->max_eps * sizeof(struct mv_dqh) *2; |
2281 | size = (size + DQH_ALIGNMENT - 1) & ~(DQH_ALIGNMENT - 1); | 2241 | size = (size + DQH_ALIGNMENT - 1) & ~(DQH_ALIGNMENT - 1); |
2282 | udc->ep_dqh = dma_alloc_coherent(&dev->dev, size, | 2242 | udc->ep_dqh = dma_alloc_coherent(&pdev->dev, size, |
2283 | &udc->ep_dqh_dma, GFP_KERNEL); | 2243 | &udc->ep_dqh_dma, GFP_KERNEL); |
2284 | 2244 | ||
2285 | if (udc->ep_dqh == NULL) { | 2245 | if (udc->ep_dqh == NULL) { |
2286 | dev_err(&dev->dev, "allocate dQH memory failed\n"); | 2246 | dev_err(&pdev->dev, "allocate dQH memory failed\n"); |
2287 | retval = -ENOMEM; | 2247 | retval = -ENOMEM; |
2288 | goto err_disable_clock; | 2248 | goto err_disable_clock; |
2289 | } | 2249 | } |
@@ -2291,7 +2251,7 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2291 | 2251 | ||
2292 | /* create dTD dma_pool resource */ | 2252 | /* create dTD dma_pool resource */ |
2293 | udc->dtd_pool = dma_pool_create("mv_dtd", | 2253 | udc->dtd_pool = dma_pool_create("mv_dtd", |
2294 | &dev->dev, | 2254 | &pdev->dev, |
2295 | sizeof(struct mv_dtd), | 2255 | sizeof(struct mv_dtd), |
2296 | DTD_ALIGNMENT, | 2256 | DTD_ALIGNMENT, |
2297 | DMA_BOUNDARY); | 2257 | DMA_BOUNDARY); |
@@ -2302,19 +2262,20 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2302 | } | 2262 | } |
2303 | 2263 | ||
2304 | size = udc->max_eps * sizeof(struct mv_ep) *2; | 2264 | size = udc->max_eps * sizeof(struct mv_ep) *2; |
2305 | udc->eps = kzalloc(size, GFP_KERNEL); | 2265 | udc->eps = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
2306 | if (udc->eps == NULL) { | 2266 | if (udc->eps == NULL) { |
2307 | dev_err(&dev->dev, "allocate ep memory failed\n"); | 2267 | dev_err(&pdev->dev, "allocate ep memory failed\n"); |
2308 | retval = -ENOMEM; | 2268 | retval = -ENOMEM; |
2309 | goto err_destroy_dma; | 2269 | goto err_destroy_dma; |
2310 | } | 2270 | } |
2311 | 2271 | ||
2312 | /* initialize ep0 status request structure */ | 2272 | /* initialize ep0 status request structure */ |
2313 | udc->status_req = kzalloc(sizeof(struct mv_req), GFP_KERNEL); | 2273 | udc->status_req = devm_kzalloc(&pdev->dev, sizeof(struct mv_req), |
2274 | GFP_KERNEL); | ||
2314 | if (!udc->status_req) { | 2275 | if (!udc->status_req) { |
2315 | dev_err(&dev->dev, "allocate status_req memory failed\n"); | 2276 | dev_err(&pdev->dev, "allocate status_req memory failed\n"); |
2316 | retval = -ENOMEM; | 2277 | retval = -ENOMEM; |
2317 | goto err_free_eps; | 2278 | goto err_destroy_dma; |
2318 | } | 2279 | } |
2319 | INIT_LIST_HEAD(&udc->status_req->queue); | 2280 | INIT_LIST_HEAD(&udc->status_req->queue); |
2320 | 2281 | ||
@@ -2329,17 +2290,17 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2329 | 2290 | ||
2330 | r = platform_get_resource(udc->dev, IORESOURCE_IRQ, 0); | 2291 | r = platform_get_resource(udc->dev, IORESOURCE_IRQ, 0); |
2331 | if (r == NULL) { | 2292 | if (r == NULL) { |
2332 | dev_err(&dev->dev, "no IRQ resource defined\n"); | 2293 | dev_err(&pdev->dev, "no IRQ resource defined\n"); |
2333 | retval = -ENODEV; | 2294 | retval = -ENODEV; |
2334 | goto err_free_status_req; | 2295 | goto err_destroy_dma; |
2335 | } | 2296 | } |
2336 | udc->irq = r->start; | 2297 | udc->irq = r->start; |
2337 | if (request_irq(udc->irq, mv_udc_irq, | 2298 | if (devm_request_irq(&pdev->dev, udc->irq, mv_udc_irq, |
2338 | IRQF_SHARED, driver_name, udc)) { | 2299 | IRQF_SHARED, driver_name, udc)) { |
2339 | dev_err(&dev->dev, "Request irq %d for UDC failed\n", | 2300 | dev_err(&pdev->dev, "Request irq %d for UDC failed\n", |
2340 | udc->irq); | 2301 | udc->irq); |
2341 | retval = -ENODEV; | 2302 | retval = -ENODEV; |
2342 | goto err_free_status_req; | 2303 | goto err_destroy_dma; |
2343 | } | 2304 | } |
2344 | 2305 | ||
2345 | /* initialize gadget structure */ | 2306 | /* initialize gadget structure */ |
@@ -2351,26 +2312,27 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2351 | 2312 | ||
2352 | /* the "gadget" abstracts/virtualizes the controller */ | 2313 | /* the "gadget" abstracts/virtualizes the controller */ |
2353 | dev_set_name(&udc->gadget.dev, "gadget"); | 2314 | dev_set_name(&udc->gadget.dev, "gadget"); |
2354 | udc->gadget.dev.parent = &dev->dev; | 2315 | udc->gadget.dev.parent = &pdev->dev; |
2355 | udc->gadget.dev.dma_mask = dev->dev.dma_mask; | 2316 | udc->gadget.dev.dma_mask = pdev->dev.dma_mask; |
2356 | udc->gadget.dev.release = gadget_release; | 2317 | udc->gadget.dev.release = gadget_release; |
2357 | udc->gadget.name = driver_name; /* gadget name */ | 2318 | udc->gadget.name = driver_name; /* gadget name */ |
2358 | 2319 | ||
2359 | retval = device_register(&udc->gadget.dev); | 2320 | retval = device_register(&udc->gadget.dev); |
2360 | if (retval) | 2321 | if (retval) |
2361 | goto err_free_irq; | 2322 | goto err_destroy_dma; |
2362 | 2323 | ||
2363 | eps_init(udc); | 2324 | eps_init(udc); |
2364 | 2325 | ||
2365 | /* VBUS detect: we can disable/enable clock on demand.*/ | 2326 | /* VBUS detect: we can disable/enable clock on demand.*/ |
2366 | if (!IS_ERR_OR_NULL(udc->transceiver)) | 2327 | if (udc->transceiver) |
2367 | udc->clock_gating = 1; | 2328 | udc->clock_gating = 1; |
2368 | else if (pdata->vbus) { | 2329 | else if (pdata->vbus) { |
2369 | udc->clock_gating = 1; | 2330 | udc->clock_gating = 1; |
2370 | retval = request_threaded_irq(pdata->vbus->irq, NULL, | 2331 | retval = devm_request_threaded_irq(&pdev->dev, |
2332 | pdata->vbus->irq, NULL, | ||
2371 | mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); | 2333 | mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); |
2372 | if (retval) { | 2334 | if (retval) { |
2373 | dev_info(&dev->dev, | 2335 | dev_info(&pdev->dev, |
2374 | "Can not request irq for VBUS, " | 2336 | "Can not request irq for VBUS, " |
2375 | "disable clock gating\n"); | 2337 | "disable clock gating\n"); |
2376 | udc->clock_gating = 0; | 2338 | udc->clock_gating = 0; |
@@ -2378,7 +2340,7 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2378 | 2340 | ||
2379 | udc->qwork = create_singlethread_workqueue("mv_udc_queue"); | 2341 | udc->qwork = create_singlethread_workqueue("mv_udc_queue"); |
2380 | if (!udc->qwork) { | 2342 | if (!udc->qwork) { |
2381 | dev_err(&dev->dev, "cannot create workqueue\n"); | 2343 | dev_err(&pdev->dev, "cannot create workqueue\n"); |
2382 | retval = -ENOMEM; | 2344 | retval = -ENOMEM; |
2383 | goto err_unregister; | 2345 | goto err_unregister; |
2384 | } | 2346 | } |
@@ -2396,53 +2358,40 @@ static int mv_udc_probe(struct platform_device *dev) | |||
2396 | else | 2358 | else |
2397 | udc->vbus_active = 1; | 2359 | udc->vbus_active = 1; |
2398 | 2360 | ||
2399 | retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); | 2361 | retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); |
2400 | if (retval) | 2362 | if (retval) |
2401 | goto err_unregister; | 2363 | goto err_create_workqueue; |
2402 | 2364 | ||
2403 | dev_info(&dev->dev, "successful probe UDC device %s clock gating.\n", | 2365 | platform_set_drvdata(pdev, udc); |
2366 | dev_info(&pdev->dev, "successful probe UDC device %s clock gating.\n", | ||
2404 | udc->clock_gating ? "with" : "without"); | 2367 | udc->clock_gating ? "with" : "without"); |
2405 | 2368 | ||
2406 | return 0; | 2369 | return 0; |
2407 | 2370 | ||
2371 | err_create_workqueue: | ||
2372 | destroy_workqueue(udc->qwork); | ||
2408 | err_unregister: | 2373 | err_unregister: |
2409 | if (udc->pdata && udc->pdata->vbus | ||
2410 | && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver)) | ||
2411 | free_irq(pdata->vbus->irq, &dev->dev); | ||
2412 | device_unregister(&udc->gadget.dev); | 2374 | device_unregister(&udc->gadget.dev); |
2413 | err_free_irq: | ||
2414 | free_irq(udc->irq, &dev->dev); | ||
2415 | err_free_status_req: | ||
2416 | kfree(udc->status_req->req.buf); | ||
2417 | kfree(udc->status_req); | ||
2418 | err_free_eps: | ||
2419 | kfree(udc->eps); | ||
2420 | err_destroy_dma: | 2375 | err_destroy_dma: |
2421 | dma_pool_destroy(udc->dtd_pool); | 2376 | dma_pool_destroy(udc->dtd_pool); |
2422 | err_free_dma: | 2377 | err_free_dma: |
2423 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, | 2378 | dma_free_coherent(&pdev->dev, udc->ep_dqh_size, |
2424 | udc->ep_dqh, udc->ep_dqh_dma); | 2379 | udc->ep_dqh, udc->ep_dqh_dma); |
2425 | err_disable_clock: | 2380 | err_disable_clock: |
2426 | mv_udc_disable_internal(udc); | 2381 | mv_udc_disable_internal(udc); |
2427 | err_iounmap_phyreg: | 2382 | |
2428 | iounmap(udc->phy_regs); | ||
2429 | err_iounmap_capreg: | ||
2430 | iounmap(udc->cap_regs); | ||
2431 | err_put_clk: | ||
2432 | for (clk_i--; clk_i >= 0; clk_i--) | ||
2433 | clk_put(udc->clk[clk_i]); | ||
2434 | the_controller = NULL; | ||
2435 | kfree(udc); | ||
2436 | return retval; | 2383 | return retval; |
2437 | } | 2384 | } |
2438 | 2385 | ||
2439 | #ifdef CONFIG_PM | 2386 | #ifdef CONFIG_PM |
2440 | static int mv_udc_suspend(struct device *_dev) | 2387 | static int mv_udc_suspend(struct device *dev) |
2441 | { | 2388 | { |
2442 | struct mv_udc *udc = the_controller; | 2389 | struct mv_udc *udc; |
2390 | |||
2391 | udc = dev_get_drvdata(dev); | ||
2443 | 2392 | ||
2444 | /* if OTG is enabled, the following will be done in OTG driver*/ | 2393 | /* if OTG is enabled, the following will be done in OTG driver*/ |
2445 | if (!IS_ERR_OR_NULL(udc->transceiver)) | 2394 | if (udc->transceiver) |
2446 | return 0; | 2395 | return 0; |
2447 | 2396 | ||
2448 | if (udc->pdata->vbus && udc->pdata->vbus->poll) | 2397 | if (udc->pdata->vbus && udc->pdata->vbus->poll) |
@@ -2469,13 +2418,15 @@ static int mv_udc_suspend(struct device *_dev) | |||
2469 | return 0; | 2418 | return 0; |
2470 | } | 2419 | } |
2471 | 2420 | ||
2472 | static int mv_udc_resume(struct device *_dev) | 2421 | static int mv_udc_resume(struct device *dev) |
2473 | { | 2422 | { |
2474 | struct mv_udc *udc = the_controller; | 2423 | struct mv_udc *udc; |
2475 | int retval; | 2424 | int retval; |
2476 | 2425 | ||
2426 | udc = dev_get_drvdata(dev); | ||
2427 | |||
2477 | /* if OTG is enabled, the following will be done in OTG driver*/ | 2428 | /* if OTG is enabled, the following will be done in OTG driver*/ |
2478 | if (!IS_ERR_OR_NULL(udc->transceiver)) | 2429 | if (udc->transceiver) |
2479 | return 0; | 2430 | return 0; |
2480 | 2431 | ||
2481 | if (!udc->clock_gating) { | 2432 | if (!udc->clock_gating) { |
@@ -2499,11 +2450,12 @@ static const struct dev_pm_ops mv_udc_pm_ops = { | |||
2499 | }; | 2450 | }; |
2500 | #endif | 2451 | #endif |
2501 | 2452 | ||
2502 | static void mv_udc_shutdown(struct platform_device *dev) | 2453 | static void mv_udc_shutdown(struct platform_device *pdev) |
2503 | { | 2454 | { |
2504 | struct mv_udc *udc = the_controller; | 2455 | struct mv_udc *udc; |
2505 | u32 mode; | 2456 | u32 mode; |
2506 | 2457 | ||
2458 | udc = platform_get_drvdata(pdev); | ||
2507 | /* reset controller mode to IDLE */ | 2459 | /* reset controller mode to IDLE */ |
2508 | mv_udc_enable(udc); | 2460 | mv_udc_enable(udc); |
2509 | mode = readl(&udc->op_regs->usbmode); | 2461 | mode = readl(&udc->op_regs->usbmode); |
@@ -2514,7 +2466,7 @@ static void mv_udc_shutdown(struct platform_device *dev) | |||
2514 | 2466 | ||
2515 | static struct platform_driver udc_driver = { | 2467 | static struct platform_driver udc_driver = { |
2516 | .probe = mv_udc_probe, | 2468 | .probe = mv_udc_probe, |
2517 | .remove = __exit_p(mv_udc_remove), | 2469 | .remove = mv_udc_remove, |
2518 | .shutdown = mv_udc_shutdown, | 2470 | .shutdown = mv_udc_shutdown, |
2519 | .driver = { | 2471 | .driver = { |
2520 | .owner = THIS_MODULE, | 2472 | .owner = THIS_MODULE, |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 708c0b55dcc8..a1b650e11339 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -116,6 +116,10 @@ static bool enable_suspend = 0; | |||
116 | /* "modprobe net2280 enable_suspend=1" etc */ | 116 | /* "modprobe net2280 enable_suspend=1" etc */ |
117 | module_param (enable_suspend, bool, S_IRUGO); | 117 | module_param (enable_suspend, bool, S_IRUGO); |
118 | 118 | ||
119 | /* force full-speed operation */ | ||
120 | static bool full_speed; | ||
121 | module_param(full_speed, bool, 0444); | ||
122 | MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!"); | ||
119 | 123 | ||
120 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") | 124 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") |
121 | 125 | ||
@@ -1899,6 +1903,10 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
1899 | retval = device_create_file (&dev->pdev->dev, &dev_attr_queues); | 1903 | retval = device_create_file (&dev->pdev->dev, &dev_attr_queues); |
1900 | if (retval) goto err_func; | 1904 | if (retval) goto err_func; |
1901 | 1905 | ||
1906 | /* Enable force-full-speed testing mode, if desired */ | ||
1907 | if (full_speed) | ||
1908 | writel(1 << FORCE_FULL_SPEED_MODE, &dev->usb->xcvrdiag); | ||
1909 | |||
1902 | /* ... then enable host detection and ep0; and we're ready | 1910 | /* ... then enable host detection and ep0; and we're ready |
1903 | * for set_configuration as well as eventual disconnect. | 1911 | * for set_configuration as well as eventual disconnect. |
1904 | */ | 1912 | */ |
@@ -1957,6 +1965,10 @@ static int net2280_stop(struct usb_gadget *_gadget, | |||
1957 | dev->driver = NULL; | 1965 | dev->driver = NULL; |
1958 | 1966 | ||
1959 | net2280_led_active (dev, 0); | 1967 | net2280_led_active (dev, 0); |
1968 | |||
1969 | /* Disable full-speed test mode */ | ||
1970 | writel(0, &dev->usb->xcvrdiag); | ||
1971 | |||
1960 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | 1972 | device_remove_file (&dev->pdev->dev, &dev_attr_function); |
1961 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); | 1973 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); |
1962 | 1974 | ||
@@ -2841,6 +2853,9 @@ static void net2280_shutdown (struct pci_dev *pdev) | |||
2841 | 2853 | ||
2842 | /* disable the pullup so the host will think we're gone */ | 2854 | /* disable the pullup so the host will think we're gone */ |
2843 | writel (0, &dev->usb->usbctl); | 2855 | writel (0, &dev->usb->usbctl); |
2856 | |||
2857 | /* Disable full-speed test mode */ | ||
2858 | writel(0, &dev->usb->xcvrdiag); | ||
2844 | } | 2859 | } |
2845 | 2860 | ||
2846 | 2861 | ||
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 661600abace8..def37403989a 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c | |||
@@ -37,7 +37,7 @@ | |||
37 | * the runtime footprint, and giving us at least some parts of what | 37 | * the runtime footprint, and giving us at least some parts of what |
38 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | 38 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. |
39 | */ | 39 | */ |
40 | #include "u_serial.c" | 40 | #define USB_FACM_INCLUDED |
41 | #include "f_acm.c" | 41 | #include "f_acm.c" |
42 | #include "f_ecm.c" | 42 | #include "f_ecm.c" |
43 | #include "f_obex.c" | 43 | #include "f_obex.c" |
@@ -101,6 +101,15 @@ MODULE_LICENSE("GPL"); | |||
101 | 101 | ||
102 | static u8 hostaddr[ETH_ALEN]; | 102 | static u8 hostaddr[ETH_ALEN]; |
103 | 103 | ||
104 | enum { | ||
105 | TTY_PORT_OBEX0, | ||
106 | TTY_PORT_OBEX1, | ||
107 | TTY_PORT_ACM, | ||
108 | TTY_PORTS_MAX, | ||
109 | }; | ||
110 | |||
111 | static unsigned char tty_lines[TTY_PORTS_MAX]; | ||
112 | |||
104 | static int __init nokia_bind_config(struct usb_configuration *c) | 113 | static int __init nokia_bind_config(struct usb_configuration *c) |
105 | { | 114 | { |
106 | int status = 0; | 115 | int status = 0; |
@@ -109,15 +118,15 @@ static int __init nokia_bind_config(struct usb_configuration *c) | |||
109 | if (status) | 118 | if (status) |
110 | printk(KERN_DEBUG "could not bind phonet config\n"); | 119 | printk(KERN_DEBUG "could not bind phonet config\n"); |
111 | 120 | ||
112 | status = obex_bind_config(c, 0); | 121 | status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX0]); |
113 | if (status) | 122 | if (status) |
114 | printk(KERN_DEBUG "could not bind obex config %d\n", 0); | 123 | printk(KERN_DEBUG "could not bind obex config %d\n", 0); |
115 | 124 | ||
116 | status = obex_bind_config(c, 1); | 125 | status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX1]); |
117 | if (status) | 126 | if (status) |
118 | printk(KERN_DEBUG "could not bind obex config %d\n", 0); | 127 | printk(KERN_DEBUG "could not bind obex config %d\n", 0); |
119 | 128 | ||
120 | status = acm_bind_config(c, 2); | 129 | status = acm_bind_config(c, tty_lines[TTY_PORT_ACM]); |
121 | if (status) | 130 | if (status) |
122 | printk(KERN_DEBUG "could not bind acm config\n"); | 131 | printk(KERN_DEBUG "could not bind acm config\n"); |
123 | 132 | ||
@@ -133,7 +142,7 @@ static struct usb_configuration nokia_config_500ma_driver = { | |||
133 | .bConfigurationValue = 1, | 142 | .bConfigurationValue = 1, |
134 | /* .iConfiguration = DYNAMIC */ | 143 | /* .iConfiguration = DYNAMIC */ |
135 | .bmAttributes = USB_CONFIG_ATT_ONE, | 144 | .bmAttributes = USB_CONFIG_ATT_ONE, |
136 | .bMaxPower = 250, /* 500mA */ | 145 | .MaxPower = 500, |
137 | }; | 146 | }; |
138 | 147 | ||
139 | static struct usb_configuration nokia_config_100ma_driver = { | 148 | static struct usb_configuration nokia_config_100ma_driver = { |
@@ -141,21 +150,24 @@ static struct usb_configuration nokia_config_100ma_driver = { | |||
141 | .bConfigurationValue = 2, | 150 | .bConfigurationValue = 2, |
142 | /* .iConfiguration = DYNAMIC */ | 151 | /* .iConfiguration = DYNAMIC */ |
143 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | 152 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, |
144 | .bMaxPower = 50, /* 100 mA */ | 153 | .MaxPower = 100, |
145 | }; | 154 | }; |
146 | 155 | ||
147 | static int __init nokia_bind(struct usb_composite_dev *cdev) | 156 | static int __init nokia_bind(struct usb_composite_dev *cdev) |
148 | { | 157 | { |
149 | struct usb_gadget *gadget = cdev->gadget; | 158 | struct usb_gadget *gadget = cdev->gadget; |
150 | int status; | 159 | int status; |
160 | int cur_line; | ||
151 | 161 | ||
152 | status = gphonet_setup(cdev->gadget); | 162 | status = gphonet_setup(cdev->gadget); |
153 | if (status < 0) | 163 | if (status < 0) |
154 | goto err_phonet; | 164 | goto err_phonet; |
155 | 165 | ||
156 | status = gserial_setup(cdev->gadget, 3); | 166 | for (cur_line = 0; cur_line < TTY_PORTS_MAX; cur_line++) { |
157 | if (status < 0) | 167 | status = gserial_alloc_line(&tty_lines[cur_line]); |
158 | goto err_serial; | 168 | if (status) |
169 | goto err_ether; | ||
170 | } | ||
159 | 171 | ||
160 | status = gether_setup(cdev->gadget, hostaddr); | 172 | status = gether_setup(cdev->gadget, hostaddr); |
161 | if (status < 0) | 173 | if (status < 0) |
@@ -192,8 +204,10 @@ static int __init nokia_bind(struct usb_composite_dev *cdev) | |||
192 | err_usb: | 204 | err_usb: |
193 | gether_cleanup(); | 205 | gether_cleanup(); |
194 | err_ether: | 206 | err_ether: |
195 | gserial_cleanup(); | 207 | cur_line--; |
196 | err_serial: | 208 | while (cur_line >= 0) |
209 | gserial_free_line(tty_lines[cur_line--]); | ||
210 | |||
197 | gphonet_cleanup(); | 211 | gphonet_cleanup(); |
198 | err_phonet: | 212 | err_phonet: |
199 | return status; | 213 | return status; |
@@ -201,8 +215,13 @@ err_phonet: | |||
201 | 215 | ||
202 | static int __exit nokia_unbind(struct usb_composite_dev *cdev) | 216 | static int __exit nokia_unbind(struct usb_composite_dev *cdev) |
203 | { | 217 | { |
218 | int i; | ||
219 | |||
204 | gphonet_cleanup(); | 220 | gphonet_cleanup(); |
205 | gserial_cleanup(); | 221 | |
222 | for (i = 0; i < TTY_PORTS_MAX; i++) | ||
223 | gserial_free_line(tty_lines[i]); | ||
224 | |||
206 | gether_cleanup(); | 225 | gether_cleanup(); |
207 | 226 | ||
208 | return 0; | 227 | return 0; |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 8bfe990caf1a..06be85c2b233 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -1309,19 +1309,20 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) | |||
1309 | return 0; | 1309 | return 0; |
1310 | } | 1310 | } |
1311 | 1311 | ||
1312 | static int omap_udc_start(struct usb_gadget_driver *driver, | 1312 | static int omap_udc_start(struct usb_gadget *g, |
1313 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1313 | struct usb_gadget_driver *driver) |
1314 | static int omap_udc_stop(struct usb_gadget_driver *driver); | 1314 | static int omap_udc_stop(struct usb_gadget *g, |
1315 | struct usb_gadget_driver *driver); | ||
1315 | 1316 | ||
1316 | static struct usb_gadget_ops omap_gadget_ops = { | 1317 | static const struct usb_gadget_ops omap_gadget_ops = { |
1317 | .get_frame = omap_get_frame, | 1318 | .get_frame = omap_get_frame, |
1318 | .wakeup = omap_wakeup, | 1319 | .wakeup = omap_wakeup, |
1319 | .set_selfpowered = omap_set_selfpowered, | 1320 | .set_selfpowered = omap_set_selfpowered, |
1320 | .vbus_session = omap_vbus_session, | 1321 | .vbus_session = omap_vbus_session, |
1321 | .vbus_draw = omap_vbus_draw, | 1322 | .vbus_draw = omap_vbus_draw, |
1322 | .pullup = omap_pullup, | 1323 | .pullup = omap_pullup, |
1323 | .start = omap_udc_start, | 1324 | .udc_start = omap_udc_start, |
1324 | .stop = omap_udc_stop, | 1325 | .udc_stop = omap_udc_stop, |
1325 | }; | 1326 | }; |
1326 | 1327 | ||
1327 | /*-------------------------------------------------------------------------*/ | 1328 | /*-------------------------------------------------------------------------*/ |
@@ -2041,28 +2042,15 @@ static inline int machine_without_vbus_sense(void) | |||
2041 | || cpu_is_omap7xx(); | 2042 | || cpu_is_omap7xx(); |
2042 | } | 2043 | } |
2043 | 2044 | ||
2044 | static int omap_udc_start(struct usb_gadget_driver *driver, | 2045 | static int omap_udc_start(struct usb_gadget *g, |
2045 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 2046 | struct usb_gadget_driver *driver) |
2046 | { | 2047 | { |
2047 | int status = -ENODEV; | 2048 | int status = -ENODEV; |
2048 | struct omap_ep *ep; | 2049 | struct omap_ep *ep; |
2049 | unsigned long flags; | 2050 | unsigned long flags; |
2050 | 2051 | ||
2051 | /* basic sanity tests */ | ||
2052 | if (!udc) | ||
2053 | return -ENODEV; | ||
2054 | if (!driver | ||
2055 | /* FIXME if otg, check: driver->is_otg */ | ||
2056 | || driver->max_speed < USB_SPEED_FULL | ||
2057 | || !bind || !driver->setup) | ||
2058 | return -EINVAL; | ||
2059 | 2052 | ||
2060 | spin_lock_irqsave(&udc->lock, flags); | 2053 | spin_lock_irqsave(&udc->lock, flags); |
2061 | if (udc->driver) { | ||
2062 | spin_unlock_irqrestore(&udc->lock, flags); | ||
2063 | return -EBUSY; | ||
2064 | } | ||
2065 | |||
2066 | /* reset state */ | 2054 | /* reset state */ |
2067 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { | 2055 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { |
2068 | ep->irqs = 0; | 2056 | ep->irqs = 0; |
@@ -2084,15 +2072,6 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2084 | if (udc->dc_clk != NULL) | 2072 | if (udc->dc_clk != NULL) |
2085 | omap_udc_enable_clock(1); | 2073 | omap_udc_enable_clock(1); |
2086 | 2074 | ||
2087 | status = bind(&udc->gadget, driver); | ||
2088 | if (status) { | ||
2089 | DBG("bind to %s --> %d\n", driver->driver.name, status); | ||
2090 | udc->gadget.dev.driver = NULL; | ||
2091 | udc->driver = NULL; | ||
2092 | goto done; | ||
2093 | } | ||
2094 | DBG("bound to driver %s\n", driver->driver.name); | ||
2095 | |||
2096 | omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); | 2075 | omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); |
2097 | 2076 | ||
2098 | /* connect to bus through transceiver */ | 2077 | /* connect to bus through transceiver */ |
@@ -2124,19 +2103,16 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2124 | done: | 2103 | done: |
2125 | if (udc->dc_clk != NULL) | 2104 | if (udc->dc_clk != NULL) |
2126 | omap_udc_enable_clock(0); | 2105 | omap_udc_enable_clock(0); |
2106 | |||
2127 | return status; | 2107 | return status; |
2128 | } | 2108 | } |
2129 | 2109 | ||
2130 | static int omap_udc_stop(struct usb_gadget_driver *driver) | 2110 | static int omap_udc_stop(struct usb_gadget *g, |
2111 | struct usb_gadget_driver *driver) | ||
2131 | { | 2112 | { |
2132 | unsigned long flags; | 2113 | unsigned long flags; |
2133 | int status = -ENODEV; | 2114 | int status = -ENODEV; |
2134 | 2115 | ||
2135 | if (!udc) | ||
2136 | return -ENODEV; | ||
2137 | if (!driver || driver != udc->driver || !driver->unbind) | ||
2138 | return -EINVAL; | ||
2139 | |||
2140 | if (udc->dc_clk != NULL) | 2116 | if (udc->dc_clk != NULL) |
2141 | omap_udc_enable_clock(1); | 2117 | omap_udc_enable_clock(1); |
2142 | 2118 | ||
@@ -2152,13 +2128,12 @@ static int omap_udc_stop(struct usb_gadget_driver *driver) | |||
2152 | udc_quiesce(udc); | 2128 | udc_quiesce(udc); |
2153 | spin_unlock_irqrestore(&udc->lock, flags); | 2129 | spin_unlock_irqrestore(&udc->lock, flags); |
2154 | 2130 | ||
2155 | driver->unbind(&udc->gadget); | ||
2156 | udc->gadget.dev.driver = NULL; | 2131 | udc->gadget.dev.driver = NULL; |
2157 | udc->driver = NULL; | 2132 | udc->driver = NULL; |
2158 | 2133 | ||
2159 | if (udc->dc_clk != NULL) | 2134 | if (udc->dc_clk != NULL) |
2160 | omap_udc_enable_clock(0); | 2135 | omap_udc_enable_clock(0); |
2161 | DBG("unregistered driver '%s'\n", driver->driver.name); | 2136 | |
2162 | return status; | 2137 | return status; |
2163 | } | 2138 | } |
2164 | 2139 | ||
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 6490c0040e3a..a787a8ef672b 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -375,6 +375,7 @@ struct pch_udc_dev { | |||
375 | struct pch_udc_cfg_data cfg_data; | 375 | struct pch_udc_cfg_data cfg_data; |
376 | struct pch_vbus_gpio_data vbus_gpio; | 376 | struct pch_vbus_gpio_data vbus_gpio; |
377 | }; | 377 | }; |
378 | #define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) | ||
378 | 379 | ||
379 | #define PCH_UDC_PCI_BAR 1 | 380 | #define PCH_UDC_PCI_BAR 1 |
380 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 | 381 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 |
@@ -384,7 +385,6 @@ struct pch_udc_dev { | |||
384 | 385 | ||
385 | static const char ep0_string[] = "ep0in"; | 386 | static const char ep0_string[] = "ep0in"; |
386 | static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ | 387 | static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ |
387 | struct pch_udc_dev *pch_udc; /* pointer to device object */ | ||
388 | static bool speed_fs; | 388 | static bool speed_fs; |
389 | module_param_named(speed_fs, speed_fs, bool, S_IRUGO); | 389 | module_param_named(speed_fs, speed_fs, bool, S_IRUGO); |
390 | MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); | 390 | MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); |
@@ -1235,9 +1235,10 @@ static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) | |||
1235 | return -EOPNOTSUPP; | 1235 | return -EOPNOTSUPP; |
1236 | } | 1236 | } |
1237 | 1237 | ||
1238 | static int pch_udc_start(struct usb_gadget_driver *driver, | 1238 | static int pch_udc_start(struct usb_gadget *g, |
1239 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1239 | struct usb_gadget_driver *driver); |
1240 | static int pch_udc_stop(struct usb_gadget_driver *driver); | 1240 | static int pch_udc_stop(struct usb_gadget *g, |
1241 | struct usb_gadget_driver *driver); | ||
1241 | static const struct usb_gadget_ops pch_udc_ops = { | 1242 | static const struct usb_gadget_ops pch_udc_ops = { |
1242 | .get_frame = pch_udc_pcd_get_frame, | 1243 | .get_frame = pch_udc_pcd_get_frame, |
1243 | .wakeup = pch_udc_pcd_wakeup, | 1244 | .wakeup = pch_udc_pcd_wakeup, |
@@ -1245,8 +1246,8 @@ static const struct usb_gadget_ops pch_udc_ops = { | |||
1245 | .pullup = pch_udc_pcd_pullup, | 1246 | .pullup = pch_udc_pcd_pullup, |
1246 | .vbus_session = pch_udc_pcd_vbus_session, | 1247 | .vbus_session = pch_udc_pcd_vbus_session, |
1247 | .vbus_draw = pch_udc_pcd_vbus_draw, | 1248 | .vbus_draw = pch_udc_pcd_vbus_draw, |
1248 | .start = pch_udc_start, | 1249 | .udc_start = pch_udc_start, |
1249 | .stop = pch_udc_stop, | 1250 | .udc_stop = pch_udc_stop, |
1250 | }; | 1251 | }; |
1251 | 1252 | ||
1252 | /** | 1253 | /** |
@@ -2981,40 +2982,15 @@ static int init_dma_pools(struct pch_udc_dev *dev) | |||
2981 | return 0; | 2982 | return 0; |
2982 | } | 2983 | } |
2983 | 2984 | ||
2984 | static int pch_udc_start(struct usb_gadget_driver *driver, | 2985 | static int pch_udc_start(struct usb_gadget *g, |
2985 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 2986 | struct usb_gadget_driver *driver) |
2986 | { | 2987 | { |
2987 | struct pch_udc_dev *dev = pch_udc; | 2988 | struct pch_udc_dev *dev = to_pch_udc(g); |
2988 | int retval; | ||
2989 | |||
2990 | if (!driver || (driver->max_speed == USB_SPEED_UNKNOWN) || !bind || | ||
2991 | !driver->setup || !driver->unbind || !driver->disconnect) { | ||
2992 | dev_err(&dev->pdev->dev, | ||
2993 | "%s: invalid driver parameter\n", __func__); | ||
2994 | return -EINVAL; | ||
2995 | } | ||
2996 | 2989 | ||
2997 | if (!dev) | ||
2998 | return -ENODEV; | ||
2999 | |||
3000 | if (dev->driver) { | ||
3001 | dev_err(&dev->pdev->dev, "%s: already bound\n", __func__); | ||
3002 | return -EBUSY; | ||
3003 | } | ||
3004 | driver->driver.bus = NULL; | 2990 | driver->driver.bus = NULL; |
3005 | dev->driver = driver; | 2991 | dev->driver = driver; |
3006 | dev->gadget.dev.driver = &driver->driver; | 2992 | dev->gadget.dev.driver = &driver->driver; |
3007 | 2993 | ||
3008 | /* Invoke the bind routine of the gadget driver */ | ||
3009 | retval = bind(&dev->gadget, driver); | ||
3010 | |||
3011 | if (retval) { | ||
3012 | dev_err(&dev->pdev->dev, "%s: binding to %s returning %d\n", | ||
3013 | __func__, driver->driver.name, retval); | ||
3014 | dev->driver = NULL; | ||
3015 | dev->gadget.dev.driver = NULL; | ||
3016 | return retval; | ||
3017 | } | ||
3018 | /* get ready for ep0 traffic */ | 2994 | /* get ready for ep0 traffic */ |
3019 | pch_udc_setup_ep0(dev); | 2995 | pch_udc_setup_ep0(dev); |
3020 | 2996 | ||
@@ -3026,30 +3002,21 @@ static int pch_udc_start(struct usb_gadget_driver *driver, | |||
3026 | return 0; | 3002 | return 0; |
3027 | } | 3003 | } |
3028 | 3004 | ||
3029 | static int pch_udc_stop(struct usb_gadget_driver *driver) | 3005 | static int pch_udc_stop(struct usb_gadget *g, |
3006 | struct usb_gadget_driver *driver) | ||
3030 | { | 3007 | { |
3031 | struct pch_udc_dev *dev = pch_udc; | 3008 | struct pch_udc_dev *dev = to_pch_udc(g); |
3032 | |||
3033 | if (!dev) | ||
3034 | return -ENODEV; | ||
3035 | |||
3036 | if (!driver || (driver != dev->driver)) { | ||
3037 | dev_err(&dev->pdev->dev, | ||
3038 | "%s: invalid driver parameter\n", __func__); | ||
3039 | return -EINVAL; | ||
3040 | } | ||
3041 | 3009 | ||
3042 | pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); | 3010 | pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); |
3043 | 3011 | ||
3044 | /* Assures that there are no pending requests with this driver */ | 3012 | /* Assures that there are no pending requests with this driver */ |
3045 | driver->disconnect(&dev->gadget); | ||
3046 | driver->unbind(&dev->gadget); | ||
3047 | dev->gadget.dev.driver = NULL; | 3013 | dev->gadget.dev.driver = NULL; |
3048 | dev->driver = NULL; | 3014 | dev->driver = NULL; |
3049 | dev->connected = 0; | 3015 | dev->connected = 0; |
3050 | 3016 | ||
3051 | /* set SD */ | 3017 | /* set SD */ |
3052 | pch_udc_set_disconnect(dev); | 3018 | pch_udc_set_disconnect(dev); |
3019 | |||
3053 | return 0; | 3020 | return 0; |
3054 | } | 3021 | } |
3055 | 3022 | ||
@@ -3164,11 +3131,6 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
3164 | int retval; | 3131 | int retval; |
3165 | struct pch_udc_dev *dev; | 3132 | struct pch_udc_dev *dev; |
3166 | 3133 | ||
3167 | /* one udc only */ | ||
3168 | if (pch_udc) { | ||
3169 | pr_err("%s: already probed\n", __func__); | ||
3170 | return -EBUSY; | ||
3171 | } | ||
3172 | /* init */ | 3134 | /* init */ |
3173 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | 3135 | dev = kzalloc(sizeof *dev, GFP_KERNEL); |
3174 | if (!dev) { | 3136 | if (!dev) { |
@@ -3207,7 +3169,6 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
3207 | retval = -ENODEV; | 3169 | retval = -ENODEV; |
3208 | goto finished; | 3170 | goto finished; |
3209 | } | 3171 | } |
3210 | pch_udc = dev; | ||
3211 | /* initialize the hardware */ | 3172 | /* initialize the hardware */ |
3212 | if (pch_udc_pcd_init(dev)) { | 3173 | if (pch_udc_pcd_init(dev)) { |
3213 | retval = -ENODEV; | 3174 | retval = -ENODEV; |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index d52e869ce202..2bbcdce942dc 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -996,9 +996,10 @@ static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
996 | return -EOPNOTSUPP; | 996 | return -EOPNOTSUPP; |
997 | } | 997 | } |
998 | 998 | ||
999 | static int pxa25x_start(struct usb_gadget_driver *driver, | 999 | static int pxa25x_udc_start(struct usb_gadget *g, |
1000 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1000 | struct usb_gadget_driver *driver); |
1001 | static int pxa25x_stop(struct usb_gadget_driver *driver); | 1001 | static int pxa25x_udc_stop(struct usb_gadget *g, |
1002 | struct usb_gadget_driver *driver); | ||
1002 | 1003 | ||
1003 | static const struct usb_gadget_ops pxa25x_udc_ops = { | 1004 | static const struct usb_gadget_ops pxa25x_udc_ops = { |
1004 | .get_frame = pxa25x_udc_get_frame, | 1005 | .get_frame = pxa25x_udc_get_frame, |
@@ -1006,8 +1007,8 @@ static const struct usb_gadget_ops pxa25x_udc_ops = { | |||
1006 | .vbus_session = pxa25x_udc_vbus_session, | 1007 | .vbus_session = pxa25x_udc_vbus_session, |
1007 | .pullup = pxa25x_udc_pullup, | 1008 | .pullup = pxa25x_udc_pullup, |
1008 | .vbus_draw = pxa25x_udc_vbus_draw, | 1009 | .vbus_draw = pxa25x_udc_vbus_draw, |
1009 | .start = pxa25x_start, | 1010 | .udc_start = pxa25x_udc_start, |
1010 | .stop = pxa25x_stop, | 1011 | .udc_stop = pxa25x_udc_stop, |
1011 | }; | 1012 | }; |
1012 | 1013 | ||
1013 | /*-------------------------------------------------------------------------*/ | 1014 | /*-------------------------------------------------------------------------*/ |
@@ -1254,23 +1255,12 @@ static void udc_enable (struct pxa25x_udc *dev) | |||
1254 | * disconnect is reported. then a host may connect again, or | 1255 | * disconnect is reported. then a host may connect again, or |
1255 | * the driver might get unbound. | 1256 | * the driver might get unbound. |
1256 | */ | 1257 | */ |
1257 | static int pxa25x_start(struct usb_gadget_driver *driver, | 1258 | static int pxa25x_udc_start(struct usb_gadget *g, |
1258 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1259 | struct usb_gadget_driver *driver) |
1259 | { | 1260 | { |
1260 | struct pxa25x_udc *dev = the_controller; | 1261 | struct pxa25x_udc *dev = to_pxa25x(g); |
1261 | int retval; | 1262 | int retval; |
1262 | 1263 | ||
1263 | if (!driver | ||
1264 | || driver->max_speed < USB_SPEED_FULL | ||
1265 | || !bind | ||
1266 | || !driver->disconnect | ||
1267 | || !driver->setup) | ||
1268 | return -EINVAL; | ||
1269 | if (!dev) | ||
1270 | return -ENODEV; | ||
1271 | if (dev->driver) | ||
1272 | return -EBUSY; | ||
1273 | |||
1274 | /* first hook up the driver ... */ | 1264 | /* first hook up the driver ... */ |
1275 | dev->driver = driver; | 1265 | dev->driver = driver; |
1276 | dev->gadget.dev.driver = &driver->driver; | 1266 | dev->gadget.dev.driver = &driver->driver; |
@@ -1278,34 +1268,20 @@ static int pxa25x_start(struct usb_gadget_driver *driver, | |||
1278 | 1268 | ||
1279 | retval = device_add (&dev->gadget.dev); | 1269 | retval = device_add (&dev->gadget.dev); |
1280 | if (retval) { | 1270 | if (retval) { |
1281 | fail: | ||
1282 | dev->driver = NULL; | 1271 | dev->driver = NULL; |
1283 | dev->gadget.dev.driver = NULL; | 1272 | dev->gadget.dev.driver = NULL; |
1284 | return retval; | 1273 | return retval; |
1285 | } | 1274 | } |
1286 | retval = bind(&dev->gadget, driver); | ||
1287 | if (retval) { | ||
1288 | DMSG("bind to driver %s --> error %d\n", | ||
1289 | driver->driver.name, retval); | ||
1290 | device_del (&dev->gadget.dev); | ||
1291 | goto fail; | ||
1292 | } | ||
1293 | 1275 | ||
1294 | /* ... then enable host detection and ep0; and we're ready | 1276 | /* ... then enable host detection and ep0; and we're ready |
1295 | * for set_configuration as well as eventual disconnect. | 1277 | * for set_configuration as well as eventual disconnect. |
1296 | */ | 1278 | */ |
1297 | DMSG("registered gadget driver '%s'\n", driver->driver.name); | ||
1298 | |||
1299 | /* connect to bus through transceiver */ | 1279 | /* connect to bus through transceiver */ |
1300 | if (!IS_ERR_OR_NULL(dev->transceiver)) { | 1280 | if (!IS_ERR_OR_NULL(dev->transceiver)) { |
1301 | retval = otg_set_peripheral(dev->transceiver->otg, | 1281 | retval = otg_set_peripheral(dev->transceiver->otg, |
1302 | &dev->gadget); | 1282 | &dev->gadget); |
1303 | if (retval) { | 1283 | if (retval) |
1304 | DMSG("can't bind to transceiver\n"); | ||
1305 | if (driver->unbind) | ||
1306 | driver->unbind(&dev->gadget); | ||
1307 | goto bind_fail; | 1284 | goto bind_fail; |
1308 | } | ||
1309 | } | 1285 | } |
1310 | 1286 | ||
1311 | pullup(dev); | 1287 | pullup(dev); |
@@ -1334,22 +1310,14 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) | |||
1334 | } | 1310 | } |
1335 | del_timer_sync(&dev->timer); | 1311 | del_timer_sync(&dev->timer); |
1336 | 1312 | ||
1337 | /* report disconnect; the driver is already quiesced */ | ||
1338 | if (driver) | ||
1339 | driver->disconnect(&dev->gadget); | ||
1340 | |||
1341 | /* re-init driver-visible data structures */ | 1313 | /* re-init driver-visible data structures */ |
1342 | udc_reinit(dev); | 1314 | udc_reinit(dev); |
1343 | } | 1315 | } |
1344 | 1316 | ||
1345 | static int pxa25x_stop(struct usb_gadget_driver *driver) | 1317 | static int pxa25x_udc_stop(struct usb_gadget*g, |
1318 | struct usb_gadget_driver *driver) | ||
1346 | { | 1319 | { |
1347 | struct pxa25x_udc *dev = the_controller; | 1320 | struct pxa25x_udc *dev = to_pxa25x(g); |
1348 | |||
1349 | if (!dev) | ||
1350 | return -ENODEV; | ||
1351 | if (!driver || driver != dev->driver || !driver->unbind) | ||
1352 | return -EINVAL; | ||
1353 | 1321 | ||
1354 | local_irq_disable(); | 1322 | local_irq_disable(); |
1355 | dev->pullup = 0; | 1323 | dev->pullup = 0; |
@@ -1360,14 +1328,12 @@ static int pxa25x_stop(struct usb_gadget_driver *driver) | |||
1360 | if (!IS_ERR_OR_NULL(dev->transceiver)) | 1328 | if (!IS_ERR_OR_NULL(dev->transceiver)) |
1361 | (void) otg_set_peripheral(dev->transceiver->otg, NULL); | 1329 | (void) otg_set_peripheral(dev->transceiver->otg, NULL); |
1362 | 1330 | ||
1363 | driver->unbind(&dev->gadget); | ||
1364 | dev->gadget.dev.driver = NULL; | 1331 | dev->gadget.dev.driver = NULL; |
1365 | dev->driver = NULL; | 1332 | dev->driver = NULL; |
1366 | 1333 | ||
1367 | device_del (&dev->gadget.dev); | 1334 | device_del (&dev->gadget.dev); |
1368 | |||
1369 | DMSG("unregistered gadget driver '%s'\n", driver->driver.name); | ||
1370 | dump_state(dev); | 1335 | dump_state(dev); |
1336 | |||
1371 | return 0; | 1337 | return 0; |
1372 | } | 1338 | } |
1373 | 1339 | ||
diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/pxa25x_udc.h index 2eca1e71fecd..3fe5931dc21a 100644 --- a/drivers/usb/gadget/pxa25x_udc.h +++ b/drivers/usb/gadget/pxa25x_udc.h | |||
@@ -126,6 +126,7 @@ struct pxa25x_udc { | |||
126 | struct dentry *debugfs_udc; | 126 | struct dentry *debugfs_udc; |
127 | #endif | 127 | #endif |
128 | }; | 128 | }; |
129 | #define to_pxa25x(g) (container_of((g), struct pxa25x_udc, gadget)) | ||
129 | 130 | ||
130 | /*-------------------------------------------------------------------------*/ | 131 | /*-------------------------------------------------------------------------*/ |
131 | 132 | ||
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 2b3b01d5f403..f7d25795821a 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -1671,9 +1671,10 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
1671 | return -EOPNOTSUPP; | 1671 | return -EOPNOTSUPP; |
1672 | } | 1672 | } |
1673 | 1673 | ||
1674 | static int pxa27x_udc_start(struct usb_gadget_driver *driver, | 1674 | static int pxa27x_udc_start(struct usb_gadget *g, |
1675 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1675 | struct usb_gadget_driver *driver); |
1676 | static int pxa27x_udc_stop(struct usb_gadget_driver *driver); | 1676 | static int pxa27x_udc_stop(struct usb_gadget *g, |
1677 | struct usb_gadget_driver *driver); | ||
1677 | 1678 | ||
1678 | static const struct usb_gadget_ops pxa_udc_ops = { | 1679 | static const struct usb_gadget_ops pxa_udc_ops = { |
1679 | .get_frame = pxa_udc_get_frame, | 1680 | .get_frame = pxa_udc_get_frame, |
@@ -1681,8 +1682,8 @@ static const struct usb_gadget_ops pxa_udc_ops = { | |||
1681 | .pullup = pxa_udc_pullup, | 1682 | .pullup = pxa_udc_pullup, |
1682 | .vbus_session = pxa_udc_vbus_session, | 1683 | .vbus_session = pxa_udc_vbus_session, |
1683 | .vbus_draw = pxa_udc_vbus_draw, | 1684 | .vbus_draw = pxa_udc_vbus_draw, |
1684 | .start = pxa27x_udc_start, | 1685 | .udc_start = pxa27x_udc_start, |
1685 | .stop = pxa27x_udc_stop, | 1686 | .udc_stop = pxa27x_udc_stop, |
1686 | }; | 1687 | }; |
1687 | 1688 | ||
1688 | /** | 1689 | /** |
@@ -1802,20 +1803,12 @@ static void udc_enable(struct pxa_udc *udc) | |||
1802 | * | 1803 | * |
1803 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise | 1804 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise |
1804 | */ | 1805 | */ |
1805 | static int pxa27x_udc_start(struct usb_gadget_driver *driver, | 1806 | static int pxa27x_udc_start(struct usb_gadget *g, |
1806 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1807 | struct usb_gadget_driver *driver) |
1807 | { | 1808 | { |
1808 | struct pxa_udc *udc = the_controller; | 1809 | struct pxa_udc *udc = to_pxa(g); |
1809 | int retval; | 1810 | int retval; |
1810 | 1811 | ||
1811 | if (!driver || driver->max_speed < USB_SPEED_FULL || !bind | ||
1812 | || !driver->disconnect || !driver->setup) | ||
1813 | return -EINVAL; | ||
1814 | if (!udc) | ||
1815 | return -ENODEV; | ||
1816 | if (udc->driver) | ||
1817 | return -EBUSY; | ||
1818 | |||
1819 | /* first hook up the driver ... */ | 1812 | /* first hook up the driver ... */ |
1820 | udc->driver = driver; | 1813 | udc->driver = driver; |
1821 | udc->gadget.dev.driver = &driver->driver; | 1814 | udc->gadget.dev.driver = &driver->driver; |
@@ -1824,23 +1817,14 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, | |||
1824 | retval = device_add(&udc->gadget.dev); | 1817 | retval = device_add(&udc->gadget.dev); |
1825 | if (retval) { | 1818 | if (retval) { |
1826 | dev_err(udc->dev, "device_add error %d\n", retval); | 1819 | dev_err(udc->dev, "device_add error %d\n", retval); |
1827 | goto add_fail; | 1820 | goto fail; |
1828 | } | 1821 | } |
1829 | retval = bind(&udc->gadget, driver); | ||
1830 | if (retval) { | ||
1831 | dev_err(udc->dev, "bind to driver %s --> error %d\n", | ||
1832 | driver->driver.name, retval); | ||
1833 | goto bind_fail; | ||
1834 | } | ||
1835 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", | ||
1836 | driver->driver.name); | ||
1837 | |||
1838 | if (!IS_ERR_OR_NULL(udc->transceiver)) { | 1822 | if (!IS_ERR_OR_NULL(udc->transceiver)) { |
1839 | retval = otg_set_peripheral(udc->transceiver->otg, | 1823 | retval = otg_set_peripheral(udc->transceiver->otg, |
1840 | &udc->gadget); | 1824 | &udc->gadget); |
1841 | if (retval) { | 1825 | if (retval) { |
1842 | dev_err(udc->dev, "can't bind to transceiver\n"); | 1826 | dev_err(udc->dev, "can't bind to transceiver\n"); |
1843 | goto transceiver_fail; | 1827 | goto fail; |
1844 | } | 1828 | } |
1845 | } | 1829 | } |
1846 | 1830 | ||
@@ -1848,12 +1832,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, | |||
1848 | udc_enable(udc); | 1832 | udc_enable(udc); |
1849 | return 0; | 1833 | return 0; |
1850 | 1834 | ||
1851 | transceiver_fail: | 1835 | fail: |
1852 | if (driver->unbind) | ||
1853 | driver->unbind(&udc->gadget); | ||
1854 | bind_fail: | ||
1855 | device_del(&udc->gadget.dev); | ||
1856 | add_fail: | ||
1857 | udc->driver = NULL; | 1836 | udc->driver = NULL; |
1858 | udc->gadget.dev.driver = NULL; | 1837 | udc->gadget.dev.driver = NULL; |
1859 | return retval; | 1838 | return retval; |
@@ -1878,9 +1857,6 @@ static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) | |||
1878 | 1857 | ||
1879 | for (i = 0; i < NR_USB_ENDPOINTS; i++) | 1858 | for (i = 0; i < NR_USB_ENDPOINTS; i++) |
1880 | pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep); | 1859 | pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep); |
1881 | |||
1882 | if (driver) | ||
1883 | driver->disconnect(&udc->gadget); | ||
1884 | } | 1860 | } |
1885 | 1861 | ||
1886 | /** | 1862 | /** |
@@ -1889,25 +1865,18 @@ static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) | |||
1889 | * | 1865 | * |
1890 | * Returns 0 if no error, -ENODEV, -EINVAL otherwise | 1866 | * Returns 0 if no error, -ENODEV, -EINVAL otherwise |
1891 | */ | 1867 | */ |
1892 | static int pxa27x_udc_stop(struct usb_gadget_driver *driver) | 1868 | static int pxa27x_udc_stop(struct usb_gadget *g, |
1869 | struct usb_gadget_driver *driver) | ||
1893 | { | 1870 | { |
1894 | struct pxa_udc *udc = the_controller; | 1871 | struct pxa_udc *udc = to_pxa(g); |
1895 | |||
1896 | if (!udc) | ||
1897 | return -ENODEV; | ||
1898 | if (!driver || driver != udc->driver || !driver->unbind) | ||
1899 | return -EINVAL; | ||
1900 | 1872 | ||
1901 | stop_activity(udc, driver); | 1873 | stop_activity(udc, driver); |
1902 | udc_disable(udc); | 1874 | udc_disable(udc); |
1903 | dplus_pullup(udc, 0); | 1875 | dplus_pullup(udc, 0); |
1904 | 1876 | ||
1905 | driver->unbind(&udc->gadget); | ||
1906 | udc->driver = NULL; | 1877 | udc->driver = NULL; |
1907 | 1878 | ||
1908 | device_del(&udc->gadget.dev); | 1879 | device_del(&udc->gadget.dev); |
1909 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", | ||
1910 | driver->driver.name); | ||
1911 | 1880 | ||
1912 | if (!IS_ERR_OR_NULL(udc->transceiver)) | 1881 | if (!IS_ERR_OR_NULL(udc->transceiver)) |
1913 | return otg_set_peripheral(udc->transceiver->otg, NULL); | 1882 | return otg_set_peripheral(udc->transceiver->otg, NULL); |
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index 79d81a4b2344..28f2b53530f5 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa27x_udc.h | |||
@@ -473,6 +473,7 @@ struct pxa_udc { | |||
473 | struct dentry *debugfs_eps; | 473 | struct dentry *debugfs_eps; |
474 | #endif | 474 | #endif |
475 | }; | 475 | }; |
476 | #define to_pxa(g) (container_of((g), struct pxa_udc, gadget)) | ||
476 | 477 | ||
477 | static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget) | 478 | static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget) |
478 | { | 479 | { |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 9a9fadd9095f..f46a1b77ce3e 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1812,7 +1812,7 @@ static int r8a66597_set_selfpowered(struct usb_gadget *gadget, int is_self) | |||
1812 | return 0; | 1812 | return 0; |
1813 | } | 1813 | } |
1814 | 1814 | ||
1815 | static struct usb_gadget_ops r8a66597_gadget_ops = { | 1815 | static const struct usb_gadget_ops r8a66597_gadget_ops = { |
1816 | .get_frame = r8a66597_get_frame, | 1816 | .get_frame = r8a66597_get_frame, |
1817 | .udc_start = r8a66597_start, | 1817 | .udc_start = r8a66597_start, |
1818 | .udc_stop = r8a66597_stop, | 1818 | .udc_stop = r8a66597_stop, |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index de80fa644b5a..c26564f29a2c 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/usb/ch9.h> | 33 | #include <linux/usb/ch9.h> |
34 | #include <linux/usb/gadget.h> | 34 | #include <linux/usb/gadget.h> |
35 | #include <linux/usb/phy.h> | ||
35 | #include <linux/platform_data/s3c-hsotg.h> | 36 | #include <linux/platform_data/s3c-hsotg.h> |
36 | 37 | ||
37 | #include <mach/map.h> | 38 | #include <mach/map.h> |
@@ -133,7 +134,9 @@ struct s3c_hsotg_ep { | |||
133 | * struct s3c_hsotg - driver state. | 134 | * struct s3c_hsotg - driver state. |
134 | * @dev: The parent device supplied to the probe function | 135 | * @dev: The parent device supplied to the probe function |
135 | * @driver: USB gadget driver | 136 | * @driver: USB gadget driver |
136 | * @plat: The platform specific configuration data. | 137 | * @phy: The otg phy transceiver structure for phy control. |
138 | * @plat: The platform specific configuration data. This can be removed once | ||
139 | * all SoCs support usb transceiver. | ||
137 | * @regs: The memory area mapped for accessing registers. | 140 | * @regs: The memory area mapped for accessing registers. |
138 | * @irq: The IRQ number we are using | 141 | * @irq: The IRQ number we are using |
139 | * @supplies: Definition of USB power supplies | 142 | * @supplies: Definition of USB power supplies |
@@ -153,6 +156,7 @@ struct s3c_hsotg_ep { | |||
153 | struct s3c_hsotg { | 156 | struct s3c_hsotg { |
154 | struct device *dev; | 157 | struct device *dev; |
155 | struct usb_gadget_driver *driver; | 158 | struct usb_gadget_driver *driver; |
159 | struct usb_phy *phy; | ||
156 | struct s3c_hsotg_plat *plat; | 160 | struct s3c_hsotg_plat *plat; |
157 | 161 | ||
158 | spinlock_t lock; | 162 | spinlock_t lock; |
@@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) | |||
2854 | struct platform_device *pdev = to_platform_device(hsotg->dev); | 2858 | struct platform_device *pdev = to_platform_device(hsotg->dev); |
2855 | 2859 | ||
2856 | dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); | 2860 | dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); |
2857 | if (hsotg->plat->phy_init) | 2861 | |
2862 | if (hsotg->phy) | ||
2863 | usb_phy_init(hsotg->phy); | ||
2864 | else if (hsotg->plat->phy_init) | ||
2858 | hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); | 2865 | hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); |
2859 | } | 2866 | } |
2860 | 2867 | ||
@@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) | |||
2869 | { | 2876 | { |
2870 | struct platform_device *pdev = to_platform_device(hsotg->dev); | 2877 | struct platform_device *pdev = to_platform_device(hsotg->dev); |
2871 | 2878 | ||
2872 | if (hsotg->plat->phy_exit) | 2879 | if (hsotg->phy) |
2880 | usb_phy_shutdown(hsotg->phy); | ||
2881 | else if (hsotg->plat->phy_exit) | ||
2873 | hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); | 2882 | hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); |
2874 | } | 2883 | } |
2875 | 2884 | ||
@@ -3055,7 +3064,7 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | |||
3055 | return 0; | 3064 | return 0; |
3056 | } | 3065 | } |
3057 | 3066 | ||
3058 | static struct usb_gadget_ops s3c_hsotg_gadget_ops = { | 3067 | static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { |
3059 | .get_frame = s3c_hsotg_gadget_getframe, | 3068 | .get_frame = s3c_hsotg_gadget_getframe, |
3060 | .udc_start = s3c_hsotg_udc_start, | 3069 | .udc_start = s3c_hsotg_udc_start, |
3061 | .udc_stop = s3c_hsotg_udc_stop, | 3070 | .udc_stop = s3c_hsotg_udc_stop, |
@@ -3492,6 +3501,7 @@ static void s3c_hsotg_release(struct device *dev) | |||
3492 | static int s3c_hsotg_probe(struct platform_device *pdev) | 3501 | static int s3c_hsotg_probe(struct platform_device *pdev) |
3493 | { | 3502 | { |
3494 | struct s3c_hsotg_plat *plat = pdev->dev.platform_data; | 3503 | struct s3c_hsotg_plat *plat = pdev->dev.platform_data; |
3504 | struct usb_phy *phy; | ||
3495 | struct device *dev = &pdev->dev; | 3505 | struct device *dev = &pdev->dev; |
3496 | struct s3c_hsotg_ep *eps; | 3506 | struct s3c_hsotg_ep *eps; |
3497 | struct s3c_hsotg *hsotg; | 3507 | struct s3c_hsotg *hsotg; |
@@ -3500,20 +3510,27 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3500 | int ret; | 3510 | int ret; |
3501 | int i; | 3511 | int i; |
3502 | 3512 | ||
3503 | plat = pdev->dev.platform_data; | ||
3504 | if (!plat) { | ||
3505 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
3506 | return -EINVAL; | ||
3507 | } | ||
3508 | |||
3509 | hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); | 3513 | hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); |
3510 | if (!hsotg) { | 3514 | if (!hsotg) { |
3511 | dev_err(dev, "cannot get memory\n"); | 3515 | dev_err(dev, "cannot get memory\n"); |
3512 | return -ENOMEM; | 3516 | return -ENOMEM; |
3513 | } | 3517 | } |
3514 | 3518 | ||
3519 | phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
3520 | if (IS_ERR_OR_NULL(phy)) { | ||
3521 | /* Fallback for pdata */ | ||
3522 | plat = pdev->dev.platform_data; | ||
3523 | if (!plat) { | ||
3524 | dev_err(&pdev->dev, "no platform data or transceiver defined\n"); | ||
3525 | return -EPROBE_DEFER; | ||
3526 | } else { | ||
3527 | hsotg->plat = plat; | ||
3528 | } | ||
3529 | } else { | ||
3530 | hsotg->phy = phy; | ||
3531 | } | ||
3532 | |||
3515 | hsotg->dev = dev; | 3533 | hsotg->dev = dev; |
3516 | hsotg->plat = plat; | ||
3517 | 3534 | ||
3518 | hsotg->clk = devm_clk_get(&pdev->dev, "otg"); | 3535 | hsotg->clk = devm_clk_get(&pdev->dev, "otg"); |
3519 | if (IS_ERR(hsotg->clk)) { | 3536 | if (IS_ERR(hsotg->clk)) { |
@@ -3571,7 +3588,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3571 | for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) | 3588 | for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) |
3572 | hsotg->supplies[i].supply = s3c_hsotg_supply_names[i]; | 3589 | hsotg->supplies[i].supply = s3c_hsotg_supply_names[i]; |
3573 | 3590 | ||
3574 | ret = regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), | 3591 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), |
3575 | hsotg->supplies); | 3592 | hsotg->supplies); |
3576 | if (ret) { | 3593 | if (ret) { |
3577 | dev_err(dev, "failed to request supplies: %d\n", ret); | 3594 | dev_err(dev, "failed to request supplies: %d\n", ret); |
@@ -3661,8 +3678,6 @@ err_ep_mem: | |||
3661 | kfree(eps); | 3678 | kfree(eps); |
3662 | err_supplies: | 3679 | err_supplies: |
3663 | s3c_hsotg_phy_disable(hsotg); | 3680 | s3c_hsotg_phy_disable(hsotg); |
3664 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | ||
3665 | |||
3666 | err_clk: | 3681 | err_clk: |
3667 | clk_disable_unprepare(hsotg->clk); | 3682 | clk_disable_unprepare(hsotg->clk); |
3668 | 3683 | ||
@@ -3687,7 +3702,6 @@ static int s3c_hsotg_remove(struct platform_device *pdev) | |||
3687 | } | 3702 | } |
3688 | 3703 | ||
3689 | s3c_hsotg_phy_disable(hsotg); | 3704 | s3c_hsotg_phy_disable(hsotg); |
3690 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | ||
3691 | 3705 | ||
3692 | clk_disable_unprepare(hsotg->clk); | 3706 | clk_disable_unprepare(hsotg->clk); |
3693 | 3707 | ||
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 94ca33bb990b..458965a1b138 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c | |||
@@ -435,7 +435,7 @@ static void s3c_hsudc_epin_intr(struct s3c_hsudc *hsudc, u32 ep_idx) | |||
435 | struct s3c_hsudc_req *hsreq; | 435 | struct s3c_hsudc_req *hsreq; |
436 | u32 csr; | 436 | u32 csr; |
437 | 437 | ||
438 | csr = readl((u32)hsudc->regs + S3C_ESR); | 438 | csr = readl(hsudc->regs + S3C_ESR); |
439 | if (csr & S3C_ESR_STALL) { | 439 | if (csr & S3C_ESR_STALL) { |
440 | writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); | 440 | writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); |
441 | return; | 441 | return; |
@@ -468,7 +468,7 @@ static void s3c_hsudc_epout_intr(struct s3c_hsudc *hsudc, u32 ep_idx) | |||
468 | struct s3c_hsudc_req *hsreq; | 468 | struct s3c_hsudc_req *hsreq; |
469 | u32 csr; | 469 | u32 csr; |
470 | 470 | ||
471 | csr = readl((u32)hsudc->regs + S3C_ESR); | 471 | csr = readl(hsudc->regs + S3C_ESR); |
472 | if (csr & S3C_ESR_STALL) { | 472 | if (csr & S3C_ESR_STALL) { |
473 | writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); | 473 | writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); |
474 | return; | 474 | return; |
@@ -901,12 +901,12 @@ static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
901 | if (list_empty(&hsep->queue) && !hsep->stopped) { | 901 | if (list_empty(&hsep->queue) && !hsep->stopped) { |
902 | offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR; | 902 | offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR; |
903 | if (ep_is_in(hsep)) { | 903 | if (ep_is_in(hsep)) { |
904 | csr = readl((u32)hsudc->regs + offset); | 904 | csr = readl(hsudc->regs + offset); |
905 | if (!(csr & S3C_ESR_TX_SUCCESS) && | 905 | if (!(csr & S3C_ESR_TX_SUCCESS) && |
906 | (s3c_hsudc_write_fifo(hsep, hsreq) == 1)) | 906 | (s3c_hsudc_write_fifo(hsep, hsreq) == 1)) |
907 | hsreq = NULL; | 907 | hsreq = NULL; |
908 | } else { | 908 | } else { |
909 | csr = readl((u32)hsudc->regs + offset); | 909 | csr = readl(hsudc->regs + offset); |
910 | if ((csr & S3C_ESR_RX_SUCCESS) | 910 | if ((csr & S3C_ESR_RX_SUCCESS) |
911 | && (s3c_hsudc_read_fifo(hsep, hsreq) == 1)) | 911 | && (s3c_hsudc_read_fifo(hsep, hsreq) == 1)) |
912 | hsreq = NULL; | 912 | hsreq = NULL; |
@@ -1254,7 +1254,7 @@ static int s3c_hsudc_vbus_draw(struct usb_gadget *gadget, unsigned mA) | |||
1254 | return -EOPNOTSUPP; | 1254 | return -EOPNOTSUPP; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | static struct usb_gadget_ops s3c_hsudc_gadget_ops = { | 1257 | static const struct usb_gadget_ops s3c_hsudc_gadget_ops = { |
1258 | .get_frame = s3c_hsudc_gadget_getframe, | 1258 | .get_frame = s3c_hsudc_gadget_getframe, |
1259 | .udc_start = s3c_hsudc_start, | 1259 | .udc_start = s3c_hsudc_start, |
1260 | .udc_stop = s3c_hsudc_stop, | 1260 | .udc_stop = s3c_hsudc_stop, |
@@ -1286,7 +1286,7 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1286 | for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) | 1286 | for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) |
1287 | hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; | 1287 | hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; |
1288 | 1288 | ||
1289 | ret = regulator_bulk_get(dev, ARRAY_SIZE(hsudc->supplies), | 1289 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsudc->supplies), |
1290 | hsudc->supplies); | 1290 | hsudc->supplies); |
1291 | if (ret != 0) { | 1291 | if (ret != 0) { |
1292 | dev_err(dev, "failed to request supplies: %d\n", ret); | 1292 | dev_err(dev, "failed to request supplies: %d\n", ret); |
@@ -1366,7 +1366,6 @@ err_res: | |||
1366 | if (!IS_ERR_OR_NULL(hsudc->transceiver)) | 1366 | if (!IS_ERR_OR_NULL(hsudc->transceiver)) |
1367 | usb_put_phy(hsudc->transceiver); | 1367 | usb_put_phy(hsudc->transceiver); |
1368 | 1368 | ||
1369 | regulator_bulk_free(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); | ||
1370 | err_supplies: | 1369 | err_supplies: |
1371 | return ret; | 1370 | return ret; |
1372 | } | 1371 | } |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index a2fa6e16d019..fc07b4381286 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -1538,9 +1538,10 @@ static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma) | |||
1538 | return -ENOTSUPP; | 1538 | return -ENOTSUPP; |
1539 | } | 1539 | } |
1540 | 1540 | ||
1541 | static int s3c2410_udc_start(struct usb_gadget_driver *driver, | 1541 | static int s3c2410_udc_start(struct usb_gadget *g, |
1542 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 1542 | struct usb_gadget_driver *driver); |
1543 | static int s3c2410_udc_stop(struct usb_gadget_driver *driver); | 1543 | static int s3c2410_udc_stop(struct usb_gadget *g, |
1544 | struct usb_gadget_driver *driver); | ||
1544 | 1545 | ||
1545 | static const struct usb_gadget_ops s3c2410_ops = { | 1546 | static const struct usb_gadget_ops s3c2410_ops = { |
1546 | .get_frame = s3c2410_udc_get_frame, | 1547 | .get_frame = s3c2410_udc_get_frame, |
@@ -1549,8 +1550,8 @@ static const struct usb_gadget_ops s3c2410_ops = { | |||
1549 | .pullup = s3c2410_udc_pullup, | 1550 | .pullup = s3c2410_udc_pullup, |
1550 | .vbus_session = s3c2410_udc_vbus_session, | 1551 | .vbus_session = s3c2410_udc_vbus_session, |
1551 | .vbus_draw = s3c2410_vbus_draw, | 1552 | .vbus_draw = s3c2410_vbus_draw, |
1552 | .start = s3c2410_udc_start, | 1553 | .udc_start = s3c2410_udc_start, |
1553 | .stop = s3c2410_udc_stop, | 1554 | .udc_stop = s3c2410_udc_stop, |
1554 | }; | 1555 | }; |
1555 | 1556 | ||
1556 | static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd) | 1557 | static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd) |
@@ -1664,33 +1665,14 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) | |||
1664 | s3c2410_udc_command(S3C2410_UDC_P_ENABLE); | 1665 | s3c2410_udc_command(S3C2410_UDC_P_ENABLE); |
1665 | } | 1666 | } |
1666 | 1667 | ||
1667 | static int s3c2410_udc_start(struct usb_gadget_driver *driver, | 1668 | static int s3c2410_udc_start(struct usb_gadget *g, |
1668 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1669 | struct usb_gadget_driver *driver) |
1669 | { | 1670 | { |
1670 | struct s3c2410_udc *udc = the_controller; | 1671 | struct s3c2410_udc *udc = to_s3c2410(g) |
1671 | int retval; | 1672 | int retval; |
1672 | 1673 | ||
1673 | dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name); | 1674 | dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name); |
1674 | 1675 | ||
1675 | /* Sanity checks */ | ||
1676 | if (!udc) | ||
1677 | return -ENODEV; | ||
1678 | |||
1679 | if (udc->driver) | ||
1680 | return -EBUSY; | ||
1681 | |||
1682 | if (!bind || !driver->setup || driver->max_speed < USB_SPEED_FULL) { | ||
1683 | dev_err(&udc->gadget.dev, "Invalid driver: bind %p setup %p speed %d\n", | ||
1684 | bind, driver->setup, driver->max_speed); | ||
1685 | return -EINVAL; | ||
1686 | } | ||
1687 | #if defined(MODULE) | ||
1688 | if (!driver->unbind) { | ||
1689 | dev_err(&udc->gadget.dev, "Invalid driver: no unbind method\n"); | ||
1690 | return -EINVAL; | ||
1691 | } | ||
1692 | #endif | ||
1693 | |||
1694 | /* Hook the driver */ | 1676 | /* Hook the driver */ |
1695 | udc->driver = driver; | 1677 | udc->driver = driver; |
1696 | udc->gadget.dev.driver = &driver->driver; | 1678 | udc->gadget.dev.driver = &driver->driver; |
@@ -1702,15 +1684,6 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, | |||
1702 | goto register_error; | 1684 | goto register_error; |
1703 | } | 1685 | } |
1704 | 1686 | ||
1705 | dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n", | ||
1706 | driver->driver.name); | ||
1707 | |||
1708 | retval = bind(&udc->gadget, driver); | ||
1709 | if (retval) { | ||
1710 | device_del(&udc->gadget.dev); | ||
1711 | goto register_error; | ||
1712 | } | ||
1713 | |||
1714 | /* Enable udc */ | 1687 | /* Enable udc */ |
1715 | s3c2410_udc_enable(udc); | 1688 | s3c2410_udc_enable(udc); |
1716 | 1689 | ||
@@ -1722,24 +1695,10 @@ register_error: | |||
1722 | return retval; | 1695 | return retval; |
1723 | } | 1696 | } |
1724 | 1697 | ||
1725 | static int s3c2410_udc_stop(struct usb_gadget_driver *driver) | 1698 | static int s3c2410_udc_stop(struct usb_gadget *g, |
1699 | struct usb_gadget_driver *driver) | ||
1726 | { | 1700 | { |
1727 | struct s3c2410_udc *udc = the_controller; | 1701 | struct s3c2410_udc *udc = to_s3c2410(g); |
1728 | |||
1729 | if (!udc) | ||
1730 | return -ENODEV; | ||
1731 | |||
1732 | if (!driver || driver != udc->driver || !driver->unbind) | ||
1733 | return -EINVAL; | ||
1734 | |||
1735 | dprintk(DEBUG_NORMAL, "usb_gadget_unregister_driver() '%s'\n", | ||
1736 | driver->driver.name); | ||
1737 | |||
1738 | /* report disconnect */ | ||
1739 | if (driver->disconnect) | ||
1740 | driver->disconnect(&udc->gadget); | ||
1741 | |||
1742 | driver->unbind(&udc->gadget); | ||
1743 | 1702 | ||
1744 | device_del(&udc->gadget.dev); | 1703 | device_del(&udc->gadget.dev); |
1745 | udc->driver = NULL; | 1704 | udc->driver = NULL; |
diff --git a/drivers/usb/gadget/s3c2410_udc.h b/drivers/usb/gadget/s3c2410_udc.h index 3e80fd5c820f..93bf225f1969 100644 --- a/drivers/usb/gadget/s3c2410_udc.h +++ b/drivers/usb/gadget/s3c2410_udc.h | |||
@@ -95,5 +95,6 @@ struct s3c2410_udc { | |||
95 | u8 vbus; | 95 | u8 vbus; |
96 | struct dentry *regs_info; | 96 | struct dentry *regs_info; |
97 | }; | 97 | }; |
98 | #define to_s3c2410(g) (container_of((g), struct s3c2410_udc, gadget)) | ||
98 | 99 | ||
99 | #endif | 100 | #endif |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 44752f531e85..68d7bb06ebcb 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -36,10 +36,8 @@ | |||
36 | * the runtime footprint, and giving us at least some parts of what | 36 | * the runtime footprint, and giving us at least some parts of what |
37 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | 37 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. |
38 | */ | 38 | */ |
39 | #include "f_acm.c" | ||
40 | #include "f_obex.c" | 39 | #include "f_obex.c" |
41 | #include "f_serial.c" | 40 | #include "f_serial.c" |
42 | #include "u_serial.c" | ||
43 | 41 | ||
44 | /*-------------------------------------------------------------------------*/ | 42 | /*-------------------------------------------------------------------------*/ |
45 | USB_GADGET_COMPOSITE_OPTIONS(); | 43 | USB_GADGET_COMPOSITE_OPTIONS(); |
@@ -128,20 +126,25 @@ module_param(n_ports, uint, 0); | |||
128 | MODULE_PARM_DESC(n_ports, "number of ports to create, default=1"); | 126 | MODULE_PARM_DESC(n_ports, "number of ports to create, default=1"); |
129 | 127 | ||
130 | /*-------------------------------------------------------------------------*/ | 128 | /*-------------------------------------------------------------------------*/ |
129 | static unsigned char tty_lines[MAX_U_SERIAL_PORTS]; | ||
131 | 130 | ||
132 | static int __init serial_bind_config(struct usb_configuration *c) | 131 | static int __init serial_bind_obex_config(struct usb_configuration *c) |
133 | { | 132 | { |
134 | unsigned i; | 133 | unsigned i; |
135 | int status = 0; | 134 | int status = 0; |
136 | 135 | ||
137 | for (i = 0; i < n_ports && status == 0; i++) { | 136 | for (i = 0; i < n_ports && status == 0; i++) |
138 | if (use_acm) | 137 | status = obex_bind_config(c, tty_lines[i]); |
139 | status = acm_bind_config(c, i); | 138 | return status; |
140 | else if (use_obex) | 139 | } |
141 | status = obex_bind_config(c, i); | 140 | |
142 | else | 141 | static int __init serial_bind_gser_config(struct usb_configuration *c) |
143 | status = gser_bind_config(c, i); | 142 | { |
144 | } | 143 | unsigned i; |
144 | int status = 0; | ||
145 | |||
146 | for (i = 0; i < n_ports && status == 0; i++) | ||
147 | status = gser_bind_config(c, tty_lines[i]); | ||
145 | return status; | 148 | return status; |
146 | } | 149 | } |
147 | 150 | ||
@@ -152,13 +155,70 @@ static struct usb_configuration serial_config_driver = { | |||
152 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | 155 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, |
153 | }; | 156 | }; |
154 | 157 | ||
158 | static struct usb_function_instance *fi_serial[MAX_U_SERIAL_PORTS]; | ||
159 | static struct usb_function *f_serial[MAX_U_SERIAL_PORTS]; | ||
160 | |||
161 | static int serial_register_ports(struct usb_composite_dev *cdev, | ||
162 | struct usb_configuration *c, const char *f_name) | ||
163 | { | ||
164 | int i; | ||
165 | int ret; | ||
166 | |||
167 | ret = usb_add_config_only(cdev, c); | ||
168 | if (ret) | ||
169 | goto out; | ||
170 | |||
171 | for (i = 0; i < n_ports; i++) { | ||
172 | struct f_serial_opts *opts; | ||
173 | |||
174 | fi_serial[i] = usb_get_function_instance(f_name); | ||
175 | if (IS_ERR(fi_serial[i])) { | ||
176 | ret = PTR_ERR(fi_serial[i]); | ||
177 | goto fail; | ||
178 | } | ||
179 | opts = container_of(fi_serial[i], struct f_serial_opts, func_inst); | ||
180 | opts->port_num = tty_lines[i]; | ||
181 | |||
182 | f_serial[i] = usb_get_function(fi_serial[i]); | ||
183 | if (IS_ERR(f_serial[i])) { | ||
184 | ret = PTR_ERR(f_serial[i]); | ||
185 | goto err_get_func; | ||
186 | } | ||
187 | |||
188 | ret = usb_add_function(c, f_serial[i]); | ||
189 | if (ret) | ||
190 | goto err_add_func; | ||
191 | } | ||
192 | |||
193 | return 0; | ||
194 | |||
195 | err_add_func: | ||
196 | usb_put_function(f_serial[i]); | ||
197 | err_get_func: | ||
198 | usb_put_function_instance(fi_serial[i]); | ||
199 | |||
200 | fail: | ||
201 | i--; | ||
202 | while (i >= 0) { | ||
203 | usb_remove_function(c, f_serial[i]); | ||
204 | usb_put_function(f_serial[i]); | ||
205 | usb_put_function_instance(fi_serial[i]); | ||
206 | i--; | ||
207 | } | ||
208 | out: | ||
209 | return ret; | ||
210 | } | ||
211 | |||
155 | static int __init gs_bind(struct usb_composite_dev *cdev) | 212 | static int __init gs_bind(struct usb_composite_dev *cdev) |
156 | { | 213 | { |
157 | int status; | 214 | int status; |
215 | int cur_line; | ||
158 | 216 | ||
159 | status = gserial_setup(cdev->gadget, n_ports); | 217 | for (cur_line = 0; cur_line < n_ports; cur_line++) { |
160 | if (status < 0) | 218 | status = gserial_alloc_line(&tty_lines[cur_line]); |
161 | return status; | 219 | if (status) |
220 | goto fail; | ||
221 | } | ||
162 | 222 | ||
163 | /* Allocate string descriptor numbers ... note that string | 223 | /* Allocate string descriptor numbers ... note that string |
164 | * contents can be overridden by the composite_dev glue. | 224 | * contents can be overridden by the composite_dev glue. |
@@ -178,8 +238,16 @@ static int __init gs_bind(struct usb_composite_dev *cdev) | |||
178 | } | 238 | } |
179 | 239 | ||
180 | /* register our configuration */ | 240 | /* register our configuration */ |
181 | status = usb_add_config(cdev, &serial_config_driver, | 241 | if (use_acm) { |
182 | serial_bind_config); | 242 | status = serial_register_ports(cdev, &serial_config_driver, |
243 | "acm"); | ||
244 | usb_ep_autoconfig_reset(cdev->gadget); | ||
245 | } else if (use_obex) | ||
246 | status = usb_add_config(cdev, &serial_config_driver, | ||
247 | serial_bind_obex_config); | ||
248 | else | ||
249 | status = usb_add_config(cdev, &serial_config_driver, | ||
250 | serial_bind_gser_config); | ||
183 | if (status < 0) | 251 | if (status < 0) |
184 | goto fail; | 252 | goto fail; |
185 | 253 | ||
@@ -189,16 +257,31 @@ static int __init gs_bind(struct usb_composite_dev *cdev) | |||
189 | return 0; | 257 | return 0; |
190 | 258 | ||
191 | fail: | 259 | fail: |
192 | gserial_cleanup(); | 260 | cur_line--; |
261 | while (cur_line >= 0) | ||
262 | gserial_free_line(tty_lines[cur_line--]); | ||
193 | return status; | 263 | return status; |
194 | } | 264 | } |
195 | 265 | ||
266 | static int gs_unbind(struct usb_composite_dev *cdev) | ||
267 | { | ||
268 | int i; | ||
269 | |||
270 | for (i = 0; i < n_ports; i++) { | ||
271 | usb_put_function(f_serial[i]); | ||
272 | usb_put_function_instance(fi_serial[i]); | ||
273 | gserial_free_line(tty_lines[i]); | ||
274 | } | ||
275 | return 0; | ||
276 | } | ||
277 | |||
196 | static __refdata struct usb_composite_driver gserial_driver = { | 278 | static __refdata struct usb_composite_driver gserial_driver = { |
197 | .name = "g_serial", | 279 | .name = "g_serial", |
198 | .dev = &device_desc, | 280 | .dev = &device_desc, |
199 | .strings = dev_strings, | 281 | .strings = dev_strings, |
200 | .max_speed = USB_SPEED_SUPER, | 282 | .max_speed = USB_SPEED_SUPER, |
201 | .bind = gs_bind, | 283 | .bind = gs_bind, |
284 | .unbind = gs_unbind, | ||
202 | }; | 285 | }; |
203 | 286 | ||
204 | static int __init init(void) | 287 | static int __init init(void) |
@@ -234,6 +317,5 @@ module_init(init); | |||
234 | static void __exit cleanup(void) | 317 | static void __exit cleanup(void) |
235 | { | 318 | { |
236 | usb_composite_unregister(&gserial_driver); | 319 | usb_composite_unregister(&gserial_driver); |
237 | gserial_cleanup(); | ||
238 | } | 320 | } |
239 | module_exit(cleanup); | 321 | module_exit(cleanup); |
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 0e3ae43454a2..4ecbf8496f48 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
@@ -93,18 +93,6 @@ | |||
93 | 93 | ||
94 | /*-------------------------------------------------------------------------*/ | 94 | /*-------------------------------------------------------------------------*/ |
95 | 95 | ||
96 | /* CBI Interrupt data structure */ | ||
97 | struct interrupt_data { | ||
98 | u8 bType; | ||
99 | u8 bValue; | ||
100 | }; | ||
101 | |||
102 | #define CBI_INTERRUPT_DATA_LEN 2 | ||
103 | |||
104 | /* CBI Accept Device-Specific Command request */ | ||
105 | #define USB_CBI_ADSC_REQUEST 0x00 | ||
106 | |||
107 | |||
108 | /* Length of a SCSI Command Data Block */ | 96 | /* Length of a SCSI Command Data Block */ |
109 | #define MAX_COMMAND_SIZE 16 | 97 | #define MAX_COMMAND_SIZE 16 |
110 | 98 | ||
@@ -385,41 +373,6 @@ static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { | |||
385 | /*.bMaxBurst = DYNAMIC, */ | 373 | /*.bMaxBurst = DYNAMIC, */ |
386 | }; | 374 | }; |
387 | 375 | ||
388 | static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = { | ||
389 | .bLength = USB_DT_USB_EXT_CAP_SIZE, | ||
390 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
391 | .bDevCapabilityType = USB_CAP_TYPE_EXT, | ||
392 | |||
393 | .bmAttributes = cpu_to_le32(USB_LPM_SUPPORT), | ||
394 | }; | ||
395 | |||
396 | static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = { | ||
397 | .bLength = USB_DT_USB_SS_CAP_SIZE, | ||
398 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
399 | .bDevCapabilityType = USB_SS_CAP_TYPE, | ||
400 | |||
401 | /* .bmAttributes = LTM is not supported yet */ | ||
402 | |||
403 | .wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION | ||
404 | | USB_FULL_SPEED_OPERATION | ||
405 | | USB_HIGH_SPEED_OPERATION | ||
406 | | USB_5GBPS_OPERATION), | ||
407 | .bFunctionalitySupport = USB_LOW_SPEED_OPERATION, | ||
408 | .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT, | ||
409 | .bU2DevExitLat = cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT), | ||
410 | }; | ||
411 | |||
412 | static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = { | ||
413 | .bLength = USB_DT_BOS_SIZE, | ||
414 | .bDescriptorType = USB_DT_BOS, | ||
415 | |||
416 | .wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE | ||
417 | + USB_DT_USB_EXT_CAP_SIZE | ||
418 | + USB_DT_USB_SS_CAP_SIZE), | ||
419 | |||
420 | .bNumDeviceCaps = 2, | ||
421 | }; | ||
422 | |||
423 | static struct usb_descriptor_header *fsg_ss_function[] = { | 376 | static struct usb_descriptor_header *fsg_ss_function[] = { |
424 | (struct usb_descriptor_header *) &fsg_intf_desc, | 377 | (struct usb_descriptor_header *) &fsg_intf_desc, |
425 | (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc, | 378 | (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc, |
@@ -429,20 +382,6 @@ static struct usb_descriptor_header *fsg_ss_function[] = { | |||
429 | NULL, | 382 | NULL, |
430 | }; | 383 | }; |
431 | 384 | ||
432 | /* Maxpacket and other transfer characteristics vary by speed. */ | ||
433 | static __maybe_unused struct usb_endpoint_descriptor * | ||
434 | fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, | ||
435 | struct usb_endpoint_descriptor *hs, | ||
436 | struct usb_endpoint_descriptor *ss) | ||
437 | { | ||
438 | if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) | ||
439 | return ss; | ||
440 | else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
441 | return hs; | ||
442 | return fs; | ||
443 | } | ||
444 | |||
445 | |||
446 | /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ | 385 | /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ |
447 | static struct usb_string fsg_strings[] = { | 386 | static struct usb_string fsg_strings[] = { |
448 | {FSG_STRING_INTERFACE, fsg_string_interface}, | 387 | {FSG_STRING_INTERFACE, fsg_string_interface}, |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 598dcc1212f0..588a9be18ef8 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/tty_flip.h> | 26 | #include <linux/tty_flip.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/export.h> | 28 | #include <linux/export.h> |
29 | #include <linux/module.h> | ||
29 | 30 | ||
30 | #include "u_serial.h" | 31 | #include "u_serial.h" |
31 | 32 | ||
@@ -35,11 +36,12 @@ | |||
35 | * "serial port" functionality through the USB gadget stack. Each such | 36 | * "serial port" functionality through the USB gadget stack. Each such |
36 | * port is exposed through a /dev/ttyGS* node. | 37 | * port is exposed through a /dev/ttyGS* node. |
37 | * | 38 | * |
38 | * After initialization (gserial_setup), these TTY port devices stay | 39 | * After this module has been loaded, the individual TTY port can be requested |
39 | * available until they are removed (gserial_cleanup). Each one may be | 40 | * (gserial_alloc_line()) and it will stay available until they are removed |
40 | * connected to a USB function (gserial_connect), or disconnected (with | 41 | * (gserial_free_line()). Each one may be connected to a USB function |
41 | * gserial_disconnect) when the USB host issues a config change event. | 42 | * (gserial_connect), or disconnected (with gserial_disconnect) when the USB |
42 | * Data can only flow when the port is connected to the host. | 43 | * host issues a config change event. Data can only flow when the port is |
44 | * connected to the host. | ||
43 | * | 45 | * |
44 | * A given TTY port can be made available in multiple configurations. | 46 | * A given TTY port can be made available in multiple configurations. |
45 | * For example, each one might expose a ttyGS0 node which provides a | 47 | * For example, each one might expose a ttyGS0 node which provides a |
@@ -119,13 +121,10 @@ struct gs_port { | |||
119 | struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ | 121 | struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ |
120 | }; | 122 | }; |
121 | 123 | ||
122 | /* increase N_PORTS if you need more */ | ||
123 | #define N_PORTS 4 | ||
124 | static struct portmaster { | 124 | static struct portmaster { |
125 | struct mutex lock; /* protect open/close */ | 125 | struct mutex lock; /* protect open/close */ |
126 | struct gs_port *port; | 126 | struct gs_port *port; |
127 | } ports[N_PORTS]; | 127 | } ports[MAX_U_SERIAL_PORTS]; |
128 | static unsigned n_ports; | ||
129 | 128 | ||
130 | #define GS_CLOSE_TIMEOUT 15 /* seconds */ | 129 | #define GS_CLOSE_TIMEOUT 15 /* seconds */ |
131 | 130 | ||
@@ -309,6 +308,7 @@ gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags) | |||
309 | 308 | ||
310 | return req; | 309 | return req; |
311 | } | 310 | } |
311 | EXPORT_SYMBOL_GPL(gs_alloc_req); | ||
312 | 312 | ||
313 | /* | 313 | /* |
314 | * gs_free_req | 314 | * gs_free_req |
@@ -320,6 +320,7 @@ void gs_free_req(struct usb_ep *ep, struct usb_request *req) | |||
320 | kfree(req->buf); | 320 | kfree(req->buf); |
321 | usb_ep_free_request(ep, req); | 321 | usb_ep_free_request(ep, req); |
322 | } | 322 | } |
323 | EXPORT_SYMBOL_GPL(gs_free_req); | ||
323 | 324 | ||
324 | /* | 325 | /* |
325 | * gs_send_packet | 326 | * gs_send_packet |
@@ -1030,10 +1031,19 @@ static int | |||
1030 | gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) | 1031 | gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) |
1031 | { | 1032 | { |
1032 | struct gs_port *port; | 1033 | struct gs_port *port; |
1034 | int ret = 0; | ||
1035 | |||
1036 | mutex_lock(&ports[port_num].lock); | ||
1037 | if (ports[port_num].port) { | ||
1038 | ret = -EBUSY; | ||
1039 | goto out; | ||
1040 | } | ||
1033 | 1041 | ||
1034 | port = kzalloc(sizeof(struct gs_port), GFP_KERNEL); | 1042 | port = kzalloc(sizeof(struct gs_port), GFP_KERNEL); |
1035 | if (port == NULL) | 1043 | if (port == NULL) { |
1036 | return -ENOMEM; | 1044 | ret = -ENOMEM; |
1045 | goto out; | ||
1046 | } | ||
1037 | 1047 | ||
1038 | tty_port_init(&port->port); | 1048 | tty_port_init(&port->port); |
1039 | spin_lock_init(&port->port_lock); | 1049 | spin_lock_init(&port->port_lock); |
@@ -1049,109 +1059,9 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) | |||
1049 | port->port_line_coding = *coding; | 1059 | port->port_line_coding = *coding; |
1050 | 1060 | ||
1051 | ports[port_num].port = port; | 1061 | ports[port_num].port = port; |
1052 | 1062 | out: | |
1053 | return 0; | 1063 | mutex_unlock(&ports[port_num].lock); |
1054 | } | 1064 | return ret; |
1055 | |||
1056 | /** | ||
1057 | * gserial_setup - initialize TTY driver for one or more ports | ||
1058 | * @g: gadget to associate with these ports | ||
1059 | * @count: how many ports to support | ||
1060 | * Context: may sleep | ||
1061 | * | ||
1062 | * The TTY stack needs to know in advance how many devices it should | ||
1063 | * plan to manage. Use this call to set up the ports you will be | ||
1064 | * exporting through USB. Later, connect them to functions based | ||
1065 | * on what configuration is activated by the USB host; and disconnect | ||
1066 | * them as appropriate. | ||
1067 | * | ||
1068 | * An example would be a two-configuration device in which both | ||
1069 | * configurations expose port 0, but through different functions. | ||
1070 | * One configuration could even expose port 1 while the other | ||
1071 | * one doesn't. | ||
1072 | * | ||
1073 | * Returns negative errno or zero. | ||
1074 | */ | ||
1075 | int gserial_setup(struct usb_gadget *g, unsigned count) | ||
1076 | { | ||
1077 | unsigned i; | ||
1078 | struct usb_cdc_line_coding coding; | ||
1079 | int status; | ||
1080 | |||
1081 | if (count == 0 || count > N_PORTS) | ||
1082 | return -EINVAL; | ||
1083 | |||
1084 | gs_tty_driver = alloc_tty_driver(count); | ||
1085 | if (!gs_tty_driver) | ||
1086 | return -ENOMEM; | ||
1087 | |||
1088 | gs_tty_driver->driver_name = "g_serial"; | ||
1089 | gs_tty_driver->name = PREFIX; | ||
1090 | /* uses dynamically assigned dev_t values */ | ||
1091 | |||
1092 | gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
1093 | gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
1094 | gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
1095 | gs_tty_driver->init_termios = tty_std_termios; | ||
1096 | |||
1097 | /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on | ||
1098 | * MS-Windows. Otherwise, most of these flags shouldn't affect | ||
1099 | * anything unless we were to actually hook up to a serial line. | ||
1100 | */ | ||
1101 | gs_tty_driver->init_termios.c_cflag = | ||
1102 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
1103 | gs_tty_driver->init_termios.c_ispeed = 9600; | ||
1104 | gs_tty_driver->init_termios.c_ospeed = 9600; | ||
1105 | |||
1106 | coding.dwDTERate = cpu_to_le32(9600); | ||
1107 | coding.bCharFormat = 8; | ||
1108 | coding.bParityType = USB_CDC_NO_PARITY; | ||
1109 | coding.bDataBits = USB_CDC_1_STOP_BITS; | ||
1110 | |||
1111 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | ||
1112 | |||
1113 | /* make devices be openable */ | ||
1114 | for (i = 0; i < count; i++) { | ||
1115 | mutex_init(&ports[i].lock); | ||
1116 | status = gs_port_alloc(i, &coding); | ||
1117 | if (status) { | ||
1118 | count = i; | ||
1119 | goto fail; | ||
1120 | } | ||
1121 | } | ||
1122 | n_ports = count; | ||
1123 | |||
1124 | /* export the driver ... */ | ||
1125 | status = tty_register_driver(gs_tty_driver); | ||
1126 | if (status) { | ||
1127 | pr_err("%s: cannot register, err %d\n", | ||
1128 | __func__, status); | ||
1129 | goto fail; | ||
1130 | } | ||
1131 | |||
1132 | /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */ | ||
1133 | for (i = 0; i < count; i++) { | ||
1134 | struct device *tty_dev; | ||
1135 | |||
1136 | tty_dev = tty_port_register_device(&ports[i].port->port, | ||
1137 | gs_tty_driver, i, &g->dev); | ||
1138 | if (IS_ERR(tty_dev)) | ||
1139 | pr_warning("%s: no classdev for port %d, err %ld\n", | ||
1140 | __func__, i, PTR_ERR(tty_dev)); | ||
1141 | } | ||
1142 | |||
1143 | pr_debug("%s: registered %d ttyGS* device%s\n", __func__, | ||
1144 | count, (count == 1) ? "" : "s"); | ||
1145 | |||
1146 | return status; | ||
1147 | fail: | ||
1148 | while (count--) { | ||
1149 | tty_port_destroy(&ports[count].port->port); | ||
1150 | kfree(ports[count].port); | ||
1151 | } | ||
1152 | put_tty_driver(gs_tty_driver); | ||
1153 | gs_tty_driver = NULL; | ||
1154 | return status; | ||
1155 | } | 1065 | } |
1156 | 1066 | ||
1157 | static int gs_closed(struct gs_port *port) | 1067 | static int gs_closed(struct gs_port *port) |
@@ -1164,55 +1074,77 @@ static int gs_closed(struct gs_port *port) | |||
1164 | return cond; | 1074 | return cond; |
1165 | } | 1075 | } |
1166 | 1076 | ||
1167 | /** | 1077 | static void gserial_free_port(struct gs_port *port) |
1168 | * gserial_cleanup - remove TTY-over-USB driver and devices | 1078 | { |
1169 | * Context: may sleep | 1079 | tasklet_kill(&port->push); |
1170 | * | 1080 | /* wait for old opens to finish */ |
1171 | * This is called to free all resources allocated by @gserial_setup(). | 1081 | wait_event(port->port.close_wait, gs_closed(port)); |
1172 | * Accordingly, it may need to wait until some open /dev/ files have | 1082 | WARN_ON(port->port_usb != NULL); |
1173 | * closed. | 1083 | tty_port_destroy(&port->port); |
1174 | * | 1084 | kfree(port); |
1175 | * The caller must have issued @gserial_disconnect() for any ports | 1085 | } |
1176 | * that had previously been connected, so that there is never any | 1086 | |
1177 | * I/O pending when it's called. | 1087 | void gserial_free_line(unsigned char port_num) |
1178 | */ | ||
1179 | void gserial_cleanup(void) | ||
1180 | { | 1088 | { |
1181 | unsigned i; | ||
1182 | struct gs_port *port; | 1089 | struct gs_port *port; |
1183 | 1090 | ||
1184 | if (!gs_tty_driver) | 1091 | mutex_lock(&ports[port_num].lock); |
1092 | if (WARN_ON(!ports[port_num].port)) { | ||
1093 | mutex_unlock(&ports[port_num].lock); | ||
1185 | return; | 1094 | return; |
1095 | } | ||
1096 | port = ports[port_num].port; | ||
1097 | ports[port_num].port = NULL; | ||
1098 | mutex_unlock(&ports[port_num].lock); | ||
1186 | 1099 | ||
1187 | /* start sysfs and /dev/ttyGS* node removal */ | 1100 | gserial_free_port(port); |
1188 | for (i = 0; i < n_ports; i++) | 1101 | tty_unregister_device(gs_tty_driver, port_num); |
1189 | tty_unregister_device(gs_tty_driver, i); | 1102 | } |
1190 | 1103 | EXPORT_SYMBOL_GPL(gserial_free_line); | |
1191 | for (i = 0; i < n_ports; i++) { | ||
1192 | /* prevent new opens */ | ||
1193 | mutex_lock(&ports[i].lock); | ||
1194 | port = ports[i].port; | ||
1195 | ports[i].port = NULL; | ||
1196 | mutex_unlock(&ports[i].lock); | ||
1197 | |||
1198 | tasklet_kill(&port->push); | ||
1199 | 1104 | ||
1200 | /* wait for old opens to finish */ | 1105 | int gserial_alloc_line(unsigned char *line_num) |
1201 | wait_event(port->port.close_wait, gs_closed(port)); | 1106 | { |
1107 | struct usb_cdc_line_coding coding; | ||
1108 | struct device *tty_dev; | ||
1109 | int ret; | ||
1110 | int port_num; | ||
1202 | 1111 | ||
1203 | WARN_ON(port->port_usb != NULL); | 1112 | coding.dwDTERate = cpu_to_le32(9600); |
1113 | coding.bCharFormat = 8; | ||
1114 | coding.bParityType = USB_CDC_NO_PARITY; | ||
1115 | coding.bDataBits = USB_CDC_1_STOP_BITS; | ||
1204 | 1116 | ||
1205 | tty_port_destroy(&port->port); | 1117 | for (port_num = 0; port_num < MAX_U_SERIAL_PORTS; port_num++) { |
1206 | kfree(port); | 1118 | ret = gs_port_alloc(port_num, &coding); |
1119 | if (ret == -EBUSY) | ||
1120 | continue; | ||
1121 | if (ret) | ||
1122 | return ret; | ||
1123 | break; | ||
1207 | } | 1124 | } |
1208 | n_ports = 0; | 1125 | if (ret) |
1126 | return ret; | ||
1209 | 1127 | ||
1210 | tty_unregister_driver(gs_tty_driver); | 1128 | /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */ |
1211 | put_tty_driver(gs_tty_driver); | 1129 | |
1212 | gs_tty_driver = NULL; | 1130 | tty_dev = tty_port_register_device(&ports[port_num].port->port, |
1131 | gs_tty_driver, port_num, NULL); | ||
1132 | if (IS_ERR(tty_dev)) { | ||
1133 | struct gs_port *port; | ||
1134 | pr_err("%s: failed to register tty for port %d, err %ld\n", | ||
1135 | __func__, port_num, PTR_ERR(tty_dev)); | ||
1213 | 1136 | ||
1214 | pr_debug("%s: cleaned up ttyGS* support\n", __func__); | 1137 | ret = PTR_ERR(tty_dev); |
1138 | port = ports[port_num].port; | ||
1139 | ports[port_num].port = NULL; | ||
1140 | gserial_free_port(port); | ||
1141 | goto err; | ||
1142 | } | ||
1143 | *line_num = port_num; | ||
1144 | err: | ||
1145 | return ret; | ||
1215 | } | 1146 | } |
1147 | EXPORT_SYMBOL_GPL(gserial_alloc_line); | ||
1216 | 1148 | ||
1217 | /** | 1149 | /** |
1218 | * gserial_connect - notify TTY I/O glue that USB link is active | 1150 | * gserial_connect - notify TTY I/O glue that USB link is active |
@@ -1229,8 +1161,8 @@ void gserial_cleanup(void) | |||
1229 | * | 1161 | * |
1230 | * Caller needs to have set up the endpoints and USB function in @dev | 1162 | * Caller needs to have set up the endpoints and USB function in @dev |
1231 | * before calling this, as well as the appropriate (speed-specific) | 1163 | * before calling this, as well as the appropriate (speed-specific) |
1232 | * endpoint descriptors, and also have set up the TTY driver by calling | 1164 | * endpoint descriptors, and also have allocate @port_num by calling |
1233 | * @gserial_setup(). | 1165 | * @gserial_alloc_line(). |
1234 | * | 1166 | * |
1235 | * Returns negative errno or zero. | 1167 | * Returns negative errno or zero. |
1236 | * On success, ep->driver_data will be overwritten. | 1168 | * On success, ep->driver_data will be overwritten. |
@@ -1241,11 +1173,18 @@ int gserial_connect(struct gserial *gser, u8 port_num) | |||
1241 | unsigned long flags; | 1173 | unsigned long flags; |
1242 | int status; | 1174 | int status; |
1243 | 1175 | ||
1244 | if (!gs_tty_driver || port_num >= n_ports) | 1176 | if (port_num >= MAX_U_SERIAL_PORTS) |
1245 | return -ENXIO; | 1177 | return -ENXIO; |
1246 | 1178 | ||
1247 | /* we "know" gserial_cleanup() hasn't been called */ | ||
1248 | port = ports[port_num].port; | 1179 | port = ports[port_num].port; |
1180 | if (!port) { | ||
1181 | pr_err("serial line %d not allocated.\n", port_num); | ||
1182 | return -EINVAL; | ||
1183 | } | ||
1184 | if (port->port_usb) { | ||
1185 | pr_err("serial line %d is in use.\n", port_num); | ||
1186 | return -EBUSY; | ||
1187 | } | ||
1249 | 1188 | ||
1250 | /* activate the endpoints */ | 1189 | /* activate the endpoints */ |
1251 | status = usb_ep_enable(gser->in); | 1190 | status = usb_ep_enable(gser->in); |
@@ -1292,7 +1231,7 @@ fail_out: | |||
1292 | gser->in->driver_data = NULL; | 1231 | gser->in->driver_data = NULL; |
1293 | return status; | 1232 | return status; |
1294 | } | 1233 | } |
1295 | 1234 | EXPORT_SYMBOL_GPL(gserial_connect); | |
1296 | /** | 1235 | /** |
1297 | * gserial_disconnect - notify TTY I/O glue that USB link is inactive | 1236 | * gserial_disconnect - notify TTY I/O glue that USB link is inactive |
1298 | * @gser: the function, on which gserial_connect() was called | 1237 | * @gser: the function, on which gserial_connect() was called |
@@ -1347,3 +1286,65 @@ void gserial_disconnect(struct gserial *gser) | |||
1347 | 1286 | ||
1348 | spin_unlock_irqrestore(&port->port_lock, flags); | 1287 | spin_unlock_irqrestore(&port->port_lock, flags); |
1349 | } | 1288 | } |
1289 | EXPORT_SYMBOL_GPL(gserial_disconnect); | ||
1290 | |||
1291 | static int userial_init(void) | ||
1292 | { | ||
1293 | unsigned i; | ||
1294 | int status; | ||
1295 | |||
1296 | gs_tty_driver = alloc_tty_driver(MAX_U_SERIAL_PORTS); | ||
1297 | if (!gs_tty_driver) | ||
1298 | return -ENOMEM; | ||
1299 | |||
1300 | gs_tty_driver->driver_name = "g_serial"; | ||
1301 | gs_tty_driver->name = PREFIX; | ||
1302 | /* uses dynamically assigned dev_t values */ | ||
1303 | |||
1304 | gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
1305 | gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
1306 | gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
1307 | gs_tty_driver->init_termios = tty_std_termios; | ||
1308 | |||
1309 | /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on | ||
1310 | * MS-Windows. Otherwise, most of these flags shouldn't affect | ||
1311 | * anything unless we were to actually hook up to a serial line. | ||
1312 | */ | ||
1313 | gs_tty_driver->init_termios.c_cflag = | ||
1314 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
1315 | gs_tty_driver->init_termios.c_ispeed = 9600; | ||
1316 | gs_tty_driver->init_termios.c_ospeed = 9600; | ||
1317 | |||
1318 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | ||
1319 | for (i = 0; i < MAX_U_SERIAL_PORTS; i++) | ||
1320 | mutex_init(&ports[i].lock); | ||
1321 | |||
1322 | /* export the driver ... */ | ||
1323 | status = tty_register_driver(gs_tty_driver); | ||
1324 | if (status) { | ||
1325 | pr_err("%s: cannot register, err %d\n", | ||
1326 | __func__, status); | ||
1327 | goto fail; | ||
1328 | } | ||
1329 | |||
1330 | pr_debug("%s: registered %d ttyGS* device%s\n", __func__, | ||
1331 | MAX_U_SERIAL_PORTS, | ||
1332 | (MAX_U_SERIAL_PORTS == 1) ? "" : "s"); | ||
1333 | |||
1334 | return status; | ||
1335 | fail: | ||
1336 | put_tty_driver(gs_tty_driver); | ||
1337 | gs_tty_driver = NULL; | ||
1338 | return status; | ||
1339 | } | ||
1340 | module_init(userial_init); | ||
1341 | |||
1342 | static void userial_cleanup(void) | ||
1343 | { | ||
1344 | tty_unregister_driver(gs_tty_driver); | ||
1345 | put_tty_driver(gs_tty_driver); | ||
1346 | gs_tty_driver = NULL; | ||
1347 | } | ||
1348 | module_exit(userial_cleanup); | ||
1349 | |||
1350 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h index 9b0fe6450fbf..66ce73a00509 100644 --- a/drivers/usb/gadget/u_serial.h +++ b/drivers/usb/gadget/u_serial.h | |||
@@ -15,6 +15,13 @@ | |||
15 | #include <linux/usb/composite.h> | 15 | #include <linux/usb/composite.h> |
16 | #include <linux/usb/cdc.h> | 16 | #include <linux/usb/cdc.h> |
17 | 17 | ||
18 | #define MAX_U_SERIAL_PORTS 4 | ||
19 | |||
20 | struct f_serial_opts { | ||
21 | struct usb_function_instance func_inst; | ||
22 | u8 port_num; | ||
23 | }; | ||
24 | |||
18 | /* | 25 | /* |
19 | * One non-multiplexed "serial" I/O port ... there can be several of these | 26 | * One non-multiplexed "serial" I/O port ... there can be several of these |
20 | * on any given USB peripheral device, if it provides enough endpoints. | 27 | * on any given USB peripheral device, if it provides enough endpoints. |
@@ -49,9 +56,9 @@ struct gserial { | |||
49 | struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags); | 56 | struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags); |
50 | void gs_free_req(struct usb_ep *, struct usb_request *req); | 57 | void gs_free_req(struct usb_ep *, struct usb_request *req); |
51 | 58 | ||
52 | /* port setup/teardown is handled by gadget driver */ | 59 | /* management of individual TTY ports */ |
53 | int gserial_setup(struct usb_gadget *g, unsigned n_ports); | 60 | int gserial_alloc_line(unsigned char *port_line); |
54 | void gserial_cleanup(void); | 61 | void gserial_free_line(unsigned char port_line); |
55 | 62 | ||
56 | /* connect/disconnect is handled by individual functions */ | 63 | /* connect/disconnect is handled by individual functions */ |
57 | int gserial_connect(struct gserial *, u8 port_num); | 64 | int gserial_connect(struct gserial *, u8 port_num); |
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 4d90a800063c..2a9cd369f71c 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c | |||
@@ -102,28 +102,6 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); | |||
102 | /* ------------------------------------------------------------------------- */ | 102 | /* ------------------------------------------------------------------------- */ |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * usb_gadget_start - tells usb device controller to start up | ||
106 | * @gadget: The gadget we want to get started | ||
107 | * @driver: The driver we want to bind to @gadget | ||
108 | * @bind: The bind function for @driver | ||
109 | * | ||
110 | * This call is issued by the UDC Class driver when it's about | ||
111 | * to register a gadget driver to the device controller, before | ||
112 | * calling gadget driver's bind() method. | ||
113 | * | ||
114 | * It allows the controller to be powered off until strictly | ||
115 | * necessary to have it powered on. | ||
116 | * | ||
117 | * Returns zero on success, else negative errno. | ||
118 | */ | ||
119 | static inline int usb_gadget_start(struct usb_gadget *gadget, | ||
120 | struct usb_gadget_driver *driver, | ||
121 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | ||
122 | { | ||
123 | return gadget->ops->start(driver, bind); | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * usb_gadget_udc_start - tells usb device controller to start up | 105 | * usb_gadget_udc_start - tells usb device controller to start up |
128 | * @gadget: The gadget we want to get started | 106 | * @gadget: The gadget we want to get started |
129 | * @driver: The driver we want to bind to @gadget | 107 | * @driver: The driver we want to bind to @gadget |
@@ -144,24 +122,6 @@ static inline int usb_gadget_udc_start(struct usb_gadget *gadget, | |||
144 | } | 122 | } |
145 | 123 | ||
146 | /** | 124 | /** |
147 | * usb_gadget_stop - tells usb device controller we don't need it anymore | ||
148 | * @gadget: The device we want to stop activity | ||
149 | * @driver: The driver to unbind from @gadget | ||
150 | * | ||
151 | * This call is issued by the UDC Class driver after calling | ||
152 | * gadget driver's unbind() method. | ||
153 | * | ||
154 | * The details are implementation specific, but it can go as | ||
155 | * far as powering off UDC completely and disable its data | ||
156 | * line pullups. | ||
157 | */ | ||
158 | static inline void usb_gadget_stop(struct usb_gadget *gadget, | ||
159 | struct usb_gadget_driver *driver) | ||
160 | { | ||
161 | gadget->ops->stop(driver); | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * usb_gadget_udc_stop - tells usb device controller we don't need it anymore | 125 | * usb_gadget_udc_stop - tells usb device controller we don't need it anymore |
166 | * @gadget: The device we want to stop activity | 126 | * @gadget: The device we want to stop activity |
167 | * @driver: The driver to unbind from @gadget | 127 | * @driver: The driver to unbind from @gadget |
@@ -246,14 +206,6 @@ err1: | |||
246 | } | 206 | } |
247 | EXPORT_SYMBOL_GPL(usb_add_gadget_udc); | 207 | EXPORT_SYMBOL_GPL(usb_add_gadget_udc); |
248 | 208 | ||
249 | static int udc_is_newstyle(struct usb_udc *udc) | ||
250 | { | ||
251 | if (udc->gadget->ops->udc_start && udc->gadget->ops->udc_stop) | ||
252 | return 1; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | |||
257 | static void usb_gadget_remove_driver(struct usb_udc *udc) | 209 | static void usb_gadget_remove_driver(struct usb_udc *udc) |
258 | { | 210 | { |
259 | dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", | 211 | dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", |
@@ -261,14 +213,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) | |||
261 | 213 | ||
262 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); | 214 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); |
263 | 215 | ||
264 | if (udc_is_newstyle(udc)) { | 216 | usb_gadget_disconnect(udc->gadget); |
265 | usb_gadget_disconnect(udc->gadget); | 217 | udc->driver->disconnect(udc->gadget); |
266 | udc->driver->disconnect(udc->gadget); | 218 | udc->driver->unbind(udc->gadget); |
267 | udc->driver->unbind(udc->gadget); | 219 | usb_gadget_udc_stop(udc->gadget, udc->driver); |
268 | usb_gadget_udc_stop(udc->gadget, udc->driver); | ||
269 | } else { | ||
270 | usb_gadget_stop(udc->gadget, udc->driver); | ||
271 | } | ||
272 | 220 | ||
273 | udc->driver = NULL; | 221 | udc->driver = NULL; |
274 | udc->dev.driver = NULL; | 222 | udc->dev.driver = NULL; |
@@ -311,6 +259,62 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc); | |||
311 | 259 | ||
312 | /* ------------------------------------------------------------------------- */ | 260 | /* ------------------------------------------------------------------------- */ |
313 | 261 | ||
262 | static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver) | ||
263 | { | ||
264 | int ret; | ||
265 | |||
266 | dev_dbg(&udc->dev, "registering UDC driver [%s]\n", | ||
267 | driver->function); | ||
268 | |||
269 | udc->driver = driver; | ||
270 | udc->dev.driver = &driver->driver; | ||
271 | |||
272 | ret = driver->bind(udc->gadget, driver); | ||
273 | if (ret) | ||
274 | goto err1; | ||
275 | ret = usb_gadget_udc_start(udc->gadget, driver); | ||
276 | if (ret) { | ||
277 | driver->unbind(udc->gadget); | ||
278 | goto err1; | ||
279 | } | ||
280 | usb_gadget_connect(udc->gadget); | ||
281 | |||
282 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); | ||
283 | return 0; | ||
284 | err1: | ||
285 | dev_err(&udc->dev, "failed to start %s: %d\n", | ||
286 | udc->driver->function, ret); | ||
287 | udc->driver = NULL; | ||
288 | udc->dev.driver = NULL; | ||
289 | return ret; | ||
290 | } | ||
291 | |||
292 | int udc_attach_driver(const char *name, struct usb_gadget_driver *driver) | ||
293 | { | ||
294 | struct usb_udc *udc = NULL; | ||
295 | int ret = -ENODEV; | ||
296 | |||
297 | mutex_lock(&udc_lock); | ||
298 | list_for_each_entry(udc, &udc_list, list) { | ||
299 | ret = strcmp(name, dev_name(&udc->dev)); | ||
300 | if (!ret) | ||
301 | break; | ||
302 | } | ||
303 | if (ret) { | ||
304 | ret = -ENODEV; | ||
305 | goto out; | ||
306 | } | ||
307 | if (udc->driver) { | ||
308 | ret = -EBUSY; | ||
309 | goto out; | ||
310 | } | ||
311 | ret = udc_bind_to_driver(udc, driver); | ||
312 | out: | ||
313 | mutex_unlock(&udc_lock); | ||
314 | return ret; | ||
315 | } | ||
316 | EXPORT_SYMBOL_GPL(udc_attach_driver); | ||
317 | |||
314 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver) | 318 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver) |
315 | { | 319 | { |
316 | struct usb_udc *udc = NULL; | 320 | struct usb_udc *udc = NULL; |
@@ -329,41 +333,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) | |||
329 | pr_debug("couldn't find an available UDC\n"); | 333 | pr_debug("couldn't find an available UDC\n"); |
330 | mutex_unlock(&udc_lock); | 334 | mutex_unlock(&udc_lock); |
331 | return -ENODEV; | 335 | return -ENODEV; |
332 | |||
333 | found: | 336 | found: |
334 | dev_dbg(&udc->dev, "registering UDC driver [%s]\n", | 337 | ret = udc_bind_to_driver(udc, driver); |
335 | driver->function); | ||
336 | |||
337 | udc->driver = driver; | ||
338 | udc->dev.driver = &driver->driver; | ||
339 | |||
340 | if (udc_is_newstyle(udc)) { | ||
341 | ret = driver->bind(udc->gadget, driver); | ||
342 | if (ret) | ||
343 | goto err1; | ||
344 | ret = usb_gadget_udc_start(udc->gadget, driver); | ||
345 | if (ret) { | ||
346 | driver->unbind(udc->gadget); | ||
347 | goto err1; | ||
348 | } | ||
349 | usb_gadget_connect(udc->gadget); | ||
350 | } else { | ||
351 | |||
352 | ret = usb_gadget_start(udc->gadget, driver, driver->bind); | ||
353 | if (ret) | ||
354 | goto err1; | ||
355 | |||
356 | } | ||
357 | |||
358 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); | ||
359 | mutex_unlock(&udc_lock); | ||
360 | return 0; | ||
361 | |||
362 | err1: | ||
363 | dev_err(&udc->dev, "failed to start %s: %d\n", | ||
364 | udc->driver->function, ret); | ||
365 | udc->driver = NULL; | ||
366 | udc->dev.driver = NULL; | ||
367 | mutex_unlock(&udc_lock); | 338 | mutex_unlock(&udc_lock); |
368 | return ret; | 339 | return ret; |
369 | } | 340 | } |
@@ -410,13 +381,11 @@ static ssize_t usb_udc_softconn_store(struct device *dev, | |||
410 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); | 381 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
411 | 382 | ||
412 | if (sysfs_streq(buf, "connect")) { | 383 | if (sysfs_streq(buf, "connect")) { |
413 | if (udc_is_newstyle(udc)) | 384 | usb_gadget_udc_start(udc->gadget, udc->driver); |
414 | usb_gadget_udc_start(udc->gadget, udc->driver); | ||
415 | usb_gadget_connect(udc->gadget); | 385 | usb_gadget_connect(udc->gadget); |
416 | } else if (sysfs_streq(buf, "disconnect")) { | 386 | } else if (sysfs_streq(buf, "disconnect")) { |
417 | usb_gadget_disconnect(udc->gadget); | 387 | usb_gadget_disconnect(udc->gadget); |
418 | if (udc_is_newstyle(udc)) | 388 | usb_gadget_udc_stop(udc->gadget, udc->driver); |
419 | usb_gadget_udc_stop(udc->gadget, udc->driver); | ||
420 | } else { | 389 | } else { |
421 | dev_err(dev, "unsupported command '%s'\n", buf); | 390 | dev_err(dev, "unsupported command '%s'\n", buf); |
422 | return -EINVAL; | 391 | return -EINVAL; |
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 69cf5c2cd335..8cef1e658c29 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c | |||
@@ -336,7 +336,7 @@ static struct usb_configuration webcam_config_driver = { | |||
336 | .bConfigurationValue = 1, | 336 | .bConfigurationValue = 1, |
337 | .iConfiguration = 0, /* dynamic */ | 337 | .iConfiguration = 0, /* dynamic */ |
338 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | 338 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, |
339 | .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, | 339 | .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW, |
340 | }; | 340 | }; |
341 | 341 | ||
342 | static int /* __init_or_exit */ | 342 | static int /* __init_or_exit */ |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 6bf4c0611365..685fa681cb65 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -10,7 +10,6 @@ | |||
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | |||
14 | /* | 13 | /* |
15 | * Gadget Zero only needs two bulk endpoints, and is an example of how you | 14 | * Gadget Zero only needs two bulk endpoints, and is an example of how you |
16 | * can write a hardware-agnostic gadget driver running inside a USB device. | 15 | * can write a hardware-agnostic gadget driver running inside a USB device. |
@@ -43,23 +42,11 @@ | |||
43 | #include <linux/kernel.h> | 42 | #include <linux/kernel.h> |
44 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
45 | #include <linux/device.h> | 44 | #include <linux/device.h> |
45 | #include <linux/module.h> | ||
46 | #include <linux/err.h> | ||
47 | #include <linux/usb/composite.h> | ||
46 | 48 | ||
47 | #include "g_zero.h" | 49 | #include "g_zero.h" |
48 | #include "gadget_chips.h" | ||
49 | |||
50 | |||
51 | /*-------------------------------------------------------------------------*/ | ||
52 | |||
53 | /* | ||
54 | * Kbuild is not very cooperative with respect to linking separately | ||
55 | * compiled library objects into one module. So for now we won't use | ||
56 | * separate compilation ... ensuring init/exit sections work to shrink | ||
57 | * the runtime footprint, and giving us at least some parts of what | ||
58 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
59 | */ | ||
60 | #include "f_sourcesink.c" | ||
61 | #include "f_loopback.c" | ||
62 | |||
63 | /*-------------------------------------------------------------------------*/ | 50 | /*-------------------------------------------------------------------------*/ |
64 | USB_GADGET_COMPOSITE_OPTIONS(); | 51 | USB_GADGET_COMPOSITE_OPTIONS(); |
65 | 52 | ||
@@ -67,9 +54,6 @@ USB_GADGET_COMPOSITE_OPTIONS(); | |||
67 | 54 | ||
68 | static const char longname[] = "Gadget Zero"; | 55 | static const char longname[] = "Gadget Zero"; |
69 | 56 | ||
70 | unsigned buflen = 4096; /* only used for bulk endpoints */ | ||
71 | module_param(buflen, uint, 0); | ||
72 | |||
73 | /* | 57 | /* |
74 | * Normally the "loopback" configuration is second (index 1) so | 58 | * Normally the "loopback" configuration is second (index 1) so |
75 | * it's not the default. Here's where to change that order, to | 59 | * it's not the default. Here's where to change that order, to |
@@ -79,6 +63,13 @@ module_param(buflen, uint, 0); | |||
79 | static bool loopdefault = 0; | 63 | static bool loopdefault = 0; |
80 | module_param(loopdefault, bool, S_IRUGO|S_IWUSR); | 64 | module_param(loopdefault, bool, S_IRUGO|S_IWUSR); |
81 | 65 | ||
66 | static struct usb_zero_options gzero_options = { | ||
67 | .isoc_interval = 4, | ||
68 | .isoc_maxpacket = 1024, | ||
69 | .bulk_buflen = 4096, | ||
70 | .qlen = 32, | ||
71 | }; | ||
72 | |||
82 | /*-------------------------------------------------------------------------*/ | 73 | /*-------------------------------------------------------------------------*/ |
83 | 74 | ||
84 | /* Thanks to NetChip Technologies for donating this product ID. | 75 | /* Thanks to NetChip Technologies for donating this product ID. |
@@ -129,20 +120,27 @@ static struct usb_otg_descriptor otg_descriptor = { | |||
129 | .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, | 120 | .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, |
130 | }; | 121 | }; |
131 | 122 | ||
132 | const struct usb_descriptor_header *otg_desc[] = { | 123 | static const struct usb_descriptor_header *otg_desc[] = { |
133 | (struct usb_descriptor_header *) &otg_descriptor, | 124 | (struct usb_descriptor_header *) &otg_descriptor, |
134 | NULL, | 125 | NULL, |
135 | }; | 126 | }; |
127 | #else | ||
128 | #define otg_desc NULL | ||
136 | #endif | 129 | #endif |
137 | 130 | ||
138 | /* string IDs are assigned dynamically */ | 131 | /* string IDs are assigned dynamically */ |
139 | /* default serial number takes at least two packets */ | 132 | /* default serial number takes at least two packets */ |
140 | static char serial[] = "0123456789.0123456789.0123456789"; | 133 | static char serial[] = "0123456789.0123456789.0123456789"; |
141 | 134 | ||
135 | #define USB_GZERO_SS_DESC (USB_GADGET_FIRST_AVAIL_IDX + 0) | ||
136 | #define USB_GZERO_LB_DESC (USB_GADGET_FIRST_AVAIL_IDX + 1) | ||
137 | |||
142 | static struct usb_string strings_dev[] = { | 138 | static struct usb_string strings_dev[] = { |
143 | [USB_GADGET_MANUFACTURER_IDX].s = "", | 139 | [USB_GADGET_MANUFACTURER_IDX].s = "", |
144 | [USB_GADGET_PRODUCT_IDX].s = longname, | 140 | [USB_GADGET_PRODUCT_IDX].s = longname, |
145 | [USB_GADGET_SERIAL_IDX].s = serial, | 141 | [USB_GADGET_SERIAL_IDX].s = serial, |
142 | [USB_GZERO_SS_DESC].s = "source and sink data", | ||
143 | [USB_GZERO_LB_DESC].s = "loop input to output", | ||
146 | { } /* end of list */ | 144 | { } /* end of list */ |
147 | }; | 145 | }; |
148 | 146 | ||
@@ -158,58 +156,6 @@ static struct usb_gadget_strings *dev_strings[] = { | |||
158 | 156 | ||
159 | /*-------------------------------------------------------------------------*/ | 157 | /*-------------------------------------------------------------------------*/ |
160 | 158 | ||
161 | struct usb_request *alloc_ep_req(struct usb_ep *ep, int len) | ||
162 | { | ||
163 | struct usb_request *req; | ||
164 | |||
165 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); | ||
166 | if (req) { | ||
167 | if (len) | ||
168 | req->length = len; | ||
169 | else | ||
170 | req->length = buflen; | ||
171 | req->buf = kmalloc(req->length, GFP_ATOMIC); | ||
172 | if (!req->buf) { | ||
173 | usb_ep_free_request(ep, req); | ||
174 | req = NULL; | ||
175 | } | ||
176 | } | ||
177 | return req; | ||
178 | } | ||
179 | |||
180 | void free_ep_req(struct usb_ep *ep, struct usb_request *req) | ||
181 | { | ||
182 | kfree(req->buf); | ||
183 | usb_ep_free_request(ep, req); | ||
184 | } | ||
185 | |||
186 | static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) | ||
187 | { | ||
188 | int value; | ||
189 | |||
190 | if (ep->driver_data) { | ||
191 | value = usb_ep_disable(ep); | ||
192 | if (value < 0) | ||
193 | DBG(cdev, "disable %s --> %d\n", | ||
194 | ep->name, value); | ||
195 | ep->driver_data = NULL; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | void disable_endpoints(struct usb_composite_dev *cdev, | ||
200 | struct usb_ep *in, struct usb_ep *out, | ||
201 | struct usb_ep *iso_in, struct usb_ep *iso_out) | ||
202 | { | ||
203 | disable_ep(cdev, in); | ||
204 | disable_ep(cdev, out); | ||
205 | if (iso_in) | ||
206 | disable_ep(cdev, iso_in); | ||
207 | if (iso_out) | ||
208 | disable_ep(cdev, iso_out); | ||
209 | } | ||
210 | |||
211 | /*-------------------------------------------------------------------------*/ | ||
212 | |||
213 | static struct timer_list autoresume_timer; | 159 | static struct timer_list autoresume_timer; |
214 | 160 | ||
215 | static void zero_autoresume(unsigned long _c) | 161 | static void zero_autoresume(unsigned long _c) |
@@ -251,8 +197,65 @@ static void zero_resume(struct usb_composite_dev *cdev) | |||
251 | 197 | ||
252 | /*-------------------------------------------------------------------------*/ | 198 | /*-------------------------------------------------------------------------*/ |
253 | 199 | ||
200 | static struct usb_configuration loopback_driver = { | ||
201 | .label = "loopback", | ||
202 | .bConfigurationValue = 2, | ||
203 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | ||
204 | /* .iConfiguration = DYNAMIC */ | ||
205 | }; | ||
206 | |||
207 | static struct usb_function *func_ss; | ||
208 | static struct usb_function_instance *func_inst_ss; | ||
209 | |||
210 | static int ss_config_setup(struct usb_configuration *c, | ||
211 | const struct usb_ctrlrequest *ctrl) | ||
212 | { | ||
213 | switch (ctrl->bRequest) { | ||
214 | case 0x5b: | ||
215 | case 0x5c: | ||
216 | return func_ss->setup(func_ss, ctrl); | ||
217 | default: | ||
218 | return -EOPNOTSUPP; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | static struct usb_configuration sourcesink_driver = { | ||
223 | .label = "source/sink", | ||
224 | .setup = ss_config_setup, | ||
225 | .bConfigurationValue = 3, | ||
226 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | ||
227 | /* .iConfiguration = DYNAMIC */ | ||
228 | }; | ||
229 | |||
230 | module_param_named(buflen, gzero_options.bulk_buflen, uint, 0); | ||
231 | module_param_named(pattern, gzero_options.pattern, uint, S_IRUGO|S_IWUSR); | ||
232 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63, 2 = none"); | ||
233 | |||
234 | module_param_named(isoc_interval, gzero_options.isoc_interval, uint, | ||
235 | S_IRUGO|S_IWUSR); | ||
236 | MODULE_PARM_DESC(isoc_interval, "1 - 16"); | ||
237 | |||
238 | module_param_named(isoc_maxpacket, gzero_options.isoc_maxpacket, uint, | ||
239 | S_IRUGO|S_IWUSR); | ||
240 | MODULE_PARM_DESC(isoc_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); | ||
241 | |||
242 | module_param_named(isoc_mult, gzero_options.isoc_mult, uint, S_IRUGO|S_IWUSR); | ||
243 | MODULE_PARM_DESC(isoc_mult, "0 - 2 (hs/ss only)"); | ||
244 | |||
245 | module_param_named(isoc_maxburst, gzero_options.isoc_maxburst, uint, | ||
246 | S_IRUGO|S_IWUSR); | ||
247 | MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)"); | ||
248 | |||
249 | static struct usb_function *func_lb; | ||
250 | static struct usb_function_instance *func_inst_lb; | ||
251 | |||
252 | module_param_named(qlen, gzero_options.qlen, uint, S_IRUGO|S_IWUSR); | ||
253 | MODULE_PARM_DESC(qlen, "depth of loopback queue"); | ||
254 | |||
254 | static int __init zero_bind(struct usb_composite_dev *cdev) | 255 | static int __init zero_bind(struct usb_composite_dev *cdev) |
255 | { | 256 | { |
257 | struct f_ss_opts *ss_opts; | ||
258 | struct f_lb_opts *lb_opts; | ||
256 | int status; | 259 | int status; |
257 | 260 | ||
258 | /* Allocate string descriptor numbers ... note that string | 261 | /* Allocate string descriptor numbers ... note that string |
@@ -268,27 +271,105 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
268 | 271 | ||
269 | setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); | 272 | setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); |
270 | 273 | ||
274 | func_inst_ss = usb_get_function_instance("SourceSink"); | ||
275 | if (IS_ERR(func_inst_ss)) | ||
276 | return PTR_ERR(func_inst_ss); | ||
277 | |||
278 | ss_opts = container_of(func_inst_ss, struct f_ss_opts, func_inst); | ||
279 | ss_opts->pattern = gzero_options.pattern; | ||
280 | ss_opts->isoc_interval = gzero_options.isoc_interval; | ||
281 | ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket; | ||
282 | ss_opts->isoc_mult = gzero_options.isoc_mult; | ||
283 | ss_opts->isoc_maxburst = gzero_options.isoc_maxpacket; | ||
284 | ss_opts->bulk_buflen = gzero_options.bulk_buflen; | ||
285 | |||
286 | func_ss = usb_get_function(func_inst_ss); | ||
287 | if (IS_ERR(func_ss)) | ||
288 | goto err_put_func_inst_ss; | ||
289 | |||
290 | func_inst_lb = usb_get_function_instance("Loopback"); | ||
291 | if (IS_ERR(func_inst_lb)) | ||
292 | goto err_put_func_ss; | ||
293 | |||
294 | lb_opts = container_of(func_inst_lb, struct f_lb_opts, func_inst); | ||
295 | lb_opts->bulk_buflen = gzero_options.bulk_buflen; | ||
296 | lb_opts->qlen = gzero_options.qlen; | ||
297 | |||
298 | func_lb = usb_get_function(func_inst_lb); | ||
299 | if (IS_ERR(func_lb)) { | ||
300 | status = PTR_ERR(func_lb); | ||
301 | goto err_put_func_inst_lb; | ||
302 | } | ||
303 | |||
304 | sourcesink_driver.iConfiguration = strings_dev[USB_GZERO_SS_DESC].id; | ||
305 | loopback_driver.iConfiguration = strings_dev[USB_GZERO_LB_DESC].id; | ||
306 | |||
307 | /* support autoresume for remote wakeup testing */ | ||
308 | sourcesink_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; | ||
309 | loopback_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; | ||
310 | sourcesink_driver.descriptors = NULL; | ||
311 | loopback_driver.descriptors = NULL; | ||
312 | if (autoresume) { | ||
313 | sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
314 | loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
315 | } | ||
316 | |||
317 | /* support OTG systems */ | ||
318 | if (gadget_is_otg(cdev->gadget)) { | ||
319 | sourcesink_driver.descriptors = otg_desc; | ||
320 | sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
321 | loopback_driver.descriptors = otg_desc; | ||
322 | loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
323 | } | ||
324 | |||
271 | /* Register primary, then secondary configuration. Note that | 325 | /* Register primary, then secondary configuration. Note that |
272 | * SH3 only allows one config... | 326 | * SH3 only allows one config... |
273 | */ | 327 | */ |
274 | if (loopdefault) { | 328 | if (loopdefault) { |
275 | loopback_add(cdev, autoresume != 0); | 329 | usb_add_config_only(cdev, &loopback_driver); |
276 | sourcesink_add(cdev, autoresume != 0); | 330 | usb_add_config_only(cdev, &sourcesink_driver); |
277 | } else { | 331 | } else { |
278 | sourcesink_add(cdev, autoresume != 0); | 332 | usb_add_config_only(cdev, &sourcesink_driver); |
279 | loopback_add(cdev, autoresume != 0); | 333 | usb_add_config_only(cdev, &loopback_driver); |
280 | } | 334 | } |
335 | status = usb_add_function(&sourcesink_driver, func_ss); | ||
336 | if (status) | ||
337 | goto err_conf_flb; | ||
338 | |||
339 | usb_ep_autoconfig_reset(cdev->gadget); | ||
340 | status = usb_add_function(&loopback_driver, func_lb); | ||
341 | if (status) | ||
342 | goto err_conf_flb; | ||
281 | 343 | ||
344 | usb_ep_autoconfig_reset(cdev->gadget); | ||
282 | usb_composite_overwrite_options(cdev, &coverwrite); | 345 | usb_composite_overwrite_options(cdev, &coverwrite); |
283 | 346 | ||
284 | INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); | 347 | INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); |
285 | 348 | ||
286 | return 0; | 349 | return 0; |
350 | |||
351 | err_conf_flb: | ||
352 | usb_put_function(func_lb); | ||
353 | func_lb = NULL; | ||
354 | err_put_func_inst_lb: | ||
355 | usb_put_function_instance(func_inst_lb); | ||
356 | func_inst_lb = NULL; | ||
357 | err_put_func_ss: | ||
358 | usb_put_function(func_ss); | ||
359 | func_ss = NULL; | ||
360 | err_put_func_inst_ss: | ||
361 | usb_put_function_instance(func_inst_ss); | ||
362 | func_inst_ss = NULL; | ||
363 | return status; | ||
287 | } | 364 | } |
288 | 365 | ||
289 | static int zero_unbind(struct usb_composite_dev *cdev) | 366 | static int zero_unbind(struct usb_composite_dev *cdev) |
290 | { | 367 | { |
291 | del_timer_sync(&autoresume_timer); | 368 | del_timer_sync(&autoresume_timer); |
369 | if (!IS_ERR_OR_NULL(func_ss)) | ||
370 | usb_put_function(func_ss); | ||
371 | if (!IS_ERR_OR_NULL(func_lb)) | ||
372 | usb_put_function(func_lb); | ||
292 | return 0; | 373 | return 0; |
293 | } | 374 | } |
294 | 375 | ||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3a21c5d683c0..c59a1126926f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -246,7 +246,7 @@ config USB_EHCI_ATH79 | |||
246 | 246 | ||
247 | config USB_OXU210HP_HCD | 247 | config USB_OXU210HP_HCD |
248 | tristate "OXU210HP HCD support" | 248 | tristate "OXU210HP HCD support" |
249 | depends on USB | 249 | depends on USB && GENERIC_HARDIRQS |
250 | ---help--- | 250 | ---help--- |
251 | The OXU210HP is an USB host/OTG/device controller. Enable this | 251 | The OXU210HP is an USB host/OTG/device controller. Enable this |
252 | option if your board has this chip. If unsure, say N. | 252 | option if your board has this chip. If unsure, say N. |
diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 6c56297ea16b..3065809546b1 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c | |||
@@ -302,7 +302,6 @@ static int mv_ehci_remove(struct platform_device *pdev) | |||
302 | { | 302 | { |
303 | struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); | 303 | struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); |
304 | struct usb_hcd *hcd = ehci_mv->hcd; | 304 | struct usb_hcd *hcd = ehci_mv->hcd; |
305 | int clk_i; | ||
306 | 305 | ||
307 | if (hcd->rh_registered) | 306 | if (hcd->rh_registered) |
308 | usb_remove_hcd(hcd); | 307 | usb_remove_hcd(hcd); |
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index e2004de6ad3d..e9301fb97eaa 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c | |||
@@ -57,7 +57,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) | |||
57 | struct usb_hcd *hcd; | 57 | struct usb_hcd *hcd; |
58 | struct resource *res; | 58 | struct resource *res; |
59 | int irq, ret; | 59 | int irq, ret; |
60 | unsigned int flags; | ||
61 | struct ehci_mxc_priv *priv; | 60 | struct ehci_mxc_priv *priv; |
62 | struct device *dev = &pdev->dev; | 61 | struct device *dev = &pdev->dev; |
63 | struct ehci_hcd *ehci; | 62 | struct ehci_hcd *ehci; |
@@ -162,25 +161,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) | |||
162 | if (ret) | 161 | if (ret) |
163 | goto err_add; | 162 | goto err_add; |
164 | 163 | ||
165 | if (pdata->otg) { | ||
166 | /* | ||
167 | * efikamx and efikasb have some hardware bug which is | ||
168 | * preventing usb to work unless CHRGVBUS is set. | ||
169 | * It's in violation of USB specs | ||
170 | */ | ||
171 | if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) { | ||
172 | flags = usb_phy_io_read(pdata->otg, | ||
173 | ULPI_OTG_CTRL); | ||
174 | flags |= ULPI_OTG_CTRL_CHRGVBUS; | ||
175 | ret = usb_phy_io_write(pdata->otg, flags, | ||
176 | ULPI_OTG_CTRL); | ||
177 | if (ret) { | ||
178 | dev_err(dev, "unable to set CHRVBUS\n"); | ||
179 | goto err_add; | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | return 0; | 164 | return 0; |
185 | 165 | ||
186 | err_add: | 166 | err_add: |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index ac17a7c3a0cd..99899e808c6a 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -288,7 +288,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
288 | { | 288 | { |
289 | struct device *dev = &pdev->dev; | 289 | struct device *dev = &pdev->dev; |
290 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 290 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
291 | struct ehci_hcd_omap_platform_data *pdata = dev->platform_data; | ||
292 | 291 | ||
293 | usb_remove_hcd(hcd); | 292 | usb_remove_hcd(hcd); |
294 | disable_put_regulator(dev->platform_data); | 293 | disable_put_regulator(dev->platform_data); |
@@ -298,13 +297,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
298 | pm_runtime_put_sync(dev); | 297 | pm_runtime_put_sync(dev); |
299 | pm_runtime_disable(dev); | 298 | pm_runtime_disable(dev); |
300 | 299 | ||
301 | if (pdata->phy_reset) { | ||
302 | if (gpio_is_valid(pdata->reset_gpio_port[0])) | ||
303 | gpio_free(pdata->reset_gpio_port[0]); | ||
304 | |||
305 | if (gpio_is_valid(pdata->reset_gpio_port[1])) | ||
306 | gpio_free(pdata->reset_gpio_port[1]); | ||
307 | } | ||
308 | return 0; | 300 | return 0; |
309 | } | 301 | } |
310 | 302 | ||
@@ -372,7 +364,7 @@ static const struct hc_driver ehci_omap_hc_driver = { | |||
372 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | 364 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, |
373 | }; | 365 | }; |
374 | 366 | ||
375 | MODULE_ALIAS("platform:omap-ehci"); | 367 | MODULE_ALIAS("platform:ehci-omap"); |
376 | MODULE_AUTHOR("Texas Instruments, Inc."); | 368 | MODULE_AUTHOR("Texas Instruments, Inc."); |
377 | MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); | 369 | MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); |
378 | 370 | ||
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 319dcfaa8735..20ebf6a8b7f4 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/of_gpio.h> | 18 | #include <linux/of_gpio.h> |
19 | #include <linux/platform_data/usb-ehci-s5p.h> | 19 | #include <linux/platform_data/usb-ehci-s5p.h> |
20 | #include <linux/usb/phy.h> | ||
21 | #include <linux/usb/samsung_usb_phy.h> | ||
20 | #include <plat/usb-phy.h> | 22 | #include <plat/usb-phy.h> |
21 | 23 | ||
22 | #define EHCI_INSNREG00(base) (base + 0x90) | 24 | #define EHCI_INSNREG00(base) (base + 0x90) |
@@ -32,6 +34,9 @@ struct s5p_ehci_hcd { | |||
32 | struct device *dev; | 34 | struct device *dev; |
33 | struct usb_hcd *hcd; | 35 | struct usb_hcd *hcd; |
34 | struct clk *clk; | 36 | struct clk *clk; |
37 | struct usb_phy *phy; | ||
38 | struct usb_otg *otg; | ||
39 | struct s5p_ehci_platdata *pdata; | ||
35 | }; | 40 | }; |
36 | 41 | ||
37 | static const struct hc_driver s5p_ehci_hc_driver = { | 42 | static const struct hc_driver s5p_ehci_hc_driver = { |
@@ -65,6 +70,26 @@ static const struct hc_driver s5p_ehci_hc_driver = { | |||
65 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | 70 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, |
66 | }; | 71 | }; |
67 | 72 | ||
73 | static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci) | ||
74 | { | ||
75 | struct platform_device *pdev = to_platform_device(s5p_ehci->dev); | ||
76 | |||
77 | if (s5p_ehci->phy) | ||
78 | usb_phy_init(s5p_ehci->phy); | ||
79 | else if (s5p_ehci->pdata->phy_init) | ||
80 | s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST); | ||
81 | } | ||
82 | |||
83 | static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci) | ||
84 | { | ||
85 | struct platform_device *pdev = to_platform_device(s5p_ehci->dev); | ||
86 | |||
87 | if (s5p_ehci->phy) | ||
88 | usb_phy_shutdown(s5p_ehci->phy); | ||
89 | else if (s5p_ehci->pdata->phy_exit) | ||
90 | s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); | ||
91 | } | ||
92 | |||
68 | static void s5p_setup_vbus_gpio(struct platform_device *pdev) | 93 | static void s5p_setup_vbus_gpio(struct platform_device *pdev) |
69 | { | 94 | { |
70 | int err; | 95 | int err; |
@@ -87,20 +112,15 @@ static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32); | |||
87 | 112 | ||
88 | static int s5p_ehci_probe(struct platform_device *pdev) | 113 | static int s5p_ehci_probe(struct platform_device *pdev) |
89 | { | 114 | { |
90 | struct s5p_ehci_platdata *pdata; | 115 | struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; |
91 | struct s5p_ehci_hcd *s5p_ehci; | 116 | struct s5p_ehci_hcd *s5p_ehci; |
92 | struct usb_hcd *hcd; | 117 | struct usb_hcd *hcd; |
93 | struct ehci_hcd *ehci; | 118 | struct ehci_hcd *ehci; |
94 | struct resource *res; | 119 | struct resource *res; |
120 | struct usb_phy *phy; | ||
95 | int irq; | 121 | int irq; |
96 | int err; | 122 | int err; |
97 | 123 | ||
98 | pdata = pdev->dev.platform_data; | ||
99 | if (!pdata) { | ||
100 | dev_err(&pdev->dev, "No platform data defined\n"); | ||
101 | return -EINVAL; | ||
102 | } | ||
103 | |||
104 | /* | 124 | /* |
105 | * Right now device-tree probed devices don't get dma_mask set. | 125 | * Right now device-tree probed devices don't get dma_mask set. |
106 | * Since shared usb code relies on it, set it here for now. | 126 | * Since shared usb code relies on it, set it here for now. |
@@ -118,6 +138,20 @@ static int s5p_ehci_probe(struct platform_device *pdev) | |||
118 | if (!s5p_ehci) | 138 | if (!s5p_ehci) |
119 | return -ENOMEM; | 139 | return -ENOMEM; |
120 | 140 | ||
141 | phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); | ||
142 | if (IS_ERR_OR_NULL(phy)) { | ||
143 | /* Fallback to pdata */ | ||
144 | if (!pdata) { | ||
145 | dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); | ||
146 | return -EPROBE_DEFER; | ||
147 | } else { | ||
148 | s5p_ehci->pdata = pdata; | ||
149 | } | ||
150 | } else { | ||
151 | s5p_ehci->phy = phy; | ||
152 | s5p_ehci->otg = phy->otg; | ||
153 | } | ||
154 | |||
121 | s5p_ehci->dev = &pdev->dev; | 155 | s5p_ehci->dev = &pdev->dev; |
122 | 156 | ||
123 | hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev, | 157 | hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev, |
@@ -163,8 +197,10 @@ static int s5p_ehci_probe(struct platform_device *pdev) | |||
163 | goto fail_io; | 197 | goto fail_io; |
164 | } | 198 | } |
165 | 199 | ||
166 | if (pdata->phy_init) | 200 | if (s5p_ehci->otg) |
167 | pdata->phy_init(pdev, S5P_USB_PHY_HOST); | 201 | s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self); |
202 | |||
203 | s5p_ehci_phy_enable(s5p_ehci); | ||
168 | 204 | ||
169 | ehci = hcd_to_ehci(hcd); | 205 | ehci = hcd_to_ehci(hcd); |
170 | ehci->caps = hcd->regs; | 206 | ehci->caps = hcd->regs; |
@@ -175,13 +211,15 @@ static int s5p_ehci_probe(struct platform_device *pdev) | |||
175 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); | 211 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
176 | if (err) { | 212 | if (err) { |
177 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); | 213 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); |
178 | goto fail_io; | 214 | goto fail_add_hcd; |
179 | } | 215 | } |
180 | 216 | ||
181 | platform_set_drvdata(pdev, s5p_ehci); | 217 | platform_set_drvdata(pdev, s5p_ehci); |
182 | 218 | ||
183 | return 0; | 219 | return 0; |
184 | 220 | ||
221 | fail_add_hcd: | ||
222 | s5p_ehci_phy_disable(s5p_ehci); | ||
185 | fail_io: | 223 | fail_io: |
186 | clk_disable_unprepare(s5p_ehci->clk); | 224 | clk_disable_unprepare(s5p_ehci->clk); |
187 | fail_clk: | 225 | fail_clk: |
@@ -191,14 +229,15 @@ fail_clk: | |||
191 | 229 | ||
192 | static int s5p_ehci_remove(struct platform_device *pdev) | 230 | static int s5p_ehci_remove(struct platform_device *pdev) |
193 | { | 231 | { |
194 | struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; | ||
195 | struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); | 232 | struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); |
196 | struct usb_hcd *hcd = s5p_ehci->hcd; | 233 | struct usb_hcd *hcd = s5p_ehci->hcd; |
197 | 234 | ||
198 | usb_remove_hcd(hcd); | 235 | usb_remove_hcd(hcd); |
199 | 236 | ||
200 | if (pdata && pdata->phy_exit) | 237 | if (s5p_ehci->otg) |
201 | pdata->phy_exit(pdev, S5P_USB_PHY_HOST); | 238 | s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self); |
239 | |||
240 | s5p_ehci_phy_disable(s5p_ehci); | ||
202 | 241 | ||
203 | clk_disable_unprepare(s5p_ehci->clk); | 242 | clk_disable_unprepare(s5p_ehci->clk); |
204 | 243 | ||
@@ -222,14 +261,14 @@ static int s5p_ehci_suspend(struct device *dev) | |||
222 | struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev); | 261 | struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev); |
223 | struct usb_hcd *hcd = s5p_ehci->hcd; | 262 | struct usb_hcd *hcd = s5p_ehci->hcd; |
224 | bool do_wakeup = device_may_wakeup(dev); | 263 | bool do_wakeup = device_may_wakeup(dev); |
225 | struct platform_device *pdev = to_platform_device(dev); | ||
226 | struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; | ||
227 | int rc; | 264 | int rc; |
228 | 265 | ||
229 | rc = ehci_suspend(hcd, do_wakeup); | 266 | rc = ehci_suspend(hcd, do_wakeup); |
230 | 267 | ||
231 | if (pdata && pdata->phy_exit) | 268 | if (s5p_ehci->otg) |
232 | pdata->phy_exit(pdev, S5P_USB_PHY_HOST); | 269 | s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self); |
270 | |||
271 | s5p_ehci_phy_disable(s5p_ehci); | ||
233 | 272 | ||
234 | clk_disable_unprepare(s5p_ehci->clk); | 273 | clk_disable_unprepare(s5p_ehci->clk); |
235 | 274 | ||
@@ -240,13 +279,13 @@ static int s5p_ehci_resume(struct device *dev) | |||
240 | { | 279 | { |
241 | struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev); | 280 | struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev); |
242 | struct usb_hcd *hcd = s5p_ehci->hcd; | 281 | struct usb_hcd *hcd = s5p_ehci->hcd; |
243 | struct platform_device *pdev = to_platform_device(dev); | ||
244 | struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; | ||
245 | 282 | ||
246 | clk_prepare_enable(s5p_ehci->clk); | 283 | clk_prepare_enable(s5p_ehci->clk); |
247 | 284 | ||
248 | if (pdata && pdata->phy_init) | 285 | if (s5p_ehci->otg) |
249 | pdata->phy_init(pdev, S5P_USB_PHY_HOST); | 286 | s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self); |
287 | |||
288 | s5p_ehci_phy_enable(s5p_ehci); | ||
250 | 289 | ||
251 | /* DMA burst Enable */ | 290 | /* DMA burst Enable */ |
252 | writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); | 291 | writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); |
@@ -266,7 +305,7 @@ static const struct dev_pm_ops s5p_ehci_pm_ops = { | |||
266 | 305 | ||
267 | #ifdef CONFIG_OF | 306 | #ifdef CONFIG_OF |
268 | static const struct of_device_id exynos_ehci_match[] = { | 307 | static const struct of_device_id exynos_ehci_match[] = { |
269 | { .compatible = "samsung,exynos-ehci" }, | 308 | { .compatible = "samsung,exynos4210-ehci" }, |
270 | {}, | 309 | {}, |
271 | }; | 310 | }; |
272 | MODULE_DEVICE_TABLE(of, exynos_ehci_match); | 311 | MODULE_DEVICE_TABLE(of, exynos_ehci_match); |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index a35bbddf8968..125e261f5bfc 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -932,7 +932,7 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh) | |||
932 | } | 932 | } |
933 | } | 933 | } |
934 | 934 | ||
935 | void schedule_ptds(struct usb_hcd *hcd) | 935 | static void schedule_ptds(struct usb_hcd *hcd) |
936 | { | 936 | { |
937 | struct isp1760_hcd *priv; | 937 | struct isp1760_hcd *priv; |
938 | struct isp1760_qh *qh, *qh_next; | 938 | struct isp1760_qh *qh, *qh_next; |
@@ -1285,7 +1285,7 @@ leave: | |||
1285 | #define SLOT_CHECK_PERIOD 200 | 1285 | #define SLOT_CHECK_PERIOD 200 |
1286 | static struct timer_list errata2_timer; | 1286 | static struct timer_list errata2_timer; |
1287 | 1287 | ||
1288 | void errata2_function(unsigned long data) | 1288 | static void errata2_function(unsigned long data) |
1289 | { | 1289 | { |
1290 | struct usb_hcd *hcd = (struct usb_hcd *) data; | 1290 | struct usb_hcd *hcd = (struct usb_hcd *) data; |
1291 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 1291 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index aa3b8844bb9f..e3b7e85120e4 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c | |||
@@ -15,14 +15,39 @@ | |||
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/platform_data/usb-exynos.h> | 17 | #include <linux/platform_data/usb-exynos.h> |
18 | #include <linux/usb/phy.h> | ||
19 | #include <linux/usb/samsung_usb_phy.h> | ||
18 | #include <plat/usb-phy.h> | 20 | #include <plat/usb-phy.h> |
19 | 21 | ||
20 | struct exynos_ohci_hcd { | 22 | struct exynos_ohci_hcd { |
21 | struct device *dev; | 23 | struct device *dev; |
22 | struct usb_hcd *hcd; | 24 | struct usb_hcd *hcd; |
23 | struct clk *clk; | 25 | struct clk *clk; |
26 | struct usb_phy *phy; | ||
27 | struct usb_otg *otg; | ||
28 | struct exynos4_ohci_platdata *pdata; | ||
24 | }; | 29 | }; |
25 | 30 | ||
31 | static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci) | ||
32 | { | ||
33 | struct platform_device *pdev = to_platform_device(exynos_ohci->dev); | ||
34 | |||
35 | if (exynos_ohci->phy) | ||
36 | usb_phy_init(exynos_ohci->phy); | ||
37 | else if (exynos_ohci->pdata->phy_init) | ||
38 | exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST); | ||
39 | } | ||
40 | |||
41 | static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci) | ||
42 | { | ||
43 | struct platform_device *pdev = to_platform_device(exynos_ohci->dev); | ||
44 | |||
45 | if (exynos_ohci->phy) | ||
46 | usb_phy_shutdown(exynos_ohci->phy); | ||
47 | else if (exynos_ohci->pdata->phy_exit) | ||
48 | exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); | ||
49 | } | ||
50 | |||
26 | static int ohci_exynos_reset(struct usb_hcd *hcd) | 51 | static int ohci_exynos_reset(struct usb_hcd *hcd) |
27 | { | 52 | { |
28 | return ohci_init(hcd_to_ohci(hcd)); | 53 | return ohci_init(hcd_to_ohci(hcd)); |
@@ -78,20 +103,15 @@ static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32); | |||
78 | 103 | ||
79 | static int exynos_ohci_probe(struct platform_device *pdev) | 104 | static int exynos_ohci_probe(struct platform_device *pdev) |
80 | { | 105 | { |
81 | struct exynos4_ohci_platdata *pdata; | 106 | struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; |
82 | struct exynos_ohci_hcd *exynos_ohci; | 107 | struct exynos_ohci_hcd *exynos_ohci; |
83 | struct usb_hcd *hcd; | 108 | struct usb_hcd *hcd; |
84 | struct ohci_hcd *ohci; | 109 | struct ohci_hcd *ohci; |
85 | struct resource *res; | 110 | struct resource *res; |
111 | struct usb_phy *phy; | ||
86 | int irq; | 112 | int irq; |
87 | int err; | 113 | int err; |
88 | 114 | ||
89 | pdata = pdev->dev.platform_data; | ||
90 | if (!pdata) { | ||
91 | dev_err(&pdev->dev, "No platform data defined\n"); | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
95 | /* | 115 | /* |
96 | * Right now device-tree probed devices don't get dma_mask set. | 116 | * Right now device-tree probed devices don't get dma_mask set. |
97 | * Since shared usb code relies on it, set it here for now. | 117 | * Since shared usb code relies on it, set it here for now. |
@@ -107,6 +127,20 @@ static int exynos_ohci_probe(struct platform_device *pdev) | |||
107 | if (!exynos_ohci) | 127 | if (!exynos_ohci) |
108 | return -ENOMEM; | 128 | return -ENOMEM; |
109 | 129 | ||
130 | phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); | ||
131 | if (IS_ERR_OR_NULL(phy)) { | ||
132 | /* Fallback to pdata */ | ||
133 | if (!pdata) { | ||
134 | dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); | ||
135 | return -EPROBE_DEFER; | ||
136 | } else { | ||
137 | exynos_ohci->pdata = pdata; | ||
138 | } | ||
139 | } else { | ||
140 | exynos_ohci->phy = phy; | ||
141 | exynos_ohci->otg = phy->otg; | ||
142 | } | ||
143 | |||
110 | exynos_ohci->dev = &pdev->dev; | 144 | exynos_ohci->dev = &pdev->dev; |
111 | 145 | ||
112 | hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, | 146 | hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, |
@@ -152,8 +186,11 @@ static int exynos_ohci_probe(struct platform_device *pdev) | |||
152 | goto fail_io; | 186 | goto fail_io; |
153 | } | 187 | } |
154 | 188 | ||
155 | if (pdata->phy_init) | 189 | if (exynos_ohci->otg) |
156 | pdata->phy_init(pdev, S5P_USB_PHY_HOST); | 190 | exynos_ohci->otg->set_host(exynos_ohci->otg, |
191 | &exynos_ohci->hcd->self); | ||
192 | |||
193 | exynos_ohci_phy_enable(exynos_ohci); | ||
157 | 194 | ||
158 | ohci = hcd_to_ohci(hcd); | 195 | ohci = hcd_to_ohci(hcd); |
159 | ohci_hcd_init(ohci); | 196 | ohci_hcd_init(ohci); |
@@ -161,13 +198,15 @@ static int exynos_ohci_probe(struct platform_device *pdev) | |||
161 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); | 198 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
162 | if (err) { | 199 | if (err) { |
163 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); | 200 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); |
164 | goto fail_io; | 201 | goto fail_add_hcd; |
165 | } | 202 | } |
166 | 203 | ||
167 | platform_set_drvdata(pdev, exynos_ohci); | 204 | platform_set_drvdata(pdev, exynos_ohci); |
168 | 205 | ||
169 | return 0; | 206 | return 0; |
170 | 207 | ||
208 | fail_add_hcd: | ||
209 | exynos_ohci_phy_disable(exynos_ohci); | ||
171 | fail_io: | 210 | fail_io: |
172 | clk_disable_unprepare(exynos_ohci->clk); | 211 | clk_disable_unprepare(exynos_ohci->clk); |
173 | fail_clk: | 212 | fail_clk: |
@@ -177,14 +216,16 @@ fail_clk: | |||
177 | 216 | ||
178 | static int exynos_ohci_remove(struct platform_device *pdev) | 217 | static int exynos_ohci_remove(struct platform_device *pdev) |
179 | { | 218 | { |
180 | struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; | ||
181 | struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); | 219 | struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); |
182 | struct usb_hcd *hcd = exynos_ohci->hcd; | 220 | struct usb_hcd *hcd = exynos_ohci->hcd; |
183 | 221 | ||
184 | usb_remove_hcd(hcd); | 222 | usb_remove_hcd(hcd); |
185 | 223 | ||
186 | if (pdata && pdata->phy_exit) | 224 | if (exynos_ohci->otg) |
187 | pdata->phy_exit(pdev, S5P_USB_PHY_HOST); | 225 | exynos_ohci->otg->set_host(exynos_ohci->otg, |
226 | &exynos_ohci->hcd->self); | ||
227 | |||
228 | exynos_ohci_phy_disable(exynos_ohci); | ||
188 | 229 | ||
189 | clk_disable_unprepare(exynos_ohci->clk); | 230 | clk_disable_unprepare(exynos_ohci->clk); |
190 | 231 | ||
@@ -208,8 +249,6 @@ static int exynos_ohci_suspend(struct device *dev) | |||
208 | struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); | 249 | struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); |
209 | struct usb_hcd *hcd = exynos_ohci->hcd; | 250 | struct usb_hcd *hcd = exynos_ohci->hcd; |
210 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | 251 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
211 | struct platform_device *pdev = to_platform_device(dev); | ||
212 | struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; | ||
213 | unsigned long flags; | 252 | unsigned long flags; |
214 | int rc = 0; | 253 | int rc = 0; |
215 | 254 | ||
@@ -228,8 +267,11 @@ static int exynos_ohci_suspend(struct device *dev) | |||
228 | 267 | ||
229 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 268 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
230 | 269 | ||
231 | if (pdata && pdata->phy_exit) | 270 | if (exynos_ohci->otg) |
232 | pdata->phy_exit(pdev, S5P_USB_PHY_HOST); | 271 | exynos_ohci->otg->set_host(exynos_ohci->otg, |
272 | &exynos_ohci->hcd->self); | ||
273 | |||
274 | exynos_ohci_phy_disable(exynos_ohci); | ||
233 | 275 | ||
234 | clk_disable_unprepare(exynos_ohci->clk); | 276 | clk_disable_unprepare(exynos_ohci->clk); |
235 | 277 | ||
@@ -243,13 +285,14 @@ static int exynos_ohci_resume(struct device *dev) | |||
243 | { | 285 | { |
244 | struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); | 286 | struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); |
245 | struct usb_hcd *hcd = exynos_ohci->hcd; | 287 | struct usb_hcd *hcd = exynos_ohci->hcd; |
246 | struct platform_device *pdev = to_platform_device(dev); | ||
247 | struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; | ||
248 | 288 | ||
249 | clk_prepare_enable(exynos_ohci->clk); | 289 | clk_prepare_enable(exynos_ohci->clk); |
250 | 290 | ||
251 | if (pdata && pdata->phy_init) | 291 | if (exynos_ohci->otg) |
252 | pdata->phy_init(pdev, S5P_USB_PHY_HOST); | 292 | exynos_ohci->otg->set_host(exynos_ohci->otg, |
293 | &exynos_ohci->hcd->self); | ||
294 | |||
295 | exynos_ohci_phy_enable(exynos_ohci); | ||
253 | 296 | ||
254 | ohci_resume(hcd, false); | 297 | ohci_resume(hcd, false); |
255 | 298 | ||
@@ -267,7 +310,7 @@ static const struct dev_pm_ops exynos_ohci_pm_ops = { | |||
267 | 310 | ||
268 | #ifdef CONFIG_OF | 311 | #ifdef CONFIG_OF |
269 | static const struct of_device_id exynos_ohci_match[] = { | 312 | static const struct of_device_id exynos_ohci_match[] = { |
270 | { .compatible = "samsung,exynos-ohci" }, | 313 | { .compatible = "samsung,exynos4210-ohci" }, |
271 | {}, | 314 | {}, |
272 | }; | 315 | }; |
273 | MODULE_DEVICE_TABLE(of, exynos_ohci_match); | 316 | MODULE_DEVICE_TABLE(of, exynos_ohci_match); |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 7482cfbe8c5e..88731b7c5f42 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -44,6 +44,7 @@ __acquires(ohci->lock) | |||
44 | // ASSERT (urb->hcpriv != 0); | 44 | // ASSERT (urb->hcpriv != 0); |
45 | 45 | ||
46 | urb_free_priv (ohci, urb->hcpriv); | 46 | urb_free_priv (ohci, urb->hcpriv); |
47 | urb->hcpriv = NULL; | ||
47 | if (likely(status == -EINPROGRESS)) | 48 | if (likely(status == -EINPROGRESS)) |
48 | status = 0; | 49 | status = 0; |
49 | 50 | ||
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index fc0b0daac93d..455737546525 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -16,6 +16,8 @@ | |||
16 | 16 | ||
17 | #include "uhci-hcd.h" | 17 | #include "uhci-hcd.h" |
18 | 18 | ||
19 | #define EXTRA_SPACE 1024 | ||
20 | |||
19 | static struct dentry *uhci_debugfs_root; | 21 | static struct dentry *uhci_debugfs_root; |
20 | 22 | ||
21 | #ifdef DEBUG | 23 | #ifdef DEBUG |
@@ -44,10 +46,6 @@ static int uhci_show_td(struct uhci_hcd *uhci, struct uhci_td *td, char *buf, | |||
44 | char *spid; | 46 | char *spid; |
45 | u32 status, token; | 47 | u32 status, token; |
46 | 48 | ||
47 | /* Try to make sure there's enough memory */ | ||
48 | if (len < 160) | ||
49 | return 0; | ||
50 | |||
51 | status = td_status(uhci, td); | 49 | status = td_status(uhci, td); |
52 | out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td, | 50 | out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td, |
53 | hc32_to_cpu(uhci, td->link)); | 51 | hc32_to_cpu(uhci, td->link)); |
@@ -64,6 +62,8 @@ static int uhci_show_td(struct uhci_hcd *uhci, struct uhci_td *td, char *buf, | |||
64 | (status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "", | 62 | (status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "", |
65 | (status & TD_CTRL_BITSTUFF) ? "BitStuff " : "", | 63 | (status & TD_CTRL_BITSTUFF) ? "BitStuff " : "", |
66 | status & 0x7ff); | 64 | status & 0x7ff); |
65 | if (out - buf > len) | ||
66 | goto done; | ||
67 | 67 | ||
68 | token = td_token(uhci, td); | 68 | token = td_token(uhci, td); |
69 | switch (uhci_packetid(token)) { | 69 | switch (uhci_packetid(token)) { |
@@ -90,6 +90,9 @@ static int uhci_show_td(struct uhci_hcd *uhci, struct uhci_td *td, char *buf, | |||
90 | spid); | 90 | spid); |
91 | out += sprintf(out, "(buf=%08x)\n", hc32_to_cpu(uhci, td->buffer)); | 91 | out += sprintf(out, "(buf=%08x)\n", hc32_to_cpu(uhci, td->buffer)); |
92 | 92 | ||
93 | done: | ||
94 | if (out - buf > len) | ||
95 | out += sprintf(out, " ...\n"); | ||
93 | return out - buf; | 96 | return out - buf; |
94 | } | 97 | } |
95 | 98 | ||
@@ -101,8 +104,6 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, | |||
101 | int i, nactive, ninactive; | 104 | int i, nactive, ninactive; |
102 | char *ptype; | 105 | char *ptype; |
103 | 106 | ||
104 | if (len < 200) | ||
105 | return 0; | ||
106 | 107 | ||
107 | out += sprintf(out, "urb_priv [%p] ", urbp); | 108 | out += sprintf(out, "urb_priv [%p] ", urbp); |
108 | out += sprintf(out, "urb [%p] ", urbp->urb); | 109 | out += sprintf(out, "urb [%p] ", urbp->urb); |
@@ -110,6 +111,8 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, | |||
110 | out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe)); | 111 | out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe)); |
111 | out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe), | 112 | out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe), |
112 | (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT")); | 113 | (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT")); |
114 | if (out - buf > len) | ||
115 | goto done; | ||
113 | 116 | ||
114 | switch (usb_pipetype(urbp->urb->pipe)) { | 117 | switch (usb_pipetype(urbp->urb->pipe)) { |
115 | case PIPE_ISOCHRONOUS: ptype = "ISO"; break; | 118 | case PIPE_ISOCHRONOUS: ptype = "ISO"; break; |
@@ -128,6 +131,9 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, | |||
128 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); | 131 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); |
129 | out += sprintf(out, "\n"); | 132 | out += sprintf(out, "\n"); |
130 | 133 | ||
134 | if (out - buf > len) | ||
135 | goto done; | ||
136 | |||
131 | i = nactive = ninactive = 0; | 137 | i = nactive = ninactive = 0; |
132 | list_for_each_entry(td, &urbp->td_list, list) { | 138 | list_for_each_entry(td, &urbp->td_list, list) { |
133 | if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC && | 139 | if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC && |
@@ -135,6 +141,8 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, | |||
135 | out += sprintf(out, "%*s%d: ", space + 2, "", i); | 141 | out += sprintf(out, "%*s%d: ", space + 2, "", i); |
136 | out += uhci_show_td(uhci, td, out, | 142 | out += uhci_show_td(uhci, td, out, |
137 | len - (out - buf), 0); | 143 | len - (out - buf), 0); |
144 | if (out - buf > len) | ||
145 | goto tail; | ||
138 | } else { | 146 | } else { |
139 | if (td_status(uhci, td) & TD_CTRL_ACTIVE) | 147 | if (td_status(uhci, td) & TD_CTRL_ACTIVE) |
140 | ++nactive; | 148 | ++nactive; |
@@ -143,10 +151,13 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, | |||
143 | } | 151 | } |
144 | } | 152 | } |
145 | if (nactive + ninactive > 0) | 153 | if (nactive + ninactive > 0) |
146 | out += sprintf(out, "%*s[skipped %d inactive and %d active " | 154 | out += sprintf(out, |
147 | "TDs]\n", | 155 | "%*s[skipped %d inactive and %d active TDs]\n", |
148 | space, "", ninactive, nactive); | 156 | space, "", ninactive, nactive); |
149 | 157 | done: | |
158 | if (out - buf > len) | ||
159 | out += sprintf(out, " ...\n"); | ||
160 | tail: | ||
150 | return out - buf; | 161 | return out - buf; |
151 | } | 162 | } |
152 | 163 | ||
@@ -158,10 +169,6 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
158 | __hc32 element = qh_element(qh); | 169 | __hc32 element = qh_element(qh); |
159 | char *qtype; | 170 | char *qtype; |
160 | 171 | ||
161 | /* Try to make sure there's enough memory */ | ||
162 | if (len < 80 * 7) | ||
163 | return 0; | ||
164 | |||
165 | switch (qh->type) { | 172 | switch (qh->type) { |
166 | case USB_ENDPOINT_XFER_ISOC: qtype = "ISO"; break; | 173 | case USB_ENDPOINT_XFER_ISOC: qtype = "ISO"; break; |
167 | case USB_ENDPOINT_XFER_INT: qtype = "INT"; break; | 174 | case USB_ENDPOINT_XFER_INT: qtype = "INT"; break; |
@@ -175,13 +182,15 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
175 | hc32_to_cpu(uhci, qh->link), | 182 | hc32_to_cpu(uhci, qh->link), |
176 | hc32_to_cpu(uhci, element)); | 183 | hc32_to_cpu(uhci, element)); |
177 | if (qh->type == USB_ENDPOINT_XFER_ISOC) | 184 | if (qh->type == USB_ENDPOINT_XFER_ISOC) |
178 | out += sprintf(out, "%*s period %d phase %d load %d us, " | 185 | out += sprintf(out, |
179 | "frame %x desc [%p]\n", | 186 | "%*s period %d phase %d load %d us, frame %x desc [%p]\n", |
180 | space, "", qh->period, qh->phase, qh->load, | 187 | space, "", qh->period, qh->phase, qh->load, |
181 | qh->iso_frame, qh->iso_packet_desc); | 188 | qh->iso_frame, qh->iso_packet_desc); |
182 | else if (qh->type == USB_ENDPOINT_XFER_INT) | 189 | else if (qh->type == USB_ENDPOINT_XFER_INT) |
183 | out += sprintf(out, "%*s period %d phase %d load %d us\n", | 190 | out += sprintf(out, "%*s period %d phase %d load %d us\n", |
184 | space, "", qh->period, qh->phase, qh->load); | 191 | space, "", qh->period, qh->phase, qh->load); |
192 | if (out - buf > len) | ||
193 | goto done; | ||
185 | 194 | ||
186 | if (element & UHCI_PTR_QH(uhci)) | 195 | if (element & UHCI_PTR_QH(uhci)) |
187 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); | 196 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); |
@@ -195,11 +204,17 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
195 | if (!(element & ~(UHCI_PTR_QH(uhci) | UHCI_PTR_DEPTH(uhci)))) | 204 | if (!(element & ~(UHCI_PTR_QH(uhci) | UHCI_PTR_DEPTH(uhci)))) |
196 | out += sprintf(out, "%*s Element is NULL (bug?)\n", space, ""); | 205 | out += sprintf(out, "%*s Element is NULL (bug?)\n", space, ""); |
197 | 206 | ||
207 | if (out - buf > len) | ||
208 | goto done; | ||
209 | |||
198 | if (list_empty(&qh->queue)) { | 210 | if (list_empty(&qh->queue)) { |
199 | out += sprintf(out, "%*s queue is empty\n", space, ""); | 211 | out += sprintf(out, "%*s queue is empty\n", space, ""); |
200 | if (qh == uhci->skel_async_qh) | 212 | if (qh == uhci->skel_async_qh) { |
201 | out += uhci_show_td(uhci, uhci->term_td, out, | 213 | out += uhci_show_td(uhci, uhci->term_td, out, |
202 | len - (out - buf), 0); | 214 | len - (out - buf), 0); |
215 | if (out - buf > len) | ||
216 | goto tail; | ||
217 | } | ||
203 | } else { | 218 | } else { |
204 | struct urb_priv *urbp = list_entry(qh->queue.next, | 219 | struct urb_priv *urbp = list_entry(qh->queue.next, |
205 | struct urb_priv, node); | 220 | struct urb_priv, node); |
@@ -211,9 +226,12 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
211 | space, ""); | 226 | space, ""); |
212 | i = nurbs = 0; | 227 | i = nurbs = 0; |
213 | list_for_each_entry(urbp, &qh->queue, node) { | 228 | list_for_each_entry(urbp, &qh->queue, node) { |
214 | if (++i <= 10) | 229 | if (++i <= 10) { |
215 | out += uhci_show_urbp(uhci, urbp, out, | 230 | out += uhci_show_urbp(uhci, urbp, out, |
216 | len - (out - buf), space + 2); | 231 | len - (out - buf), space + 2); |
232 | if (out - buf > len) | ||
233 | goto tail; | ||
234 | } | ||
217 | else | 235 | else |
218 | ++nurbs; | 236 | ++nurbs; |
219 | } | 237 | } |
@@ -222,24 +240,27 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
222 | space, "", nurbs); | 240 | space, "", nurbs); |
223 | } | 241 | } |
224 | 242 | ||
243 | if (out - buf > len) | ||
244 | goto done; | ||
245 | |||
225 | if (qh->dummy_td) { | 246 | if (qh->dummy_td) { |
226 | out += sprintf(out, "%*s Dummy TD\n", space, ""); | 247 | out += sprintf(out, "%*s Dummy TD\n", space, ""); |
227 | out += uhci_show_td(uhci, qh->dummy_td, out, | 248 | out += uhci_show_td(uhci, qh->dummy_td, out, |
228 | len - (out - buf), 0); | 249 | len - (out - buf), 0); |
250 | if (out - buf > len) | ||
251 | goto tail; | ||
229 | } | 252 | } |
230 | 253 | ||
254 | done: | ||
255 | if (out - buf > len) | ||
256 | out += sprintf(out, " ...\n"); | ||
257 | tail: | ||
231 | return out - buf; | 258 | return out - buf; |
232 | } | 259 | } |
233 | 260 | ||
234 | static int uhci_show_sc(int port, unsigned short status, char *buf, int len) | 261 | static int uhci_show_sc(int port, unsigned short status, char *buf) |
235 | { | 262 | { |
236 | char *out = buf; | 263 | return sprintf(buf, " stat%d = %04x %s%s%s%s%s%s%s%s%s%s\n", |
237 | |||
238 | /* Try to make sure there's enough memory */ | ||
239 | if (len < 160) | ||
240 | return 0; | ||
241 | |||
242 | out += sprintf(out, " stat%d = %04x %s%s%s%s%s%s%s%s%s%s\n", | ||
243 | port, | 264 | port, |
244 | status, | 265 | status, |
245 | (status & USBPORTSC_SUSP) ? " Suspend" : "", | 266 | (status & USBPORTSC_SUSP) ? " Suspend" : "", |
@@ -252,19 +273,12 @@ static int uhci_show_sc(int port, unsigned short status, char *buf, int len) | |||
252 | (status & USBPORTSC_PE) ? " Enabled" : "", | 273 | (status & USBPORTSC_PE) ? " Enabled" : "", |
253 | (status & USBPORTSC_CSC) ? " ConnectChange" : "", | 274 | (status & USBPORTSC_CSC) ? " ConnectChange" : "", |
254 | (status & USBPORTSC_CCS) ? " Connected" : ""); | 275 | (status & USBPORTSC_CCS) ? " Connected" : ""); |
255 | |||
256 | return out - buf; | ||
257 | } | 276 | } |
258 | 277 | ||
259 | static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len) | 278 | static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf) |
260 | { | 279 | { |
261 | char *out = buf; | ||
262 | char *rh_state; | 280 | char *rh_state; |
263 | 281 | ||
264 | /* Try to make sure there's enough memory */ | ||
265 | if (len < 60) | ||
266 | return 0; | ||
267 | |||
268 | switch (uhci->rh_state) { | 282 | switch (uhci->rh_state) { |
269 | case UHCI_RH_RESET: | 283 | case UHCI_RH_RESET: |
270 | rh_state = "reset"; break; | 284 | rh_state = "reset"; break; |
@@ -283,9 +297,8 @@ static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len) | |||
283 | default: | 297 | default: |
284 | rh_state = "?"; break; | 298 | rh_state = "?"; break; |
285 | } | 299 | } |
286 | out += sprintf(out, "Root-hub state: %s FSBR: %d\n", | 300 | return sprintf(buf, "Root-hub state: %s FSBR: %d\n", |
287 | rh_state, uhci->fsbr_is_on); | 301 | rh_state, uhci->fsbr_is_on); |
288 | return out - buf; | ||
289 | } | 302 | } |
290 | 303 | ||
291 | static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) | 304 | static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) |
@@ -296,9 +309,6 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) | |||
296 | unsigned char sof; | 309 | unsigned char sof; |
297 | unsigned short portsc1, portsc2; | 310 | unsigned short portsc1, portsc2; |
298 | 311 | ||
299 | /* Try to make sure there's enough memory */ | ||
300 | if (len < 80 * 9) | ||
301 | return 0; | ||
302 | 312 | ||
303 | usbcmd = uhci_readw(uhci, 0); | 313 | usbcmd = uhci_readw(uhci, 0); |
304 | usbstat = uhci_readw(uhci, 2); | 314 | usbstat = uhci_readw(uhci, 2); |
@@ -319,6 +329,8 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) | |||
319 | (usbcmd & USBCMD_GRESET) ? "GRESET " : "", | 329 | (usbcmd & USBCMD_GRESET) ? "GRESET " : "", |
320 | (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "", | 330 | (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "", |
321 | (usbcmd & USBCMD_RS) ? "RS " : ""); | 331 | (usbcmd & USBCMD_RS) ? "RS " : ""); |
332 | if (out - buf > len) | ||
333 | goto done; | ||
322 | 334 | ||
323 | out += sprintf(out, " usbstat = %04x %s%s%s%s%s%s\n", | 335 | out += sprintf(out, " usbstat = %04x %s%s%s%s%s%s\n", |
324 | usbstat, | 336 | usbstat, |
@@ -328,19 +340,33 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) | |||
328 | (usbstat & USBSTS_RD) ? "ResumeDetect " : "", | 340 | (usbstat & USBSTS_RD) ? "ResumeDetect " : "", |
329 | (usbstat & USBSTS_ERROR) ? "USBError " : "", | 341 | (usbstat & USBSTS_ERROR) ? "USBError " : "", |
330 | (usbstat & USBSTS_USBINT) ? "USBINT " : ""); | 342 | (usbstat & USBSTS_USBINT) ? "USBINT " : ""); |
343 | if (out - buf > len) | ||
344 | goto done; | ||
331 | 345 | ||
332 | out += sprintf(out, " usbint = %04x\n", usbint); | 346 | out += sprintf(out, " usbint = %04x\n", usbint); |
333 | out += sprintf(out, " usbfrnum = (%d)%03x\n", (usbfrnum >> 10) & 1, | 347 | out += sprintf(out, " usbfrnum = (%d)%03x\n", (usbfrnum >> 10) & 1, |
334 | 0xfff & (4*(unsigned int)usbfrnum)); | 348 | 0xfff & (4*(unsigned int)usbfrnum)); |
335 | out += sprintf(out, " flbaseadd = %08x\n", flbaseadd); | 349 | out += sprintf(out, " flbaseadd = %08x\n", flbaseadd); |
336 | out += sprintf(out, " sof = %02x\n", sof); | 350 | out += sprintf(out, " sof = %02x\n", sof); |
337 | out += uhci_show_sc(1, portsc1, out, len - (out - buf)); | 351 | if (out - buf > len) |
338 | out += uhci_show_sc(2, portsc2, out, len - (out - buf)); | 352 | goto done; |
339 | out += sprintf(out, "Most recent frame: %x (%d) " | 353 | |
340 | "Last ISO frame: %x (%d)\n", | 354 | out += uhci_show_sc(1, portsc1, out); |
355 | if (out - buf > len) | ||
356 | goto done; | ||
357 | |||
358 | out += uhci_show_sc(2, portsc2, out); | ||
359 | if (out - buf > len) | ||
360 | goto done; | ||
361 | |||
362 | out += sprintf(out, | ||
363 | "Most recent frame: %x (%d) Last ISO frame: %x (%d)\n", | ||
341 | uhci->frame_number, uhci->frame_number & 1023, | 364 | uhci->frame_number, uhci->frame_number & 1023, |
342 | uhci->last_iso_frame, uhci->last_iso_frame & 1023); | 365 | uhci->last_iso_frame, uhci->last_iso_frame & 1023); |
343 | 366 | ||
367 | done: | ||
368 | if (out - buf > len) | ||
369 | out += sprintf(out, " ...\n"); | ||
344 | return out - buf; | 370 | return out - buf; |
345 | } | 371 | } |
346 | 372 | ||
@@ -360,9 +386,13 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
360 | "int8", "int4", "int2", "async", "term" | 386 | "int8", "int4", "int2", "async", "term" |
361 | }; | 387 | }; |
362 | 388 | ||
363 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); | 389 | out += uhci_show_root_hub_state(uhci, out); |
390 | if (out - buf > len) | ||
391 | goto done; | ||
364 | out += sprintf(out, "HC status\n"); | 392 | out += sprintf(out, "HC status\n"); |
365 | out += uhci_show_status(uhci, out, len - (out - buf)); | 393 | out += uhci_show_status(uhci, out, len - (out - buf)); |
394 | if (out - buf > len) | ||
395 | goto tail; | ||
366 | 396 | ||
367 | out += sprintf(out, "Periodic load table\n"); | 397 | out += sprintf(out, "Periodic load table\n"); |
368 | for (i = 0; i < MAX_PHASE; ++i) { | 398 | for (i = 0; i < MAX_PHASE; ++i) { |
@@ -375,7 +405,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
375 | uhci_to_hcd(uhci)->self.bandwidth_int_reqs, | 405 | uhci_to_hcd(uhci)->self.bandwidth_int_reqs, |
376 | uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); | 406 | uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); |
377 | if (debug <= 1) | 407 | if (debug <= 1) |
378 | return out - buf; | 408 | goto tail; |
379 | 409 | ||
380 | out += sprintf(out, "Frame List\n"); | 410 | out += sprintf(out, "Frame List\n"); |
381 | nframes = 10; | 411 | nframes = 10; |
@@ -383,6 +413,8 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
383 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 413 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
384 | __hc32 qh_dma; | 414 | __hc32 qh_dma; |
385 | 415 | ||
416 | if (out - buf > len) | ||
417 | goto done; | ||
386 | j = 0; | 418 | j = 0; |
387 | td = uhci->frame_cpu[i]; | 419 | td = uhci->frame_cpu[i]; |
388 | link = uhci->frame[i]; | 420 | link = uhci->frame[i]; |
@@ -401,15 +433,20 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
401 | td = list_entry(tmp, struct uhci_td, fl_list); | 433 | td = list_entry(tmp, struct uhci_td, fl_list); |
402 | tmp = tmp->next; | 434 | tmp = tmp->next; |
403 | if (link != LINK_TO_TD(uhci, td)) { | 435 | if (link != LINK_TO_TD(uhci, td)) { |
404 | if (nframes > 0) | 436 | if (nframes > 0) { |
405 | out += sprintf(out, " link does " | 437 | out += sprintf(out, |
406 | "not match list entry!\n"); | 438 | " link does not match list entry!\n"); |
407 | else | 439 | if (out - buf > len) |
440 | goto done; | ||
441 | } else | ||
408 | ++nerrs; | 442 | ++nerrs; |
409 | } | 443 | } |
410 | if (nframes > 0) | 444 | if (nframes > 0) { |
411 | out += uhci_show_td(uhci, td, out, | 445 | out += uhci_show_td(uhci, td, out, |
412 | len - (out - buf), 4); | 446 | len - (out - buf), 4); |
447 | if (out - buf > len) | ||
448 | goto tail; | ||
449 | } | ||
413 | link = td->link; | 450 | link = td->link; |
414 | } while (tmp != head); | 451 | } while (tmp != head); |
415 | 452 | ||
@@ -423,9 +460,11 @@ check_link: | |||
423 | i, hc32_to_cpu(uhci, link)); | 460 | i, hc32_to_cpu(uhci, link)); |
424 | j = 1; | 461 | j = 1; |
425 | } | 462 | } |
426 | out += sprintf(out, " link does not match " | 463 | out += sprintf(out, |
427 | "QH (%08x)!\n", | 464 | " link does not match QH (%08x)!\n", |
428 | hc32_to_cpu(uhci, qh_dma)); | 465 | hc32_to_cpu(uhci, qh_dma)); |
466 | if (out - buf > len) | ||
467 | goto done; | ||
429 | } else | 468 | } else |
430 | ++nerrs; | 469 | ++nerrs; |
431 | } | 470 | } |
@@ -436,18 +475,27 @@ check_link: | |||
436 | 475 | ||
437 | out += sprintf(out, "Skeleton QHs\n"); | 476 | out += sprintf(out, "Skeleton QHs\n"); |
438 | 477 | ||
478 | if (out - buf > len) | ||
479 | goto done; | ||
480 | |||
439 | fsbr_link = 0; | 481 | fsbr_link = 0; |
440 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { | 482 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { |
441 | int cnt = 0; | 483 | int cnt = 0; |
442 | 484 | ||
443 | qh = uhci->skelqh[i]; | 485 | qh = uhci->skelqh[i]; |
444 | out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \ | 486 | out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); |
445 | out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4); | 487 | out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4); |
488 | if (out - buf > len) | ||
489 | goto tail; | ||
446 | 490 | ||
447 | /* Last QH is the Terminating QH, it's different */ | 491 | /* Last QH is the Terminating QH, it's different */ |
448 | if (i == SKEL_TERM) { | 492 | if (i == SKEL_TERM) { |
449 | if (qh_element(qh) != LINK_TO_TD(uhci, uhci->term_td)) | 493 | if (qh_element(qh) != LINK_TO_TD(uhci, uhci->term_td)) { |
450 | out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); | 494 | out += sprintf(out, |
495 | " skel_term_qh element is not set to term_td!\n"); | ||
496 | if (out - buf > len) | ||
497 | goto done; | ||
498 | } | ||
451 | link = fsbr_link; | 499 | link = fsbr_link; |
452 | if (!link) | 500 | if (!link) |
453 | link = LINK_TO_QH(uhci, uhci->skel_term_qh); | 501 | link = LINK_TO_QH(uhci, uhci->skel_term_qh); |
@@ -460,9 +508,12 @@ check_link: | |||
460 | while (tmp != head) { | 508 | while (tmp != head) { |
461 | qh = list_entry(tmp, struct uhci_qh, node); | 509 | qh = list_entry(tmp, struct uhci_qh, node); |
462 | tmp = tmp->next; | 510 | tmp = tmp->next; |
463 | if (++cnt <= 10) | 511 | if (++cnt <= 10) { |
464 | out += uhci_show_qh(uhci, qh, out, | 512 | out += uhci_show_qh(uhci, qh, out, |
465 | len - (out - buf), 4); | 513 | len - (out - buf), 4); |
514 | if (out - buf > len) | ||
515 | goto tail; | ||
516 | } | ||
466 | if (!fsbr_link && qh->skel >= SKEL_FSBR) | 517 | if (!fsbr_link && qh->skel >= SKEL_FSBR) |
467 | fsbr_link = LINK_TO_QH(uhci, qh); | 518 | fsbr_link = LINK_TO_QH(uhci, qh); |
468 | } | 519 | } |
@@ -480,9 +531,17 @@ check_link: | |||
480 | link = LINK_TO_QH(uhci, uhci->skel_term_qh); | 531 | link = LINK_TO_QH(uhci, uhci->skel_term_qh); |
481 | check_qh_link: | 532 | check_qh_link: |
482 | if (qh->link != link) | 533 | if (qh->link != link) |
483 | out += sprintf(out, " last QH not linked to next skeleton!\n"); | 534 | out += sprintf(out, |
535 | " last QH not linked to next skeleton!\n"); | ||
536 | |||
537 | if (out - buf > len) | ||
538 | goto done; | ||
484 | } | 539 | } |
485 | 540 | ||
541 | done: | ||
542 | if (out - buf > len) | ||
543 | out += sprintf(out, " ...\n"); | ||
544 | tail: | ||
486 | return out - buf; | 545 | return out - buf; |
487 | } | 546 | } |
488 | 547 | ||
@@ -514,7 +573,8 @@ static int uhci_debug_open(struct inode *inode, struct file *file) | |||
514 | up->size = 0; | 573 | up->size = 0; |
515 | spin_lock_irqsave(&uhci->lock, flags); | 574 | spin_lock_irqsave(&uhci->lock, flags); |
516 | if (uhci->is_initialized) | 575 | if (uhci->is_initialized) |
517 | up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT); | 576 | up->size = uhci_sprint_schedule(uhci, up->data, |
577 | MAX_OUTPUT - EXTRA_SPACE); | ||
518 | spin_unlock_irqrestore(&uhci->lock, flags); | 578 | spin_unlock_irqrestore(&uhci->lock, flags); |
519 | 579 | ||
520 | file->private_data = up; | 580 | file->private_data = up; |
@@ -529,7 +589,9 @@ static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence) | |||
529 | 589 | ||
530 | up = file->private_data; | 590 | up = file->private_data; |
531 | 591 | ||
532 | /* XXX: atomic 64bit seek access, but that needs to be fixed in the VFS */ | 592 | /* |
593 | * XXX: atomic 64bit seek access, but that needs to be fixed in the VFS | ||
594 | */ | ||
533 | switch (whence) { | 595 | switch (whence) { |
534 | case 0: | 596 | case 0: |
535 | new = off; | 597 | new = off; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 4f64d24eebc8..4a86b63745b8 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -453,20 +453,19 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) | |||
453 | 453 | ||
454 | if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { | 454 | if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { |
455 | if (status & USBSTS_HSE) | 455 | if (status & USBSTS_HSE) |
456 | dev_err(uhci_dev(uhci), "host system error, " | 456 | dev_err(uhci_dev(uhci), |
457 | "PCI problems?\n"); | 457 | "host system error, PCI problems?\n"); |
458 | if (status & USBSTS_HCPE) | 458 | if (status & USBSTS_HCPE) |
459 | dev_err(uhci_dev(uhci), "host controller process " | 459 | dev_err(uhci_dev(uhci), |
460 | "error, something bad happened!\n"); | 460 | "host controller process error, something bad happened!\n"); |
461 | if (status & USBSTS_HCH) { | 461 | if (status & USBSTS_HCH) { |
462 | if (uhci->rh_state >= UHCI_RH_RUNNING) { | 462 | if (uhci->rh_state >= UHCI_RH_RUNNING) { |
463 | dev_err(uhci_dev(uhci), | 463 | dev_err(uhci_dev(uhci), |
464 | "host controller halted, " | 464 | "host controller halted, very bad!\n"); |
465 | "very bad!\n"); | ||
466 | if (debug > 1 && errbuf) { | 465 | if (debug > 1 && errbuf) { |
467 | /* Print the schedule for debugging */ | 466 | /* Print the schedule for debugging */ |
468 | uhci_sprint_schedule(uhci, | 467 | uhci_sprint_schedule(uhci, errbuf, |
469 | errbuf, ERRBUF_LEN); | 468 | ERRBUF_LEN - EXTRA_SPACE); |
470 | lprintk(errbuf); | 469 | lprintk(errbuf); |
471 | } | 470 | } |
472 | uhci_hc_died(uhci); | 471 | uhci_hc_died(uhci); |
@@ -592,8 +591,8 @@ static int uhci_start(struct usb_hcd *hcd) | |||
592 | UHCI_NUMFRAMES * sizeof(*uhci->frame), | 591 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
593 | &uhci->frame_dma_handle, 0); | 592 | &uhci->frame_dma_handle, 0); |
594 | if (!uhci->frame) { | 593 | if (!uhci->frame) { |
595 | dev_err(uhci_dev(uhci), "unable to allocate " | 594 | dev_err(uhci_dev(uhci), |
596 | "consistent memory for frame list\n"); | 595 | "unable to allocate consistent memory for frame list\n"); |
597 | goto err_alloc_frame; | 596 | goto err_alloc_frame; |
598 | } | 597 | } |
599 | memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame)); | 598 | memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame)); |
@@ -601,8 +600,8 @@ static int uhci_start(struct usb_hcd *hcd) | |||
601 | uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), | 600 | uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), |
602 | GFP_KERNEL); | 601 | GFP_KERNEL); |
603 | if (!uhci->frame_cpu) { | 602 | if (!uhci->frame_cpu) { |
604 | dev_err(uhci_dev(uhci), "unable to allocate " | 603 | dev_err(uhci_dev(uhci), |
605 | "memory for frame pointers\n"); | 604 | "unable to allocate memory for frame pointers\n"); |
606 | goto err_alloc_frame_cpu; | 605 | goto err_alloc_frame_cpu; |
607 | } | 606 | } |
608 | 607 | ||
@@ -737,8 +736,8 @@ static int uhci_rh_suspend(struct usb_hcd *hcd) | |||
737 | */ | 736 | */ |
738 | else if (hcd->self.root_hub->do_remote_wakeup && | 737 | else if (hcd->self.root_hub->do_remote_wakeup && |
739 | uhci->resuming_ports) { | 738 | uhci->resuming_ports) { |
740 | dev_dbg(uhci_dev(uhci), "suspend failed because a port " | 739 | dev_dbg(uhci_dev(uhci), |
741 | "is resuming\n"); | 740 | "suspend failed because a port is resuming\n"); |
742 | rc = -EBUSY; | 741 | rc = -EBUSY; |
743 | } else | 742 | } else |
744 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 743 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
@@ -829,8 +828,8 @@ static int uhci_count_ports(struct usb_hcd *hcd) | |||
829 | 828 | ||
830 | /* Anything greater than 7 is weird so we'll ignore it. */ | 829 | /* Anything greater than 7 is weird so we'll ignore it. */ |
831 | if (port > UHCI_RH_MAXCHILD) { | 830 | if (port > UHCI_RH_MAXCHILD) { |
832 | dev_info(uhci_dev(uhci), "port count misdetected? " | 831 | dev_info(uhci_dev(uhci), |
833 | "forcing to 2 ports\n"); | 832 | "port count misdetected? forcing to 2 ports\n"); |
834 | port = 2; | 833 | port = 2; |
835 | } | 834 | } |
836 | 835 | ||
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 7af2b7052047..6f986d82472d 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -212,10 +212,6 @@ struct uhci_qh { | |||
212 | #define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ | 212 | #define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ |
213 | #define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */ | 213 | #define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */ |
214 | 214 | ||
215 | #define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ | ||
216 | TD_CTRL_BABBLE | TD_CTRL_CRCTIME | \ | ||
217 | TD_CTRL_BITSTUFF) | ||
218 | |||
219 | #define uhci_maxerr(err) ((err) << TD_CTRL_C_ERR_SHIFT) | 215 | #define uhci_maxerr(err) ((err) << TD_CTRL_C_ERR_SHIFT) |
220 | #define uhci_status_bits(ctrl_sts) ((ctrl_sts) & 0xF60000) | 216 | #define uhci_status_bits(ctrl_sts) ((ctrl_sts) & 0xF60000) |
221 | #define uhci_actual_length(ctrl_sts) (((ctrl_sts) + 1) & \ | 217 | #define uhci_actual_length(ctrl_sts) (((ctrl_sts) + 1) & \ |
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 15d13229ddbb..f87bee6d2789 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
@@ -21,8 +21,8 @@ static const __u8 root_hub_hub_des[] = | |||
21 | 0x00, /* (per-port OC, no power switching) */ | 21 | 0x00, /* (per-port OC, no power switching) */ |
22 | 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ | 22 | 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ |
23 | 0x00, /* __u8 bHubContrCurrent; 0 mA */ | 23 | 0x00, /* __u8 bHubContrCurrent; 0 mA */ |
24 | 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ | 24 | 0x00, /* __u8 DeviceRemovable; *** 7 Ports max */ |
25 | 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ | 25 | 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max */ |
26 | }; | 26 | }; |
27 | 27 | ||
28 | #define UHCI_RH_MAXCHILD 7 | 28 | #define UHCI_RH_MAXCHILD 7 |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 15921fd55048..f0976d8190bc 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -1200,7 +1200,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1200 | if (debug > 1 && errbuf) { | 1200 | if (debug > 1 && errbuf) { |
1201 | /* Print the chain for debugging */ | 1201 | /* Print the chain for debugging */ |
1202 | uhci_show_qh(uhci, urbp->qh, errbuf, | 1202 | uhci_show_qh(uhci, urbp->qh, errbuf, |
1203 | ERRBUF_LEN, 0); | 1203 | ERRBUF_LEN - EXTRA_SPACE, 0); |
1204 | lprintk(errbuf); | 1204 | lprintk(errbuf); |
1205 | } | 1205 | } |
1206 | } | 1206 | } |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7f76a49e90d3..882875465301 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2708,13 +2708,11 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) | |||
2708 | { | 2708 | { |
2709 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 2709 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
2710 | u32 status; | 2710 | u32 status; |
2711 | union xhci_trb *trb; | ||
2712 | u64 temp_64; | 2711 | u64 temp_64; |
2713 | union xhci_trb *event_ring_deq; | 2712 | union xhci_trb *event_ring_deq; |
2714 | dma_addr_t deq; | 2713 | dma_addr_t deq; |
2715 | 2714 | ||
2716 | spin_lock(&xhci->lock); | 2715 | spin_lock(&xhci->lock); |
2717 | trb = xhci->event_ring->dequeue; | ||
2718 | /* Check if the xHC generated the interrupt, or the irq is shared */ | 2716 | /* Check if the xHC generated the interrupt, or the irq is shared */ |
2719 | status = xhci_readl(xhci, &xhci->op_regs->status); | 2717 | status = xhci_readl(xhci, &xhci->op_regs->status); |
2720 | if (status == 0xffffffff) | 2718 | if (status == 0xffffffff) |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index fecde69bfa7d..3b1a3f4ec5e9 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -250,3 +250,9 @@ config USB_EZUSB_FX2 | |||
250 | help | 250 | help |
251 | Say Y here if you need EZUSB device support. | 251 | Say Y here if you need EZUSB device support. |
252 | (Cypress FX/FX2/FX2LP microcontrollers) | 252 | (Cypress FX/FX2/FX2LP microcontrollers) |
253 | |||
254 | config USB_HSIC_USB3503 | ||
255 | tristate "USB3503 HSIC to USB20 Driver" | ||
256 | depends on I2C | ||
257 | help | ||
258 | This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver. | ||
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 3e99a643294b..3e1bd70b06ea 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -26,5 +26,6 @@ obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o | |||
26 | obj-$(CONFIG_USB_USS720) += uss720.o | 26 | obj-$(CONFIG_USB_USS720) += uss720.o |
27 | obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o | 27 | obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o |
28 | obj-$(CONFIG_USB_YUREX) += yurex.o | 28 | obj-$(CONFIG_USB_YUREX) += yurex.o |
29 | obj-$(CONFIG_USB_HSIC_USB3503) += usb3503.o | ||
29 | 30 | ||
30 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ | 31 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ |
diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c new file mode 100644 index 000000000000..f713f6aeb6e5 --- /dev/null +++ b/drivers/usb/misc/usb3503.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* | ||
2 | * Driver for SMSC USB3503 USB 2.0 hub controller driver | ||
3 | * | ||
4 | * Copyright (c) 2012-2013 Dongjin Kim (tobetter@gmail.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/of_gpio.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/platform_data/usb3503.h> | ||
29 | |||
30 | #define USB3503_VIDL 0x00 | ||
31 | #define USB3503_VIDM 0x01 | ||
32 | #define USB3503_PIDL 0x02 | ||
33 | #define USB3503_PIDM 0x03 | ||
34 | #define USB3503_DIDL 0x04 | ||
35 | #define USB3503_DIDM 0x05 | ||
36 | |||
37 | #define USB3503_CFG1 0x06 | ||
38 | #define USB3503_SELF_BUS_PWR (1 << 7) | ||
39 | |||
40 | #define USB3503_CFG2 0x07 | ||
41 | #define USB3503_CFG3 0x08 | ||
42 | #define USB3503_NRD 0x09 | ||
43 | |||
44 | #define USB3503_PDS 0x0a | ||
45 | #define USB3503_PORT1 (1 << 1) | ||
46 | #define USB3503_PORT2 (1 << 2) | ||
47 | #define USB3503_PORT3 (1 << 3) | ||
48 | |||
49 | #define USB3503_SP_ILOCK 0xe7 | ||
50 | #define USB3503_SPILOCK_CONNECT (1 << 1) | ||
51 | #define USB3503_SPILOCK_CONFIG (1 << 0) | ||
52 | |||
53 | #define USB3503_CFGP 0xee | ||
54 | #define USB3503_CLKSUSP (1 << 7) | ||
55 | |||
56 | struct usb3503 { | ||
57 | enum usb3503_mode mode; | ||
58 | struct i2c_client *client; | ||
59 | int gpio_intn; | ||
60 | int gpio_reset; | ||
61 | int gpio_connect; | ||
62 | }; | ||
63 | |||
64 | static int usb3503_write_register(struct i2c_client *client, | ||
65 | char reg, char data) | ||
66 | { | ||
67 | return i2c_smbus_write_byte_data(client, reg, data); | ||
68 | } | ||
69 | |||
70 | static int usb3503_read_register(struct i2c_client *client, char reg) | ||
71 | { | ||
72 | return i2c_smbus_read_byte_data(client, reg); | ||
73 | } | ||
74 | |||
75 | static int usb3503_set_bits(struct i2c_client *client, char reg, char req) | ||
76 | { | ||
77 | int err; | ||
78 | |||
79 | err = usb3503_read_register(client, reg); | ||
80 | if (err < 0) | ||
81 | return err; | ||
82 | |||
83 | err = usb3503_write_register(client, reg, err | req); | ||
84 | if (err < 0) | ||
85 | return err; | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static int usb3503_clear_bits(struct i2c_client *client, char reg, char req) | ||
91 | { | ||
92 | int err; | ||
93 | |||
94 | err = usb3503_read_register(client, reg); | ||
95 | if (err < 0) | ||
96 | return err; | ||
97 | |||
98 | err = usb3503_write_register(client, reg, err & ~req); | ||
99 | if (err < 0) | ||
100 | return err; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int usb3503_reset(int gpio_reset, int state) | ||
106 | { | ||
107 | if (gpio_is_valid(gpio_reset)) | ||
108 | gpio_set_value(gpio_reset, state); | ||
109 | |||
110 | /* Wait RefClk when RESET_N is released, otherwise Hub will | ||
111 | * not transition to Hub Communication Stage. | ||
112 | */ | ||
113 | if (state) | ||
114 | msleep(100); | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode) | ||
120 | { | ||
121 | struct i2c_client *i2c = hub->client; | ||
122 | int err = 0; | ||
123 | |||
124 | switch (mode) { | ||
125 | case USB3503_MODE_HUB: | ||
126 | usb3503_reset(hub->gpio_reset, 1); | ||
127 | |||
128 | /* SP_ILOCK: set connect_n, config_n for config */ | ||
129 | err = usb3503_write_register(i2c, USB3503_SP_ILOCK, | ||
130 | (USB3503_SPILOCK_CONNECT | ||
131 | | USB3503_SPILOCK_CONFIG)); | ||
132 | if (err < 0) { | ||
133 | dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err); | ||
134 | goto err_hubmode; | ||
135 | } | ||
136 | |||
137 | /* PDS : Port2,3 Disable For Self Powered Operation */ | ||
138 | err = usb3503_set_bits(i2c, USB3503_PDS, | ||
139 | (USB3503_PORT2 | USB3503_PORT3)); | ||
140 | if (err < 0) { | ||
141 | dev_err(&i2c->dev, "PDS failed (%d)\n", err); | ||
142 | goto err_hubmode; | ||
143 | } | ||
144 | |||
145 | /* CFG1 : SELF_BUS_PWR -> Self-Powerd operation */ | ||
146 | err = usb3503_set_bits(i2c, USB3503_CFG1, USB3503_SELF_BUS_PWR); | ||
147 | if (err < 0) { | ||
148 | dev_err(&i2c->dev, "CFG1 failed (%d)\n", err); | ||
149 | goto err_hubmode; | ||
150 | } | ||
151 | |||
152 | /* SP_LOCK: clear connect_n, config_n for hub connect */ | ||
153 | err = usb3503_clear_bits(i2c, USB3503_SP_ILOCK, | ||
154 | (USB3503_SPILOCK_CONNECT | ||
155 | | USB3503_SPILOCK_CONFIG)); | ||
156 | if (err < 0) { | ||
157 | dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err); | ||
158 | goto err_hubmode; | ||
159 | } | ||
160 | |||
161 | hub->mode = mode; | ||
162 | dev_info(&i2c->dev, "switched to HUB mode\n"); | ||
163 | break; | ||
164 | |||
165 | case USB3503_MODE_STANDBY: | ||
166 | usb3503_reset(hub->gpio_reset, 0); | ||
167 | |||
168 | hub->mode = mode; | ||
169 | dev_info(&i2c->dev, "switched to STANDBY mode\n"); | ||
170 | break; | ||
171 | |||
172 | default: | ||
173 | dev_err(&i2c->dev, "unknown mode is request\n"); | ||
174 | err = -EINVAL; | ||
175 | break; | ||
176 | } | ||
177 | |||
178 | err_hubmode: | ||
179 | return err; | ||
180 | } | ||
181 | |||
182 | static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | ||
183 | { | ||
184 | struct usb3503_platform_data *pdata = i2c->dev.platform_data; | ||
185 | struct device_node *np = i2c->dev.of_node; | ||
186 | struct usb3503 *hub; | ||
187 | int err = -ENOMEM; | ||
188 | u32 mode = USB3503_MODE_UNKNOWN; | ||
189 | |||
190 | hub = kzalloc(sizeof(struct usb3503), GFP_KERNEL); | ||
191 | if (!hub) { | ||
192 | dev_err(&i2c->dev, "private data alloc fail\n"); | ||
193 | return err; | ||
194 | } | ||
195 | |||
196 | i2c_set_clientdata(i2c, hub); | ||
197 | hub->client = i2c; | ||
198 | |||
199 | if (pdata) { | ||
200 | hub->gpio_intn = pdata->gpio_intn; | ||
201 | hub->gpio_connect = pdata->gpio_connect; | ||
202 | hub->gpio_reset = pdata->gpio_reset; | ||
203 | hub->mode = pdata->initial_mode; | ||
204 | } else if (np) { | ||
205 | hub->gpio_intn = of_get_named_gpio(np, "connect-gpios", 0); | ||
206 | if (hub->gpio_intn == -EPROBE_DEFER) | ||
207 | return -EPROBE_DEFER; | ||
208 | hub->gpio_connect = of_get_named_gpio(np, "intn-gpios", 0); | ||
209 | if (hub->gpio_connect == -EPROBE_DEFER) | ||
210 | return -EPROBE_DEFER; | ||
211 | hub->gpio_reset = of_get_named_gpio(np, "reset-gpios", 0); | ||
212 | if (hub->gpio_reset == -EPROBE_DEFER) | ||
213 | return -EPROBE_DEFER; | ||
214 | of_property_read_u32(np, "initial-mode", &mode); | ||
215 | hub->mode = mode; | ||
216 | } | ||
217 | |||
218 | if (gpio_is_valid(hub->gpio_intn)) { | ||
219 | err = gpio_request_one(hub->gpio_intn, | ||
220 | GPIOF_OUT_INIT_HIGH, "usb3503 intn"); | ||
221 | if (err) { | ||
222 | dev_err(&i2c->dev, | ||
223 | "unable to request GPIO %d as connect pin (%d)\n", | ||
224 | hub->gpio_intn, err); | ||
225 | goto err_out; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | if (gpio_is_valid(hub->gpio_connect)) { | ||
230 | err = gpio_request_one(hub->gpio_connect, | ||
231 | GPIOF_OUT_INIT_HIGH, "usb3503 connect"); | ||
232 | if (err) { | ||
233 | dev_err(&i2c->dev, | ||
234 | "unable to request GPIO %d as connect pin (%d)\n", | ||
235 | hub->gpio_connect, err); | ||
236 | goto err_gpio_connect; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | if (gpio_is_valid(hub->gpio_reset)) { | ||
241 | err = gpio_request_one(hub->gpio_reset, | ||
242 | GPIOF_OUT_INIT_LOW, "usb3503 reset"); | ||
243 | if (err) { | ||
244 | dev_err(&i2c->dev, | ||
245 | "unable to request GPIO %d as reset pin (%d)\n", | ||
246 | hub->gpio_reset, err); | ||
247 | goto err_gpio_reset; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | usb3503_switch_mode(hub, hub->mode); | ||
252 | |||
253 | dev_info(&i2c->dev, "%s: probed on %s mode\n", __func__, | ||
254 | (hub->mode == USB3503_MODE_HUB) ? "hub" : "standby"); | ||
255 | |||
256 | return 0; | ||
257 | |||
258 | err_gpio_reset: | ||
259 | if (gpio_is_valid(hub->gpio_connect)) | ||
260 | gpio_free(hub->gpio_connect); | ||
261 | err_gpio_connect: | ||
262 | if (gpio_is_valid(hub->gpio_intn)) | ||
263 | gpio_free(hub->gpio_intn); | ||
264 | err_out: | ||
265 | kfree(hub); | ||
266 | |||
267 | return err; | ||
268 | } | ||
269 | |||
270 | static int usb3503_remove(struct i2c_client *i2c) | ||
271 | { | ||
272 | struct usb3503 *hub = i2c_get_clientdata(i2c); | ||
273 | |||
274 | if (gpio_is_valid(hub->gpio_intn)) | ||
275 | gpio_free(hub->gpio_intn); | ||
276 | if (gpio_is_valid(hub->gpio_connect)) | ||
277 | gpio_free(hub->gpio_connect); | ||
278 | if (gpio_is_valid(hub->gpio_reset)) | ||
279 | gpio_free(hub->gpio_reset); | ||
280 | |||
281 | kfree(hub); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static const struct i2c_device_id usb3503_id[] = { | ||
287 | { USB3503_I2C_NAME, 0 }, | ||
288 | { } | ||
289 | }; | ||
290 | MODULE_DEVICE_TABLE(i2c, usb3503_id); | ||
291 | |||
292 | #ifdef CONFIG_OF | ||
293 | static const struct of_device_id usb3503_of_match[] = { | ||
294 | { .compatible = "smsc,usb3503", }, | ||
295 | {}, | ||
296 | }; | ||
297 | MODULE_DEVICE_TABLE(of, usb3503_of_match); | ||
298 | #endif | ||
299 | |||
300 | static struct i2c_driver usb3503_driver = { | ||
301 | .driver = { | ||
302 | .name = USB3503_I2C_NAME, | ||
303 | .of_match_table = of_match_ptr(usb3503_of_match), | ||
304 | }, | ||
305 | .probe = usb3503_probe, | ||
306 | .remove = usb3503_remove, | ||
307 | .id_table = usb3503_id, | ||
308 | }; | ||
309 | |||
310 | static int __init usb3503_init(void) | ||
311 | { | ||
312 | return i2c_add_driver(&usb3503_driver); | ||
313 | } | ||
314 | |||
315 | static void __exit usb3503_exit(void) | ||
316 | { | ||
317 | i2c_del_driver(&usb3503_driver); | ||
318 | } | ||
319 | |||
320 | module_init(usb3503_init); | ||
321 | module_exit(usb3503_exit); | ||
322 | |||
323 | MODULE_AUTHOR("Dongjin Kim <tobetter@gmail.com>"); | ||
324 | MODULE_DESCRIPTION("USB3503 USB HUB driver"); | ||
325 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 268148de9714..8b4ca1cb450a 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -13,6 +13,12 @@ | |||
13 | 13 | ||
14 | /*-------------------------------------------------------------------------*/ | 14 | /*-------------------------------------------------------------------------*/ |
15 | 15 | ||
16 | static int override_alt = -1; | ||
17 | module_param_named(alt, override_alt, int, 0644); | ||
18 | MODULE_PARM_DESC(alt, ">= 0 to override altsetting selection"); | ||
19 | |||
20 | /*-------------------------------------------------------------------------*/ | ||
21 | |||
16 | /* FIXME make these public somewhere; usbdevfs.h? */ | 22 | /* FIXME make these public somewhere; usbdevfs.h? */ |
17 | struct usbtest_param { | 23 | struct usbtest_param { |
18 | /* inputs */ | 24 | /* inputs */ |
@@ -103,6 +109,10 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf) | |||
103 | iso_in = iso_out = NULL; | 109 | iso_in = iso_out = NULL; |
104 | alt = intf->altsetting + tmp; | 110 | alt = intf->altsetting + tmp; |
105 | 111 | ||
112 | if (override_alt >= 0 && | ||
113 | override_alt != alt->desc.bAlternateSetting) | ||
114 | continue; | ||
115 | |||
106 | /* take the first altsetting with in-bulk + out-bulk; | 116 | /* take the first altsetting with in-bulk + out-bulk; |
107 | * ignore other endpoints and altsettings. | 117 | * ignore other endpoints and altsettings. |
108 | */ | 118 | */ |
@@ -144,6 +154,7 @@ try_iso: | |||
144 | 154 | ||
145 | found: | 155 | found: |
146 | udev = testdev_to_usbdev(dev); | 156 | udev = testdev_to_usbdev(dev); |
157 | dev->info->alt = alt->desc.bAlternateSetting; | ||
147 | if (alt->desc.bAlternateSetting != 0) { | 158 | if (alt->desc.bAlternateSetting != 0) { |
148 | tmp = usb_set_interface(udev, | 159 | tmp = usb_set_interface(udev, |
149 | alt->desc.bInterfaceNumber, | 160 | alt->desc.bInterfaceNumber, |
@@ -2280,7 +2291,7 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2280 | wtest = " intr-out"; | 2291 | wtest = " intr-out"; |
2281 | } | 2292 | } |
2282 | } else { | 2293 | } else { |
2283 | if (info->autoconf) { | 2294 | if (override_alt >= 0 || info->autoconf) { |
2284 | int status; | 2295 | int status; |
2285 | 2296 | ||
2286 | status = get_endpoints(dev, intf); | 2297 | status = get_endpoints(dev, intf); |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 23a0b7f0892d..45b19e2c60ba 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC | |||
11 | select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) | 11 | select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) |
12 | select TWL4030_USB if MACH_OMAP_3430SDP | 12 | select TWL4030_USB if MACH_OMAP_3430SDP |
13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | 13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA |
14 | select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | ||
14 | select USB_OTG_UTILS | 15 | select USB_OTG_UTILS |
15 | help | 16 | help |
16 | Say Y here if your system has a dual role high speed USB | 17 | Say Y here if your system has a dual role high speed USB |
@@ -45,6 +46,7 @@ config USB_MUSB_DA8XX | |||
45 | 46 | ||
46 | config USB_MUSB_TUSB6010 | 47 | config USB_MUSB_TUSB6010 |
47 | tristate "TUSB6010" | 48 | tristate "TUSB6010" |
49 | depends on GENERIC_HARDIRQS | ||
48 | 50 | ||
49 | config USB_MUSB_OMAP2PLUS | 51 | config USB_MUSB_OMAP2PLUS |
50 | tristate "OMAP2430 and onwards" | 52 | tristate "OMAP2430 and onwards" |
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index c107d7cdfa69..59eea219034a 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c | |||
@@ -365,7 +365,7 @@ static int am35x_musb_init(struct musb *musb) | |||
365 | usb_nop_xceiv_register(); | 365 | usb_nop_xceiv_register(); |
366 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 366 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
367 | if (IS_ERR_OR_NULL(musb->xceiv)) | 367 | if (IS_ERR_OR_NULL(musb->xceiv)) |
368 | return -ENODEV; | 368 | return -EPROBE_DEFER; |
369 | 369 | ||
370 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); | 370 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); |
371 | 371 | ||
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 14dab9f9b3d0..dbb31b30c7fa 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -406,7 +406,7 @@ static int bfin_musb_init(struct musb *musb) | |||
406 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 406 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
407 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 407 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
408 | gpio_free(musb->config->gpio_vrsel); | 408 | gpio_free(musb->config->gpio_vrsel); |
409 | return -ENODEV; | 409 | return -EPROBE_DEFER; |
410 | } | 410 | } |
411 | 411 | ||
412 | bfin_musb_reg_init(musb); | 412 | bfin_musb_reg_init(musb); |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 97996af2646e..7c71769d71ff 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
@@ -410,6 +410,7 @@ static int da8xx_musb_init(struct musb *musb) | |||
410 | { | 410 | { |
411 | void __iomem *reg_base = musb->ctrl_base; | 411 | void __iomem *reg_base = musb->ctrl_base; |
412 | u32 rev; | 412 | u32 rev; |
413 | int ret = -ENODEV; | ||
413 | 414 | ||
414 | musb->mregs += DA8XX_MENTOR_CORE_OFFSET; | 415 | musb->mregs += DA8XX_MENTOR_CORE_OFFSET; |
415 | 416 | ||
@@ -420,8 +421,10 @@ static int da8xx_musb_init(struct musb *musb) | |||
420 | 421 | ||
421 | usb_nop_xceiv_register(); | 422 | usb_nop_xceiv_register(); |
422 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 423 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
423 | if (IS_ERR_OR_NULL(musb->xceiv)) | 424 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
425 | ret = -EPROBE_DEFER; | ||
424 | goto fail; | 426 | goto fail; |
427 | } | ||
425 | 428 | ||
426 | setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); | 429 | setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); |
427 | 430 | ||
@@ -441,7 +444,7 @@ static int da8xx_musb_init(struct musb *musb) | |||
441 | musb->isr = da8xx_musb_interrupt; | 444 | musb->isr = da8xx_musb_interrupt; |
442 | return 0; | 445 | return 0; |
443 | fail: | 446 | fail: |
444 | return -ENODEV; | 447 | return ret; |
445 | } | 448 | } |
446 | 449 | ||
447 | static int da8xx_musb_exit(struct musb *musb) | 450 | static int da8xx_musb_exit(struct musb *musb) |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index b1c01cad28b2..e040d9103735 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -380,11 +380,14 @@ static int davinci_musb_init(struct musb *musb) | |||
380 | { | 380 | { |
381 | void __iomem *tibase = musb->ctrl_base; | 381 | void __iomem *tibase = musb->ctrl_base; |
382 | u32 revision; | 382 | u32 revision; |
383 | int ret = -ENODEV; | ||
383 | 384 | ||
384 | usb_nop_xceiv_register(); | 385 | usb_nop_xceiv_register(); |
385 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 386 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
386 | if (IS_ERR_OR_NULL(musb->xceiv)) | 387 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
388 | ret = -EPROBE_DEFER; | ||
387 | goto unregister; | 389 | goto unregister; |
390 | } | ||
388 | 391 | ||
389 | musb->mregs += DAVINCI_BASE_OFFSET; | 392 | musb->mregs += DAVINCI_BASE_OFFSET; |
390 | 393 | ||
@@ -438,7 +441,7 @@ fail: | |||
438 | usb_put_phy(musb->xceiv); | 441 | usb_put_phy(musb->xceiv); |
439 | unregister: | 442 | unregister: |
440 | usb_nop_xceiv_unregister(); | 443 | usb_nop_xceiv_unregister(); |
441 | return -ENODEV; | 444 | return ret; |
442 | } | 445 | } |
443 | 446 | ||
444 | static int davinci_musb_exit(struct musb *musb) | 447 | static int davinci_musb_exit(struct musb *musb) |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index fd3486745e64..60b41cc28da4 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1993,6 +1993,7 @@ fail2: | |||
1993 | musb_platform_exit(musb); | 1993 | musb_platform_exit(musb); |
1994 | 1994 | ||
1995 | fail1: | 1995 | fail1: |
1996 | pm_runtime_disable(musb->controller); | ||
1996 | dev_err(musb->controller, | 1997 | dev_err(musb->controller, |
1997 | "musb_init_controller failed with status %d\n", status); | 1998 | "musb_init_controller failed with status %d\n", status); |
1998 | 1999 | ||
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 99f470d26a38..6bb89715b637 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/of.h> | ||
35 | #include <linux/err.h> | 34 | #include <linux/err.h> |
36 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
37 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
@@ -419,7 +418,7 @@ static int dsps_musb_init(struct musb *musb) | |||
419 | usb_nop_xceiv_register(); | 418 | usb_nop_xceiv_register(); |
420 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 419 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
421 | if (IS_ERR_OR_NULL(musb->xceiv)) | 420 | if (IS_ERR_OR_NULL(musb->xceiv)) |
422 | return -ENODEV; | 421 | return -EPROBE_DEFER; |
423 | 422 | ||
424 | /* Returns zero if e.g. not clocked */ | 423 | /* Returns zero if e.g. not clocked */ |
425 | rev = dsps_readl(reg_base, wrp->revision); | 424 | rev = dsps_readl(reg_base, wrp->revision); |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 876787438c2f..be18537c5f14 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -408,7 +408,19 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
408 | csr |= (MUSB_TXCSR_DMAENAB | 408 | csr |= (MUSB_TXCSR_DMAENAB |
409 | | MUSB_TXCSR_DMAMODE | 409 | | MUSB_TXCSR_DMAMODE |
410 | | MUSB_TXCSR_MODE); | 410 | | MUSB_TXCSR_MODE); |
411 | if (!musb_ep->hb_mult) | 411 | /* |
412 | * Enable Autoset according to table | ||
413 | * below | ||
414 | * bulk_split hb_mult Autoset_Enable | ||
415 | * 0 0 Yes(Normal) | ||
416 | * 0 >0 No(High BW ISO) | ||
417 | * 1 0 Yes(HS bulk) | ||
418 | * 1 >0 Yes(FS bulk) | ||
419 | */ | ||
420 | if (!musb_ep->hb_mult || | ||
421 | (musb_ep->hb_mult && | ||
422 | can_bulk_split(musb, | ||
423 | musb_ep->type))) | ||
412 | csr |= MUSB_TXCSR_AUTOSET; | 424 | csr |= MUSB_TXCSR_AUTOSET; |
413 | } | 425 | } |
414 | csr &= ~MUSB_TXCSR_P_UNDERRUN; | 426 | csr &= ~MUSB_TXCSR_P_UNDERRUN; |
@@ -1110,11 +1122,15 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
1110 | /* Set TXMAXP with the FIFO size of the endpoint | 1122 | /* Set TXMAXP with the FIFO size of the endpoint |
1111 | * to disable double buffering mode. | 1123 | * to disable double buffering mode. |
1112 | */ | 1124 | */ |
1113 | if (musb->double_buffer_not_ok) | 1125 | if (musb->double_buffer_not_ok) { |
1114 | musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); | 1126 | musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); |
1115 | else | 1127 | } else { |
1128 | if (can_bulk_split(musb, musb_ep->type)) | ||
1129 | musb_ep->hb_mult = (hw_ep->max_packet_sz_tx / | ||
1130 | musb_ep->packet_sz) - 1; | ||
1116 | musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | 1131 | musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz |
1117 | | (musb_ep->hb_mult << 11)); | 1132 | | (musb_ep->hb_mult << 11)); |
1133 | } | ||
1118 | 1134 | ||
1119 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; | 1135 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; |
1120 | if (musb_readw(regs, MUSB_TXCSR) | 1136 | if (musb_readw(regs, MUSB_TXCSR) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index e9f0fd9ddd2d..1ce1fcf3f3e7 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -634,7 +634,17 @@ static bool musb_tx_dma_program(struct dma_controller *dma, | |||
634 | mode = 1; | 634 | mode = 1; |
635 | csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB; | 635 | csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB; |
636 | /* autoset shouldn't be set in high bandwidth */ | 636 | /* autoset shouldn't be set in high bandwidth */ |
637 | if (qh->hb_mult == 1) | 637 | /* |
638 | * Enable Autoset according to table | ||
639 | * below | ||
640 | * bulk_split hb_mult Autoset_Enable | ||
641 | * 0 1 Yes(Normal) | ||
642 | * 0 >1 No(High BW ISO) | ||
643 | * 1 1 Yes(HS bulk) | ||
644 | * 1 >1 Yes(FS bulk) | ||
645 | */ | ||
646 | if (qh->hb_mult == 1 || (qh->hb_mult > 1 && | ||
647 | can_bulk_split(hw_ep->musb, qh->type))) | ||
638 | csr |= MUSB_TXCSR_AUTOSET; | 648 | csr |= MUSB_TXCSR_AUTOSET; |
639 | } else { | 649 | } else { |
640 | mode = 0; | 650 | mode = 0; |
@@ -746,7 +756,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
746 | /* general endpoint setup */ | 756 | /* general endpoint setup */ |
747 | if (epnum) { | 757 | if (epnum) { |
748 | /* flush all old state, set default */ | 758 | /* flush all old state, set default */ |
749 | musb_h_tx_flush_fifo(hw_ep); | 759 | /* |
760 | * We could be flushing valid | ||
761 | * packets in double buffering | ||
762 | * case | ||
763 | */ | ||
764 | if (!hw_ep->tx_double_buffered) | ||
765 | musb_h_tx_flush_fifo(hw_ep); | ||
750 | 766 | ||
751 | /* | 767 | /* |
752 | * We must not clear the DMAMODE bit before or in | 768 | * We must not clear the DMAMODE bit before or in |
@@ -763,11 +779,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
763 | ); | 779 | ); |
764 | csr |= MUSB_TXCSR_MODE; | 780 | csr |= MUSB_TXCSR_MODE; |
765 | 781 | ||
766 | if (usb_gettoggle(urb->dev, qh->epnum, 1)) | 782 | if (!hw_ep->tx_double_buffered) { |
767 | csr |= MUSB_TXCSR_H_WR_DATATOGGLE | 783 | if (usb_gettoggle(urb->dev, qh->epnum, 1)) |
768 | | MUSB_TXCSR_H_DATATOGGLE; | 784 | csr |= MUSB_TXCSR_H_WR_DATATOGGLE |
769 | else | 785 | | MUSB_TXCSR_H_DATATOGGLE; |
770 | csr |= MUSB_TXCSR_CLRDATATOG; | 786 | else |
787 | csr |= MUSB_TXCSR_CLRDATATOG; | ||
788 | } | ||
771 | 789 | ||
772 | musb_writew(epio, MUSB_TXCSR, csr); | 790 | musb_writew(epio, MUSB_TXCSR, csr); |
773 | /* REVISIT may need to clear FLUSHFIFO ... */ | 791 | /* REVISIT may need to clear FLUSHFIFO ... */ |
@@ -791,17 +809,19 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
791 | /* protocol/endpoint/interval/NAKlimit */ | 809 | /* protocol/endpoint/interval/NAKlimit */ |
792 | if (epnum) { | 810 | if (epnum) { |
793 | musb_writeb(epio, MUSB_TXTYPE, qh->type_reg); | 811 | musb_writeb(epio, MUSB_TXTYPE, qh->type_reg); |
794 | if (musb->double_buffer_not_ok) | 812 | if (musb->double_buffer_not_ok) { |
795 | musb_writew(epio, MUSB_TXMAXP, | 813 | musb_writew(epio, MUSB_TXMAXP, |
796 | hw_ep->max_packet_sz_tx); | 814 | hw_ep->max_packet_sz_tx); |
797 | else if (can_bulk_split(musb, qh->type)) | 815 | } else if (can_bulk_split(musb, qh->type)) { |
816 | qh->hb_mult = hw_ep->max_packet_sz_tx | ||
817 | / packet_sz; | ||
798 | musb_writew(epio, MUSB_TXMAXP, packet_sz | 818 | musb_writew(epio, MUSB_TXMAXP, packet_sz |
799 | | ((hw_ep->max_packet_sz_tx / | 819 | | ((qh->hb_mult) - 1) << 11); |
800 | packet_sz) - 1) << 11); | 820 | } else { |
801 | else | ||
802 | musb_writew(epio, MUSB_TXMAXP, | 821 | musb_writew(epio, MUSB_TXMAXP, |
803 | qh->maxpacket | | 822 | qh->maxpacket | |
804 | ((qh->hb_mult - 1) << 11)); | 823 | ((qh->hb_mult - 1) << 11)); |
824 | } | ||
805 | musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg); | 825 | musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg); |
806 | } else { | 826 | } else { |
807 | musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg); | 827 | musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg); |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index acd5f9d71d03..1762354fe793 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/err.h> | 37 | #include <linux/err.h> |
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/usb/musb-omap.h> | 39 | #include <linux/usb/musb-omap.h> |
40 | #include <linux/usb/omap_control_usb.h> | ||
40 | 41 | ||
41 | #include "musb_core.h" | 42 | #include "musb_core.h" |
42 | #include "omap2430.h" | 43 | #include "omap2430.h" |
@@ -46,7 +47,7 @@ struct omap2430_glue { | |||
46 | struct platform_device *musb; | 47 | struct platform_device *musb; |
47 | enum omap_musb_vbus_id_status status; | 48 | enum omap_musb_vbus_id_status status; |
48 | struct work_struct omap_musb_mailbox_work; | 49 | struct work_struct omap_musb_mailbox_work; |
49 | u32 __iomem *control_otghs; | 50 | struct device *control_otghs; |
50 | }; | 51 | }; |
51 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | 52 | #define glue_to_musb(g) platform_get_drvdata(g->musb) |
52 | 53 | ||
@@ -54,26 +55,6 @@ struct omap2430_glue *_glue; | |||
54 | 55 | ||
55 | static struct timer_list musb_idle_timer; | 56 | static struct timer_list musb_idle_timer; |
56 | 57 | ||
57 | /** | ||
58 | * omap4_usb_phy_mailbox - write to usb otg mailbox | ||
59 | * @glue: struct omap2430_glue * | ||
60 | * @val: the value to be written to the mailbox | ||
61 | * | ||
62 | * On detection of a device (ID pin is grounded), this API should be called | ||
63 | * to set AVALID, VBUSVALID and ID pin is grounded. | ||
64 | * | ||
65 | * When OMAP is connected to a host (OMAP in device mode), this API | ||
66 | * is called to set AVALID, VBUSVALID and ID pin in high impedance. | ||
67 | * | ||
68 | * XXX: This function will be removed once we have a seperate driver for | ||
69 | * control module | ||
70 | */ | ||
71 | static void omap4_usb_phy_mailbox(struct omap2430_glue *glue, u32 val) | ||
72 | { | ||
73 | if (glue->control_otghs) | ||
74 | writel(val, glue->control_otghs); | ||
75 | } | ||
76 | |||
77 | static void musb_do_idle(unsigned long _musb) | 58 | static void musb_do_idle(unsigned long _musb) |
78 | { | 59 | { |
79 | struct musb *musb = (void *)_musb; | 60 | struct musb *musb = (void *)_musb; |
@@ -255,11 +236,11 @@ static inline void omap2430_low_level_init(struct musb *musb) | |||
255 | void omap_musb_mailbox(enum omap_musb_vbus_id_status status) | 236 | void omap_musb_mailbox(enum omap_musb_vbus_id_status status) |
256 | { | 237 | { |
257 | struct omap2430_glue *glue = _glue; | 238 | struct omap2430_glue *glue = _glue; |
258 | struct musb *musb = glue_to_musb(glue); | ||
259 | 239 | ||
260 | glue->status = status; | 240 | if (glue && glue_to_musb(glue)) { |
261 | if (!musb) { | 241 | glue->status = status; |
262 | dev_err(glue->dev, "musb core is not yet ready\n"); | 242 | } else { |
243 | pr_err("%s: musb core is not yet ready\n", __func__); | ||
263 | return; | 244 | return; |
264 | } | 245 | } |
265 | 246 | ||
@@ -269,7 +250,6 @@ EXPORT_SYMBOL_GPL(omap_musb_mailbox); | |||
269 | 250 | ||
270 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) | 251 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) |
271 | { | 252 | { |
272 | u32 val; | ||
273 | struct musb *musb = glue_to_musb(glue); | 253 | struct musb *musb = glue_to_musb(glue); |
274 | struct device *dev = musb->controller; | 254 | struct device *dev = musb->controller; |
275 | struct musb_hdrc_platform_data *pdata = dev->platform_data; | 255 | struct musb_hdrc_platform_data *pdata = dev->platform_data; |
@@ -285,8 +265,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
285 | musb->xceiv->last_event = USB_EVENT_ID; | 265 | musb->xceiv->last_event = USB_EVENT_ID; |
286 | if (musb->gadget_driver) { | 266 | if (musb->gadget_driver) { |
287 | pm_runtime_get_sync(dev); | 267 | pm_runtime_get_sync(dev); |
288 | val = AVALID | VBUSVALID; | 268 | omap_control_usb_set_mode(glue->control_otghs, |
289 | omap4_usb_phy_mailbox(glue, val); | 269 | USB_MODE_HOST); |
290 | omap2430_musb_set_vbus(musb, 1); | 270 | omap2430_musb_set_vbus(musb, 1); |
291 | } | 271 | } |
292 | break; | 272 | break; |
@@ -299,8 +279,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
299 | musb->xceiv->last_event = USB_EVENT_VBUS; | 279 | musb->xceiv->last_event = USB_EVENT_VBUS; |
300 | if (musb->gadget_driver) | 280 | if (musb->gadget_driver) |
301 | pm_runtime_get_sync(dev); | 281 | pm_runtime_get_sync(dev); |
302 | val = IDDIG | AVALID | VBUSVALID; | 282 | omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); |
303 | omap4_usb_phy_mailbox(glue, val); | ||
304 | break; | 283 | break; |
305 | 284 | ||
306 | case OMAP_MUSB_ID_FLOAT: | 285 | case OMAP_MUSB_ID_FLOAT: |
@@ -317,8 +296,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
317 | if (musb->xceiv->otg->set_vbus) | 296 | if (musb->xceiv->otg->set_vbus) |
318 | otg_set_vbus(musb->xceiv->otg, 0); | 297 | otg_set_vbus(musb->xceiv->otg, 0); |
319 | } | 298 | } |
320 | val = SESSEND | IDDIG; | 299 | omap_control_usb_set_mode(glue->control_otghs, |
321 | omap4_usb_phy_mailbox(glue, val); | 300 | USB_MODE_DISCONNECT); |
322 | break; | 301 | break; |
323 | default: | 302 | default: |
324 | dev_dbg(dev, "ID float\n"); | 303 | dev_dbg(dev, "ID float\n"); |
@@ -366,10 +345,15 @@ static int omap2430_musb_init(struct musb *musb) | |||
366 | * up through ULPI. TWL4030-family PMICs include one, | 345 | * up through ULPI. TWL4030-family PMICs include one, |
367 | * which needs a driver, drivers aren't always needed. | 346 | * which needs a driver, drivers aren't always needed. |
368 | */ | 347 | */ |
369 | musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | 348 | if (dev->parent->of_node) |
349 | musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, | ||
350 | "usb-phy", 0); | ||
351 | else | ||
352 | musb->xceiv = devm_usb_get_phy_dev(dev, 0); | ||
353 | |||
370 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 354 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
371 | pr_err("HS USB OTG: no transceiver configured\n"); | 355 | pr_err("HS USB OTG: no transceiver configured\n"); |
372 | return -ENODEV; | 356 | return -EPROBE_DEFER; |
373 | } | 357 | } |
374 | 358 | ||
375 | musb->isr = omap2430_musb_interrupt; | 359 | musb->isr = omap2430_musb_interrupt; |
@@ -415,7 +399,6 @@ err1: | |||
415 | static void omap2430_musb_enable(struct musb *musb) | 399 | static void omap2430_musb_enable(struct musb *musb) |
416 | { | 400 | { |
417 | u8 devctl; | 401 | u8 devctl; |
418 | u32 val; | ||
419 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | 402 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); |
420 | struct device *dev = musb->controller; | 403 | struct device *dev = musb->controller; |
421 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); | 404 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); |
@@ -425,8 +408,7 @@ static void omap2430_musb_enable(struct musb *musb) | |||
425 | switch (glue->status) { | 408 | switch (glue->status) { |
426 | 409 | ||
427 | case OMAP_MUSB_ID_GROUND: | 410 | case OMAP_MUSB_ID_GROUND: |
428 | val = AVALID | VBUSVALID; | 411 | omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST); |
429 | omap4_usb_phy_mailbox(glue, val); | ||
430 | if (data->interface_type != MUSB_INTERFACE_UTMI) | 412 | if (data->interface_type != MUSB_INTERFACE_UTMI) |
431 | break; | 413 | break; |
432 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 414 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
@@ -445,8 +427,7 @@ static void omap2430_musb_enable(struct musb *musb) | |||
445 | break; | 427 | break; |
446 | 428 | ||
447 | case OMAP_MUSB_VBUS_VALID: | 429 | case OMAP_MUSB_VBUS_VALID: |
448 | val = IDDIG | AVALID | VBUSVALID; | 430 | omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); |
449 | omap4_usb_phy_mailbox(glue, val); | ||
450 | break; | 431 | break; |
451 | 432 | ||
452 | default: | 433 | default: |
@@ -456,14 +437,12 @@ static void omap2430_musb_enable(struct musb *musb) | |||
456 | 437 | ||
457 | static void omap2430_musb_disable(struct musb *musb) | 438 | static void omap2430_musb_disable(struct musb *musb) |
458 | { | 439 | { |
459 | u32 val; | ||
460 | struct device *dev = musb->controller; | 440 | struct device *dev = musb->controller; |
461 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); | 441 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); |
462 | 442 | ||
463 | if (glue->status != OMAP_MUSB_UNKNOWN) { | 443 | if (glue->status != OMAP_MUSB_UNKNOWN) |
464 | val = SESSEND | IDDIG; | 444 | omap_control_usb_set_mode(glue->control_otghs, |
465 | omap4_usb_phy_mailbox(glue, val); | 445 | USB_MODE_DISCONNECT); |
466 | } | ||
467 | } | 446 | } |
468 | 447 | ||
469 | static int omap2430_musb_exit(struct musb *musb) | 448 | static int omap2430_musb_exit(struct musb *musb) |
@@ -498,7 +477,6 @@ static int omap2430_probe(struct platform_device *pdev) | |||
498 | struct omap2430_glue *glue; | 477 | struct omap2430_glue *glue; |
499 | struct device_node *np = pdev->dev.of_node; | 478 | struct device_node *np = pdev->dev.of_node; |
500 | struct musb_hdrc_config *config; | 479 | struct musb_hdrc_config *config; |
501 | struct resource *res; | ||
502 | int ret = -ENOMEM; | 480 | int ret = -ENOMEM; |
503 | 481 | ||
504 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | 482 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
@@ -521,29 +499,23 @@ static int omap2430_probe(struct platform_device *pdev) | |||
521 | glue->musb = musb; | 499 | glue->musb = musb; |
522 | glue->status = OMAP_MUSB_UNKNOWN; | 500 | glue->status = OMAP_MUSB_UNKNOWN; |
523 | 501 | ||
524 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
525 | |||
526 | glue->control_otghs = devm_ioremap_resource(&pdev->dev, res); | ||
527 | |||
528 | if (np) { | 502 | if (np) { |
529 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 503 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
530 | if (!pdata) { | 504 | if (!pdata) { |
531 | dev_err(&pdev->dev, | 505 | dev_err(&pdev->dev, |
532 | "failed to allocate musb platfrom data\n"); | 506 | "failed to allocate musb platfrom data\n"); |
533 | ret = -ENOMEM; | ||
534 | goto err2; | 507 | goto err2; |
535 | } | 508 | } |
536 | 509 | ||
537 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 510 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
538 | if (!data) { | 511 | if (!data) { |
539 | dev_err(&pdev->dev, | 512 | dev_err(&pdev->dev, |
540 | "failed to allocate musb board data\n"); | 513 | "failed to allocate musb board data\n"); |
541 | ret = -ENOMEM; | ||
542 | goto err2; | 514 | goto err2; |
543 | } | 515 | } |
544 | 516 | ||
545 | config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); | 517 | config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); |
546 | if (!data) { | 518 | if (!config) { |
547 | dev_err(&pdev->dev, | 519 | dev_err(&pdev->dev, |
548 | "failed to allocate musb hdrc config\n"); | 520 | "failed to allocate musb hdrc config\n"); |
549 | goto err2; | 521 | goto err2; |
@@ -556,11 +528,22 @@ static int omap2430_probe(struct platform_device *pdev) | |||
556 | of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits); | 528 | of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits); |
557 | of_property_read_u32(np, "power", (u32 *)&pdata->power); | 529 | of_property_read_u32(np, "power", (u32 *)&pdata->power); |
558 | config->multipoint = of_property_read_bool(np, "multipoint"); | 530 | config->multipoint = of_property_read_bool(np, "multipoint"); |
531 | pdata->has_mailbox = of_property_read_bool(np, | ||
532 | "ti,has-mailbox"); | ||
559 | 533 | ||
560 | pdata->board_data = data; | 534 | pdata->board_data = data; |
561 | pdata->config = config; | 535 | pdata->config = config; |
562 | } | 536 | } |
563 | 537 | ||
538 | if (pdata->has_mailbox) { | ||
539 | glue->control_otghs = omap_get_control_dev(); | ||
540 | if (IS_ERR(glue->control_otghs)) { | ||
541 | dev_vdbg(&pdev->dev, "Failed to get control device\n"); | ||
542 | return -ENODEV; | ||
543 | } | ||
544 | } else { | ||
545 | glue->control_otghs = ERR_PTR(-ENODEV); | ||
546 | } | ||
564 | pdata->platform_ops = &omap2430_ops; | 547 | pdata->platform_ops = &omap2430_ops; |
565 | 548 | ||
566 | platform_set_drvdata(pdev, glue); | 549 | platform_set_drvdata(pdev, glue); |
diff --git a/drivers/usb/musb/omap2430.h b/drivers/usb/musb/omap2430.h index 8ef656659fcb..1b5e83a9840e 100644 --- a/drivers/usb/musb/omap2430.h +++ b/drivers/usb/musb/omap2430.h | |||
@@ -49,13 +49,4 @@ | |||
49 | #define OTG_FORCESTDBY 0x414 | 49 | #define OTG_FORCESTDBY 0x414 |
50 | # define ENABLEFORCE (1 << 0) | 50 | # define ENABLEFORCE (1 << 0) |
51 | 51 | ||
52 | /* | ||
53 | * Control Module bit definitions | ||
54 | * XXX: Will be removed once we have a driver for control module. | ||
55 | */ | ||
56 | #define AVALID BIT(0) | ||
57 | #define BVALID BIT(1) | ||
58 | #define VBUSVALID BIT(2) | ||
59 | #define SESSEND BIT(3) | ||
60 | #define IDDIG BIT(4) | ||
61 | #endif /* __MUSB_OMAP243X_H__ */ | 52 | #endif /* __MUSB_OMAP243X_H__ */ |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 3969813c217d..464bd23cccda 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -1069,7 +1069,7 @@ static int tusb_musb_init(struct musb *musb) | |||
1069 | usb_nop_xceiv_register(); | 1069 | usb_nop_xceiv_register(); |
1070 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 1070 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
1071 | if (IS_ERR_OR_NULL(musb->xceiv)) | 1071 | if (IS_ERR_OR_NULL(musb->xceiv)) |
1072 | return -ENODEV; | 1072 | return -EPROBE_DEFER; |
1073 | 1073 | ||
1074 | pdev = to_platform_device(musb->controller); | 1074 | pdev = to_platform_device(musb->controller); |
1075 | 1075 | ||
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index a27ca1a9c994..13a392913769 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
@@ -61,7 +61,7 @@ static int ux500_musb_init(struct musb *musb) | |||
61 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 61 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
62 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 62 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
63 | pr_err("HS USB OTG: no transceiver configured\n"); | 63 | pr_err("HS USB OTG: no transceiver configured\n"); |
64 | return -ENODEV; | 64 | return -EPROBE_DEFER; |
65 | } | 65 | } |
66 | 66 | ||
67 | musb->isr = ux500_musb_interrupt; | 67 | musb->isr = ux500_musb_interrupt; |
@@ -108,7 +108,7 @@ static int ux500_probe(struct platform_device *pdev) | |||
108 | goto err3; | 108 | goto err3; |
109 | } | 109 | } |
110 | 110 | ||
111 | ret = clk_enable(clk); | 111 | ret = clk_prepare_enable(clk); |
112 | if (ret) { | 112 | if (ret) { |
113 | dev_err(&pdev->dev, "failed to enable clock\n"); | 113 | dev_err(&pdev->dev, "failed to enable clock\n"); |
114 | goto err4; | 114 | goto err4; |
@@ -148,7 +148,7 @@ static int ux500_probe(struct platform_device *pdev) | |||
148 | return 0; | 148 | return 0; |
149 | 149 | ||
150 | err5: | 150 | err5: |
151 | clk_disable(clk); | 151 | clk_disable_unprepare(clk); |
152 | 152 | ||
153 | err4: | 153 | err4: |
154 | clk_put(clk); | 154 | clk_put(clk); |
@@ -168,7 +168,7 @@ static int ux500_remove(struct platform_device *pdev) | |||
168 | struct ux500_glue *glue = platform_get_drvdata(pdev); | 168 | struct ux500_glue *glue = platform_get_drvdata(pdev); |
169 | 169 | ||
170 | platform_device_unregister(glue->musb); | 170 | platform_device_unregister(glue->musb); |
171 | clk_disable(glue->clk); | 171 | clk_disable_unprepare(glue->clk); |
172 | clk_put(glue->clk); | 172 | clk_put(glue->clk); |
173 | kfree(glue); | 173 | kfree(glue); |
174 | 174 | ||
@@ -182,7 +182,7 @@ static int ux500_suspend(struct device *dev) | |||
182 | struct musb *musb = glue_to_musb(glue); | 182 | struct musb *musb = glue_to_musb(glue); |
183 | 183 | ||
184 | usb_phy_set_suspend(musb->xceiv, 1); | 184 | usb_phy_set_suspend(musb->xceiv, 1); |
185 | clk_disable(glue->clk); | 185 | clk_disable_unprepare(glue->clk); |
186 | 186 | ||
187 | return 0; | 187 | return 0; |
188 | } | 188 | } |
@@ -193,7 +193,7 @@ static int ux500_resume(struct device *dev) | |||
193 | struct musb *musb = glue_to_musb(glue); | 193 | struct musb *musb = glue_to_musb(glue); |
194 | int ret; | 194 | int ret; |
195 | 195 | ||
196 | ret = clk_enable(glue->clk); | 196 | ret = clk_prepare_enable(glue->clk); |
197 | if (ret) { | 197 | if (ret) { |
198 | dev_err(dev, "failed to enable clock\n"); | 198 | dev_err(dev, "failed to enable clock\n"); |
199 | return ret; | 199 | return ret; |
diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c index eace975991a8..b6a9be31133b 100644 --- a/drivers/usb/otg/mv_otg.c +++ b/drivers/usb/otg/mv_otg.c | |||
@@ -420,7 +420,7 @@ static void mv_otg_work(struct work_struct *work) | |||
420 | struct usb_otg *otg; | 420 | struct usb_otg *otg; |
421 | int old_state; | 421 | int old_state; |
422 | 422 | ||
423 | mvotg = container_of((struct delayed_work *)work, struct mv_otg, work); | 423 | mvotg = container_of(to_delayed_work(work), struct mv_otg, work); |
424 | 424 | ||
425 | run: | 425 | run: |
426 | /* work queue is single thread, or we need spin_lock to protect */ | 426 | /* work queue is single thread, or we need spin_lock to protect */ |
@@ -662,18 +662,9 @@ static struct attribute_group inputs_attr_group = { | |||
662 | int mv_otg_remove(struct platform_device *pdev) | 662 | int mv_otg_remove(struct platform_device *pdev) |
663 | { | 663 | { |
664 | struct mv_otg *mvotg = platform_get_drvdata(pdev); | 664 | struct mv_otg *mvotg = platform_get_drvdata(pdev); |
665 | int clk_i; | ||
666 | 665 | ||
667 | sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group); | 666 | sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group); |
668 | 667 | ||
669 | if (mvotg->irq) | ||
670 | free_irq(mvotg->irq, mvotg); | ||
671 | |||
672 | if (mvotg->pdata->vbus) | ||
673 | free_irq(mvotg->pdata->vbus->irq, mvotg); | ||
674 | if (mvotg->pdata->id) | ||
675 | free_irq(mvotg->pdata->id->irq, mvotg); | ||
676 | |||
677 | if (mvotg->qwork) { | 668 | if (mvotg->qwork) { |
678 | flush_workqueue(mvotg->qwork); | 669 | flush_workqueue(mvotg->qwork); |
679 | destroy_workqueue(mvotg->qwork); | 670 | destroy_workqueue(mvotg->qwork); |
@@ -681,21 +672,9 @@ int mv_otg_remove(struct platform_device *pdev) | |||
681 | 672 | ||
682 | mv_otg_disable(mvotg); | 673 | mv_otg_disable(mvotg); |
683 | 674 | ||
684 | if (mvotg->cap_regs) | ||
685 | iounmap(mvotg->cap_regs); | ||
686 | |||
687 | if (mvotg->phy_regs) | ||
688 | iounmap(mvotg->phy_regs); | ||
689 | |||
690 | for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++) | ||
691 | clk_put(mvotg->clk[clk_i]); | ||
692 | |||
693 | usb_remove_phy(&mvotg->phy); | 675 | usb_remove_phy(&mvotg->phy); |
694 | platform_set_drvdata(pdev, NULL); | 676 | platform_set_drvdata(pdev, NULL); |
695 | 677 | ||
696 | kfree(mvotg->phy.otg); | ||
697 | kfree(mvotg); | ||
698 | |||
699 | return 0; | 678 | return 0; |
700 | } | 679 | } |
701 | 680 | ||
@@ -714,17 +693,15 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
714 | } | 693 | } |
715 | 694 | ||
716 | size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum; | 695 | size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum; |
717 | mvotg = kzalloc(size, GFP_KERNEL); | 696 | mvotg = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
718 | if (!mvotg) { | 697 | if (!mvotg) { |
719 | dev_err(&pdev->dev, "failed to allocate memory!\n"); | 698 | dev_err(&pdev->dev, "failed to allocate memory!\n"); |
720 | return -ENOMEM; | 699 | return -ENOMEM; |
721 | } | 700 | } |
722 | 701 | ||
723 | otg = kzalloc(sizeof *otg, GFP_KERNEL); | 702 | otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); |
724 | if (!otg) { | 703 | if (!otg) |
725 | kfree(mvotg); | ||
726 | return -ENOMEM; | 704 | return -ENOMEM; |
727 | } | ||
728 | 705 | ||
729 | platform_set_drvdata(pdev, mvotg); | 706 | platform_set_drvdata(pdev, mvotg); |
730 | 707 | ||
@@ -733,18 +710,18 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
733 | 710 | ||
734 | mvotg->clknum = pdata->clknum; | 711 | mvotg->clknum = pdata->clknum; |
735 | for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) { | 712 | for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) { |
736 | mvotg->clk[clk_i] = clk_get(&pdev->dev, pdata->clkname[clk_i]); | 713 | mvotg->clk[clk_i] = devm_clk_get(&pdev->dev, |
714 | pdata->clkname[clk_i]); | ||
737 | if (IS_ERR(mvotg->clk[clk_i])) { | 715 | if (IS_ERR(mvotg->clk[clk_i])) { |
738 | retval = PTR_ERR(mvotg->clk[clk_i]); | 716 | retval = PTR_ERR(mvotg->clk[clk_i]); |
739 | goto err_put_clk; | 717 | return retval; |
740 | } | 718 | } |
741 | } | 719 | } |
742 | 720 | ||
743 | mvotg->qwork = create_singlethread_workqueue("mv_otg_queue"); | 721 | mvotg->qwork = create_singlethread_workqueue("mv_otg_queue"); |
744 | if (!mvotg->qwork) { | 722 | if (!mvotg->qwork) { |
745 | dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n"); | 723 | dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n"); |
746 | retval = -ENOMEM; | 724 | return -ENOMEM; |
747 | goto err_put_clk; | ||
748 | } | 725 | } |
749 | 726 | ||
750 | INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); | 727 | INIT_DELAYED_WORK(&mvotg->work, mv_otg_work); |
@@ -772,7 +749,7 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
772 | goto err_destroy_workqueue; | 749 | goto err_destroy_workqueue; |
773 | } | 750 | } |
774 | 751 | ||
775 | mvotg->phy_regs = ioremap(r->start, resource_size(r)); | 752 | mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); |
776 | if (mvotg->phy_regs == NULL) { | 753 | if (mvotg->phy_regs == NULL) { |
777 | dev_err(&pdev->dev, "failed to map phy I/O memory\n"); | 754 | dev_err(&pdev->dev, "failed to map phy I/O memory\n"); |
778 | retval = -EFAULT; | 755 | retval = -EFAULT; |
@@ -784,21 +761,21 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
784 | if (r == NULL) { | 761 | if (r == NULL) { |
785 | dev_err(&pdev->dev, "no I/O memory resource defined\n"); | 762 | dev_err(&pdev->dev, "no I/O memory resource defined\n"); |
786 | retval = -ENODEV; | 763 | retval = -ENODEV; |
787 | goto err_unmap_phyreg; | 764 | goto err_destroy_workqueue; |
788 | } | 765 | } |
789 | 766 | ||
790 | mvotg->cap_regs = ioremap(r->start, resource_size(r)); | 767 | mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); |
791 | if (mvotg->cap_regs == NULL) { | 768 | if (mvotg->cap_regs == NULL) { |
792 | dev_err(&pdev->dev, "failed to map I/O memory\n"); | 769 | dev_err(&pdev->dev, "failed to map I/O memory\n"); |
793 | retval = -EFAULT; | 770 | retval = -EFAULT; |
794 | goto err_unmap_phyreg; | 771 | goto err_destroy_workqueue; |
795 | } | 772 | } |
796 | 773 | ||
797 | /* we will acces controller register, so enable the udc controller */ | 774 | /* we will acces controller register, so enable the udc controller */ |
798 | retval = mv_otg_enable_internal(mvotg); | 775 | retval = mv_otg_enable_internal(mvotg); |
799 | if (retval) { | 776 | if (retval) { |
800 | dev_err(&pdev->dev, "mv otg enable error %d\n", retval); | 777 | dev_err(&pdev->dev, "mv otg enable error %d\n", retval); |
801 | goto err_unmap_capreg; | 778 | goto err_destroy_workqueue; |
802 | } | 779 | } |
803 | 780 | ||
804 | mvotg->op_regs = | 781 | mvotg->op_regs = |
@@ -806,9 +783,9 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
806 | + (readl(mvotg->cap_regs) & CAPLENGTH_MASK)); | 783 | + (readl(mvotg->cap_regs) & CAPLENGTH_MASK)); |
807 | 784 | ||
808 | if (pdata->id) { | 785 | if (pdata->id) { |
809 | retval = request_threaded_irq(pdata->id->irq, NULL, | 786 | retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq, |
810 | mv_otg_inputs_irq, | 787 | NULL, mv_otg_inputs_irq, |
811 | IRQF_ONESHOT, "id", mvotg); | 788 | IRQF_ONESHOT, "id", mvotg); |
812 | if (retval) { | 789 | if (retval) { |
813 | dev_info(&pdev->dev, | 790 | dev_info(&pdev->dev, |
814 | "Failed to request irq for ID\n"); | 791 | "Failed to request irq for ID\n"); |
@@ -818,9 +795,9 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
818 | 795 | ||
819 | if (pdata->vbus) { | 796 | if (pdata->vbus) { |
820 | mvotg->clock_gating = 1; | 797 | mvotg->clock_gating = 1; |
821 | retval = request_threaded_irq(pdata->vbus->irq, NULL, | 798 | retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq, |
822 | mv_otg_inputs_irq, | 799 | NULL, mv_otg_inputs_irq, |
823 | IRQF_ONESHOT, "vbus", mvotg); | 800 | IRQF_ONESHOT, "vbus", mvotg); |
824 | if (retval) { | 801 | if (retval) { |
825 | dev_info(&pdev->dev, | 802 | dev_info(&pdev->dev, |
826 | "Failed to request irq for VBUS, " | 803 | "Failed to request irq for VBUS, " |
@@ -844,7 +821,7 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
844 | } | 821 | } |
845 | 822 | ||
846 | mvotg->irq = r->start; | 823 | mvotg->irq = r->start; |
847 | if (request_irq(mvotg->irq, mv_otg_irq, IRQF_SHARED, | 824 | if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED, |
848 | driver_name, mvotg)) { | 825 | driver_name, mvotg)) { |
849 | dev_err(&pdev->dev, "Request irq %d for OTG failed\n", | 826 | dev_err(&pdev->dev, "Request irq %d for OTG failed\n", |
850 | mvotg->irq); | 827 | mvotg->irq); |
@@ -857,14 +834,14 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
857 | if (retval < 0) { | 834 | if (retval < 0) { |
858 | dev_err(&pdev->dev, "can't register transceiver, %d\n", | 835 | dev_err(&pdev->dev, "can't register transceiver, %d\n", |
859 | retval); | 836 | retval); |
860 | goto err_free_irq; | 837 | goto err_disable_clk; |
861 | } | 838 | } |
862 | 839 | ||
863 | retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group); | 840 | retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group); |
864 | if (retval < 0) { | 841 | if (retval < 0) { |
865 | dev_dbg(&pdev->dev, | 842 | dev_dbg(&pdev->dev, |
866 | "Can't register sysfs attr group: %d\n", retval); | 843 | "Can't register sysfs attr group: %d\n", retval); |
867 | goto err_set_transceiver; | 844 | goto err_remove_phy; |
868 | } | 845 | } |
869 | 846 | ||
870 | spin_lock_init(&mvotg->wq_lock); | 847 | spin_lock_init(&mvotg->wq_lock); |
@@ -879,30 +856,15 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
879 | 856 | ||
880 | return 0; | 857 | return 0; |
881 | 858 | ||
882 | err_set_transceiver: | 859 | err_remove_phy: |
883 | usb_remove_phy(&mvotg->phy); | 860 | usb_remove_phy(&mvotg->phy); |
884 | err_free_irq: | ||
885 | free_irq(mvotg->irq, mvotg); | ||
886 | err_disable_clk: | 861 | err_disable_clk: |
887 | if (pdata->vbus) | ||
888 | free_irq(pdata->vbus->irq, mvotg); | ||
889 | if (pdata->id) | ||
890 | free_irq(pdata->id->irq, mvotg); | ||
891 | mv_otg_disable_internal(mvotg); | 862 | mv_otg_disable_internal(mvotg); |
892 | err_unmap_capreg: | ||
893 | iounmap(mvotg->cap_regs); | ||
894 | err_unmap_phyreg: | ||
895 | iounmap(mvotg->phy_regs); | ||
896 | err_destroy_workqueue: | 863 | err_destroy_workqueue: |
897 | flush_workqueue(mvotg->qwork); | 864 | flush_workqueue(mvotg->qwork); |
898 | destroy_workqueue(mvotg->qwork); | 865 | destroy_workqueue(mvotg->qwork); |
899 | err_put_clk: | ||
900 | for (clk_i--; clk_i >= 0; clk_i--) | ||
901 | clk_put(mvotg->clk[clk_i]); | ||
902 | 866 | ||
903 | platform_set_drvdata(pdev, NULL); | 867 | platform_set_drvdata(pdev, NULL); |
904 | kfree(otg); | ||
905 | kfree(mvotg); | ||
906 | 868 | ||
907 | return retval; | 869 | return retval; |
908 | } | 870 | } |
diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index 60df28a294b7..b0d9f119c749 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c | |||
@@ -76,6 +76,25 @@ static void mxs_phy_shutdown(struct usb_phy *phy) | |||
76 | clk_disable_unprepare(mxs_phy->clk); | 76 | clk_disable_unprepare(mxs_phy->clk); |
77 | } | 77 | } |
78 | 78 | ||
79 | static int mxs_phy_suspend(struct usb_phy *x, int suspend) | ||
80 | { | ||
81 | struct mxs_phy *mxs_phy = to_mxs_phy(x); | ||
82 | |||
83 | if (suspend) { | ||
84 | writel_relaxed(0xffffffff, x->io_priv + HW_USBPHY_PWD); | ||
85 | writel_relaxed(BM_USBPHY_CTRL_CLKGATE, | ||
86 | x->io_priv + HW_USBPHY_CTRL_SET); | ||
87 | clk_disable_unprepare(mxs_phy->clk); | ||
88 | } else { | ||
89 | clk_prepare_enable(mxs_phy->clk); | ||
90 | writel_relaxed(BM_USBPHY_CTRL_CLKGATE, | ||
91 | x->io_priv + HW_USBPHY_CTRL_CLR); | ||
92 | writel_relaxed(0, x->io_priv + HW_USBPHY_PWD); | ||
93 | } | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
79 | static int mxs_phy_on_connect(struct usb_phy *phy, | 98 | static int mxs_phy_on_connect(struct usb_phy *phy, |
80 | enum usb_device_speed speed) | 99 | enum usb_device_speed speed) |
81 | { | 100 | { |
@@ -137,6 +156,7 @@ static int mxs_phy_probe(struct platform_device *pdev) | |||
137 | mxs_phy->phy.label = DRIVER_NAME; | 156 | mxs_phy->phy.label = DRIVER_NAME; |
138 | mxs_phy->phy.init = mxs_phy_init; | 157 | mxs_phy->phy.init = mxs_phy_init; |
139 | mxs_phy->phy.shutdown = mxs_phy_shutdown; | 158 | mxs_phy->phy.shutdown = mxs_phy_shutdown; |
159 | mxs_phy->phy.set_suspend = mxs_phy_suspend; | ||
140 | mxs_phy->phy.notify_connect = mxs_phy_on_connect; | 160 | mxs_phy->phy.notify_connect = mxs_phy_on_connect; |
141 | mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; | 161 | mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; |
142 | 162 | ||
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index a30c04115115..e1814397ca3a 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c | |||
@@ -13,11 +13,14 @@ | |||
13 | #include <linux/export.h> | 13 | #include <linux/export.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/module.h> | ||
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/of.h> | ||
17 | 19 | ||
18 | #include <linux/usb/otg.h> | 20 | #include <linux/usb/otg.h> |
19 | 21 | ||
20 | static LIST_HEAD(phy_list); | 22 | static LIST_HEAD(phy_list); |
23 | static LIST_HEAD(phy_bind_list); | ||
21 | static DEFINE_SPINLOCK(phy_lock); | 24 | static DEFINE_SPINLOCK(phy_lock); |
22 | 25 | ||
23 | static struct usb_phy *__usb_find_phy(struct list_head *list, | 26 | static struct usb_phy *__usb_find_phy(struct list_head *list, |
@@ -35,6 +38,38 @@ static struct usb_phy *__usb_find_phy(struct list_head *list, | |||
35 | return ERR_PTR(-ENODEV); | 38 | return ERR_PTR(-ENODEV); |
36 | } | 39 | } |
37 | 40 | ||
41 | static struct usb_phy *__usb_find_phy_dev(struct device *dev, | ||
42 | struct list_head *list, u8 index) | ||
43 | { | ||
44 | struct usb_phy_bind *phy_bind = NULL; | ||
45 | |||
46 | list_for_each_entry(phy_bind, list, list) { | ||
47 | if (!(strcmp(phy_bind->dev_name, dev_name(dev))) && | ||
48 | phy_bind->index == index) { | ||
49 | if (phy_bind->phy) | ||
50 | return phy_bind->phy; | ||
51 | else | ||
52 | return ERR_PTR(-EPROBE_DEFER); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | return ERR_PTR(-ENODEV); | ||
57 | } | ||
58 | |||
59 | static struct usb_phy *__of_usb_find_phy(struct device_node *node) | ||
60 | { | ||
61 | struct usb_phy *phy; | ||
62 | |||
63 | list_for_each_entry(phy, &phy_list, head) { | ||
64 | if (node != phy->dev->of_node) | ||
65 | continue; | ||
66 | |||
67 | return phy; | ||
68 | } | ||
69 | |||
70 | return ERR_PTR(-ENODEV); | ||
71 | } | ||
72 | |||
38 | static void devm_usb_phy_release(struct device *dev, void *res) | 73 | static void devm_usb_phy_release(struct device *dev, void *res) |
39 | { | 74 | { |
40 | struct usb_phy *phy = *(struct usb_phy **)res; | 75 | struct usb_phy *phy = *(struct usb_phy **)res; |
@@ -110,6 +145,133 @@ err0: | |||
110 | } | 145 | } |
111 | EXPORT_SYMBOL(usb_get_phy); | 146 | EXPORT_SYMBOL(usb_get_phy); |
112 | 147 | ||
148 | /** | ||
149 | * devm_usb_get_phy_by_phandle - find the USB PHY by phandle | ||
150 | * @dev - device that requests this phy | ||
151 | * @phandle - name of the property holding the phy phandle value | ||
152 | * @index - the index of the phy | ||
153 | * | ||
154 | * Returns the phy driver associated with the given phandle value, | ||
155 | * after getting a refcount to it, -ENODEV if there is no such phy or | ||
156 | * -EPROBE_DEFER if there is a phandle to the phy, but the device is | ||
157 | * not yet loaded. While at that, it also associates the device with | ||
158 | * the phy using devres. On driver detach, release function is invoked | ||
159 | * on the devres data, then, devres data is freed. | ||
160 | * | ||
161 | * For use by USB host and peripheral drivers. | ||
162 | */ | ||
163 | struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, | ||
164 | const char *phandle, u8 index) | ||
165 | { | ||
166 | struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr; | ||
167 | unsigned long flags; | ||
168 | struct device_node *node; | ||
169 | |||
170 | if (!dev->of_node) { | ||
171 | dev_dbg(dev, "device does not have a device node entry\n"); | ||
172 | return ERR_PTR(-EINVAL); | ||
173 | } | ||
174 | |||
175 | node = of_parse_phandle(dev->of_node, phandle, index); | ||
176 | if (!node) { | ||
177 | dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, | ||
178 | dev->of_node->full_name); | ||
179 | return ERR_PTR(-ENODEV); | ||
180 | } | ||
181 | |||
182 | ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); | ||
183 | if (!ptr) { | ||
184 | dev_dbg(dev, "failed to allocate memory for devres\n"); | ||
185 | goto err0; | ||
186 | } | ||
187 | |||
188 | spin_lock_irqsave(&phy_lock, flags); | ||
189 | |||
190 | phy = __of_usb_find_phy(node); | ||
191 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { | ||
192 | phy = ERR_PTR(-EPROBE_DEFER); | ||
193 | devres_free(ptr); | ||
194 | goto err1; | ||
195 | } | ||
196 | |||
197 | *ptr = phy; | ||
198 | devres_add(dev, ptr); | ||
199 | |||
200 | get_device(phy->dev); | ||
201 | |||
202 | err1: | ||
203 | spin_unlock_irqrestore(&phy_lock, flags); | ||
204 | |||
205 | err0: | ||
206 | of_node_put(node); | ||
207 | |||
208 | return phy; | ||
209 | } | ||
210 | EXPORT_SYMBOL(devm_usb_get_phy_by_phandle); | ||
211 | |||
212 | /** | ||
213 | * usb_get_phy_dev - find the USB PHY | ||
214 | * @dev - device that requests this phy | ||
215 | * @index - the index of the phy | ||
216 | * | ||
217 | * Returns the phy driver, after getting a refcount to it; or | ||
218 | * -ENODEV if there is no such phy. The caller is responsible for | ||
219 | * calling usb_put_phy() to release that count. | ||
220 | * | ||
221 | * For use by USB host and peripheral drivers. | ||
222 | */ | ||
223 | struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) | ||
224 | { | ||
225 | struct usb_phy *phy = NULL; | ||
226 | unsigned long flags; | ||
227 | |||
228 | spin_lock_irqsave(&phy_lock, flags); | ||
229 | |||
230 | phy = __usb_find_phy_dev(dev, &phy_bind_list, index); | ||
231 | if (IS_ERR(phy)) { | ||
232 | pr_err("unable to find transceiver\n"); | ||
233 | goto err0; | ||
234 | } | ||
235 | |||
236 | get_device(phy->dev); | ||
237 | |||
238 | err0: | ||
239 | spin_unlock_irqrestore(&phy_lock, flags); | ||
240 | |||
241 | return phy; | ||
242 | } | ||
243 | EXPORT_SYMBOL(usb_get_phy_dev); | ||
244 | |||
245 | /** | ||
246 | * devm_usb_get_phy_dev - find the USB PHY using device ptr and index | ||
247 | * @dev - device that requests this phy | ||
248 | * @index - the index of the phy | ||
249 | * | ||
250 | * Gets the phy using usb_get_phy_dev(), and associates a device with it using | ||
251 | * devres. On driver detach, release function is invoked on the devres data, | ||
252 | * then, devres data is freed. | ||
253 | * | ||
254 | * For use by USB host and peripheral drivers. | ||
255 | */ | ||
256 | struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) | ||
257 | { | ||
258 | struct usb_phy **ptr, *phy; | ||
259 | |||
260 | ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); | ||
261 | if (!ptr) | ||
262 | return NULL; | ||
263 | |||
264 | phy = usb_get_phy_dev(dev, index); | ||
265 | if (!IS_ERR(phy)) { | ||
266 | *ptr = phy; | ||
267 | devres_add(dev, ptr); | ||
268 | } else | ||
269 | devres_free(ptr); | ||
270 | |||
271 | return phy; | ||
272 | } | ||
273 | EXPORT_SYMBOL(devm_usb_get_phy_dev); | ||
274 | |||
113 | /** | 275 | /** |
114 | * devm_usb_put_phy - release the USB PHY | 276 | * devm_usb_put_phy - release the USB PHY |
115 | * @dev - device that wants to release this phy | 277 | * @dev - device that wants to release this phy |
@@ -185,6 +347,36 @@ out: | |||
185 | EXPORT_SYMBOL(usb_add_phy); | 347 | EXPORT_SYMBOL(usb_add_phy); |
186 | 348 | ||
187 | /** | 349 | /** |
350 | * usb_add_phy_dev - declare the USB PHY | ||
351 | * @x: the USB phy to be used; or NULL | ||
352 | * | ||
353 | * This call is exclusively for use by phy drivers, which | ||
354 | * coordinate the activities of drivers for host and peripheral | ||
355 | * controllers, and in some cases for VBUS current regulation. | ||
356 | */ | ||
357 | int usb_add_phy_dev(struct usb_phy *x) | ||
358 | { | ||
359 | struct usb_phy_bind *phy_bind; | ||
360 | unsigned long flags; | ||
361 | |||
362 | if (!x->dev) { | ||
363 | dev_err(x->dev, "no device provided for PHY\n"); | ||
364 | return -EINVAL; | ||
365 | } | ||
366 | |||
367 | spin_lock_irqsave(&phy_lock, flags); | ||
368 | list_for_each_entry(phy_bind, &phy_bind_list, list) | ||
369 | if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev)))) | ||
370 | phy_bind->phy = x; | ||
371 | |||
372 | list_add_tail(&x->head, &phy_list); | ||
373 | |||
374 | spin_unlock_irqrestore(&phy_lock, flags); | ||
375 | return 0; | ||
376 | } | ||
377 | EXPORT_SYMBOL(usb_add_phy_dev); | ||
378 | |||
379 | /** | ||
188 | * usb_remove_phy - remove the OTG PHY | 380 | * usb_remove_phy - remove the OTG PHY |
189 | * @x: the USB OTG PHY to be removed; | 381 | * @x: the USB OTG PHY to be removed; |
190 | * | 382 | * |
@@ -193,14 +385,55 @@ EXPORT_SYMBOL(usb_add_phy); | |||
193 | void usb_remove_phy(struct usb_phy *x) | 385 | void usb_remove_phy(struct usb_phy *x) |
194 | { | 386 | { |
195 | unsigned long flags; | 387 | unsigned long flags; |
388 | struct usb_phy_bind *phy_bind; | ||
196 | 389 | ||
197 | spin_lock_irqsave(&phy_lock, flags); | 390 | spin_lock_irqsave(&phy_lock, flags); |
198 | if (x) | 391 | if (x) { |
392 | list_for_each_entry(phy_bind, &phy_bind_list, list) | ||
393 | if (phy_bind->phy == x) | ||
394 | phy_bind->phy = NULL; | ||
199 | list_del(&x->head); | 395 | list_del(&x->head); |
396 | } | ||
200 | spin_unlock_irqrestore(&phy_lock, flags); | 397 | spin_unlock_irqrestore(&phy_lock, flags); |
201 | } | 398 | } |
202 | EXPORT_SYMBOL(usb_remove_phy); | 399 | EXPORT_SYMBOL(usb_remove_phy); |
203 | 400 | ||
401 | /** | ||
402 | * usb_bind_phy - bind the phy and the controller that uses the phy | ||
403 | * @dev_name: the device name of the device that will bind to the phy | ||
404 | * @index: index to specify the port number | ||
405 | * @phy_dev_name: the device name of the phy | ||
406 | * | ||
407 | * Fills the phy_bind structure with the dev_name and phy_dev_name. This will | ||
408 | * be used when the phy driver registers the phy and when the controller | ||
409 | * requests this phy. | ||
410 | * | ||
411 | * To be used by platform specific initialization code. | ||
412 | */ | ||
413 | int __init usb_bind_phy(const char *dev_name, u8 index, | ||
414 | const char *phy_dev_name) | ||
415 | { | ||
416 | struct usb_phy_bind *phy_bind; | ||
417 | unsigned long flags; | ||
418 | |||
419 | phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL); | ||
420 | if (!phy_bind) { | ||
421 | pr_err("phy_bind(): No memory for phy_bind"); | ||
422 | return -ENOMEM; | ||
423 | } | ||
424 | |||
425 | phy_bind->dev_name = dev_name; | ||
426 | phy_bind->phy_dev_name = phy_dev_name; | ||
427 | phy_bind->index = index; | ||
428 | |||
429 | spin_lock_irqsave(&phy_lock, flags); | ||
430 | list_add_tail(&phy_bind->list, &phy_bind_list); | ||
431 | spin_unlock_irqrestore(&phy_lock, flags); | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | EXPORT_SYMBOL_GPL(usb_bind_phy); | ||
436 | |||
204 | const char *otg_state_string(enum usb_otg_state state) | 437 | const char *otg_state_string(enum usb_otg_state state) |
205 | { | 438 | { |
206 | switch (state) { | 439 | switch (state) { |
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 0a701938ab53..a994715a3101 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -610,6 +610,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
610 | twl->phy.dev = twl->dev; | 610 | twl->phy.dev = twl->dev; |
611 | twl->phy.label = "twl4030"; | 611 | twl->phy.label = "twl4030"; |
612 | twl->phy.otg = otg; | 612 | twl->phy.otg = otg; |
613 | twl->phy.type = USB_PHY_TYPE_USB2; | ||
613 | twl->phy.set_suspend = twl4030_set_suspend; | 614 | twl->phy.set_suspend = twl4030_set_suspend; |
614 | 615 | ||
615 | otg->phy = &twl->phy; | 616 | otg->phy = &twl->phy; |
@@ -624,7 +625,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
624 | dev_err(&pdev->dev, "ldo init failed\n"); | 625 | dev_err(&pdev->dev, "ldo init failed\n"); |
625 | return err; | 626 | return err; |
626 | } | 627 | } |
627 | usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); | 628 | usb_add_phy_dev(&twl->phy); |
628 | 629 | ||
629 | platform_set_drvdata(pdev, twl); | 630 | platform_set_drvdata(pdev, twl); |
630 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 631 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 5de6e7f39f9c..65217a590068 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig | |||
@@ -8,12 +8,32 @@ config OMAP_USB2 | |||
8 | tristate "OMAP USB2 PHY Driver" | 8 | tristate "OMAP USB2 PHY Driver" |
9 | depends on ARCH_OMAP2PLUS | 9 | depends on ARCH_OMAP2PLUS |
10 | select USB_OTG_UTILS | 10 | select USB_OTG_UTILS |
11 | select OMAP_CONTROL_USB | ||
11 | help | 12 | help |
12 | Enable this to support the transceiver that is part of SOC. This | 13 | Enable this to support the transceiver that is part of SOC. This |
13 | driver takes care of all the PHY functionality apart from comparator. | 14 | driver takes care of all the PHY functionality apart from comparator. |
14 | The USB OTG controller communicates with the comparator using this | 15 | The USB OTG controller communicates with the comparator using this |
15 | driver. | 16 | driver. |
16 | 17 | ||
18 | config OMAP_USB3 | ||
19 | tristate "OMAP USB3 PHY Driver" | ||
20 | select USB_OTG_UTILS | ||
21 | select OMAP_CONTROL_USB | ||
22 | help | ||
23 | Enable this to support the USB3 PHY that is part of SOC. This | ||
24 | driver takes care of all the PHY functionality apart from comparator. | ||
25 | This driver interacts with the "OMAP Control USB Driver" to power | ||
26 | on/off the PHY. | ||
27 | |||
28 | config OMAP_CONTROL_USB | ||
29 | tristate "OMAP CONTROL USB Driver" | ||
30 | help | ||
31 | Enable this to add support for the USB part present in the control | ||
32 | module. This driver has API to power on the USB2 PHY and to write to | ||
33 | the mailbox. The mailbox is present only in omap4 and the register to | ||
34 | power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an | ||
35 | additional register to power on USB3 PHY. | ||
36 | |||
17 | config USB_ISP1301 | 37 | config USB_ISP1301 |
18 | tristate "NXP ISP1301 USB transceiver support" | 38 | tristate "NXP ISP1301 USB transceiver support" |
19 | depends on USB || USB_GADGET | 39 | depends on USB || USB_GADGET |
@@ -45,3 +65,11 @@ config USB_RCAR_PHY | |||
45 | 65 | ||
46 | To compile this driver as a module, choose M here: the | 66 | To compile this driver as a module, choose M here: the |
47 | module will be called rcar-phy. | 67 | module will be called rcar-phy. |
68 | |||
69 | config SAMSUNG_USBPHY | ||
70 | bool "Samsung USB PHY controller Driver" | ||
71 | depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS | ||
72 | select USB_OTG_UTILS | ||
73 | help | ||
74 | Enable this to support Samsung USB phy controller for samsung | ||
75 | SoCs. | ||
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 1a579a860a03..b13faa193e0c 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile | |||
@@ -5,7 +5,10 @@ | |||
5 | ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG | 5 | ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG |
6 | 6 | ||
7 | obj-$(CONFIG_OMAP_USB2) += omap-usb2.o | 7 | obj-$(CONFIG_OMAP_USB2) += omap-usb2.o |
8 | obj-$(CONFIG_OMAP_USB3) += omap-usb3.o | ||
9 | obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o | ||
8 | obj-$(CONFIG_USB_ISP1301) += isp1301.o | 10 | obj-$(CONFIG_USB_ISP1301) += isp1301.o |
9 | obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o | 11 | obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o |
10 | obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o | 12 | obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o |
11 | obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o | 13 | obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o |
14 | obj-$(CONFIG_SAMSUNG_USBPHY) += samsung-usbphy.o | ||
diff --git a/drivers/usb/phy/omap-control-usb.c b/drivers/usb/phy/omap-control-usb.c new file mode 100644 index 000000000000..5323b71c3521 --- /dev/null +++ b/drivers/usb/phy/omap-control-usb.c | |||
@@ -0,0 +1,295 @@ | |||
1 | /* | ||
2 | * omap-control-usb.c - The USB part of control module. | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/usb/omap_control_usb.h> | ||
27 | |||
28 | static struct omap_control_usb *control_usb; | ||
29 | |||
30 | /** | ||
31 | * omap_get_control_dev - returns the device pointer for this control device | ||
32 | * | ||
33 | * This API should be called to get the device pointer for this control | ||
34 | * module device. This device pointer should be used for called other | ||
35 | * exported API's in this driver. | ||
36 | * | ||
37 | * To be used by PHY driver and glue driver. | ||
38 | */ | ||
39 | struct device *omap_get_control_dev(void) | ||
40 | { | ||
41 | if (!control_usb) | ||
42 | return ERR_PTR(-ENODEV); | ||
43 | |||
44 | return control_usb->dev; | ||
45 | } | ||
46 | EXPORT_SYMBOL_GPL(omap_get_control_dev); | ||
47 | |||
48 | /** | ||
49 | * omap_control_usb3_phy_power - power on/off the serializer using control | ||
50 | * module | ||
51 | * @dev: the control module device | ||
52 | * @on: 0 to off and 1 to on based on powering on or off the PHY | ||
53 | * | ||
54 | * usb3 PHY driver should call this API to power on or off the PHY. | ||
55 | */ | ||
56 | void omap_control_usb3_phy_power(struct device *dev, bool on) | ||
57 | { | ||
58 | u32 val; | ||
59 | unsigned long rate; | ||
60 | struct omap_control_usb *control_usb = dev_get_drvdata(dev); | ||
61 | |||
62 | if (control_usb->type != OMAP_CTRL_DEV_TYPE2) | ||
63 | return; | ||
64 | |||
65 | rate = clk_get_rate(control_usb->sys_clk); | ||
66 | rate = rate/1000000; | ||
67 | |||
68 | val = readl(control_usb->phy_power); | ||
69 | |||
70 | if (on) { | ||
71 | val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK | | ||
72 | OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK); | ||
73 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON << | ||
74 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | ||
75 | val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT; | ||
76 | } else { | ||
77 | val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK; | ||
78 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << | ||
79 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | ||
80 | } | ||
81 | |||
82 | writel(val, control_usb->phy_power); | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power); | ||
85 | |||
86 | /** | ||
87 | * omap_control_usb_phy_power - power on/off the phy using control module reg | ||
88 | * @dev: the control module device | ||
89 | * @on: 0 or 1, based on powering on or off the PHY | ||
90 | */ | ||
91 | void omap_control_usb_phy_power(struct device *dev, int on) | ||
92 | { | ||
93 | u32 val; | ||
94 | struct omap_control_usb *control_usb = dev_get_drvdata(dev); | ||
95 | |||
96 | val = readl(control_usb->dev_conf); | ||
97 | |||
98 | if (on) | ||
99 | val &= ~OMAP_CTRL_DEV_PHY_PD; | ||
100 | else | ||
101 | val |= OMAP_CTRL_DEV_PHY_PD; | ||
102 | |||
103 | writel(val, control_usb->dev_conf); | ||
104 | } | ||
105 | EXPORT_SYMBOL_GPL(omap_control_usb_phy_power); | ||
106 | |||
107 | /** | ||
108 | * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded | ||
109 | * @ctrl_usb: struct omap_control_usb * | ||
110 | * | ||
111 | * Writes to the mailbox register to notify the usb core that a usb | ||
112 | * device has been connected. | ||
113 | */ | ||
114 | static void omap_control_usb_host_mode(struct omap_control_usb *ctrl_usb) | ||
115 | { | ||
116 | u32 val; | ||
117 | |||
118 | val = readl(ctrl_usb->otghs_control); | ||
119 | val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); | ||
120 | val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; | ||
121 | writel(val, ctrl_usb->otghs_control); | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high | ||
126 | * impedance | ||
127 | * @ctrl_usb: struct omap_control_usb * | ||
128 | * | ||
129 | * Writes to the mailbox register to notify the usb core that it has been | ||
130 | * connected to a usb host. | ||
131 | */ | ||
132 | static void omap_control_usb_device_mode(struct omap_control_usb *ctrl_usb) | ||
133 | { | ||
134 | u32 val; | ||
135 | |||
136 | val = readl(ctrl_usb->otghs_control); | ||
137 | val &= ~OMAP_CTRL_DEV_SESSEND; | ||
138 | val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | | ||
139 | OMAP_CTRL_DEV_VBUSVALID; | ||
140 | writel(val, ctrl_usb->otghs_control); | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high | ||
145 | * impedance | ||
146 | * @ctrl_usb: struct omap_control_usb * | ||
147 | * | ||
148 | * Writes to the mailbox register to notify the usb core it's now in | ||
149 | * disconnected state. | ||
150 | */ | ||
151 | static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb) | ||
152 | { | ||
153 | u32 val; | ||
154 | |||
155 | val = readl(ctrl_usb->otghs_control); | ||
156 | val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); | ||
157 | val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; | ||
158 | writel(val, ctrl_usb->otghs_control); | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * omap_control_usb_set_mode - Calls to functions to set USB in one of host mode | ||
163 | * or device mode or to denote disconnected state | ||
164 | * @dev: the control module device | ||
165 | * @mode: The mode to which usb should be configured | ||
166 | * | ||
167 | * This is an API to write to the mailbox register to notify the usb core that | ||
168 | * a usb device has been connected. | ||
169 | */ | ||
170 | void omap_control_usb_set_mode(struct device *dev, | ||
171 | enum omap_control_usb_mode mode) | ||
172 | { | ||
173 | struct omap_control_usb *ctrl_usb; | ||
174 | |||
175 | if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1) | ||
176 | return; | ||
177 | |||
178 | ctrl_usb = dev_get_drvdata(dev); | ||
179 | |||
180 | switch (mode) { | ||
181 | case USB_MODE_HOST: | ||
182 | omap_control_usb_host_mode(ctrl_usb); | ||
183 | break; | ||
184 | case USB_MODE_DEVICE: | ||
185 | omap_control_usb_device_mode(ctrl_usb); | ||
186 | break; | ||
187 | case USB_MODE_DISCONNECT: | ||
188 | omap_control_usb_set_sessionend(ctrl_usb); | ||
189 | break; | ||
190 | default: | ||
191 | dev_vdbg(dev, "invalid omap control usb mode\n"); | ||
192 | } | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); | ||
195 | |||
196 | static int omap_control_usb_probe(struct platform_device *pdev) | ||
197 | { | ||
198 | struct resource *res; | ||
199 | struct device_node *np = pdev->dev.of_node; | ||
200 | struct omap_control_usb_platform_data *pdata = pdev->dev.platform_data; | ||
201 | |||
202 | control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb), | ||
203 | GFP_KERNEL); | ||
204 | if (!control_usb) { | ||
205 | dev_err(&pdev->dev, "unable to alloc memory for control usb\n"); | ||
206 | return -ENOMEM; | ||
207 | } | ||
208 | |||
209 | if (np) { | ||
210 | of_property_read_u32(np, "ti,type", &control_usb->type); | ||
211 | } else if (pdata) { | ||
212 | control_usb->type = pdata->type; | ||
213 | } else { | ||
214 | dev_err(&pdev->dev, "no pdata present\n"); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | control_usb->dev = &pdev->dev; | ||
219 | |||
220 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
221 | "control_dev_conf"); | ||
222 | control_usb->dev_conf = devm_request_and_ioremap(&pdev->dev, res); | ||
223 | if (!control_usb->dev_conf) { | ||
224 | dev_err(&pdev->dev, "Failed to obtain io memory\n"); | ||
225 | return -EADDRNOTAVAIL; | ||
226 | } | ||
227 | |||
228 | if (control_usb->type == OMAP_CTRL_DEV_TYPE1) { | ||
229 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
230 | "otghs_control"); | ||
231 | control_usb->otghs_control = devm_request_and_ioremap( | ||
232 | &pdev->dev, res); | ||
233 | if (!control_usb->otghs_control) { | ||
234 | dev_err(&pdev->dev, "Failed to obtain io memory\n"); | ||
235 | return -EADDRNOTAVAIL; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | if (control_usb->type == OMAP_CTRL_DEV_TYPE2) { | ||
240 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
241 | "phy_power_usb"); | ||
242 | control_usb->phy_power = devm_request_and_ioremap( | ||
243 | &pdev->dev, res); | ||
244 | if (!control_usb->phy_power) { | ||
245 | dev_dbg(&pdev->dev, "Failed to obtain io memory\n"); | ||
246 | return -EADDRNOTAVAIL; | ||
247 | } | ||
248 | |||
249 | control_usb->sys_clk = devm_clk_get(control_usb->dev, | ||
250 | "sys_clkin"); | ||
251 | if (IS_ERR(control_usb->sys_clk)) { | ||
252 | pr_err("%s: unable to get sys_clkin\n", __func__); | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | dev_set_drvdata(control_usb->dev, control_usb); | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | #ifdef CONFIG_OF | ||
264 | static const struct of_device_id omap_control_usb_id_table[] = { | ||
265 | { .compatible = "ti,omap-control-usb" }, | ||
266 | {} | ||
267 | }; | ||
268 | MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); | ||
269 | #endif | ||
270 | |||
271 | static struct platform_driver omap_control_usb_driver = { | ||
272 | .probe = omap_control_usb_probe, | ||
273 | .driver = { | ||
274 | .name = "omap-control-usb", | ||
275 | .owner = THIS_MODULE, | ||
276 | .of_match_table = of_match_ptr(omap_control_usb_id_table), | ||
277 | }, | ||
278 | }; | ||
279 | |||
280 | static int __init omap_control_usb_init(void) | ||
281 | { | ||
282 | return platform_driver_register(&omap_control_usb_driver); | ||
283 | } | ||
284 | subsys_initcall(omap_control_usb_init); | ||
285 | |||
286 | static void __exit omap_control_usb_exit(void) | ||
287 | { | ||
288 | platform_driver_unregister(&omap_control_usb_driver); | ||
289 | } | ||
290 | module_exit(omap_control_usb_exit); | ||
291 | |||
292 | MODULE_ALIAS("platform: omap_control_usb"); | ||
293 | MODULE_AUTHOR("Texas Instruments Inc."); | ||
294 | MODULE_DESCRIPTION("OMAP Control Module USB Driver"); | ||
295 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c index 2fdb8ede5f1c..844ab68f08d0 100644 --- a/drivers/usb/phy/omap-usb2.c +++ b/drivers/usb/phy/omap-usb2.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/usb/omap_control_usb.h> | ||
30 | 31 | ||
31 | /** | 32 | /** |
32 | * omap_usb2_set_comparator - links the comparator present in the sytem with | 33 | * omap_usb2_set_comparator - links the comparator present in the sytem with |
@@ -52,29 +53,6 @@ int omap_usb2_set_comparator(struct phy_companion *comparator) | |||
52 | } | 53 | } |
53 | EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); | 54 | EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); |
54 | 55 | ||
55 | /** | ||
56 | * omap_usb_phy_power - power on/off the phy using control module reg | ||
57 | * @phy: struct omap_usb * | ||
58 | * @on: 0 or 1, based on powering on or off the PHY | ||
59 | * | ||
60 | * XXX: Remove this function once control module driver gets merged | ||
61 | */ | ||
62 | static void omap_usb_phy_power(struct omap_usb *phy, int on) | ||
63 | { | ||
64 | u32 val; | ||
65 | |||
66 | if (on) { | ||
67 | val = readl(phy->control_dev); | ||
68 | if (val & PHY_PD) { | ||
69 | writel(~PHY_PD, phy->control_dev); | ||
70 | /* XXX: add proper documentation for this delay */ | ||
71 | mdelay(200); | ||
72 | } | ||
73 | } else { | ||
74 | writel(PHY_PD, phy->control_dev); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) | 56 | static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) |
79 | { | 57 | { |
80 | struct omap_usb *phy = phy_to_omapusb(otg->phy); | 58 | struct omap_usb *phy = phy_to_omapusb(otg->phy); |
@@ -124,7 +102,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend) | |||
124 | struct omap_usb *phy = phy_to_omapusb(x); | 102 | struct omap_usb *phy = phy_to_omapusb(x); |
125 | 103 | ||
126 | if (suspend && !phy->is_suspended) { | 104 | if (suspend && !phy->is_suspended) { |
127 | omap_usb_phy_power(phy, 0); | 105 | omap_control_usb_phy_power(phy->control_dev, 0); |
128 | pm_runtime_put_sync(phy->dev); | 106 | pm_runtime_put_sync(phy->dev); |
129 | phy->is_suspended = 1; | 107 | phy->is_suspended = 1; |
130 | } else if (!suspend && phy->is_suspended) { | 108 | } else if (!suspend && phy->is_suspended) { |
@@ -134,7 +112,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend) | |||
134 | ret); | 112 | ret); |
135 | return ret; | 113 | return ret; |
136 | } | 114 | } |
137 | omap_usb_phy_power(phy, 1); | 115 | omap_control_usb_phy_power(phy->control_dev, 1); |
138 | phy->is_suspended = 0; | 116 | phy->is_suspended = 0; |
139 | } | 117 | } |
140 | 118 | ||
@@ -145,7 +123,6 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
145 | { | 123 | { |
146 | struct omap_usb *phy; | 124 | struct omap_usb *phy; |
147 | struct usb_otg *otg; | 125 | struct usb_otg *otg; |
148 | struct resource *res; | ||
149 | 126 | ||
150 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); | 127 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); |
151 | if (!phy) { | 128 | if (!phy) { |
@@ -165,15 +142,16 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
165 | phy->phy.label = "omap-usb2"; | 142 | phy->phy.label = "omap-usb2"; |
166 | phy->phy.set_suspend = omap_usb2_suspend; | 143 | phy->phy.set_suspend = omap_usb2_suspend; |
167 | phy->phy.otg = otg; | 144 | phy->phy.otg = otg; |
145 | phy->phy.type = USB_PHY_TYPE_USB2; | ||
168 | 146 | ||
169 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 147 | phy->control_dev = omap_get_control_dev(); |
170 | 148 | if (IS_ERR(phy->control_dev)) { | |
171 | phy->control_dev = devm_ioremap_resource(&pdev->dev, res); | 149 | dev_dbg(&pdev->dev, "Failed to get control device\n"); |
172 | if (IS_ERR(phy->control_dev)) | 150 | return -ENODEV; |
173 | return PTR_ERR(phy->control_dev); | 151 | } |
174 | 152 | ||
175 | phy->is_suspended = 1; | 153 | phy->is_suspended = 1; |
176 | omap_usb_phy_power(phy, 0); | 154 | omap_control_usb_phy_power(phy->control_dev, 0); |
177 | 155 | ||
178 | otg->set_host = omap_usb_set_host; | 156 | otg->set_host = omap_usb_set_host; |
179 | otg->set_peripheral = omap_usb_set_peripheral; | 157 | otg->set_peripheral = omap_usb_set_peripheral; |
@@ -188,7 +166,13 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
188 | } | 166 | } |
189 | clk_prepare(phy->wkupclk); | 167 | clk_prepare(phy->wkupclk); |
190 | 168 | ||
191 | usb_add_phy(&phy->phy, USB_PHY_TYPE_USB2); | 169 | phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); |
170 | if (IS_ERR(phy->optclk)) | ||
171 | dev_vdbg(&pdev->dev, "unable to get refclk960m\n"); | ||
172 | else | ||
173 | clk_prepare(phy->optclk); | ||
174 | |||
175 | usb_add_phy_dev(&phy->phy); | ||
192 | 176 | ||
193 | platform_set_drvdata(pdev, phy); | 177 | platform_set_drvdata(pdev, phy); |
194 | 178 | ||
@@ -202,6 +186,8 @@ static int omap_usb2_remove(struct platform_device *pdev) | |||
202 | struct omap_usb *phy = platform_get_drvdata(pdev); | 186 | struct omap_usb *phy = platform_get_drvdata(pdev); |
203 | 187 | ||
204 | clk_unprepare(phy->wkupclk); | 188 | clk_unprepare(phy->wkupclk); |
189 | if (!IS_ERR(phy->optclk)) | ||
190 | clk_unprepare(phy->optclk); | ||
205 | usb_remove_phy(&phy->phy); | 191 | usb_remove_phy(&phy->phy); |
206 | 192 | ||
207 | return 0; | 193 | return 0; |
@@ -215,6 +201,8 @@ static int omap_usb2_runtime_suspend(struct device *dev) | |||
215 | struct omap_usb *phy = platform_get_drvdata(pdev); | 201 | struct omap_usb *phy = platform_get_drvdata(pdev); |
216 | 202 | ||
217 | clk_disable(phy->wkupclk); | 203 | clk_disable(phy->wkupclk); |
204 | if (!IS_ERR(phy->optclk)) | ||
205 | clk_disable(phy->optclk); | ||
218 | 206 | ||
219 | return 0; | 207 | return 0; |
220 | } | 208 | } |
@@ -226,9 +214,25 @@ static int omap_usb2_runtime_resume(struct device *dev) | |||
226 | struct omap_usb *phy = platform_get_drvdata(pdev); | 214 | struct omap_usb *phy = platform_get_drvdata(pdev); |
227 | 215 | ||
228 | ret = clk_enable(phy->wkupclk); | 216 | ret = clk_enable(phy->wkupclk); |
229 | if (ret < 0) | 217 | if (ret < 0) { |
230 | dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); | 218 | dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); |
219 | goto err0; | ||
220 | } | ||
221 | |||
222 | if (!IS_ERR(phy->optclk)) { | ||
223 | ret = clk_enable(phy->optclk); | ||
224 | if (ret < 0) { | ||
225 | dev_err(phy->dev, "Failed to enable optclk %d\n", ret); | ||
226 | goto err1; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | return 0; | ||
231 | |||
232 | err1: | ||
233 | clk_disable(phy->wkupclk); | ||
231 | 234 | ||
235 | err0: | ||
232 | return ret; | 236 | return ret; |
233 | } | 237 | } |
234 | 238 | ||
diff --git a/drivers/usb/phy/omap-usb3.c b/drivers/usb/phy/omap-usb3.c new file mode 100644 index 000000000000..fadc0c2b65bb --- /dev/null +++ b/drivers/usb/phy/omap-usb3.c | |||
@@ -0,0 +1,355 @@ | |||
1 | /* | ||
2 | * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP. | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/usb/omap_usb.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/clk.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/pm_runtime.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/usb/omap_control_usb.h> | ||
29 | |||
30 | #define NUM_SYS_CLKS 5 | ||
31 | #define PLL_STATUS 0x00000004 | ||
32 | #define PLL_GO 0x00000008 | ||
33 | #define PLL_CONFIGURATION1 0x0000000C | ||
34 | #define PLL_CONFIGURATION2 0x00000010 | ||
35 | #define PLL_CONFIGURATION3 0x00000014 | ||
36 | #define PLL_CONFIGURATION4 0x00000020 | ||
37 | |||
38 | #define PLL_REGM_MASK 0x001FFE00 | ||
39 | #define PLL_REGM_SHIFT 0x9 | ||
40 | #define PLL_REGM_F_MASK 0x0003FFFF | ||
41 | #define PLL_REGM_F_SHIFT 0x0 | ||
42 | #define PLL_REGN_MASK 0x000001FE | ||
43 | #define PLL_REGN_SHIFT 0x1 | ||
44 | #define PLL_SELFREQDCO_MASK 0x0000000E | ||
45 | #define PLL_SELFREQDCO_SHIFT 0x1 | ||
46 | #define PLL_SD_MASK 0x0003FC00 | ||
47 | #define PLL_SD_SHIFT 0x9 | ||
48 | #define SET_PLL_GO 0x1 | ||
49 | #define PLL_TICOPWDN 0x10000 | ||
50 | #define PLL_LOCK 0x2 | ||
51 | #define PLL_IDLE 0x1 | ||
52 | |||
53 | /* | ||
54 | * This is an Empirical value that works, need to confirm the actual | ||
55 | * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status | ||
56 | * to be correctly reflected in the USB3PHY_PLL_STATUS register. | ||
57 | */ | ||
58 | # define PLL_IDLE_TIME 100; | ||
59 | |||
60 | enum sys_clk_rate { | ||
61 | CLK_RATE_UNDEFINED = -1, | ||
62 | CLK_RATE_12MHZ, | ||
63 | CLK_RATE_16MHZ, | ||
64 | CLK_RATE_19MHZ, | ||
65 | CLK_RATE_26MHZ, | ||
66 | CLK_RATE_38MHZ | ||
67 | }; | ||
68 | |||
69 | static struct usb_dpll_params omap_usb3_dpll_params[NUM_SYS_CLKS] = { | ||
70 | {1250, 5, 4, 20, 0}, /* 12 MHz */ | ||
71 | {3125, 20, 4, 20, 0}, /* 16.8 MHz */ | ||
72 | {1172, 8, 4, 20, 65537}, /* 19.2 MHz */ | ||
73 | {1250, 12, 4, 20, 0}, /* 26 MHz */ | ||
74 | {3125, 47, 4, 20, 92843}, /* 38.4 MHz */ | ||
75 | }; | ||
76 | |||
77 | static int omap_usb3_suspend(struct usb_phy *x, int suspend) | ||
78 | { | ||
79 | struct omap_usb *phy = phy_to_omapusb(x); | ||
80 | int val; | ||
81 | int timeout = PLL_IDLE_TIME; | ||
82 | |||
83 | if (suspend && !phy->is_suspended) { | ||
84 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
85 | val |= PLL_IDLE; | ||
86 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
87 | |||
88 | do { | ||
89 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
90 | if (val & PLL_TICOPWDN) | ||
91 | break; | ||
92 | udelay(1); | ||
93 | } while (--timeout); | ||
94 | |||
95 | omap_control_usb3_phy_power(phy->control_dev, 0); | ||
96 | |||
97 | phy->is_suspended = 1; | ||
98 | } else if (!suspend && phy->is_suspended) { | ||
99 | phy->is_suspended = 0; | ||
100 | |||
101 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
102 | val &= ~PLL_IDLE; | ||
103 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
104 | |||
105 | do { | ||
106 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
107 | if (!(val & PLL_TICOPWDN)) | ||
108 | break; | ||
109 | udelay(1); | ||
110 | } while (--timeout); | ||
111 | } | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static inline enum sys_clk_rate __get_sys_clk_index(unsigned long rate) | ||
117 | { | ||
118 | switch (rate) { | ||
119 | case 12000000: | ||
120 | return CLK_RATE_12MHZ; | ||
121 | case 16800000: | ||
122 | return CLK_RATE_16MHZ; | ||
123 | case 19200000: | ||
124 | return CLK_RATE_19MHZ; | ||
125 | case 26000000: | ||
126 | return CLK_RATE_26MHZ; | ||
127 | case 38400000: | ||
128 | return CLK_RATE_38MHZ; | ||
129 | default: | ||
130 | return CLK_RATE_UNDEFINED; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void omap_usb_dpll_relock(struct omap_usb *phy) | ||
135 | { | ||
136 | u32 val; | ||
137 | unsigned long timeout; | ||
138 | |||
139 | omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); | ||
140 | |||
141 | timeout = jiffies + msecs_to_jiffies(20); | ||
142 | do { | ||
143 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
144 | if (val & PLL_LOCK) | ||
145 | break; | ||
146 | } while (!WARN_ON(time_after(jiffies, timeout))); | ||
147 | } | ||
148 | |||
149 | static int omap_usb_dpll_lock(struct omap_usb *phy) | ||
150 | { | ||
151 | u32 val; | ||
152 | unsigned long rate; | ||
153 | enum sys_clk_rate clk_index; | ||
154 | |||
155 | rate = clk_get_rate(phy->sys_clk); | ||
156 | clk_index = __get_sys_clk_index(rate); | ||
157 | |||
158 | if (clk_index == CLK_RATE_UNDEFINED) { | ||
159 | pr_err("dpll cannot be locked for sys clk freq:%luHz\n", rate); | ||
160 | return -EINVAL; | ||
161 | } | ||
162 | |||
163 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); | ||
164 | val &= ~PLL_REGN_MASK; | ||
165 | val |= omap_usb3_dpll_params[clk_index].n << PLL_REGN_SHIFT; | ||
166 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); | ||
167 | |||
168 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
169 | val &= ~PLL_SELFREQDCO_MASK; | ||
170 | val |= omap_usb3_dpll_params[clk_index].freq << PLL_SELFREQDCO_SHIFT; | ||
171 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
172 | |||
173 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); | ||
174 | val &= ~PLL_REGM_MASK; | ||
175 | val |= omap_usb3_dpll_params[clk_index].m << PLL_REGM_SHIFT; | ||
176 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); | ||
177 | |||
178 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); | ||
179 | val &= ~PLL_REGM_F_MASK; | ||
180 | val |= omap_usb3_dpll_params[clk_index].mf << PLL_REGM_F_SHIFT; | ||
181 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); | ||
182 | |||
183 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); | ||
184 | val &= ~PLL_SD_MASK; | ||
185 | val |= omap_usb3_dpll_params[clk_index].sd << PLL_SD_SHIFT; | ||
186 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); | ||
187 | |||
188 | omap_usb_dpll_relock(phy); | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int omap_usb3_init(struct usb_phy *x) | ||
194 | { | ||
195 | struct omap_usb *phy = phy_to_omapusb(x); | ||
196 | |||
197 | omap_usb_dpll_lock(phy); | ||
198 | omap_control_usb3_phy_power(phy->control_dev, 1); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int omap_usb3_probe(struct platform_device *pdev) | ||
204 | { | ||
205 | struct omap_usb *phy; | ||
206 | struct resource *res; | ||
207 | |||
208 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); | ||
209 | if (!phy) { | ||
210 | dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n"); | ||
211 | return -ENOMEM; | ||
212 | } | ||
213 | |||
214 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); | ||
215 | phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); | ||
216 | if (!phy->pll_ctrl_base) { | ||
217 | dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n"); | ||
218 | return -ENOMEM; | ||
219 | } | ||
220 | |||
221 | phy->dev = &pdev->dev; | ||
222 | |||
223 | phy->phy.dev = phy->dev; | ||
224 | phy->phy.label = "omap-usb3"; | ||
225 | phy->phy.init = omap_usb3_init; | ||
226 | phy->phy.set_suspend = omap_usb3_suspend; | ||
227 | phy->phy.type = USB_PHY_TYPE_USB3; | ||
228 | |||
229 | phy->is_suspended = 1; | ||
230 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); | ||
231 | if (IS_ERR(phy->wkupclk)) { | ||
232 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); | ||
233 | return PTR_ERR(phy->wkupclk); | ||
234 | } | ||
235 | clk_prepare(phy->wkupclk); | ||
236 | |||
237 | phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); | ||
238 | if (IS_ERR(phy->optclk)) { | ||
239 | dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); | ||
240 | return PTR_ERR(phy->optclk); | ||
241 | } | ||
242 | clk_prepare(phy->optclk); | ||
243 | |||
244 | phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); | ||
245 | if (IS_ERR(phy->sys_clk)) { | ||
246 | pr_err("%s: unable to get sys_clkin\n", __func__); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | phy->control_dev = omap_get_control_dev(); | ||
251 | if (IS_ERR(phy->control_dev)) { | ||
252 | dev_dbg(&pdev->dev, "Failed to get control device\n"); | ||
253 | return -ENODEV; | ||
254 | } | ||
255 | |||
256 | omap_control_usb3_phy_power(phy->control_dev, 0); | ||
257 | usb_add_phy_dev(&phy->phy); | ||
258 | |||
259 | platform_set_drvdata(pdev, phy); | ||
260 | |||
261 | pm_runtime_enable(phy->dev); | ||
262 | pm_runtime_get(&pdev->dev); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int omap_usb3_remove(struct platform_device *pdev) | ||
268 | { | ||
269 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
270 | |||
271 | clk_unprepare(phy->wkupclk); | ||
272 | clk_unprepare(phy->optclk); | ||
273 | usb_remove_phy(&phy->phy); | ||
274 | if (!pm_runtime_suspended(&pdev->dev)) | ||
275 | pm_runtime_put(&pdev->dev); | ||
276 | pm_runtime_disable(&pdev->dev); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | #ifdef CONFIG_PM_RUNTIME | ||
282 | |||
283 | static int omap_usb3_runtime_suspend(struct device *dev) | ||
284 | { | ||
285 | struct platform_device *pdev = to_platform_device(dev); | ||
286 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
287 | |||
288 | clk_disable(phy->wkupclk); | ||
289 | clk_disable(phy->optclk); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int omap_usb3_runtime_resume(struct device *dev) | ||
295 | { | ||
296 | u32 ret = 0; | ||
297 | struct platform_device *pdev = to_platform_device(dev); | ||
298 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
299 | |||
300 | ret = clk_enable(phy->optclk); | ||
301 | if (ret) { | ||
302 | dev_err(phy->dev, "Failed to enable optclk %d\n", ret); | ||
303 | goto err1; | ||
304 | } | ||
305 | |||
306 | ret = clk_enable(phy->wkupclk); | ||
307 | if (ret) { | ||
308 | dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); | ||
309 | goto err2; | ||
310 | } | ||
311 | |||
312 | return 0; | ||
313 | |||
314 | err2: | ||
315 | clk_disable(phy->optclk); | ||
316 | |||
317 | err1: | ||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | static const struct dev_pm_ops omap_usb3_pm_ops = { | ||
322 | SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume, | ||
323 | NULL) | ||
324 | }; | ||
325 | |||
326 | #define DEV_PM_OPS (&omap_usb3_pm_ops) | ||
327 | #else | ||
328 | #define DEV_PM_OPS NULL | ||
329 | #endif | ||
330 | |||
331 | #ifdef CONFIG_OF | ||
332 | static const struct of_device_id omap_usb3_id_table[] = { | ||
333 | { .compatible = "ti,omap-usb3" }, | ||
334 | {} | ||
335 | }; | ||
336 | MODULE_DEVICE_TABLE(of, omap_usb3_id_table); | ||
337 | #endif | ||
338 | |||
339 | static struct platform_driver omap_usb3_driver = { | ||
340 | .probe = omap_usb3_probe, | ||
341 | .remove = omap_usb3_remove, | ||
342 | .driver = { | ||
343 | .name = "omap-usb3", | ||
344 | .owner = THIS_MODULE, | ||
345 | .pm = DEV_PM_OPS, | ||
346 | .of_match_table = of_match_ptr(omap_usb3_id_table), | ||
347 | }, | ||
348 | }; | ||
349 | |||
350 | module_platform_driver(omap_usb3_driver); | ||
351 | |||
352 | MODULE_ALIAS("platform: omap_usb3"); | ||
353 | MODULE_AUTHOR("Texas Instruments Inc."); | ||
354 | MODULE_DESCRIPTION("OMAP USB3 phy driver"); | ||
355 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c new file mode 100644 index 000000000000..6ea553733832 --- /dev/null +++ b/drivers/usb/phy/samsung-usbphy.c | |||
@@ -0,0 +1,930 @@ | |||
1 | /* linux/drivers/usb/phy/samsung-usbphy.c | ||
2 | * | ||
3 | * Copyright (c) 2012 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * Author: Praveen Paneri <p.paneri@samsung.com> | ||
7 | * | ||
8 | * Samsung USB2.0 PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and | ||
9 | * OHCI-EXYNOS controllers. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/of.h> | ||
29 | #include <linux/of_address.h> | ||
30 | #include <linux/usb/otg.h> | ||
31 | #include <linux/usb/samsung_usb_phy.h> | ||
32 | #include <linux/platform_data/samsung-usbphy.h> | ||
33 | |||
34 | /* Register definitions */ | ||
35 | |||
36 | #define SAMSUNG_PHYPWR (0x00) | ||
37 | |||
38 | #define PHYPWR_NORMAL_MASK (0x19 << 0) | ||
39 | #define PHYPWR_OTG_DISABLE (0x1 << 4) | ||
40 | #define PHYPWR_ANALOG_POWERDOWN (0x1 << 3) | ||
41 | #define PHYPWR_FORCE_SUSPEND (0x1 << 1) | ||
42 | /* For Exynos4 */ | ||
43 | #define PHYPWR_NORMAL_MASK_PHY0 (0x39 << 0) | ||
44 | #define PHYPWR_SLEEP_PHY0 (0x1 << 5) | ||
45 | |||
46 | #define SAMSUNG_PHYCLK (0x04) | ||
47 | |||
48 | #define PHYCLK_MODE_USB11 (0x1 << 6) | ||
49 | #define PHYCLK_EXT_OSC (0x1 << 5) | ||
50 | #define PHYCLK_COMMON_ON_N (0x1 << 4) | ||
51 | #define PHYCLK_ID_PULL (0x1 << 2) | ||
52 | #define PHYCLK_CLKSEL_MASK (0x3 << 0) | ||
53 | #define PHYCLK_CLKSEL_48M (0x0 << 0) | ||
54 | #define PHYCLK_CLKSEL_12M (0x2 << 0) | ||
55 | #define PHYCLK_CLKSEL_24M (0x3 << 0) | ||
56 | |||
57 | #define SAMSUNG_RSTCON (0x08) | ||
58 | |||
59 | #define RSTCON_PHYLINK_SWRST (0x1 << 2) | ||
60 | #define RSTCON_HLINK_SWRST (0x1 << 1) | ||
61 | #define RSTCON_SWRST (0x1 << 0) | ||
62 | |||
63 | /* EXYNOS5 */ | ||
64 | #define EXYNOS5_PHY_HOST_CTRL0 (0x00) | ||
65 | |||
66 | #define HOST_CTRL0_PHYSWRSTALL (0x1 << 31) | ||
67 | |||
68 | #define HOST_CTRL0_REFCLKSEL_MASK (0x3 << 19) | ||
69 | #define HOST_CTRL0_REFCLKSEL_XTAL (0x0 << 19) | ||
70 | #define HOST_CTRL0_REFCLKSEL_EXTL (0x1 << 19) | ||
71 | #define HOST_CTRL0_REFCLKSEL_CLKCORE (0x2 << 19) | ||
72 | |||
73 | #define HOST_CTRL0_FSEL_MASK (0x7 << 16) | ||
74 | #define HOST_CTRL0_FSEL(_x) ((_x) << 16) | ||
75 | |||
76 | #define FSEL_CLKSEL_50M (0x7) | ||
77 | #define FSEL_CLKSEL_24M (0x5) | ||
78 | #define FSEL_CLKSEL_20M (0x4) | ||
79 | #define FSEL_CLKSEL_19200K (0x3) | ||
80 | #define FSEL_CLKSEL_12M (0x2) | ||
81 | #define FSEL_CLKSEL_10M (0x1) | ||
82 | #define FSEL_CLKSEL_9600K (0x0) | ||
83 | |||
84 | #define HOST_CTRL0_TESTBURNIN (0x1 << 11) | ||
85 | #define HOST_CTRL0_RETENABLE (0x1 << 10) | ||
86 | #define HOST_CTRL0_COMMONON_N (0x1 << 9) | ||
87 | #define HOST_CTRL0_SIDDQ (0x1 << 6) | ||
88 | #define HOST_CTRL0_FORCESLEEP (0x1 << 5) | ||
89 | #define HOST_CTRL0_FORCESUSPEND (0x1 << 4) | ||
90 | #define HOST_CTRL0_WORDINTERFACE (0x1 << 3) | ||
91 | #define HOST_CTRL0_UTMISWRST (0x1 << 2) | ||
92 | #define HOST_CTRL0_LINKSWRST (0x1 << 1) | ||
93 | #define HOST_CTRL0_PHYSWRST (0x1 << 0) | ||
94 | |||
95 | #define EXYNOS5_PHY_HOST_TUNE0 (0x04) | ||
96 | |||
97 | #define EXYNOS5_PHY_HSIC_CTRL1 (0x10) | ||
98 | |||
99 | #define EXYNOS5_PHY_HSIC_TUNE1 (0x14) | ||
100 | |||
101 | #define EXYNOS5_PHY_HSIC_CTRL2 (0x20) | ||
102 | |||
103 | #define EXYNOS5_PHY_HSIC_TUNE2 (0x24) | ||
104 | |||
105 | #define HSIC_CTRL_REFCLKSEL_MASK (0x3 << 23) | ||
106 | #define HSIC_CTRL_REFCLKSEL (0x2 << 23) | ||
107 | |||
108 | #define HSIC_CTRL_REFCLKDIV_MASK (0x7f << 16) | ||
109 | #define HSIC_CTRL_REFCLKDIV(_x) ((_x) << 16) | ||
110 | #define HSIC_CTRL_REFCLKDIV_12 (0x24 << 16) | ||
111 | #define HSIC_CTRL_REFCLKDIV_15 (0x1c << 16) | ||
112 | #define HSIC_CTRL_REFCLKDIV_16 (0x1a << 16) | ||
113 | #define HSIC_CTRL_REFCLKDIV_19_2 (0x15 << 16) | ||
114 | #define HSIC_CTRL_REFCLKDIV_20 (0x14 << 16) | ||
115 | |||
116 | #define HSIC_CTRL_SIDDQ (0x1 << 6) | ||
117 | #define HSIC_CTRL_FORCESLEEP (0x1 << 5) | ||
118 | #define HSIC_CTRL_FORCESUSPEND (0x1 << 4) | ||
119 | #define HSIC_CTRL_WORDINTERFACE (0x1 << 3) | ||
120 | #define HSIC_CTRL_UTMISWRST (0x1 << 2) | ||
121 | #define HSIC_CTRL_PHYSWRST (0x1 << 0) | ||
122 | |||
123 | #define EXYNOS5_PHY_HOST_EHCICTRL (0x30) | ||
124 | |||
125 | #define HOST_EHCICTRL_ENAINCRXALIGN (0x1 << 29) | ||
126 | #define HOST_EHCICTRL_ENAINCR4 (0x1 << 28) | ||
127 | #define HOST_EHCICTRL_ENAINCR8 (0x1 << 27) | ||
128 | #define HOST_EHCICTRL_ENAINCR16 (0x1 << 26) | ||
129 | |||
130 | #define EXYNOS5_PHY_HOST_OHCICTRL (0x34) | ||
131 | |||
132 | #define HOST_OHCICTRL_SUSPLGCY (0x1 << 3) | ||
133 | #define HOST_OHCICTRL_APPSTARTCLK (0x1 << 2) | ||
134 | #define HOST_OHCICTRL_CNTSEL (0x1 << 1) | ||
135 | #define HOST_OHCICTRL_CLKCKTRST (0x1 << 0) | ||
136 | |||
137 | #define EXYNOS5_PHY_OTG_SYS (0x38) | ||
138 | |||
139 | #define OTG_SYS_PHYLINK_SWRESET (0x1 << 14) | ||
140 | #define OTG_SYS_LINKSWRST_UOTG (0x1 << 13) | ||
141 | #define OTG_SYS_PHY0_SWRST (0x1 << 12) | ||
142 | |||
143 | #define OTG_SYS_REFCLKSEL_MASK (0x3 << 9) | ||
144 | #define OTG_SYS_REFCLKSEL_XTAL (0x0 << 9) | ||
145 | #define OTG_SYS_REFCLKSEL_EXTL (0x1 << 9) | ||
146 | #define OTG_SYS_REFCLKSEL_CLKCORE (0x2 << 9) | ||
147 | |||
148 | #define OTG_SYS_IDPULLUP_UOTG (0x1 << 8) | ||
149 | #define OTG_SYS_COMMON_ON (0x1 << 7) | ||
150 | |||
151 | #define OTG_SYS_FSEL_MASK (0x7 << 4) | ||
152 | #define OTG_SYS_FSEL(_x) ((_x) << 4) | ||
153 | |||
154 | #define OTG_SYS_FORCESLEEP (0x1 << 3) | ||
155 | #define OTG_SYS_OTGDISABLE (0x1 << 2) | ||
156 | #define OTG_SYS_SIDDQ_UOTG (0x1 << 1) | ||
157 | #define OTG_SYS_FORCESUSPEND (0x1 << 0) | ||
158 | |||
159 | #define EXYNOS5_PHY_OTG_TUNE (0x40) | ||
160 | |||
161 | #ifndef MHZ | ||
162 | #define MHZ (1000*1000) | ||
163 | #endif | ||
164 | |||
165 | #ifndef KHZ | ||
166 | #define KHZ (1000) | ||
167 | #endif | ||
168 | |||
169 | #define EXYNOS_USBHOST_PHY_CTRL_OFFSET (0x4) | ||
170 | #define S3C64XX_USBPHY_ENABLE (0x1 << 16) | ||
171 | #define EXYNOS_USBPHY_ENABLE (0x1 << 0) | ||
172 | #define EXYNOS_USB20PHY_CFG_HOST_LINK (0x1 << 0) | ||
173 | |||
174 | enum samsung_cpu_type { | ||
175 | TYPE_S3C64XX, | ||
176 | TYPE_EXYNOS4210, | ||
177 | TYPE_EXYNOS5250, | ||
178 | }; | ||
179 | |||
180 | /* | ||
181 | * struct samsung_usbphy_drvdata - driver data for various SoC variants | ||
182 | * @cpu_type: machine identifier | ||
183 | * @devphy_en_mask: device phy enable mask for PHY CONTROL register | ||
184 | * @hostphy_en_mask: host phy enable mask for PHY CONTROL register | ||
185 | * @devphy_reg_offset: offset to DEVICE PHY CONTROL register from | ||
186 | * mapped address of system controller. | ||
187 | * @hostphy_reg_offset: offset to HOST PHY CONTROL register from | ||
188 | * mapped address of system controller. | ||
189 | * | ||
190 | * Here we have a separate mask for device type phy. | ||
191 | * Having different masks for host and device type phy helps | ||
192 | * in setting independent masks in case of SoCs like S5PV210, | ||
193 | * in which PHY0 and PHY1 enable bits belong to same register | ||
194 | * placed at position 0 and 1 respectively. | ||
195 | * Although for newer SoCs like exynos these bits belong to | ||
196 | * different registers altogether placed at position 0. | ||
197 | */ | ||
198 | struct samsung_usbphy_drvdata { | ||
199 | int cpu_type; | ||
200 | int devphy_en_mask; | ||
201 | int hostphy_en_mask; | ||
202 | u32 devphy_reg_offset; | ||
203 | u32 hostphy_reg_offset; | ||
204 | }; | ||
205 | |||
206 | /* | ||
207 | * struct samsung_usbphy - transceiver driver state | ||
208 | * @phy: transceiver structure | ||
209 | * @plat: platform data | ||
210 | * @dev: The parent device supplied to the probe function | ||
211 | * @clk: usb phy clock | ||
212 | * @regs: usb phy controller registers memory base | ||
213 | * @pmuregs: USB device PHY_CONTROL register memory base | ||
214 | * @sysreg: USB2.0 PHY_CFG register memory base | ||
215 | * @ref_clk_freq: reference clock frequency selection | ||
216 | * @drv_data: driver data available for different SoCs | ||
217 | * @phy_type: Samsung SoCs specific phy types: #HOST | ||
218 | * #DEVICE | ||
219 | * @phy_usage: usage count for phy | ||
220 | * @lock: lock for phy operations | ||
221 | */ | ||
222 | struct samsung_usbphy { | ||
223 | struct usb_phy phy; | ||
224 | struct samsung_usbphy_data *plat; | ||
225 | struct device *dev; | ||
226 | struct clk *clk; | ||
227 | void __iomem *regs; | ||
228 | void __iomem *pmuregs; | ||
229 | void __iomem *sysreg; | ||
230 | int ref_clk_freq; | ||
231 | const struct samsung_usbphy_drvdata *drv_data; | ||
232 | enum samsung_usb_phy_type phy_type; | ||
233 | atomic_t phy_usage; | ||
234 | spinlock_t lock; | ||
235 | }; | ||
236 | |||
237 | #define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy) | ||
238 | |||
239 | int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host) | ||
240 | { | ||
241 | if (!otg) | ||
242 | return -ENODEV; | ||
243 | |||
244 | if (!otg->host) | ||
245 | otg->host = host; | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy) | ||
251 | { | ||
252 | struct device_node *usbphy_sys; | ||
253 | |||
254 | /* Getting node for system controller interface for usb-phy */ | ||
255 | usbphy_sys = of_get_child_by_name(sphy->dev->of_node, "usbphy-sys"); | ||
256 | if (!usbphy_sys) { | ||
257 | dev_err(sphy->dev, "No sys-controller interface for usb-phy\n"); | ||
258 | return -ENODEV; | ||
259 | } | ||
260 | |||
261 | sphy->pmuregs = of_iomap(usbphy_sys, 0); | ||
262 | |||
263 | if (sphy->pmuregs == NULL) { | ||
264 | dev_err(sphy->dev, "Can't get usb-phy pmu control register\n"); | ||
265 | goto err0; | ||
266 | } | ||
267 | |||
268 | sphy->sysreg = of_iomap(usbphy_sys, 1); | ||
269 | |||
270 | /* | ||
271 | * Not returning error code here, since this situation is not fatal. | ||
272 | * Few SoCs may not have this switch available | ||
273 | */ | ||
274 | if (sphy->sysreg == NULL) | ||
275 | dev_warn(sphy->dev, "Can't get usb-phy sysreg cfg register\n"); | ||
276 | |||
277 | of_node_put(usbphy_sys); | ||
278 | |||
279 | return 0; | ||
280 | |||
281 | err0: | ||
282 | of_node_put(usbphy_sys); | ||
283 | return -ENXIO; | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | * Set isolation here for phy. | ||
288 | * Here 'on = true' would mean USB PHY block is isolated, hence | ||
289 | * de-activated and vice-versa. | ||
290 | */ | ||
291 | static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) | ||
292 | { | ||
293 | void __iomem *reg = NULL; | ||
294 | u32 reg_val; | ||
295 | u32 en_mask = 0; | ||
296 | |||
297 | if (!sphy->pmuregs) { | ||
298 | dev_warn(sphy->dev, "Can't set pmu isolation\n"); | ||
299 | return; | ||
300 | } | ||
301 | |||
302 | switch (sphy->drv_data->cpu_type) { | ||
303 | case TYPE_S3C64XX: | ||
304 | /* | ||
305 | * Do nothing: We will add here once S3C64xx goes for DT support | ||
306 | */ | ||
307 | break; | ||
308 | case TYPE_EXYNOS4210: | ||
309 | /* | ||
310 | * Fall through since exynos4210 and exynos5250 have similar | ||
311 | * register architecture: two separate registers for host and | ||
312 | * device phy control with enable bit at position 0. | ||
313 | */ | ||
314 | case TYPE_EXYNOS5250: | ||
315 | if (sphy->phy_type == USB_PHY_TYPE_DEVICE) { | ||
316 | reg = sphy->pmuregs + | ||
317 | sphy->drv_data->devphy_reg_offset; | ||
318 | en_mask = sphy->drv_data->devphy_en_mask; | ||
319 | } else if (sphy->phy_type == USB_PHY_TYPE_HOST) { | ||
320 | reg = sphy->pmuregs + | ||
321 | sphy->drv_data->hostphy_reg_offset; | ||
322 | en_mask = sphy->drv_data->hostphy_en_mask; | ||
323 | } | ||
324 | break; | ||
325 | default: | ||
326 | dev_err(sphy->dev, "Invalid SoC type\n"); | ||
327 | return; | ||
328 | } | ||
329 | |||
330 | reg_val = readl(reg); | ||
331 | |||
332 | if (on) | ||
333 | reg_val &= ~en_mask; | ||
334 | else | ||
335 | reg_val |= en_mask; | ||
336 | |||
337 | writel(reg_val, reg); | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | * Configure the mode of working of usb-phy here: HOST/DEVICE. | ||
342 | */ | ||
343 | static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy) | ||
344 | { | ||
345 | u32 reg; | ||
346 | |||
347 | if (!sphy->sysreg) { | ||
348 | dev_warn(sphy->dev, "Can't configure specified phy mode\n"); | ||
349 | return; | ||
350 | } | ||
351 | |||
352 | reg = readl(sphy->sysreg); | ||
353 | |||
354 | if (sphy->phy_type == USB_PHY_TYPE_DEVICE) | ||
355 | reg &= ~EXYNOS_USB20PHY_CFG_HOST_LINK; | ||
356 | else if (sphy->phy_type == USB_PHY_TYPE_HOST) | ||
357 | reg |= EXYNOS_USB20PHY_CFG_HOST_LINK; | ||
358 | |||
359 | writel(reg, sphy->sysreg); | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * PHYs are different for USB Device and USB Host. | ||
364 | * This make sure that correct PHY type is selected before | ||
365 | * any operation on PHY. | ||
366 | */ | ||
367 | static int samsung_usbphy_set_type(struct usb_phy *phy, | ||
368 | enum samsung_usb_phy_type phy_type) | ||
369 | { | ||
370 | struct samsung_usbphy *sphy = phy_to_sphy(phy); | ||
371 | |||
372 | sphy->phy_type = phy_type; | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | /* | ||
378 | * Returns reference clock frequency selection value | ||
379 | */ | ||
380 | static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) | ||
381 | { | ||
382 | struct clk *ref_clk; | ||
383 | int refclk_freq = 0; | ||
384 | |||
385 | /* | ||
386 | * In exynos5250 USB host and device PHY use | ||
387 | * external crystal clock XXTI | ||
388 | */ | ||
389 | if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) | ||
390 | ref_clk = clk_get(sphy->dev, "ext_xtal"); | ||
391 | else | ||
392 | ref_clk = clk_get(sphy->dev, "xusbxti"); | ||
393 | if (IS_ERR(ref_clk)) { | ||
394 | dev_err(sphy->dev, "Failed to get reference clock\n"); | ||
395 | return PTR_ERR(ref_clk); | ||
396 | } | ||
397 | |||
398 | if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) { | ||
399 | /* set clock frequency for PLL */ | ||
400 | switch (clk_get_rate(ref_clk)) { | ||
401 | case 9600 * KHZ: | ||
402 | refclk_freq = FSEL_CLKSEL_9600K; | ||
403 | break; | ||
404 | case 10 * MHZ: | ||
405 | refclk_freq = FSEL_CLKSEL_10M; | ||
406 | break; | ||
407 | case 12 * MHZ: | ||
408 | refclk_freq = FSEL_CLKSEL_12M; | ||
409 | break; | ||
410 | case 19200 * KHZ: | ||
411 | refclk_freq = FSEL_CLKSEL_19200K; | ||
412 | break; | ||
413 | case 20 * MHZ: | ||
414 | refclk_freq = FSEL_CLKSEL_20M; | ||
415 | break; | ||
416 | case 50 * MHZ: | ||
417 | refclk_freq = FSEL_CLKSEL_50M; | ||
418 | break; | ||
419 | case 24 * MHZ: | ||
420 | default: | ||
421 | /* default reference clock */ | ||
422 | refclk_freq = FSEL_CLKSEL_24M; | ||
423 | break; | ||
424 | } | ||
425 | } else { | ||
426 | switch (clk_get_rate(ref_clk)) { | ||
427 | case 12 * MHZ: | ||
428 | refclk_freq = PHYCLK_CLKSEL_12M; | ||
429 | break; | ||
430 | case 24 * MHZ: | ||
431 | refclk_freq = PHYCLK_CLKSEL_24M; | ||
432 | break; | ||
433 | case 48 * MHZ: | ||
434 | refclk_freq = PHYCLK_CLKSEL_48M; | ||
435 | break; | ||
436 | default: | ||
437 | if (sphy->drv_data->cpu_type == TYPE_S3C64XX) | ||
438 | refclk_freq = PHYCLK_CLKSEL_48M; | ||
439 | else | ||
440 | refclk_freq = PHYCLK_CLKSEL_24M; | ||
441 | break; | ||
442 | } | ||
443 | } | ||
444 | clk_put(ref_clk); | ||
445 | |||
446 | return refclk_freq; | ||
447 | } | ||
448 | |||
449 | static bool exynos5_phyhost_is_on(void *regs) | ||
450 | { | ||
451 | u32 reg; | ||
452 | |||
453 | reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0); | ||
454 | |||
455 | return !(reg & HOST_CTRL0_SIDDQ); | ||
456 | } | ||
457 | |||
458 | static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy) | ||
459 | { | ||
460 | void __iomem *regs = sphy->regs; | ||
461 | u32 phyclk = sphy->ref_clk_freq; | ||
462 | u32 phyhost; | ||
463 | u32 phyotg; | ||
464 | u32 phyhsic; | ||
465 | u32 ehcictrl; | ||
466 | u32 ohcictrl; | ||
467 | |||
468 | /* | ||
469 | * phy_usage helps in keeping usage count for phy | ||
470 | * so that the first consumer enabling the phy is also | ||
471 | * the last consumer to disable it. | ||
472 | */ | ||
473 | |||
474 | atomic_inc(&sphy->phy_usage); | ||
475 | |||
476 | if (exynos5_phyhost_is_on(regs)) { | ||
477 | dev_info(sphy->dev, "Already power on PHY\n"); | ||
478 | return; | ||
479 | } | ||
480 | |||
481 | /* Host configuration */ | ||
482 | phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); | ||
483 | |||
484 | /* phy reference clock configuration */ | ||
485 | phyhost &= ~HOST_CTRL0_FSEL_MASK; | ||
486 | phyhost |= HOST_CTRL0_FSEL(phyclk); | ||
487 | |||
488 | /* host phy reset */ | ||
489 | phyhost &= ~(HOST_CTRL0_PHYSWRST | | ||
490 | HOST_CTRL0_PHYSWRSTALL | | ||
491 | HOST_CTRL0_SIDDQ | | ||
492 | /* Enable normal mode of operation */ | ||
493 | HOST_CTRL0_FORCESUSPEND | | ||
494 | HOST_CTRL0_FORCESLEEP); | ||
495 | |||
496 | /* Link reset */ | ||
497 | phyhost |= (HOST_CTRL0_LINKSWRST | | ||
498 | HOST_CTRL0_UTMISWRST | | ||
499 | /* COMMON Block configuration during suspend */ | ||
500 | HOST_CTRL0_COMMONON_N); | ||
501 | writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); | ||
502 | udelay(10); | ||
503 | phyhost &= ~(HOST_CTRL0_LINKSWRST | | ||
504 | HOST_CTRL0_UTMISWRST); | ||
505 | writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); | ||
506 | |||
507 | /* OTG configuration */ | ||
508 | phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); | ||
509 | |||
510 | /* phy reference clock configuration */ | ||
511 | phyotg &= ~OTG_SYS_FSEL_MASK; | ||
512 | phyotg |= OTG_SYS_FSEL(phyclk); | ||
513 | |||
514 | /* Enable normal mode of operation */ | ||
515 | phyotg &= ~(OTG_SYS_FORCESUSPEND | | ||
516 | OTG_SYS_SIDDQ_UOTG | | ||
517 | OTG_SYS_FORCESLEEP | | ||
518 | OTG_SYS_REFCLKSEL_MASK | | ||
519 | /* COMMON Block configuration during suspend */ | ||
520 | OTG_SYS_COMMON_ON); | ||
521 | |||
522 | /* OTG phy & link reset */ | ||
523 | phyotg |= (OTG_SYS_PHY0_SWRST | | ||
524 | OTG_SYS_LINKSWRST_UOTG | | ||
525 | OTG_SYS_PHYLINK_SWRESET | | ||
526 | OTG_SYS_OTGDISABLE | | ||
527 | /* Set phy refclk */ | ||
528 | OTG_SYS_REFCLKSEL_CLKCORE); | ||
529 | |||
530 | writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); | ||
531 | udelay(10); | ||
532 | phyotg &= ~(OTG_SYS_PHY0_SWRST | | ||
533 | OTG_SYS_LINKSWRST_UOTG | | ||
534 | OTG_SYS_PHYLINK_SWRESET); | ||
535 | writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); | ||
536 | |||
537 | /* HSIC phy configuration */ | ||
538 | phyhsic = (HSIC_CTRL_REFCLKDIV_12 | | ||
539 | HSIC_CTRL_REFCLKSEL | | ||
540 | HSIC_CTRL_PHYSWRST); | ||
541 | writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); | ||
542 | writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); | ||
543 | udelay(10); | ||
544 | phyhsic &= ~HSIC_CTRL_PHYSWRST; | ||
545 | writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); | ||
546 | writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); | ||
547 | |||
548 | udelay(80); | ||
549 | |||
550 | /* enable EHCI DMA burst */ | ||
551 | ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL); | ||
552 | ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN | | ||
553 | HOST_EHCICTRL_ENAINCR4 | | ||
554 | HOST_EHCICTRL_ENAINCR8 | | ||
555 | HOST_EHCICTRL_ENAINCR16); | ||
556 | writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL); | ||
557 | |||
558 | /* set ohci_suspend_on_n */ | ||
559 | ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL); | ||
560 | ohcictrl |= HOST_OHCICTRL_SUSPLGCY; | ||
561 | writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL); | ||
562 | } | ||
563 | |||
564 | static void samsung_usbphy_enable(struct samsung_usbphy *sphy) | ||
565 | { | ||
566 | void __iomem *regs = sphy->regs; | ||
567 | u32 phypwr; | ||
568 | u32 phyclk; | ||
569 | u32 rstcon; | ||
570 | |||
571 | /* set clock frequency for PLL */ | ||
572 | phyclk = sphy->ref_clk_freq; | ||
573 | phypwr = readl(regs + SAMSUNG_PHYPWR); | ||
574 | rstcon = readl(regs + SAMSUNG_RSTCON); | ||
575 | |||
576 | switch (sphy->drv_data->cpu_type) { | ||
577 | case TYPE_S3C64XX: | ||
578 | phyclk &= ~PHYCLK_COMMON_ON_N; | ||
579 | phypwr &= ~PHYPWR_NORMAL_MASK; | ||
580 | rstcon |= RSTCON_SWRST; | ||
581 | break; | ||
582 | case TYPE_EXYNOS4210: | ||
583 | phypwr &= ~PHYPWR_NORMAL_MASK_PHY0; | ||
584 | rstcon |= RSTCON_SWRST; | ||
585 | default: | ||
586 | break; | ||
587 | } | ||
588 | |||
589 | writel(phyclk, regs + SAMSUNG_PHYCLK); | ||
590 | /* Configure PHY0 for normal operation*/ | ||
591 | writel(phypwr, regs + SAMSUNG_PHYPWR); | ||
592 | /* reset all ports of PHY and Link */ | ||
593 | writel(rstcon, regs + SAMSUNG_RSTCON); | ||
594 | udelay(10); | ||
595 | rstcon &= ~RSTCON_SWRST; | ||
596 | writel(rstcon, regs + SAMSUNG_RSTCON); | ||
597 | } | ||
598 | |||
599 | static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy) | ||
600 | { | ||
601 | void __iomem *regs = sphy->regs; | ||
602 | u32 phyhost; | ||
603 | u32 phyotg; | ||
604 | u32 phyhsic; | ||
605 | |||
606 | if (atomic_dec_return(&sphy->phy_usage) > 0) { | ||
607 | dev_info(sphy->dev, "still being used\n"); | ||
608 | return; | ||
609 | } | ||
610 | |||
611 | phyhsic = (HSIC_CTRL_REFCLKDIV_12 | | ||
612 | HSIC_CTRL_REFCLKSEL | | ||
613 | HSIC_CTRL_SIDDQ | | ||
614 | HSIC_CTRL_FORCESLEEP | | ||
615 | HSIC_CTRL_FORCESUSPEND); | ||
616 | writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1); | ||
617 | writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2); | ||
618 | |||
619 | phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0); | ||
620 | phyhost |= (HOST_CTRL0_SIDDQ | | ||
621 | HOST_CTRL0_FORCESUSPEND | | ||
622 | HOST_CTRL0_FORCESLEEP | | ||
623 | HOST_CTRL0_PHYSWRST | | ||
624 | HOST_CTRL0_PHYSWRSTALL); | ||
625 | writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0); | ||
626 | |||
627 | phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS); | ||
628 | phyotg |= (OTG_SYS_FORCESUSPEND | | ||
629 | OTG_SYS_SIDDQ_UOTG | | ||
630 | OTG_SYS_FORCESLEEP); | ||
631 | writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS); | ||
632 | } | ||
633 | |||
634 | static void samsung_usbphy_disable(struct samsung_usbphy *sphy) | ||
635 | { | ||
636 | void __iomem *regs = sphy->regs; | ||
637 | u32 phypwr; | ||
638 | |||
639 | phypwr = readl(regs + SAMSUNG_PHYPWR); | ||
640 | |||
641 | switch (sphy->drv_data->cpu_type) { | ||
642 | case TYPE_S3C64XX: | ||
643 | phypwr |= PHYPWR_NORMAL_MASK; | ||
644 | break; | ||
645 | case TYPE_EXYNOS4210: | ||
646 | phypwr |= PHYPWR_NORMAL_MASK_PHY0; | ||
647 | default: | ||
648 | break; | ||
649 | } | ||
650 | |||
651 | /* Disable analog and otg block power */ | ||
652 | writel(phypwr, regs + SAMSUNG_PHYPWR); | ||
653 | } | ||
654 | |||
655 | /* | ||
656 | * The function passed to the usb driver for phy initialization | ||
657 | */ | ||
658 | static int samsung_usbphy_init(struct usb_phy *phy) | ||
659 | { | ||
660 | struct samsung_usbphy *sphy; | ||
661 | struct usb_bus *host = NULL; | ||
662 | unsigned long flags; | ||
663 | int ret = 0; | ||
664 | |||
665 | sphy = phy_to_sphy(phy); | ||
666 | |||
667 | host = phy->otg->host; | ||
668 | |||
669 | /* Enable the phy clock */ | ||
670 | ret = clk_prepare_enable(sphy->clk); | ||
671 | if (ret) { | ||
672 | dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); | ||
673 | return ret; | ||
674 | } | ||
675 | |||
676 | spin_lock_irqsave(&sphy->lock, flags); | ||
677 | |||
678 | if (host) { | ||
679 | /* setting default phy-type for USB 2.0 */ | ||
680 | if (!strstr(dev_name(host->controller), "ehci") || | ||
681 | !strstr(dev_name(host->controller), "ohci")) | ||
682 | samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); | ||
683 | } else { | ||
684 | samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); | ||
685 | } | ||
686 | |||
687 | /* Disable phy isolation */ | ||
688 | if (sphy->plat && sphy->plat->pmu_isolation) | ||
689 | sphy->plat->pmu_isolation(false); | ||
690 | else | ||
691 | samsung_usbphy_set_isolation(sphy, false); | ||
692 | |||
693 | /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */ | ||
694 | samsung_usbphy_cfg_sel(sphy); | ||
695 | |||
696 | /* Initialize usb phy registers */ | ||
697 | if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) | ||
698 | samsung_exynos5_usbphy_enable(sphy); | ||
699 | else | ||
700 | samsung_usbphy_enable(sphy); | ||
701 | |||
702 | spin_unlock_irqrestore(&sphy->lock, flags); | ||
703 | |||
704 | /* Disable the phy clock */ | ||
705 | clk_disable_unprepare(sphy->clk); | ||
706 | |||
707 | return ret; | ||
708 | } | ||
709 | |||
710 | /* | ||
711 | * The function passed to the usb driver for phy shutdown | ||
712 | */ | ||
713 | static void samsung_usbphy_shutdown(struct usb_phy *phy) | ||
714 | { | ||
715 | struct samsung_usbphy *sphy; | ||
716 | struct usb_bus *host = NULL; | ||
717 | unsigned long flags; | ||
718 | |||
719 | sphy = phy_to_sphy(phy); | ||
720 | |||
721 | host = phy->otg->host; | ||
722 | |||
723 | if (clk_prepare_enable(sphy->clk)) { | ||
724 | dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); | ||
725 | return; | ||
726 | } | ||
727 | |||
728 | spin_lock_irqsave(&sphy->lock, flags); | ||
729 | |||
730 | if (host) { | ||
731 | /* setting default phy-type for USB 2.0 */ | ||
732 | if (!strstr(dev_name(host->controller), "ehci") || | ||
733 | !strstr(dev_name(host->controller), "ohci")) | ||
734 | samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); | ||
735 | } else { | ||
736 | samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); | ||
737 | } | ||
738 | |||
739 | /* De-initialize usb phy registers */ | ||
740 | if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) | ||
741 | samsung_exynos5_usbphy_disable(sphy); | ||
742 | else | ||
743 | samsung_usbphy_disable(sphy); | ||
744 | |||
745 | /* Enable phy isolation */ | ||
746 | if (sphy->plat && sphy->plat->pmu_isolation) | ||
747 | sphy->plat->pmu_isolation(true); | ||
748 | else | ||
749 | samsung_usbphy_set_isolation(sphy, true); | ||
750 | |||
751 | spin_unlock_irqrestore(&sphy->lock, flags); | ||
752 | |||
753 | clk_disable_unprepare(sphy->clk); | ||
754 | } | ||
755 | |||
756 | static const struct of_device_id samsung_usbphy_dt_match[]; | ||
757 | |||
758 | static inline const struct samsung_usbphy_drvdata | ||
759 | *samsung_usbphy_get_driver_data(struct platform_device *pdev) | ||
760 | { | ||
761 | if (pdev->dev.of_node) { | ||
762 | const struct of_device_id *match; | ||
763 | match = of_match_node(samsung_usbphy_dt_match, | ||
764 | pdev->dev.of_node); | ||
765 | return match->data; | ||
766 | } | ||
767 | |||
768 | return (struct samsung_usbphy_drvdata *) | ||
769 | platform_get_device_id(pdev)->driver_data; | ||
770 | } | ||
771 | |||
772 | static int samsung_usbphy_probe(struct platform_device *pdev) | ||
773 | { | ||
774 | struct samsung_usbphy *sphy; | ||
775 | struct usb_otg *otg; | ||
776 | struct samsung_usbphy_data *pdata = pdev->dev.platform_data; | ||
777 | const struct samsung_usbphy_drvdata *drv_data; | ||
778 | struct device *dev = &pdev->dev; | ||
779 | struct resource *phy_mem; | ||
780 | void __iomem *phy_base; | ||
781 | struct clk *clk; | ||
782 | int ret; | ||
783 | |||
784 | phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
785 | if (!phy_mem) { | ||
786 | dev_err(dev, "%s: missing mem resource\n", __func__); | ||
787 | return -ENODEV; | ||
788 | } | ||
789 | |||
790 | phy_base = devm_request_and_ioremap(dev, phy_mem); | ||
791 | if (!phy_base) { | ||
792 | dev_err(dev, "%s: register mapping failed\n", __func__); | ||
793 | return -ENXIO; | ||
794 | } | ||
795 | |||
796 | sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); | ||
797 | if (!sphy) | ||
798 | return -ENOMEM; | ||
799 | |||
800 | otg = devm_kzalloc(dev, sizeof(*otg), GFP_KERNEL); | ||
801 | if (!otg) | ||
802 | return -ENOMEM; | ||
803 | |||
804 | drv_data = samsung_usbphy_get_driver_data(pdev); | ||
805 | |||
806 | if (drv_data->cpu_type == TYPE_EXYNOS5250) | ||
807 | clk = devm_clk_get(dev, "usbhost"); | ||
808 | else | ||
809 | clk = devm_clk_get(dev, "otg"); | ||
810 | |||
811 | if (IS_ERR(clk)) { | ||
812 | dev_err(dev, "Failed to get otg clock\n"); | ||
813 | return PTR_ERR(clk); | ||
814 | } | ||
815 | |||
816 | sphy->dev = dev; | ||
817 | |||
818 | if (dev->of_node) { | ||
819 | ret = samsung_usbphy_parse_dt(sphy); | ||
820 | if (ret < 0) | ||
821 | return ret; | ||
822 | } else { | ||
823 | if (!pdata) { | ||
824 | dev_err(dev, "no platform data specified\n"); | ||
825 | return -EINVAL; | ||
826 | } | ||
827 | } | ||
828 | |||
829 | sphy->plat = pdata; | ||
830 | sphy->regs = phy_base; | ||
831 | sphy->clk = clk; | ||
832 | sphy->drv_data = drv_data; | ||
833 | sphy->phy.dev = sphy->dev; | ||
834 | sphy->phy.label = "samsung-usbphy"; | ||
835 | sphy->phy.init = samsung_usbphy_init; | ||
836 | sphy->phy.shutdown = samsung_usbphy_shutdown; | ||
837 | sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); | ||
838 | |||
839 | sphy->phy.otg = otg; | ||
840 | sphy->phy.otg->phy = &sphy->phy; | ||
841 | sphy->phy.otg->set_host = samsung_usbphy_set_host; | ||
842 | |||
843 | spin_lock_init(&sphy->lock); | ||
844 | |||
845 | platform_set_drvdata(pdev, sphy); | ||
846 | |||
847 | return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2); | ||
848 | } | ||
849 | |||
850 | static int samsung_usbphy_remove(struct platform_device *pdev) | ||
851 | { | ||
852 | struct samsung_usbphy *sphy = platform_get_drvdata(pdev); | ||
853 | |||
854 | usb_remove_phy(&sphy->phy); | ||
855 | |||
856 | if (sphy->pmuregs) | ||
857 | iounmap(sphy->pmuregs); | ||
858 | if (sphy->sysreg) | ||
859 | iounmap(sphy->sysreg); | ||
860 | |||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | static const struct samsung_usbphy_drvdata usbphy_s3c64xx = { | ||
865 | .cpu_type = TYPE_S3C64XX, | ||
866 | .devphy_en_mask = S3C64XX_USBPHY_ENABLE, | ||
867 | }; | ||
868 | |||
869 | static const struct samsung_usbphy_drvdata usbphy_exynos4 = { | ||
870 | .cpu_type = TYPE_EXYNOS4210, | ||
871 | .devphy_en_mask = EXYNOS_USBPHY_ENABLE, | ||
872 | .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, | ||
873 | }; | ||
874 | |||
875 | static struct samsung_usbphy_drvdata usbphy_exynos5 = { | ||
876 | .cpu_type = TYPE_EXYNOS5250, | ||
877 | .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, | ||
878 | .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET, | ||
879 | }; | ||
880 | |||
881 | #ifdef CONFIG_OF | ||
882 | static const struct of_device_id samsung_usbphy_dt_match[] = { | ||
883 | { | ||
884 | .compatible = "samsung,s3c64xx-usbphy", | ||
885 | .data = &usbphy_s3c64xx, | ||
886 | }, { | ||
887 | .compatible = "samsung,exynos4210-usbphy", | ||
888 | .data = &usbphy_exynos4, | ||
889 | }, { | ||
890 | .compatible = "samsung,exynos5250-usbphy", | ||
891 | .data = &usbphy_exynos5 | ||
892 | }, | ||
893 | {}, | ||
894 | }; | ||
895 | MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match); | ||
896 | #endif | ||
897 | |||
898 | static struct platform_device_id samsung_usbphy_driver_ids[] = { | ||
899 | { | ||
900 | .name = "s3c64xx-usbphy", | ||
901 | .driver_data = (unsigned long)&usbphy_s3c64xx, | ||
902 | }, { | ||
903 | .name = "exynos4210-usbphy", | ||
904 | .driver_data = (unsigned long)&usbphy_exynos4, | ||
905 | }, { | ||
906 | .name = "exynos5250-usbphy", | ||
907 | .driver_data = (unsigned long)&usbphy_exynos5, | ||
908 | }, | ||
909 | {}, | ||
910 | }; | ||
911 | |||
912 | MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids); | ||
913 | |||
914 | static struct platform_driver samsung_usbphy_driver = { | ||
915 | .probe = samsung_usbphy_probe, | ||
916 | .remove = samsung_usbphy_remove, | ||
917 | .id_table = samsung_usbphy_driver_ids, | ||
918 | .driver = { | ||
919 | .name = "samsung-usbphy", | ||
920 | .owner = THIS_MODULE, | ||
921 | .of_match_table = of_match_ptr(samsung_usbphy_dt_match), | ||
922 | }, | ||
923 | }; | ||
924 | |||
925 | module_platform_driver(samsung_usbphy_driver); | ||
926 | |||
927 | MODULE_DESCRIPTION("Samsung USB phy controller"); | ||
928 | MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>"); | ||
929 | MODULE_LICENSE("GPL"); | ||
930 | MODULE_ALIAS("platform:samsung-usbphy"); | ||
diff --git a/drivers/usb/renesas_usbhs/Kconfig b/drivers/usb/renesas_usbhs/Kconfig index 6f4afa436381..29feb00d7f39 100644 --- a/drivers/usb/renesas_usbhs/Kconfig +++ b/drivers/usb/renesas_usbhs/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | config USB_RENESAS_USBHS | 5 | config USB_RENESAS_USBHS |
6 | tristate 'Renesas USBHS controller' | 6 | tristate 'Renesas USBHS controller' |
7 | depends on USB && USB_GADGET | 7 | depends on USB && USB_GADGET && GENERIC_HARDIRQS |
8 | default n | 8 | default n |
9 | help | 9 | help |
10 | Renesas USBHS is a discrete USB host and peripheral controller chip | 10 | Renesas USBHS is a discrete USB host and peripheral controller chip |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index f2985cd88021..78fca978b2d0 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -900,7 +900,7 @@ static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) | |||
900 | return 0; | 900 | return 0; |
901 | } | 901 | } |
902 | 902 | ||
903 | static struct usb_gadget_ops usbhsg_gadget_ops = { | 903 | static const struct usb_gadget_ops usbhsg_gadget_ops = { |
904 | .get_frame = usbhsg_get_frame, | 904 | .get_frame = usbhsg_get_frame, |
905 | .set_selfpowered = usbhsg_set_selfpowered, | 905 | .set_selfpowered = usbhsg_set_selfpowered, |
906 | .udc_start = usbhsg_gadget_start, | 906 | .udc_start = usbhsg_gadget_start, |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 76f462241738..dad8363e5b2a 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -647,6 +647,18 @@ config USB_SERIAL_VIVOPAY_SERIAL | |||
647 | To compile this driver as a module, choose M here: the | 647 | To compile this driver as a module, choose M here: the |
648 | module will be called vivopay-serial. | 648 | module will be called vivopay-serial. |
649 | 649 | ||
650 | config USB_SERIAL_XSENS_MT | ||
651 | tristate "Xsens motion tracker serial interface driver" | ||
652 | help | ||
653 | Say Y here if you want to use Xsens motion trackers. | ||
654 | |||
655 | This driver supports the new generation of motion trackers | ||
656 | by Xsens. Older devices can be accessed using the FTDI_SIO | ||
657 | driver. | ||
658 | |||
659 | To compile this driver as a module, choose M here: the | ||
660 | module will be called xsens_mt. | ||
661 | |||
650 | config USB_SERIAL_ZIO | 662 | config USB_SERIAL_ZIO |
651 | tristate "ZIO Motherboard USB serial interface driver" | 663 | tristate "ZIO Motherboard USB serial interface driver" |
652 | help | 664 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 3b3e7308d476..eaf5ca14dfeb 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -61,5 +61,6 @@ obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o | |||
61 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o | 61 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o |
62 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o | 62 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o |
63 | obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o | 63 | obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o |
64 | obj-$(CONFIG_USB_SERIAL_XSENS_MT) += xsens_mt.o | ||
64 | obj-$(CONFIG_USB_SERIAL_ZIO) += zio.o | 65 | obj-$(CONFIG_USB_SERIAL_ZIO) += zio.o |
65 | obj-$(CONFIG_USB_SERIAL_ZTE) += zte_ev.o | 66 | obj-$(CONFIG_USB_SERIAL_ZTE) += zte_ev.o |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 90ceef1776c3..d07fccf3bab5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1886,24 +1886,22 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | |||
1886 | { | 1886 | { |
1887 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1887 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1888 | 1888 | ||
1889 | mutex_lock(&port->serial->disc_mutex); | 1889 | /* Disable flow control */ |
1890 | if (!port->serial->disconnected) { | 1890 | if (!on) { |
1891 | /* Disable flow control */ | 1891 | if (usb_control_msg(port->serial->dev, |
1892 | if (!on && usb_control_msg(port->serial->dev, | ||
1893 | usb_sndctrlpipe(port->serial->dev, 0), | 1892 | usb_sndctrlpipe(port->serial->dev, 0), |
1894 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1893 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1895 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1894 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1896 | 0, priv->interface, NULL, 0, | 1895 | 0, priv->interface, NULL, 0, |
1897 | WDR_TIMEOUT) < 0) { | 1896 | WDR_TIMEOUT) < 0) { |
1898 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 1897 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
1899 | } | 1898 | } |
1900 | /* drop RTS and DTR */ | ||
1901 | if (on) | ||
1902 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1903 | else | ||
1904 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1905 | } | 1899 | } |
1906 | mutex_unlock(&port->serial->disc_mutex); | 1900 | /* drop RTS and DTR */ |
1901 | if (on) | ||
1902 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1903 | else | ||
1904 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1907 | } | 1905 | } |
1908 | 1906 | ||
1909 | /* | 1907 | /* |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 82afc4d6a327..641ab3da2d83 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -521,65 +521,6 @@ exit_is_tx_active: | |||
521 | return bytes_left; | 521 | return bytes_left; |
522 | } | 522 | } |
523 | 523 | ||
524 | static void chase_port(struct edgeport_port *port, unsigned long timeout, | ||
525 | int flush) | ||
526 | { | ||
527 | int baud_rate; | ||
528 | struct tty_struct *tty = tty_port_tty_get(&port->port->port); | ||
529 | struct usb_serial *serial = port->port->serial; | ||
530 | wait_queue_t wait; | ||
531 | unsigned long flags; | ||
532 | |||
533 | if (!tty) | ||
534 | return; | ||
535 | |||
536 | if (!timeout) | ||
537 | timeout = (HZ * EDGE_CLOSING_WAIT)/100; | ||
538 | |||
539 | /* wait for data to drain from the buffer */ | ||
540 | spin_lock_irqsave(&port->ep_lock, flags); | ||
541 | init_waitqueue_entry(&wait, current); | ||
542 | add_wait_queue(&tty->write_wait, &wait); | ||
543 | for (;;) { | ||
544 | set_current_state(TASK_INTERRUPTIBLE); | ||
545 | if (kfifo_len(&port->write_fifo) == 0 | ||
546 | || timeout == 0 || signal_pending(current) | ||
547 | || serial->disconnected) | ||
548 | /* disconnect */ | ||
549 | break; | ||
550 | spin_unlock_irqrestore(&port->ep_lock, flags); | ||
551 | timeout = schedule_timeout(timeout); | ||
552 | spin_lock_irqsave(&port->ep_lock, flags); | ||
553 | } | ||
554 | set_current_state(TASK_RUNNING); | ||
555 | remove_wait_queue(&tty->write_wait, &wait); | ||
556 | if (flush) | ||
557 | kfifo_reset_out(&port->write_fifo); | ||
558 | spin_unlock_irqrestore(&port->ep_lock, flags); | ||
559 | tty_kref_put(tty); | ||
560 | |||
561 | /* wait for data to drain from the device */ | ||
562 | timeout += jiffies; | ||
563 | while ((long)(jiffies - timeout) < 0 && !signal_pending(current) | ||
564 | && !serial->disconnected) { | ||
565 | /* not disconnected */ | ||
566 | if (!tx_active(port)) | ||
567 | break; | ||
568 | msleep(10); | ||
569 | } | ||
570 | |||
571 | /* disconnected */ | ||
572 | if (serial->disconnected) | ||
573 | return; | ||
574 | |||
575 | /* wait one more character time, based on baud rate */ | ||
576 | /* (tx_active doesn't seem to wait for the last byte) */ | ||
577 | baud_rate = port->baud_rate; | ||
578 | if (baud_rate == 0) | ||
579 | baud_rate = 50; | ||
580 | msleep(max(1, DIV_ROUND_UP(10000, baud_rate))); | ||
581 | } | ||
582 | |||
583 | static int choose_config(struct usb_device *dev) | 524 | static int choose_config(struct usb_device *dev) |
584 | { | 525 | { |
585 | /* | 526 | /* |
@@ -1944,6 +1885,8 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1944 | 1885 | ||
1945 | ++edge_serial->num_ports_open; | 1886 | ++edge_serial->num_ports_open; |
1946 | 1887 | ||
1888 | port->port.drain_delay = 1; | ||
1889 | |||
1947 | goto release_es_lock; | 1890 | goto release_es_lock; |
1948 | 1891 | ||
1949 | unlink_int_urb: | 1892 | unlink_int_urb: |
@@ -1959,6 +1902,7 @@ static void edge_close(struct usb_serial_port *port) | |||
1959 | struct edgeport_serial *edge_serial; | 1902 | struct edgeport_serial *edge_serial; |
1960 | struct edgeport_port *edge_port; | 1903 | struct edgeport_port *edge_port; |
1961 | struct usb_serial *serial = port->serial; | 1904 | struct usb_serial *serial = port->serial; |
1905 | unsigned long flags; | ||
1962 | int port_number; | 1906 | int port_number; |
1963 | 1907 | ||
1964 | edge_serial = usb_get_serial_data(port->serial); | 1908 | edge_serial = usb_get_serial_data(port->serial); |
@@ -1970,12 +1914,12 @@ static void edge_close(struct usb_serial_port *port) | |||
1970 | * this flag and dump add read data */ | 1914 | * this flag and dump add read data */ |
1971 | edge_port->close_pending = 1; | 1915 | edge_port->close_pending = 1; |
1972 | 1916 | ||
1973 | /* chase the port close and flush */ | ||
1974 | chase_port(edge_port, (HZ * closing_wait) / 100, 1); | ||
1975 | |||
1976 | usb_kill_urb(port->read_urb); | 1917 | usb_kill_urb(port->read_urb); |
1977 | usb_kill_urb(port->write_urb); | 1918 | usb_kill_urb(port->write_urb); |
1978 | edge_port->ep_write_urb_in_use = 0; | 1919 | edge_port->ep_write_urb_in_use = 0; |
1920 | spin_lock_irqsave(&edge_port->ep_lock, flags); | ||
1921 | kfifo_reset_out(&edge_port->write_fifo); | ||
1922 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | ||
1979 | 1923 | ||
1980 | /* assuming we can still talk to the device, | 1924 | /* assuming we can still talk to the device, |
1981 | * send a close port command to it */ | 1925 | * send a close port command to it */ |
@@ -2101,16 +2045,21 @@ static int edge_chars_in_buffer(struct tty_struct *tty) | |||
2101 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 2045 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
2102 | int chars = 0; | 2046 | int chars = 0; |
2103 | unsigned long flags; | 2047 | unsigned long flags; |
2048 | int ret; | ||
2104 | 2049 | ||
2105 | if (edge_port == NULL) | 2050 | if (edge_port == NULL) |
2106 | return 0; | 2051 | return 0; |
2107 | if (edge_port->close_pending == 1) | ||
2108 | return 0; | ||
2109 | 2052 | ||
2110 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2053 | spin_lock_irqsave(&edge_port->ep_lock, flags); |
2111 | chars = kfifo_len(&edge_port->write_fifo); | 2054 | chars = kfifo_len(&edge_port->write_fifo); |
2112 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | 2055 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); |
2113 | 2056 | ||
2057 | if (!chars) { | ||
2058 | ret = tx_active(edge_port); | ||
2059 | if (ret > 0) | ||
2060 | chars = ret; | ||
2061 | } | ||
2062 | |||
2114 | dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); | 2063 | dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); |
2115 | return chars; | 2064 | return chars; |
2116 | } | 2065 | } |
@@ -2448,10 +2397,15 @@ static int get_serial_info(struct edgeport_port *edge_port, | |||
2448 | struct serial_struct __user *retinfo) | 2397 | struct serial_struct __user *retinfo) |
2449 | { | 2398 | { |
2450 | struct serial_struct tmp; | 2399 | struct serial_struct tmp; |
2400 | unsigned cwait; | ||
2451 | 2401 | ||
2452 | if (!retinfo) | 2402 | if (!retinfo) |
2453 | return -EFAULT; | 2403 | return -EFAULT; |
2454 | 2404 | ||
2405 | cwait = edge_port->port->port.closing_wait; | ||
2406 | if (cwait != ASYNC_CLOSING_WAIT_NONE) | ||
2407 | cwait = jiffies_to_msecs(closing_wait) / 10; | ||
2408 | |||
2455 | memset(&tmp, 0, sizeof(tmp)); | 2409 | memset(&tmp, 0, sizeof(tmp)); |
2456 | 2410 | ||
2457 | tmp.type = PORT_16550A; | 2411 | tmp.type = PORT_16550A; |
@@ -2462,7 +2416,7 @@ static int get_serial_info(struct edgeport_port *edge_port, | |||
2462 | tmp.xmit_fifo_size = edge_port->port->bulk_out_size; | 2416 | tmp.xmit_fifo_size = edge_port->port->bulk_out_size; |
2463 | tmp.baud_base = 9600; | 2417 | tmp.baud_base = 9600; |
2464 | tmp.close_delay = 5*HZ; | 2418 | tmp.close_delay = 5*HZ; |
2465 | tmp.closing_wait = closing_wait; | 2419 | tmp.closing_wait = cwait; |
2466 | 2420 | ||
2467 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 2421 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
2468 | return -EFAULT; | 2422 | return -EFAULT; |
@@ -2517,8 +2471,7 @@ static void edge_break(struct tty_struct *tty, int break_state) | |||
2517 | int status; | 2471 | int status; |
2518 | int bv = 0; /* Off */ | 2472 | int bv = 0; /* Off */ |
2519 | 2473 | ||
2520 | /* chase the port close */ | 2474 | tty_wait_until_sent(tty, 0); |
2521 | chase_port(edge_port, 0, 0); | ||
2522 | 2475 | ||
2523 | if (break_state == -1) | 2476 | if (break_state == -1) |
2524 | bv = 1; /* On */ | 2477 | bv = 1; /* On */ |
@@ -2591,6 +2544,8 @@ static int edge_port_probe(struct usb_serial_port *port) | |||
2591 | return ret; | 2544 | return ret; |
2592 | } | 2545 | } |
2593 | 2546 | ||
2547 | port->port.closing_wait = msecs_to_jiffies(closing_wait * 10); | ||
2548 | |||
2594 | return 0; | 2549 | return 0; |
2595 | } | 2550 | } |
2596 | 2551 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 97bc49f68efd..3d95637f3d68 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -298,7 +298,7 @@ static void usa26_indat_callback(struct urb *urb) | |||
298 | endpoint = usb_pipeendpoint(urb->pipe); | 298 | endpoint = usb_pipeendpoint(urb->pipe); |
299 | 299 | ||
300 | if (status) { | 300 | if (status) { |
301 | dev_dbg(&urb->dev->dev,"%s - nonzero status: %x on endpoint %d.\n", | 301 | dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n", |
302 | __func__, status, endpoint); | 302 | __func__, status, endpoint); |
303 | return; | 303 | return; |
304 | } | 304 | } |
@@ -532,7 +532,7 @@ static void usa28_instat_callback(struct urb *urb) | |||
532 | 532 | ||
533 | /* | 533 | /* |
534 | dev_dbg(&urb->dev->dev, | 534 | dev_dbg(&urb->dev->dev, |
535 | "%s %x %x %x %x %x %x %x %x %x %x %x %x", __func__, | 535 | "%s %x %x %x %x %x %x %x %x %x %x %x %x", __func__, |
536 | data[0], data[1], data[2], data[3], data[4], data[5], | 536 | data[0], data[1], data[2], data[3], data[4], data[5], |
537 | data[6], data[7], data[8], data[9], data[10], data[11]); | 537 | data[6], data[7], data[8], data[9], data[10], data[11]); |
538 | */ | 538 | */ |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index b6911757c855..d9c86516fed4 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -499,19 +499,15 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) | |||
499 | unsigned int control_state; | 499 | unsigned int control_state; |
500 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 500 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
501 | 501 | ||
502 | mutex_lock(&port->serial->disc_mutex); | 502 | spin_lock_irq(&priv->lock); |
503 | if (!port->serial->disconnected) { | 503 | if (on) |
504 | /* drop DTR and RTS */ | 504 | priv->control_state |= TIOCM_DTR | TIOCM_RTS; |
505 | spin_lock_irq(&priv->lock); | 505 | else |
506 | if (on) | 506 | priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); |
507 | priv->control_state |= TIOCM_DTR | TIOCM_RTS; | 507 | control_state = priv->control_state; |
508 | else | 508 | spin_unlock_irq(&priv->lock); |
509 | priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); | 509 | |
510 | control_state = priv->control_state; | 510 | mct_u232_set_modem_ctrl(port, control_state); |
511 | spin_unlock_irq(&priv->lock); | ||
512 | mct_u232_set_modem_ctrl(port, control_state); | ||
513 | } | ||
514 | mutex_unlock(&port->serial->disc_mutex); | ||
515 | } | 511 | } |
516 | 512 | ||
517 | static void mct_u232_close(struct usb_serial_port *port) | 513 | static void mct_u232_close(struct usb_serial_port *port) |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 567bc77d6397..f7d339d8187b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -479,6 +479,7 @@ static const struct option_blacklist_info four_g_w14_blacklist = { | |||
479 | 479 | ||
480 | static const struct option_blacklist_info alcatel_x200_blacklist = { | 480 | static const struct option_blacklist_info alcatel_x200_blacklist = { |
481 | .sendsetup = BIT(0) | BIT(1), | 481 | .sendsetup = BIT(0) | BIT(1), |
482 | .reserved = BIT(4), | ||
482 | }; | 483 | }; |
483 | 484 | ||
484 | static const struct option_blacklist_info zte_0037_blacklist = { | 485 | static const struct option_blacklist_info zte_0037_blacklist = { |
@@ -575,8 +576,14 @@ static const struct usb_device_id option_ids[] = { | |||
575 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, | 576 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, |
576 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, | 577 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, |
577 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, | 578 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, |
579 | { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), | ||
580 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
581 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, | ||
582 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, | ||
578 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), | 583 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), |
579 | .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, | 584 | .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, |
585 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, | ||
586 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, | ||
580 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), | 587 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), |
581 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 588 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
582 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), | 589 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), |
@@ -1215,7 +1222,14 @@ static const struct usb_device_id option_ids[] = { | |||
1215 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), | 1222 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), |
1216 | .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist | 1223 | .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist |
1217 | }, | 1224 | }, |
1218 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, | 1225 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), |
1226 | .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, | ||
1227 | { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052), | ||
1228 | .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, | ||
1229 | { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6), | ||
1230 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
1231 | { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7), | ||
1232 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, | ||
1219 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), | 1233 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), |
1220 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1234 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
1221 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 1235 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index d152be97d041..a8d5110d4cc5 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
@@ -945,19 +945,17 @@ static void qt2_dtr_rts(struct usb_serial_port *port, int on) | |||
945 | struct usb_device *dev = port->serial->dev; | 945 | struct usb_device *dev = port->serial->dev; |
946 | struct qt2_port_private *port_priv = usb_get_serial_port_data(port); | 946 | struct qt2_port_private *port_priv = usb_get_serial_port_data(port); |
947 | 947 | ||
948 | mutex_lock(&port->serial->disc_mutex); | 948 | /* Disable flow control */ |
949 | if (!port->serial->disconnected) { | 949 | if (!on) { |
950 | /* Disable flow control */ | 950 | if (qt2_setregister(dev, port_priv->device_port, |
951 | if (!on && qt2_setregister(dev, port_priv->device_port, | ||
952 | UART_MCR, 0) < 0) | 951 | UART_MCR, 0) < 0) |
953 | dev_warn(&port->dev, "error from flowcontrol urb\n"); | 952 | dev_warn(&port->dev, "error from flowcontrol urb\n"); |
954 | /* drop RTS and DTR */ | ||
955 | if (on) | ||
956 | update_mctrl(port_priv, TIOCM_DTR | TIOCM_RTS, 0); | ||
957 | else | ||
958 | update_mctrl(port_priv, 0, TIOCM_DTR | TIOCM_RTS); | ||
959 | } | 953 | } |
960 | mutex_unlock(&port->serial->disc_mutex); | 954 | /* drop RTS and DTR */ |
955 | if (on) | ||
956 | update_mctrl(port_priv, TIOCM_DTR | TIOCM_RTS, 0); | ||
957 | else | ||
958 | update_mctrl(port_priv, 0, TIOCM_DTR | TIOCM_RTS); | ||
961 | } | 959 | } |
962 | 960 | ||
963 | static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) | 961 | static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index af06f2f5f38b..d4426c038c32 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -861,19 +861,13 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
861 | 861 | ||
862 | static void sierra_dtr_rts(struct usb_serial_port *port, int on) | 862 | static void sierra_dtr_rts(struct usb_serial_port *port, int on) |
863 | { | 863 | { |
864 | struct usb_serial *serial = port->serial; | ||
865 | struct sierra_port_private *portdata; | 864 | struct sierra_port_private *portdata; |
866 | 865 | ||
867 | portdata = usb_get_serial_port_data(port); | 866 | portdata = usb_get_serial_port_data(port); |
868 | portdata->rts_state = on; | 867 | portdata->rts_state = on; |
869 | portdata->dtr_state = on; | 868 | portdata->dtr_state = on; |
870 | 869 | ||
871 | if (serial->dev) { | 870 | sierra_send_setup(port); |
872 | mutex_lock(&serial->disc_mutex); | ||
873 | if (!serial->disconnected) | ||
874 | sierra_send_setup(port); | ||
875 | mutex_unlock(&serial->disc_mutex); | ||
876 | } | ||
877 | } | 871 | } |
878 | 872 | ||
879 | static int sierra_startup(struct usb_serial *serial) | 873 | static int sierra_startup(struct usb_serial *serial) |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 4543ea350229..d938396171e8 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -506,19 +506,16 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) | |||
506 | { | 506 | { |
507 | struct usb_device *dev = port->serial->dev; | 507 | struct usb_device *dev = port->serial->dev; |
508 | 508 | ||
509 | mutex_lock(&port->serial->disc_mutex); | 509 | /* Disable flow control */ |
510 | if (!port->serial->disconnected) { | 510 | if (!on) { |
511 | /* Disable flow control */ | 511 | if (ssu100_setregister(dev, 0, UART_MCR, 0) < 0) |
512 | if (!on && | ||
513 | ssu100_setregister(dev, 0, UART_MCR, 0) < 0) | ||
514 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 512 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
515 | /* drop RTS and DTR */ | ||
516 | if (on) | ||
517 | set_mctrl(dev, TIOCM_DTR | TIOCM_RTS); | ||
518 | else | ||
519 | clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS); | ||
520 | } | 513 | } |
521 | mutex_unlock(&port->serial->disc_mutex); | 514 | /* drop RTS and DTR */ |
515 | if (on) | ||
516 | set_mctrl(dev, TIOCM_DTR | TIOCM_RTS); | ||
517 | else | ||
518 | clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS); | ||
522 | } | 519 | } |
523 | 520 | ||
524 | static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) | 521 | static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 64bda135ba7e..a19ed74d770d 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -361,15 +361,21 @@ static int serial_write_room(struct tty_struct *tty) | |||
361 | static int serial_chars_in_buffer(struct tty_struct *tty) | 361 | static int serial_chars_in_buffer(struct tty_struct *tty) |
362 | { | 362 | { |
363 | struct usb_serial_port *port = tty->driver_data; | 363 | struct usb_serial_port *port = tty->driver_data; |
364 | struct usb_serial *serial = port->serial; | ||
365 | int count = 0; | ||
364 | 366 | ||
365 | dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); | 367 | dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); |
366 | 368 | ||
369 | mutex_lock(&serial->disc_mutex); | ||
367 | /* if the device was unplugged then any remaining characters | 370 | /* if the device was unplugged then any remaining characters |
368 | fell out of the connector ;) */ | 371 | fell out of the connector ;) */ |
369 | if (port->serial->disconnected) | 372 | if (serial->disconnected) |
370 | return 0; | 373 | count = 0; |
371 | /* pass on to the driver specific version of this function */ | 374 | else |
372 | return port->serial->type->chars_in_buffer(tty); | 375 | count = serial->type->chars_in_buffer(tty); |
376 | mutex_unlock(&serial->disc_mutex); | ||
377 | |||
378 | return count; | ||
373 | } | 379 | } |
374 | 380 | ||
375 | static void serial_throttle(struct tty_struct *tty) | 381 | static void serial_throttle(struct tty_struct *tty) |
@@ -688,10 +694,20 @@ static int serial_carrier_raised(struct tty_port *port) | |||
688 | static void serial_dtr_rts(struct tty_port *port, int on) | 694 | static void serial_dtr_rts(struct tty_port *port, int on) |
689 | { | 695 | { |
690 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); | 696 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); |
691 | struct usb_serial_driver *drv = p->serial->type; | 697 | struct usb_serial *serial = p->serial; |
698 | struct usb_serial_driver *drv = serial->type; | ||
692 | 699 | ||
693 | if (drv->dtr_rts) | 700 | if (!drv->dtr_rts) |
701 | return; | ||
702 | /* | ||
703 | * Work-around bug in the tty-layer which can result in dtr_rts | ||
704 | * being called after a disconnect (and tty_unregister_device | ||
705 | * has returned). Remove once bug has been squashed. | ||
706 | */ | ||
707 | mutex_lock(&serial->disc_mutex); | ||
708 | if (!serial->disconnected) | ||
694 | drv->dtr_rts(p, on); | 709 | drv->dtr_rts(p, on); |
710 | mutex_unlock(&serial->disc_mutex); | ||
695 | } | 711 | } |
696 | 712 | ||
697 | static const struct tty_port_operations serial_port_ops = { | 713 | static const struct tty_port_operations serial_port_ops = { |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 01c94aada56c..1355a6cd4508 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) | 39 | void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) |
40 | { | 40 | { |
41 | struct usb_serial *serial = port->serial; | ||
42 | struct usb_wwan_port_private *portdata; | 41 | struct usb_wwan_port_private *portdata; |
43 | struct usb_wwan_intf_private *intfdata; | 42 | struct usb_wwan_intf_private *intfdata; |
44 | 43 | ||
@@ -48,12 +47,11 @@ void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) | |||
48 | return; | 47 | return; |
49 | 48 | ||
50 | portdata = usb_get_serial_port_data(port); | 49 | portdata = usb_get_serial_port_data(port); |
51 | mutex_lock(&serial->disc_mutex); | 50 | /* FIXME: locking */ |
52 | portdata->rts_state = on; | 51 | portdata->rts_state = on; |
53 | portdata->dtr_state = on; | 52 | portdata->dtr_state = on; |
54 | if (serial->dev) | 53 | |
55 | intfdata->send_setup(port); | 54 | intfdata->send_setup(port); |
56 | mutex_unlock(&serial->disc_mutex); | ||
57 | } | 55 | } |
58 | EXPORT_SYMBOL(usb_wwan_dtr_rts); | 56 | EXPORT_SYMBOL(usb_wwan_dtr_rts); |
59 | 57 | ||
diff --git a/drivers/usb/serial/xsens_mt.c b/drivers/usb/serial/xsens_mt.c new file mode 100644 index 000000000000..1d5798d891bc --- /dev/null +++ b/drivers/usb/serial/xsens_mt.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * Xsens MT USB driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Xsens <info@xsens.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/tty.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/usb.h> | ||
16 | #include <linux/usb/serial.h> | ||
17 | #include <linux/uaccess.h> | ||
18 | |||
19 | #define XSENS_VID 0x2639 | ||
20 | |||
21 | #define MTi_10_IMU_PID 0x0001 | ||
22 | #define MTi_20_VRU_PID 0x0002 | ||
23 | #define MTi_30_AHRS_PID 0x0003 | ||
24 | |||
25 | #define MTi_100_IMU_PID 0x0011 | ||
26 | #define MTi_200_VRU_PID 0x0012 | ||
27 | #define MTi_300_AHRS_PID 0x0013 | ||
28 | |||
29 | #define MTi_G_700_GPS_INS_PID 0x0017 | ||
30 | |||
31 | static const struct usb_device_id id_table[] = { | ||
32 | { USB_DEVICE(XSENS_VID, MTi_10_IMU_PID) }, | ||
33 | { USB_DEVICE(XSENS_VID, MTi_20_VRU_PID) }, | ||
34 | { USB_DEVICE(XSENS_VID, MTi_30_AHRS_PID) }, | ||
35 | |||
36 | { USB_DEVICE(XSENS_VID, MTi_100_IMU_PID) }, | ||
37 | { USB_DEVICE(XSENS_VID, MTi_200_VRU_PID) }, | ||
38 | { USB_DEVICE(XSENS_VID, MTi_300_AHRS_PID) }, | ||
39 | |||
40 | { USB_DEVICE(XSENS_VID, MTi_G_700_GPS_INS_PID) }, | ||
41 | { }, | ||
42 | }; | ||
43 | MODULE_DEVICE_TABLE(usb, id_table); | ||
44 | |||
45 | static int has_required_endpoints(const struct usb_host_interface *interface) | ||
46 | { | ||
47 | __u8 i; | ||
48 | int has_bulk_in = 0; | ||
49 | int has_bulk_out = 0; | ||
50 | |||
51 | for (i = 0; i < interface->desc.bNumEndpoints; ++i) { | ||
52 | if (usb_endpoint_is_bulk_in(&interface->endpoint[i].desc)) | ||
53 | has_bulk_in = 1; | ||
54 | else if (usb_endpoint_is_bulk_out(&interface->endpoint[i].desc)) | ||
55 | has_bulk_out = 1; | ||
56 | } | ||
57 | |||
58 | return has_bulk_in && has_bulk_out; | ||
59 | } | ||
60 | |||
61 | static int xsens_mt_probe(struct usb_serial *serial, | ||
62 | const struct usb_device_id *id) | ||
63 | { | ||
64 | if (!has_required_endpoints(serial->interface->cur_altsetting)) | ||
65 | return -ENODEV; | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static struct usb_serial_driver xsens_mt_device = { | ||
70 | .driver = { | ||
71 | .owner = THIS_MODULE, | ||
72 | .name = "xsens_mt", | ||
73 | }, | ||
74 | .id_table = id_table, | ||
75 | .num_ports = 1, | ||
76 | |||
77 | .probe = xsens_mt_probe, | ||
78 | }; | ||
79 | |||
80 | static struct usb_serial_driver * const serial_drivers[] = { | ||
81 | &xsens_mt_device, NULL | ||
82 | }; | ||
83 | |||
84 | module_usb_serial_driver(serial_drivers, id_table); | ||
85 | |||
86 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 16b0bf055eeb..7ab9046ae0ec 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c | |||
@@ -147,7 +147,7 @@ static int usb_stor_huawei_dongles_pid(struct us_data *us) | |||
147 | int idProduct; | 147 | int idProduct; |
148 | 148 | ||
149 | idesc = &us->pusb_intf->cur_altsetting->desc; | 149 | idesc = &us->pusb_intf->cur_altsetting->desc; |
150 | idProduct = us->pusb_dev->descriptor.idProduct; | 150 | idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); |
151 | /* The first port is CDROM, | 151 | /* The first port is CDROM, |
152 | * means the dongle in the single port mode, | 152 | * means the dongle in the single port mode, |
153 | * and a switch command is required to be sent. */ | 153 | * and a switch command is required to be sent. */ |
@@ -169,7 +169,7 @@ int usb_stor_huawei_init(struct us_data *us) | |||
169 | int result = 0; | 169 | int result = 0; |
170 | 170 | ||
171 | if (usb_stor_huawei_dongles_pid(us)) { | 171 | if (usb_stor_huawei_dongles_pid(us)) { |
172 | if (us->pusb_dev->descriptor.idProduct >= 0x1446) | 172 | if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) |
173 | result = usb_stor_huawei_scsi_init(us); | 173 | result = usb_stor_huawei_scsi_init(us); |
174 | else | 174 | else |
175 | result = usb_stor_huawei_feature_init(us); | 175 | result = usb_stor_huawei_feature_init(us); |
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 98b98eef7527..d966b59f7d7b 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -66,6 +66,8 @@ enum { | |||
66 | DATA_OUT_URB_INFLIGHT = (1 << 10), | 66 | DATA_OUT_URB_INFLIGHT = (1 << 10), |
67 | COMMAND_COMPLETED = (1 << 11), | 67 | COMMAND_COMPLETED = (1 << 11), |
68 | COMMAND_ABORTED = (1 << 12), | 68 | COMMAND_ABORTED = (1 << 12), |
69 | UNLINK_DATA_URBS = (1 << 13), | ||
70 | IS_IN_WORK_LIST = (1 << 14), | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | /* Overrides scsi_pointer */ | 73 | /* Overrides scsi_pointer */ |
@@ -82,11 +84,36 @@ struct uas_cmd_info { | |||
82 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, | 84 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, |
83 | struct uas_dev_info *devinfo, gfp_t gfp); | 85 | struct uas_dev_info *devinfo, gfp_t gfp); |
84 | static void uas_do_work(struct work_struct *work); | 86 | static void uas_do_work(struct work_struct *work); |
87 | static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller); | ||
85 | 88 | ||
86 | static DECLARE_WORK(uas_work, uas_do_work); | 89 | static DECLARE_WORK(uas_work, uas_do_work); |
87 | static DEFINE_SPINLOCK(uas_work_lock); | 90 | static DEFINE_SPINLOCK(uas_work_lock); |
88 | static LIST_HEAD(uas_work_list); | 91 | static LIST_HEAD(uas_work_list); |
89 | 92 | ||
93 | static void uas_unlink_data_urbs(struct uas_dev_info *devinfo, | ||
94 | struct uas_cmd_info *cmdinfo) | ||
95 | { | ||
96 | unsigned long flags; | ||
97 | |||
98 | /* | ||
99 | * The UNLINK_DATA_URBS flag makes sure uas_try_complete | ||
100 | * (called by urb completion) doesn't release cmdinfo | ||
101 | * underneath us. | ||
102 | */ | ||
103 | spin_lock_irqsave(&devinfo->lock, flags); | ||
104 | cmdinfo->state |= UNLINK_DATA_URBS; | ||
105 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
106 | |||
107 | if (cmdinfo->data_in_urb) | ||
108 | usb_unlink_urb(cmdinfo->data_in_urb); | ||
109 | if (cmdinfo->data_out_urb) | ||
110 | usb_unlink_urb(cmdinfo->data_out_urb); | ||
111 | |||
112 | spin_lock_irqsave(&devinfo->lock, flags); | ||
113 | cmdinfo->state &= ~UNLINK_DATA_URBS; | ||
114 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
115 | } | ||
116 | |||
90 | static void uas_do_work(struct work_struct *work) | 117 | static void uas_do_work(struct work_struct *work) |
91 | { | 118 | { |
92 | struct uas_cmd_info *cmdinfo; | 119 | struct uas_cmd_info *cmdinfo; |
@@ -106,6 +133,8 @@ static void uas_do_work(struct work_struct *work) | |||
106 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | 133 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; |
107 | spin_lock_irqsave(&devinfo->lock, flags); | 134 | spin_lock_irqsave(&devinfo->lock, flags); |
108 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); | 135 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); |
136 | if (!err) | ||
137 | cmdinfo->state &= ~IS_IN_WORK_LIST; | ||
109 | spin_unlock_irqrestore(&devinfo->lock, flags); | 138 | spin_unlock_irqrestore(&devinfo->lock, flags); |
110 | if (err) { | 139 | if (err) { |
111 | list_del(&cmdinfo->list); | 140 | list_del(&cmdinfo->list); |
@@ -117,6 +146,45 @@ static void uas_do_work(struct work_struct *work) | |||
117 | } | 146 | } |
118 | } | 147 | } |
119 | 148 | ||
149 | static void uas_abort_work(struct uas_dev_info *devinfo) | ||
150 | { | ||
151 | struct uas_cmd_info *cmdinfo; | ||
152 | struct uas_cmd_info *temp; | ||
153 | struct list_head list; | ||
154 | unsigned long flags; | ||
155 | |||
156 | spin_lock_irq(&uas_work_lock); | ||
157 | list_replace_init(&uas_work_list, &list); | ||
158 | spin_unlock_irq(&uas_work_lock); | ||
159 | |||
160 | spin_lock_irqsave(&devinfo->lock, flags); | ||
161 | list_for_each_entry_safe(cmdinfo, temp, &list, list) { | ||
162 | struct scsi_pointer *scp = (void *)cmdinfo; | ||
163 | struct scsi_cmnd *cmnd = container_of(scp, | ||
164 | struct scsi_cmnd, SCp); | ||
165 | struct uas_dev_info *di = (void *)cmnd->device->hostdata; | ||
166 | |||
167 | if (di == devinfo) { | ||
168 | cmdinfo->state |= COMMAND_ABORTED; | ||
169 | cmdinfo->state &= ~IS_IN_WORK_LIST; | ||
170 | if (devinfo->resetting) { | ||
171 | /* uas_stat_cmplt() will not do that | ||
172 | * when a device reset is in | ||
173 | * progress */ | ||
174 | cmdinfo->state &= ~COMMAND_INFLIGHT; | ||
175 | } | ||
176 | uas_try_complete(cmnd, __func__); | ||
177 | } else { | ||
178 | /* not our uas device, relink into list */ | ||
179 | list_del(&cmdinfo->list); | ||
180 | spin_lock_irq(&uas_work_lock); | ||
181 | list_add_tail(&cmdinfo->list, &uas_work_list); | ||
182 | spin_unlock_irq(&uas_work_lock); | ||
183 | } | ||
184 | } | ||
185 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
186 | } | ||
187 | |||
120 | static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) | 188 | static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) |
121 | { | 189 | { |
122 | struct sense_iu *sense_iu = urb->transfer_buffer; | 190 | struct sense_iu *sense_iu = urb->transfer_buffer; |
@@ -168,7 +236,7 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller) | |||
168 | struct uas_cmd_info *ci = (void *)&cmnd->SCp; | 236 | struct uas_cmd_info *ci = (void *)&cmnd->SCp; |
169 | 237 | ||
170 | scmd_printk(KERN_INFO, cmnd, "%s %p tag %d, inflight:" | 238 | scmd_printk(KERN_INFO, cmnd, "%s %p tag %d, inflight:" |
171 | "%s%s%s%s%s%s%s%s%s%s%s%s\n", | 239 | "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", |
172 | caller, cmnd, cmnd->request->tag, | 240 | caller, cmnd, cmnd->request->tag, |
173 | (ci->state & SUBMIT_STATUS_URB) ? " s-st" : "", | 241 | (ci->state & SUBMIT_STATUS_URB) ? " s-st" : "", |
174 | (ci->state & ALLOC_DATA_IN_URB) ? " a-in" : "", | 242 | (ci->state & ALLOC_DATA_IN_URB) ? " a-in" : "", |
@@ -181,7 +249,9 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller) | |||
181 | (ci->state & DATA_IN_URB_INFLIGHT) ? " IN" : "", | 249 | (ci->state & DATA_IN_URB_INFLIGHT) ? " IN" : "", |
182 | (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT" : "", | 250 | (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT" : "", |
183 | (ci->state & COMMAND_COMPLETED) ? " done" : "", | 251 | (ci->state & COMMAND_COMPLETED) ? " done" : "", |
184 | (ci->state & COMMAND_ABORTED) ? " abort" : ""); | 252 | (ci->state & COMMAND_ABORTED) ? " abort" : "", |
253 | (ci->state & UNLINK_DATA_URBS) ? " unlink": "", | ||
254 | (ci->state & IS_IN_WORK_LIST) ? " work" : ""); | ||
185 | } | 255 | } |
186 | 256 | ||
187 | static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) | 257 | static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) |
@@ -192,7 +262,8 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) | |||
192 | WARN_ON(!spin_is_locked(&devinfo->lock)); | 262 | WARN_ON(!spin_is_locked(&devinfo->lock)); |
193 | if (cmdinfo->state & (COMMAND_INFLIGHT | | 263 | if (cmdinfo->state & (COMMAND_INFLIGHT | |
194 | DATA_IN_URB_INFLIGHT | | 264 | DATA_IN_URB_INFLIGHT | |
195 | DATA_OUT_URB_INFLIGHT)) | 265 | DATA_OUT_URB_INFLIGHT | |
266 | UNLINK_DATA_URBS)) | ||
196 | return -EBUSY; | 267 | return -EBUSY; |
197 | BUG_ON(cmdinfo->state & COMMAND_COMPLETED); | 268 | BUG_ON(cmdinfo->state & COMMAND_COMPLETED); |
198 | cmdinfo->state |= COMMAND_COMPLETED; | 269 | cmdinfo->state |= COMMAND_COMPLETED; |
@@ -217,6 +288,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, | |||
217 | if (err) { | 288 | if (err) { |
218 | spin_lock(&uas_work_lock); | 289 | spin_lock(&uas_work_lock); |
219 | list_add_tail(&cmdinfo->list, &uas_work_list); | 290 | list_add_tail(&cmdinfo->list, &uas_work_list); |
291 | cmdinfo->state |= IS_IN_WORK_LIST; | ||
220 | spin_unlock(&uas_work_lock); | 292 | spin_unlock(&uas_work_lock); |
221 | schedule_work(&uas_work); | 293 | schedule_work(&uas_work); |
222 | } | 294 | } |
@@ -274,16 +346,9 @@ static void uas_stat_cmplt(struct urb *urb) | |||
274 | uas_sense(urb, cmnd); | 346 | uas_sense(urb, cmnd); |
275 | if (cmnd->result != 0) { | 347 | if (cmnd->result != 0) { |
276 | /* cancel data transfers on error */ | 348 | /* cancel data transfers on error */ |
277 | if (cmdinfo->state & DATA_IN_URB_INFLIGHT) { | 349 | spin_unlock_irqrestore(&devinfo->lock, flags); |
278 | spin_unlock_irqrestore(&devinfo->lock, flags); | 350 | uas_unlink_data_urbs(devinfo, cmdinfo); |
279 | usb_unlink_urb(cmdinfo->data_in_urb); | 351 | spin_lock_irqsave(&devinfo->lock, flags); |
280 | spin_lock_irqsave(&devinfo->lock, flags); | ||
281 | } | ||
282 | if (cmdinfo->state & DATA_OUT_URB_INFLIGHT) { | ||
283 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
284 | usb_unlink_urb(cmdinfo->data_out_urb); | ||
285 | spin_lock_irqsave(&devinfo->lock, flags); | ||
286 | } | ||
287 | } | 352 | } |
288 | cmdinfo->state &= ~COMMAND_INFLIGHT; | 353 | cmdinfo->state &= ~COMMAND_INFLIGHT; |
289 | uas_try_complete(cmnd, __func__); | 354 | uas_try_complete(cmnd, __func__); |
@@ -579,6 +644,12 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
579 | 644 | ||
580 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); | 645 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); |
581 | 646 | ||
647 | if (devinfo->resetting) { | ||
648 | cmnd->result = DID_ERROR << 16; | ||
649 | cmnd->scsi_done(cmnd); | ||
650 | return 0; | ||
651 | } | ||
652 | |||
582 | spin_lock_irqsave(&devinfo->lock, flags); | 653 | spin_lock_irqsave(&devinfo->lock, flags); |
583 | if (devinfo->cmnd) { | 654 | if (devinfo->cmnd) { |
584 | spin_unlock_irqrestore(&devinfo->lock, flags); | 655 | spin_unlock_irqrestore(&devinfo->lock, flags); |
@@ -623,6 +694,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
623 | } | 694 | } |
624 | spin_lock(&uas_work_lock); | 695 | spin_lock(&uas_work_lock); |
625 | list_add_tail(&cmdinfo->list, &uas_work_list); | 696 | list_add_tail(&cmdinfo->list, &uas_work_list); |
697 | cmdinfo->state |= IS_IN_WORK_LIST; | ||
626 | spin_unlock(&uas_work_lock); | 698 | spin_unlock(&uas_work_lock); |
627 | schedule_work(&uas_work); | 699 | schedule_work(&uas_work); |
628 | } | 700 | } |
@@ -689,8 +761,23 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) | |||
689 | uas_log_cmd_state(cmnd, __func__); | 761 | uas_log_cmd_state(cmnd, __func__); |
690 | spin_lock_irqsave(&devinfo->lock, flags); | 762 | spin_lock_irqsave(&devinfo->lock, flags); |
691 | cmdinfo->state |= COMMAND_ABORTED; | 763 | cmdinfo->state |= COMMAND_ABORTED; |
692 | spin_unlock_irqrestore(&devinfo->lock, flags); | 764 | if (cmdinfo->state & IS_IN_WORK_LIST) { |
693 | ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK); | 765 | spin_lock(&uas_work_lock); |
766 | list_del(&cmdinfo->list); | ||
767 | cmdinfo->state &= ~IS_IN_WORK_LIST; | ||
768 | spin_unlock(&uas_work_lock); | ||
769 | } | ||
770 | if (cmdinfo->state & COMMAND_INFLIGHT) { | ||
771 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
772 | ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK); | ||
773 | } else { | ||
774 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
775 | uas_unlink_data_urbs(devinfo, cmdinfo); | ||
776 | spin_lock_irqsave(&devinfo->lock, flags); | ||
777 | uas_try_complete(cmnd, __func__); | ||
778 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
779 | ret = SUCCESS; | ||
780 | } | ||
694 | return ret; | 781 | return ret; |
695 | } | 782 | } |
696 | 783 | ||
@@ -709,6 +796,7 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
709 | int err; | 796 | int err; |
710 | 797 | ||
711 | devinfo->resetting = 1; | 798 | devinfo->resetting = 1; |
799 | uas_abort_work(devinfo); | ||
712 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | 800 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); |
713 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | 801 | usb_kill_anchored_urbs(&devinfo->sense_urbs); |
714 | usb_kill_anchored_urbs(&devinfo->data_urbs); | 802 | usb_kill_anchored_urbs(&devinfo->data_urbs); |
@@ -903,6 +991,8 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
903 | 991 | ||
904 | shost->max_cmd_len = 16 + 252; | 992 | shost->max_cmd_len = 16 + 252; |
905 | shost->max_id = 1; | 993 | shost->max_id = 1; |
994 | shost->max_lun = 256; | ||
995 | shost->max_channel = 0; | ||
906 | shost->sg_tablesize = udev->bus->sg_tablesize; | 996 | shost->sg_tablesize = udev->bus->sg_tablesize; |
907 | 997 | ||
908 | devinfo->intf = intf; | 998 | devinfo->intf = intf; |
@@ -954,10 +1044,12 @@ static void uas_disconnect(struct usb_interface *intf) | |||
954 | struct Scsi_Host *shost = usb_get_intfdata(intf); | 1044 | struct Scsi_Host *shost = usb_get_intfdata(intf); |
955 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 1045 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; |
956 | 1046 | ||
957 | scsi_remove_host(shost); | 1047 | devinfo->resetting = 1; |
1048 | uas_abort_work(devinfo); | ||
958 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | 1049 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); |
959 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | 1050 | usb_kill_anchored_urbs(&devinfo->sense_urbs); |
960 | usb_kill_anchored_urbs(&devinfo->data_urbs); | 1051 | usb_kill_anchored_urbs(&devinfo->data_urbs); |
1052 | scsi_remove_host(shost); | ||
961 | uas_free_streams(devinfo); | 1053 | uas_free_streams(devinfo); |
962 | kfree(devinfo); | 1054 | kfree(devinfo); |
963 | } | 1055 | } |
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h index 2c8553026222..65a6a75066a8 100644 --- a/drivers/usb/storage/unusual_cypress.h +++ b/drivers/usb/storage/unusual_cypress.h | |||
@@ -31,7 +31,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, | |||
31 | "Cypress ISD-300LP", | 31 | "Cypress ISD-300LP", |
32 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), | 32 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), |
33 | 33 | ||
34 | UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x9999, | 34 | UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x0219, |
35 | "Super Top", | 35 | "Super Top", |
36 | "USB 2.0 SATA BRIDGE", | 36 | "USB 2.0 SATA BRIDGE", |
37 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), | 37 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index cf09b6ba71ff..d6bee407af02 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -988,6 +988,9 @@ int usb_stor_probe2(struct us_data *us) | |||
988 | if (us->fflags & US_FL_SINGLE_LUN) | 988 | if (us->fflags & US_FL_SINGLE_LUN) |
989 | us->max_lun = 0; | 989 | us->max_lun = 0; |
990 | 990 | ||
991 | if (!(us->fflags & US_FL_SCM_MULT_TARG)) | ||
992 | us_to_host(us)->max_id = 1; | ||
993 | |||
991 | /* Find the endpoints and calculate pipe values */ | 994 | /* Find the endpoints and calculate pipe values */ |
992 | result = get_pipes(us); | 995 | result = get_pipes(us); |
993 | if (result) | 996 | if (result) |
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 57c01ab09ad8..6ef94bce8c0d 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
@@ -695,9 +695,9 @@ error_dto_alloc: | |||
695 | cnt--; | 695 | cnt--; |
696 | error_seg_kzalloc: | 696 | error_seg_kzalloc: |
697 | /* use the fact that cnt is left at were it failed */ | 697 | /* use the fact that cnt is left at were it failed */ |
698 | for (; cnt > 0; cnt--) { | 698 | for (; cnt >= 0; cnt--) { |
699 | if (xfer->is_inbound == 0) | 699 | if (xfer->seg[cnt] && xfer->is_inbound == 0) |
700 | kfree(xfer->seg[cnt]->dto_urb); | 700 | usb_free_urb(xfer->seg[cnt]->dto_urb); |
701 | kfree(xfer->seg[cnt]); | 701 | kfree(xfer->seg[cnt]); |
702 | } | 702 | } |
703 | error_segs_kzalloc: | 703 | error_segs_kzalloc: |