diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-27 12:32:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-27 12:32:20 -0400 |
commit | 1993cbf06aa95c0fcf080f2e858c116306b6c29e (patch) | |
tree | 48fed02d854e4a1133fcd380da5627401e6292d4 /drivers/usb/core/phy.c | |
parent | 7ff5000268355c63dc948ecb01f4de17987586e5 (diff) | |
parent | 573a094873752d225041b1059a662eca013a54f4 (diff) |
Merge tag 'usb-4.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH:
"Here are a number of USB driver fixes for reported problems for
4.17-rc3.
The "largest" here is a number of phy core changes for reported
problems with the -rc1 release. There's also the usual musb and xhci
fixes, as well as new device id updates. There are also some usbip
fixes for reported problems as more people start to use that code with
containers.
All of these have been in linux-next with no reported issues, except
the last few new device ids, which are "obviously correct" :)"
* tag 'usb-4.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (26 commits)
USB: musb: dsps: drop duplicate phy initialisation
USB: musb: host: prevent core phy initialisation
usb: core: phy: add the SPDX-License-Identifier and include guard
xhci: Fix Kernel oops in xhci dbgtty
usb: select USB_COMMON for usb role switch config
usb: core: phy: add missing forward declaration for "struct device"
usb: core: phy: make it a no-op if CONFIG_GENERIC_PHY is disabled
usb: core: use phy_exit during suspend if wake up is not supported
usb: core: split usb_phy_roothub_{init,alloc}
usb: core: phy: fix return value of usb_phy_roothub_exit()
usb: typec: ucsi: Increase command completion timeout value
Revert "xhci: plat: Register shutdown for xhci_plat"
usb: core: Add quirk for HP v222w 16GB Mini
Documentation: typec.rst: Use literal-block element with ascii art
usb: typec: ucsi: fix tracepoint related build error
usbip: usbip_event: fix to not print kernel pointer address
usbip: usbip_host: fix to hold parent lock for device_attach() calls
usbip: vhci_hcd: Fix usb device and sockfd leaks
usbip: vhci_hcd: check rhport before using in vhci_hub_control()
USB: Increment wakeup count on remote wakeup.
...
Diffstat (limited to 'drivers/usb/core/phy.c')
-rw-r--r-- | drivers/usb/core/phy.c | 93 |
1 files changed, 66 insertions, 27 deletions
diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 09b7c43c0ea4..9879767452a2 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c | |||
@@ -19,19 +19,6 @@ struct usb_phy_roothub { | |||
19 | struct list_head list; | 19 | struct list_head list; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) | ||
23 | { | ||
24 | struct usb_phy_roothub *roothub_entry; | ||
25 | |||
26 | roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); | ||
27 | if (!roothub_entry) | ||
28 | return ERR_PTR(-ENOMEM); | ||
29 | |||
30 | INIT_LIST_HEAD(&roothub_entry->list); | ||
31 | |||
32 | return roothub_entry; | ||
33 | } | ||
34 | |||
35 | static int usb_phy_roothub_add_phy(struct device *dev, int index, | 22 | static int usb_phy_roothub_add_phy(struct device *dev, int index, |
36 | struct list_head *list) | 23 | struct list_head *list) |
37 | { | 24 | { |
@@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, | |||
45 | return PTR_ERR(phy); | 32 | return PTR_ERR(phy); |
46 | } | 33 | } |
47 | 34 | ||
48 | roothub_entry = usb_phy_roothub_alloc(dev); | 35 | roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); |
49 | if (IS_ERR(roothub_entry)) | 36 | if (!roothub_entry) |
50 | return PTR_ERR(roothub_entry); | 37 | return -ENOMEM; |
38 | |||
39 | INIT_LIST_HEAD(&roothub_entry->list); | ||
51 | 40 | ||
52 | roothub_entry->phy = phy; | 41 | roothub_entry->phy = phy; |
53 | 42 | ||
@@ -56,28 +45,44 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, | |||
56 | return 0; | 45 | return 0; |
57 | } | 46 | } |
58 | 47 | ||
59 | struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) | 48 | struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) |
60 | { | 49 | { |
61 | struct usb_phy_roothub *phy_roothub; | 50 | struct usb_phy_roothub *phy_roothub; |
62 | struct usb_phy_roothub *roothub_entry; | ||
63 | struct list_head *head; | ||
64 | int i, num_phys, err; | 51 | int i, num_phys, err; |
65 | 52 | ||
53 | if (!IS_ENABLED(CONFIG_GENERIC_PHY)) | ||
54 | return NULL; | ||
55 | |||
66 | num_phys = of_count_phandle_with_args(dev->of_node, "phys", | 56 | num_phys = of_count_phandle_with_args(dev->of_node, "phys", |
67 | "#phy-cells"); | 57 | "#phy-cells"); |
68 | if (num_phys <= 0) | 58 | if (num_phys <= 0) |
69 | return NULL; | 59 | return NULL; |
70 | 60 | ||
71 | phy_roothub = usb_phy_roothub_alloc(dev); | 61 | phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); |
72 | if (IS_ERR(phy_roothub)) | 62 | if (!phy_roothub) |
73 | return phy_roothub; | 63 | return ERR_PTR(-ENOMEM); |
64 | |||
65 | INIT_LIST_HEAD(&phy_roothub->list); | ||
74 | 66 | ||
75 | for (i = 0; i < num_phys; i++) { | 67 | for (i = 0; i < num_phys; i++) { |
76 | err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); | 68 | err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); |
77 | if (err) | 69 | if (err) |
78 | goto err_out; | 70 | return ERR_PTR(err); |
79 | } | 71 | } |
80 | 72 | ||
73 | return phy_roothub; | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc); | ||
76 | |||
77 | int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub) | ||
78 | { | ||
79 | struct usb_phy_roothub *roothub_entry; | ||
80 | struct list_head *head; | ||
81 | int err; | ||
82 | |||
83 | if (!phy_roothub) | ||
84 | return 0; | ||
85 | |||
81 | head = &phy_roothub->list; | 86 | head = &phy_roothub->list; |
82 | 87 | ||
83 | list_for_each_entry(roothub_entry, head, list) { | 88 | list_for_each_entry(roothub_entry, head, list) { |
@@ -86,14 +91,13 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) | |||
86 | goto err_exit_phys; | 91 | goto err_exit_phys; |
87 | } | 92 | } |
88 | 93 | ||
89 | return phy_roothub; | 94 | return 0; |
90 | 95 | ||
91 | err_exit_phys: | 96 | err_exit_phys: |
92 | list_for_each_entry_continue_reverse(roothub_entry, head, list) | 97 | list_for_each_entry_continue_reverse(roothub_entry, head, list) |
93 | phy_exit(roothub_entry->phy); | 98 | phy_exit(roothub_entry->phy); |
94 | 99 | ||
95 | err_out: | 100 | return err; |
96 | return ERR_PTR(err); | ||
97 | } | 101 | } |
98 | EXPORT_SYMBOL_GPL(usb_phy_roothub_init); | 102 | EXPORT_SYMBOL_GPL(usb_phy_roothub_init); |
99 | 103 | ||
@@ -111,7 +115,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub) | |||
111 | list_for_each_entry(roothub_entry, head, list) { | 115 | list_for_each_entry(roothub_entry, head, list) { |
112 | err = phy_exit(roothub_entry->phy); | 116 | err = phy_exit(roothub_entry->phy); |
113 | if (err) | 117 | if (err) |
114 | ret = ret; | 118 | ret = err; |
115 | } | 119 | } |
116 | 120 | ||
117 | return ret; | 121 | return ret; |
@@ -156,3 +160,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) | |||
156 | phy_power_off(roothub_entry->phy); | 160 | phy_power_off(roothub_entry->phy); |
157 | } | 161 | } |
158 | EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); | 162 | EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); |
163 | |||
164 | int usb_phy_roothub_suspend(struct device *controller_dev, | ||
165 | struct usb_phy_roothub *phy_roothub) | ||
166 | { | ||
167 | usb_phy_roothub_power_off(phy_roothub); | ||
168 | |||
169 | /* keep the PHYs initialized so the device can wake up the system */ | ||
170 | if (device_may_wakeup(controller_dev)) | ||
171 | return 0; | ||
172 | |||
173 | return usb_phy_roothub_exit(phy_roothub); | ||
174 | } | ||
175 | EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); | ||
176 | |||
177 | int usb_phy_roothub_resume(struct device *controller_dev, | ||
178 | struct usb_phy_roothub *phy_roothub) | ||
179 | { | ||
180 | int err; | ||
181 | |||
182 | /* if the device can't wake up the system _exit was called */ | ||
183 | if (!device_may_wakeup(controller_dev)) { | ||
184 | err = usb_phy_roothub_init(phy_roothub); | ||
185 | if (err) | ||
186 | return err; | ||
187 | } | ||
188 | |||
189 | err = usb_phy_roothub_power_on(phy_roothub); | ||
190 | |||
191 | /* undo _init if _power_on failed */ | ||
192 | if (err && !device_may_wakeup(controller_dev)) | ||
193 | usb_phy_roothub_exit(phy_roothub); | ||
194 | |||
195 | return err; | ||
196 | } | ||
197 | EXPORT_SYMBOL_GPL(usb_phy_roothub_resume); | ||