* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-14 18:27 ` [PATCH 2/2] USB: misc: Add onboard_usb_hub driver Matthias Kaehlcke
@ 2020-09-14 19:52 ` Matthias Kaehlcke
2020-09-14 20:14 ` Alan Stern
` (2 subsequent siblings)
3 siblings, 0 replies; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-14 19:52 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Frank Rowand
Cc: Alan Stern, Krzysztof Kozlowski, Bastien Nocera,
Ravi Chandra Sadineni, linux-usb, Stephen Boyd, devicetree,
Douglas Anderson, Peter Chen, linux-kernel, Alexander A. Klimov,
Masahiro Yamada
Hi,
I just noticed that building this results in a compilation error, due
to a missing brace. I tested this patch, but with another patch on top
with debug logs, the other patch adds the brace.
I'll still hold off a bit before sending v2, for if others have
comments.
On Mon, Sep 14, 2020 at 11:27:49AM -0700, Matthias Kaehlcke wrote:
> diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c
> new file mode 100644
> index 000000000000..e5a816d0b124
> --- /dev/null
> +++ b/drivers/usb/misc/onboard_usb_hub.c
>
> +static int onboard_hub_suspend(struct platform_device *pdev, pm_message_t msg)
> +{
> + struct onboard_hub *hub = dev_get_drvdata(&pdev->dev);
> + int rc = 0;
> +
> + if (!hub->cfg.power_off_in_suspend)
> + return 0;
> +
> + hub->has_wakeup_capable_descendants = false;
> +
> + if (hub->cfg.wakeup_source) {
> + struct udev_node *node;
> +
> + mutex_lock(&hub->lock);
> +
> + list_for_each_entry(node, &hub->udev_list, list) {
> + if (usb_wakeup_enabled_descendants(node->udev)) {
> + hub->has_wakeup_capable_descendants = true;
> + break;
missing brace here: }
> + }
> +
> + mutex_unlock(&hub->lock);
> + }
> +
> + if (!hub->has_wakeup_capable_descendants)
> + rc = onboard_hub_power_off(hub);
> +
> + return rc;
> +}
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-14 18:27 ` [PATCH 2/2] USB: misc: Add onboard_usb_hub driver Matthias Kaehlcke
2020-09-14 19:52 ` Matthias Kaehlcke
@ 2020-09-14 20:14 ` Alan Stern
2020-09-14 21:14 ` Matthias Kaehlcke
2020-09-15 2:32 ` kernel test robot
2020-09-15 2:55 ` Peter Chen
3 siblings, 1 reply; 23+ messages in thread
From: Alan Stern @ 2020-09-14 20:14 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb, Stephen Boyd, devicetree, Douglas Anderson, Peter Chen,
linux-kernel, Alexander A. Klimov, Masahiro Yamada
On Mon, Sep 14, 2020 at 11:27:49AM -0700, Matthias Kaehlcke wrote:
> The main issue this driver addresses is that a USB hub needs to be
> powered before it can be discovered. For onboard hubs this is often
> solved by supplying the hub with an 'always-on' regulator, which is
> kind of a hack. Some onboard hubs may require further initialization
> steps, like changing the state of a GPIO or enabling a clock, which
> requires further hacks. This driver creates a platform device
> representing the hub which performs the necessary initialization.
> Currently it only supports switching on a single regulator, support
> for multiple regulators or other actions can be added as needed.
> Different initialization sequences can be supported based on the
> compatible string.
>
> Besides performing the initialization the driver can be configured
> to power the hub off during system suspend. This can help to extend
> battery life on battery powered devices, which have no requirements
> to keep the hub powered during suspend. The driver can also be
> configured to leave the hub powered when a wakeup capable USB device
> is connected when suspending, and keeping it powered otherwise.
>
> Technically the driver consists of two drivers, the platform driver
> described above and a very thin USB driver that subclasses the
> generic hub driver.
Actually it subclasses the generic usb device driver, not the hub
driver.
> The purpose of this driver is to provide the
> platform driver with the USB devices corresponding to the hub(s)
> (a hub controller may provide multiple 'logical' hubs, e.g. one
> to support USB 2.0 and another for USB 3.x).
>
> Co-developed-by: Ravi Chandra Sadineni <ravisadineni@chromium.org>
> Signed-off-by: Ravi Chandra Sadineni <ravisadineni@chromium.org>
> Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
> ---
> This is an evolution of '[RFC] USB: misc: Add usb_hub_pwr driver'
> (https://lore.kernel.org/patchwork/patch/1299239/).
>
> Changes in v1:
> - renamed the driver to 'onboard_usb_hub'
> - single file for platform and USB driver
> - USB hub devices register with the platform device
> - the DT includes a phandle of the platform device
> - the platform device now controls when power is turned off
> - the USB driver became a very thin subclass of the generic hub
> driver
> - enabled autosuspend support
See https://marc.info/?l=linux-usb&m=159914635920888&w=2 and the
accompanying submissions. You'll probably want to include those updates
in your driver.
Alan Stern
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-14 20:14 ` Alan Stern
@ 2020-09-14 21:14 ` Matthias Kaehlcke
0 siblings, 0 replies; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-14 21:14 UTC (permalink / raw)
To: Alan Stern
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb, Stephen Boyd, devicetree, Douglas Anderson, Peter Chen,
linux-kernel, Alexander A. Klimov, Masahiro Yamada
Hi Alan,
thanks for your feedback!
On Mon, Sep 14, 2020 at 04:14:03PM -0400, Alan Stern wrote:
> On Mon, Sep 14, 2020 at 11:27:49AM -0700, Matthias Kaehlcke wrote:
> > The main issue this driver addresses is that a USB hub needs to be
> > powered before it can be discovered. For onboard hubs this is often
> > solved by supplying the hub with an 'always-on' regulator, which is
> > kind of a hack. Some onboard hubs may require further initialization
> > steps, like changing the state of a GPIO or enabling a clock, which
> > requires further hacks. This driver creates a platform device
> > representing the hub which performs the necessary initialization.
> > Currently it only supports switching on a single regulator, support
> > for multiple regulators or other actions can be added as needed.
> > Different initialization sequences can be supported based on the
> > compatible string.
> >
> > Besides performing the initialization the driver can be configured
> > to power the hub off during system suspend. This can help to extend
> > battery life on battery powered devices, which have no requirements
> > to keep the hub powered during suspend. The driver can also be
> > configured to leave the hub powered when a wakeup capable USB device
> > is connected when suspending, and keeping it powered otherwise.
> >
> > Technically the driver consists of two drivers, the platform driver
> > described above and a very thin USB driver that subclasses the
> > generic hub driver.
>
> Actually it subclasses the generic usb device driver, not the hub
> driver.
ok, I'll change it in the next version.
> > The purpose of this driver is to provide the
> > platform driver with the USB devices corresponding to the hub(s)
> > (a hub controller may provide multiple 'logical' hubs, e.g. one
> > to support USB 2.0 and another for USB 3.x).
> >
> > Co-developed-by: Ravi Chandra Sadineni <ravisadineni@chromium.org>
> > Signed-off-by: Ravi Chandra Sadineni <ravisadineni@chromium.org>
> > Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
> > ---
> > This is an evolution of '[RFC] USB: misc: Add usb_hub_pwr driver'
> > (https://lore.kernel.org/patchwork/patch/1299239/).
> >
> > Changes in v1:
> > - renamed the driver to 'onboard_usb_hub'
> > - single file for platform and USB driver
> > - USB hub devices register with the platform device
> > - the DT includes a phandle of the platform device
> > - the platform device now controls when power is turned off
> > - the USB driver became a very thin subclass of the generic hub
> > driver
> > - enabled autosuspend support
>
> See https://marc.info/?l=linux-usb&m=159914635920888&w=2 and the
> accompanying submissions. You'll probably want to include those updates
> in your driver.
Thanks for the pointer! I'll change the driver to use pm_ptr as suggested.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-14 18:27 ` [PATCH 2/2] USB: misc: Add onboard_usb_hub driver Matthias Kaehlcke
2020-09-14 19:52 ` Matthias Kaehlcke
2020-09-14 20:14 ` Alan Stern
@ 2020-09-15 2:32 ` kernel test robot
2020-09-15 2:55 ` Peter Chen
3 siblings, 0 replies; 23+ messages in thread
From: kernel test robot @ 2020-09-15 2:32 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 15300 bytes --]
Hi Matthias,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on usb/usb-testing]
[also build test ERROR on robh/for-next balbi-usb/testing/next peter.chen-usb/ci-for-usb-next v5.9-rc5 next-20200914]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Matthias-Kaehlcke/dt-bindings-usb-Add-binding-for-onboard-USB-hubs/20200915-024225
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: sh-allmodconfig (attached as .config)
compiler: sh4-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sh
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
drivers/usb/misc/onboard_usb_hub.c: In function 'onboard_hub_suspend':
>> drivers/usb/misc/onboard_usb_hub.c:98:12: error: invalid storage class for function 'onboard_hub_resume'
98 | static int onboard_hub_resume(struct platform_device *pdev)
| ^~~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:98:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
98 | static int onboard_hub_resume(struct platform_device *pdev)
| ^~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:111:12: error: invalid storage class for function 'onboard_hub_add_usbdev'
111 | static int onboard_hub_add_usbdev(struct onboard_hub *hub, struct usb_device *udev)
| ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:128:12: error: invalid storage class for function 'onboard_hub_remove_usbdev'
128 | static int onboard_hub_remove_usbdev(struct onboard_hub *hub, struct usb_device *udev)
| ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:150:12: error: invalid storage class for function 'onboard_hub_probe'
150 | static int onboard_hub_probe(struct platform_device *pdev)
| ^~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:175:12: error: invalid storage class for function 'onboard_hub_remove'
175 | static int onboard_hub_remove(struct platform_device *pdev)
| ^~~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:187:1: warning: 'alias' attribute ignored [-Wattributes]
187 | MODULE_DEVICE_TABLE(of, onboard_hub_match);
| ^~~~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:190:11: error: initializer element is not constant
190 | .probe = onboard_hub_probe,
| ^~~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:190:11: note: (near initialization for 'onboard_hub_driver.probe')
drivers/usb/misc/onboard_usb_hub.c:191:12: error: initializer element is not constant
191 | .remove = onboard_hub_remove,
| ^~~~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:191:12: note: (near initialization for 'onboard_hub_driver.remove')
drivers/usb/misc/onboard_usb_hub.c:194:12: error: initializer element is not constant
194 | .resume = onboard_hub_resume,
| ^~~~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:194:12: note: (near initialization for 'onboard_hub_driver.resume')
>> drivers/usb/misc/onboard_usb_hub.c:206:28: error: invalid storage class for function '_find_onboard_hub'
206 | static struct onboard_hub *_find_onboard_hub(struct device *dev)
| ^~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:232:12: error: invalid storage class for function 'onboard_hub_usbdev_probe'
232 | static int onboard_hub_usbdev_probe(struct usb_device *udev)
| ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:252:13: error: invalid storage class for function 'onboard_hub_usbdev_disconnect'
252 | static void onboard_hub_usbdev_disconnect(struct usb_device *udev)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:271:1: warning: 'alias' attribute ignored [-Wattributes]
271 | MODULE_DEVICE_TABLE(usb, onboard_hub_id_table);
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:276:11: error: initializer element is not constant
276 | .probe = onboard_hub_usbdev_probe,
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:276:11: note: (near initialization for 'onboard_hub_usbdev_driver.probe')
drivers/usb/misc/onboard_usb_hub.c:277:16: error: initializer element is not constant
277 | .disconnect = onboard_hub_usbdev_disconnect,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:277:16: note: (near initialization for 'onboard_hub_usbdev_driver.disconnect')
>> drivers/usb/misc/onboard_usb_hub.c:285:19: error: invalid storage class for function 'onboard_hub_init'
285 | static int __init onboard_hub_init(void)
| ^~~~~~~~~~~~~~~~
In file included from drivers/usb/misc/onboard_usb_hub.c:10:
include/linux/module.h:131:42: error: invalid storage class for function '__inittest'
131 | static inline initcall_t __maybe_unused __inittest(void) \
| ^~~~~~~~~~
include/linux/module.h:122:30: note: in expansion of macro 'module_init'
122 | #define device_initcall(fn) module_init(fn)
| ^~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:295:1: note: in expansion of macro 'device_initcall'
295 | device_initcall(onboard_hub_init);
| ^~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:295:1: warning: 'alias' attribute ignored [-Wattributes]
>> drivers/usb/misc/onboard_usb_hub.c:297:20: error: invalid storage class for function 'onboard_hub_exit'
297 | static void __exit onboard_hub_exit(void)
| ^~~~~~~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:297:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
297 | static void __exit onboard_hub_exit(void)
| ^~~~~~
In file included from drivers/usb/misc/onboard_usb_hub.c:10:
include/linux/module.h:137:42: error: invalid storage class for function '__exittest'
137 | static inline exitcall_t __maybe_unused __exittest(void) \
| ^~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:302:1: note: in expansion of macro 'module_exit'
302 | module_exit(onboard_hub_exit);
| ^~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:302:1: warning: 'alias' attribute ignored [-Wattributes]
In file included from include/linux/module.h:21,
from drivers/usb/misc/onboard_usb_hub.c:10:
include/linux/moduleparam.h:24:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
24 | static const char __UNIQUE_ID(name)[] \
| ^~~~~~
include/linux/module.h:162:32: note: in expansion of macro '__MODULE_INFO'
162 | #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
| ^~~~~~~~~~~~~
include/linux/module.h:232:32: note: in expansion of macro 'MODULE_INFO'
232 | #define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
| ^~~~~~~~~~~
drivers/usb/misc/onboard_usb_hub.c:304:1: note: in expansion of macro 'MODULE_AUTHOR'
304 | MODULE_AUTHOR("Matthias Kaehlcke <mka@chromium.org>");
| ^~~~~~~~~~~~~
>> drivers/usb/misc/onboard_usb_hub.c:306:1: error: expected declaration or statement at end of input
306 | MODULE_LICENSE("GPL v2");
| ^~~~~~~~~~~~~~
At top level:
drivers/usb/misc/onboard_usb_hub.c:68:12: warning: 'onboard_hub_suspend' defined but not used [-Wunused-function]
68 | static int onboard_hub_suspend(struct platform_device *pdev, pm_message_t msg)
| ^~~~~~~~~~~~~~~~~~~
# https://github.com/0day-ci/linux/commit/81bbd2f3188c281e1c2f3fccb36d53d6ff3d9a89
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Matthias-Kaehlcke/dt-bindings-usb-Add-binding-for-onboard-USB-hubs/20200915-024225
git checkout 81bbd2f3188c281e1c2f3fccb36d53d6ff3d9a89
vim +/onboard_hub_resume +98 drivers/usb/misc/onboard_usb_hub.c
97
> 98 static int onboard_hub_resume(struct platform_device *pdev)
99 {
100 struct onboard_hub *hub = dev_get_drvdata(&pdev->dev);
101 int rc = 0;
102
103 if (hub->cfg.power_off_in_suspend && !hub->has_wakeup_capable_descendants)
104 rc = onboard_hub_power_on(hub);
105
106 return rc;
107 }
108
109 #endif
110
> 111 static int onboard_hub_add_usbdev(struct onboard_hub *hub, struct usb_device *udev)
112 {
113 struct udev_node *node;
114
115 node = devm_kzalloc(hub->dev, sizeof(*node), GFP_KERNEL);
116 if (!node)
117 return -ENOMEM;
118
119 node->udev = udev;
120
121 mutex_lock(&hub->lock);
122 list_add(&node->list, &hub->udev_list);
123 mutex_unlock(&hub->lock);
124
125 return 0;
126 }
127
> 128 static int onboard_hub_remove_usbdev(struct onboard_hub *hub, struct usb_device *udev)
129 {
130 struct udev_node *node;
131
132 mutex_lock(&hub->lock);
133
134 list_for_each_entry(node, &hub->udev_list, list) {
135 if (node->udev == udev) {
136 list_del(&node->list);
137 devm_kfree(hub->dev, node);
138 break;
139 }
140 }
141
142 mutex_unlock(&hub->lock);
143
144 if (node == NULL)
145 return -EINVAL;
146
147 return 0;
148 }
149
> 150 static int onboard_hub_probe(struct platform_device *pdev)
151 {
152 struct device *dev = &pdev->dev;
153 struct onboard_hub *hub;
154
155 hub = devm_kzalloc(dev, sizeof(*hub), GFP_KERNEL);
156 if (!hub)
157 return -ENOMEM;
158
159 hub->vdd = devm_regulator_get(dev, "vdd");
160 if (IS_ERR(hub->vdd))
161 return PTR_ERR(hub->vdd);
162
163 hub->dev = dev;
164 mutex_init(&hub->lock);
165 INIT_LIST_HEAD(&hub->udev_list);
166
167 hub->cfg.power_off_in_suspend = of_property_read_bool(dev->of_node, "power-off-in-suspend");
168 hub->cfg.wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source");
169
170 dev_set_drvdata(dev, hub);
171
172 return onboard_hub_power_on(hub);
173 }
174
> 175 static int onboard_hub_remove(struct platform_device *pdev)
176 {
177 struct onboard_hub *hub = dev_get_drvdata(&pdev->dev);
178
179 return onboard_hub_power_off(hub);
180 }
181
182 static const struct of_device_id onboard_hub_match[] = {
183 { .compatible = "onboard-usb-hub" },
184 { .compatible = "realtek,rts5411" },
185 {}
186 };
> 187 MODULE_DEVICE_TABLE(of, onboard_hub_match);
188
189 static struct platform_driver onboard_hub_driver = {
> 190 .probe = onboard_hub_probe,
> 191 .remove = onboard_hub_remove,
192 #ifdef CONFIG_PM
193 .suspend = onboard_hub_suspend,
> 194 .resume = onboard_hub_resume,
195 #endif
196 .driver = {
197 .name = "onboard-usb-hub",
198 .of_match_table = onboard_hub_match,
199 },
200 };
201
202 /************************** USB driver **************************/
203
204 #define VENDOR_ID_REALTEK 0x0bda
205
> 206 static struct onboard_hub *_find_onboard_hub(struct device *dev)
207 {
208 const phandle *ph;
209 struct device_node *np;
210 struct platform_device *pdev;
211
212 ph = of_get_property(dev->of_node, "hub", NULL);
213 if (!ph) {
214 dev_err(dev, "failed to read 'hub' property\n");
215 return ERR_PTR(-EINVAL);
216 }
217
218 np = of_find_node_by_phandle(be32_to_cpu(*ph));
219 if (!np) {
220 dev_err(dev, "failed find device node for onboard hub\n");
221 return ERR_PTR(-EINVAL);
222 }
223
224 pdev = of_find_device_by_node(np);
225 of_node_put(np);
226 if (!pdev)
227 return ERR_PTR(-EPROBE_DEFER);
228
229 return dev_get_drvdata(&pdev->dev);
230 }
231
> 232 static int onboard_hub_usbdev_probe(struct usb_device *udev)
233 {
234 struct device *dev = &udev->dev;
235 struct onboard_hub *hub;
236
237 /* ignore supported hubs without device tree node */
238 if (!dev->of_node)
239 return -ENODEV;
240
241 hub = _find_onboard_hub(dev);
242 if (IS_ERR(hub))
243 return PTR_ERR(dev);
244
245 dev_set_drvdata(dev, hub);
246
247 onboard_hub_add_usbdev(hub, udev);
248
249 return 0;
250 }
251
> 252 static void onboard_hub_usbdev_disconnect(struct usb_device *udev)
253 {
254 struct onboard_hub *hub = dev_get_drvdata(&udev->dev);
255
256 onboard_hub_remove_usbdev(hub, udev);
257
258 put_device(hub->dev);
259 }
260
261 static const struct usb_device_id onboard_hub_id_table[] = {
262 { .idVendor = VENDOR_ID_REALTEK,
263 .idProduct = 0x0411, /* RTS5411 USB 3.0 */
264 .match_flags = USB_DEVICE_ID_MATCH_DEVICE },
265 { .idVendor = VENDOR_ID_REALTEK,
266 .idProduct = 0x5411, /* RTS5411 USB 2.0 */
267 .match_flags = USB_DEVICE_ID_MATCH_DEVICE },
268 {},
269 };
270
271 MODULE_DEVICE_TABLE(usb, onboard_hub_id_table);
272
273 static struct usb_device_driver onboard_hub_usbdev_driver = {
274
275 .name = "onboard-usb-hub",
> 276 .probe = onboard_hub_usbdev_probe,
277 .disconnect = onboard_hub_usbdev_disconnect,
278 .generic_subclass = 1,
279 .supports_autosuspend = 1,
280 .id_table = onboard_hub_id_table,
281 };
282
283 /************************** Driver (de)registration **************************/
284
> 285 static int __init onboard_hub_init(void)
286 {
287 int rc;
288
289 rc = platform_driver_register(&onboard_hub_driver);
290 if (rc)
291 return rc;
292
293 return usb_register_device_driver(&onboard_hub_usbdev_driver, THIS_MODULE);
294 }
> 295 device_initcall(onboard_hub_init);
296
> 297 static void __exit onboard_hub_exit(void)
298 {
299 usb_deregister_device_driver(&onboard_hub_usbdev_driver);
300 platform_driver_unregister(&onboard_hub_driver);
301 }
302 module_exit(onboard_hub_exit);
303
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 52725 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-14 18:27 ` [PATCH 2/2] USB: misc: Add onboard_usb_hub driver Matthias Kaehlcke
` (2 preceding siblings ...)
2020-09-15 2:32 ` kernel test robot
@ 2020-09-15 2:55 ` Peter Chen
2020-09-15 5:02 ` Matthias Kaehlcke
3 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2020-09-15 2:55 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
On 20-09-14 11:27:49, Matthias Kaehlcke wrote:
> The main issue this driver addresses is that a USB hub needs to be
> powered before it can be discovered. For onboard hubs this is often
> solved by supplying the hub with an 'always-on' regulator, which is
> kind of a hack. Some onboard hubs may require further initialization
> steps, like changing the state of a GPIO or enabling a clock, which
> requires further hacks. This driver creates a platform device
> representing the hub which performs the necessary initialization.
> Currently it only supports switching on a single regulator, support
> for multiple regulators or other actions can be added as needed.
> Different initialization sequences can be supported based on the
> compatible string.
>
> Besides performing the initialization the driver can be configured
> to power the hub off during system suspend. This can help to extend
> battery life on battery powered devices, which have no requirements
> to keep the hub powered during suspend. The driver can also be
> configured to leave the hub powered when a wakeup capable USB device
> is connected when suspending, and keeping it powered otherwise.
>
> Technically the driver consists of two drivers, the platform driver
> described above and a very thin USB driver that subclasses the
> generic hub driver. The purpose of this driver is to provide the
> platform driver with the USB devices corresponding to the hub(s)
> (a hub controller may provide multiple 'logical' hubs, e.g. one
> to support USB 2.0 and another for USB 3.x).
I agree with Alan, you may change this driver to apply for generic
onboard USB devices.
> +static int onboard_hub_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct onboard_hub *hub;
> +
> + hub = devm_kzalloc(dev, sizeof(*hub), GFP_KERNEL);
> + if (!hub)
> + return -ENOMEM;
> +
> + hub->vdd = devm_regulator_get(dev, "vdd");
> + if (IS_ERR(hub->vdd))
> + return PTR_ERR(hub->vdd);
> +
> + hub->dev = dev;
> + mutex_init(&hub->lock);
> + INIT_LIST_HEAD(&hub->udev_list);
> +
> + hub->cfg.power_off_in_suspend = of_property_read_bool(dev->of_node, "power-off-in-suspend");
> + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source");
Do you really need these two properties? If the device (and its children
if existed) has wakeup enabled, you keep power in suspend, otherwise,
you could close it, any exceptions?
Peter
> +
> + dev_set_drvdata(dev, hub);
> +
> + return onboard_hub_power_on(hub);
> +}
> +
> +static int onboard_hub_remove(struct platform_device *pdev)
> +{
> + struct onboard_hub *hub = dev_get_drvdata(&pdev->dev);
> +
> + return onboard_hub_power_off(hub);
> +}
> +
> +static const struct of_device_id onboard_hub_match[] = {
> + { .compatible = "onboard-usb-hub" },
> + { .compatible = "realtek,rts5411" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, onboard_hub_match);
> +
> +static struct platform_driver onboard_hub_driver = {
> + .probe = onboard_hub_probe,
> + .remove = onboard_hub_remove,
> +#ifdef CONFIG_PM
> + .suspend = onboard_hub_suspend,
> + .resume = onboard_hub_resume,
> +#endif
> + .driver = {
> + .name = "onboard-usb-hub",
> + .of_match_table = onboard_hub_match,
> + },
> +};
> +
> +/************************** USB driver **************************/
> +
> +#define VENDOR_ID_REALTEK 0x0bda
> +
> +static struct onboard_hub *_find_onboard_hub(struct device *dev)
> +{
> + const phandle *ph;
> + struct device_node *np;
> + struct platform_device *pdev;
> +
> + ph = of_get_property(dev->of_node, "hub", NULL);
> + if (!ph) {
> + dev_err(dev, "failed to read 'hub' property\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + np = of_find_node_by_phandle(be32_to_cpu(*ph));
> + if (!np) {
> + dev_err(dev, "failed find device node for onboard hub\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + pdev = of_find_device_by_node(np);
> + of_node_put(np);
> + if (!pdev)
> + return ERR_PTR(-EPROBE_DEFER);
> +
> + return dev_get_drvdata(&pdev->dev);
> +}
> +
> +static int onboard_hub_usbdev_probe(struct usb_device *udev)
> +{
> + struct device *dev = &udev->dev;
> + struct onboard_hub *hub;
> +
> + /* ignore supported hubs without device tree node */
> + if (!dev->of_node)
> + return -ENODEV;
> +
> + hub = _find_onboard_hub(dev);
> + if (IS_ERR(hub))
> + return PTR_ERR(dev);
> +
> + dev_set_drvdata(dev, hub);
> +
> + onboard_hub_add_usbdev(hub, udev);
> +
> + return 0;
> +}
> +
> +static void onboard_hub_usbdev_disconnect(struct usb_device *udev)
> +{
> + struct onboard_hub *hub = dev_get_drvdata(&udev->dev);
> +
> + onboard_hub_remove_usbdev(hub, udev);
> +
> + put_device(hub->dev);
> +}
> +
> +static const struct usb_device_id onboard_hub_id_table[] = {
> + { .idVendor = VENDOR_ID_REALTEK,
> + .idProduct = 0x0411, /* RTS5411 USB 3.0 */
> + .match_flags = USB_DEVICE_ID_MATCH_DEVICE },
> + { .idVendor = VENDOR_ID_REALTEK,
> + .idProduct = 0x5411, /* RTS5411 USB 2.0 */
> + .match_flags = USB_DEVICE_ID_MATCH_DEVICE },
> + {},
> +};
> +
> +MODULE_DEVICE_TABLE(usb, onboard_hub_id_table);
> +
> +static struct usb_device_driver onboard_hub_usbdev_driver = {
> +
> + .name = "onboard-usb-hub",
> + .probe = onboard_hub_usbdev_probe,
> + .disconnect = onboard_hub_usbdev_disconnect,
> + .generic_subclass = 1,
> + .supports_autosuspend = 1,
> + .id_table = onboard_hub_id_table,
> +};
> +
> +/************************** Driver (de)registration **************************/
> +
> +static int __init onboard_hub_init(void)
> +{
> + int rc;
> +
> + rc = platform_driver_register(&onboard_hub_driver);
> + if (rc)
> + return rc;
> +
> + return usb_register_device_driver(&onboard_hub_usbdev_driver, THIS_MODULE);
> +}
> +device_initcall(onboard_hub_init);
> +
> +static void __exit onboard_hub_exit(void)
> +{
> + usb_deregister_device_driver(&onboard_hub_usbdev_driver);
> + platform_driver_unregister(&onboard_hub_driver);
> +}
> +module_exit(onboard_hub_exit);
> +
> +MODULE_AUTHOR("Matthias Kaehlcke <mka@chromium.org>");
> +MODULE_DESCRIPTION("Onboard USB Hub driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.28.0.618.gf4bc123cb7-goog
>
--
Thanks,
Peter Chen
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-15 2:55 ` Peter Chen
@ 2020-09-15 5:02 ` Matthias Kaehlcke
2020-09-15 7:05 ` Peter Chen
0 siblings, 1 reply; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-15 5:02 UTC (permalink / raw)
To: Peter Chen
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
Hi Peter,
thanks for your comments!
On Tue, Sep 15, 2020 at 02:55:06AM +0000, Peter Chen wrote:
> On 20-09-14 11:27:49, Matthias Kaehlcke wrote:
> > The main issue this driver addresses is that a USB hub needs to be
> > powered before it can be discovered. For onboard hubs this is often
> > solved by supplying the hub with an 'always-on' regulator, which is
> > kind of a hack. Some onboard hubs may require further initialization
> > steps, like changing the state of a GPIO or enabling a clock, which
> > requires further hacks. This driver creates a platform device
> > representing the hub which performs the necessary initialization.
> > Currently it only supports switching on a single regulator, support
> > for multiple regulators or other actions can be added as needed.
> > Different initialization sequences can be supported based on the
> > compatible string.
> >
> > Besides performing the initialization the driver can be configured
> > to power the hub off during system suspend. This can help to extend
> > battery life on battery powered devices, which have no requirements
> > to keep the hub powered during suspend. The driver can also be
> > configured to leave the hub powered when a wakeup capable USB device
> > is connected when suspending, and keeping it powered otherwise.
> >
> > Technically the driver consists of two drivers, the platform driver
> > described above and a very thin USB driver that subclasses the
> > generic hub driver. The purpose of this driver is to provide the
> > platform driver with the USB devices corresponding to the hub(s)
> > (a hub controller may provide multiple 'logical' hubs, e.g. one
> > to support USB 2.0 and another for USB 3.x).
>
> I agree with Alan, you may change this driver to apply for generic
> onboard USB devices.
I interpreted that Alan only corrected my terminology and didn't
suggest to extend the driver to generic onboard devices. Actually I
like that we now have a abstraction for a specific physical 'device',
rather than the initial usb_hub_pwr/usb_hub_psupply split, which seemed
a bit contrived (thanks Doug!).
> > +static int onboard_hub_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct onboard_hub *hub;
> > +
> > + hub = devm_kzalloc(dev, sizeof(*hub), GFP_KERNEL);
> > + if (!hub)
> > + return -ENOMEM;
> > +
> > + hub->vdd = devm_regulator_get(dev, "vdd");
> > + if (IS_ERR(hub->vdd))
> > + return PTR_ERR(hub->vdd);
> > +
> > + hub->dev = dev;
> > + mutex_init(&hub->lock);
> > + INIT_LIST_HEAD(&hub->udev_list);
> > +
> > + hub->cfg.power_off_in_suspend = of_property_read_bool(dev->of_node, "power-off-in-suspend");
> > + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source");
>
> Do you really need these two properties? If the device (and its children
> if existed) has wakeup enabled, you keep power in suspend, otherwise,
> you could close it, any exceptions?
That would work for my use case, but I'm not sure it's a universally
good configuration.
I don't have a specific USB device in mind, but you could have a device
that shouldn't lose it's context during suspend or keep operating
autonomously (e.g. a sensor with a large buffer collecting samples). Not
sure if something like this exists in the real though.
I'm not an expert, but it seems there are USB controllers with wakeup
support which is always enabled. A board with such a controller then
couldn't have a policy to power down the hub regardless of wakeup
capable devices being connected.
Thanks
Matthias
^ permalink raw reply [flat|nested] 23+ messages in thread* RE: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-15 5:02 ` Matthias Kaehlcke
@ 2020-09-15 7:05 ` Peter Chen
2020-09-15 23:03 ` Matthias Kaehlcke
0 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2020-09-15 7:05 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
> > > + hub->cfg.power_off_in_suspend =
> of_property_read_bool(dev->of_node, "power-off-in-suspend");
> > > + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node,
> > > +"wakeup-source");
> >
> > Do you really need these two properties? If the device (and its
> > children if existed) has wakeup enabled, you keep power in suspend,
> > otherwise, you could close it, any exceptions?
>
> That would work for my use case, but I'm not sure it's a universally good
> configuration.
>
> I don't have a specific USB device in mind, but you could have a device that
> shouldn't lose it's context during suspend or keep operating autonomously (e.g.
> a sensor with a large buffer collecting samples). Not sure if something like this
> exists in the real though.
>
> I'm not an expert, but it seems there are USB controllers with wakeup support
> which is always enabled. A board with such a controller then couldn't have a
> policy to power down the hub regardless of wakeup capable devices being
> connected.
>
Whether or not it is a wakeup_source, it could get through its or its children's /sys/../power/wakeup
value, you have already used usb_wakeup_enabled_descendants to know it. If the onboard HUB
needs to reflect wakeup signal, it should not power off its regulator.
For another property power-off-in-suspend, I think it is also a user option, but not a hardware feature.
If (wakeup-source || ! power-off-in-suspend)
power off;
else
keep power;
Peter
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-15 7:05 ` Peter Chen
@ 2020-09-15 23:03 ` Matthias Kaehlcke
2020-09-16 2:14 ` Alan Stern
2020-09-16 8:19 ` Peter Chen
0 siblings, 2 replies; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-15 23:03 UTC (permalink / raw)
To: Peter Chen
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
Hi Peter,
On Tue, Sep 15, 2020 at 07:05:38AM +0000, Peter Chen wrote:
>
> > > > + hub->cfg.power_off_in_suspend =
> > of_property_read_bool(dev->of_node, "power-off-in-suspend");
> > > > + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node,
> > > > +"wakeup-source");
> > >
> > > Do you really need these two properties? If the device (and its
> > > children if existed) has wakeup enabled, you keep power in suspend,
> > > otherwise, you could close it, any exceptions?
> >
> > That would work for my use case, but I'm not sure it's a universally good
> > configuration.
> >
> > I don't have a specific USB device in mind, but you could have a device that
> > shouldn't lose it's context during suspend or keep operating autonomously (e.g.
> > a sensor with a large buffer collecting samples). Not sure if something like this
> > exists in the real though.
> >
> > I'm not an expert, but it seems there are USB controllers with wakeup support
> > which is always enabled. A board with such a controller then couldn't have a
> > policy to power down the hub regardless of wakeup capable devices being
> > connected.
> >
>
> Whether or not it is a wakeup_source, it could get through its or its children's
> /sys/../power/wakeup value, you have already used usb_wakeup_enabled_descendants
> to know it.
I conceptually agree, but in practice there are some conflicting details:
wakeup for the hubs on my system is by default disabled, yet USB wakeup works
regardless, so the flag doesn't really provide useful information. I guess we
could still use it if there is no better way, but it doesn't seem ideal.
Similar for udev->bus->controller, according to sysfs it doesn't even have wakeup
support. Please let me know if there is a reliable way to check if wakeup is
enabled on the controller of a device.
> If the onboard HUB needs to reflect wakeup signal, it should not power off its regulator.
>
> For another property power-off-in-suspend, I think it is also a user option,
> but not a hardware feature.
Ok, I think you are suggesting a sysfs attribute instead of a DT property, that
sounds good to me.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-15 23:03 ` Matthias Kaehlcke
@ 2020-09-16 2:14 ` Alan Stern
2020-09-16 19:27 ` Matthias Kaehlcke
2020-09-16 8:19 ` Peter Chen
1 sibling, 1 reply; 23+ messages in thread
From: Alan Stern @ 2020-09-16 2:14 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Peter Chen, Greg Kroah-Hartman, Rob Herring, Frank Rowand,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
On Tue, Sep 15, 2020 at 04:03:45PM -0700, Matthias Kaehlcke wrote:
> Hi Peter,
>
> On Tue, Sep 15, 2020 at 07:05:38AM +0000, Peter Chen wrote:
> > Whether or not it is a wakeup_source, it could get through its or its children's
> > /sys/../power/wakeup value, you have already used usb_wakeup_enabled_descendants
> > to know it.
>
> I conceptually agree, but in practice there are some conflicting details:
>
> wakeup for the hubs on my system is by default disabled, yet USB wakeup works
> regardless, so the flag doesn't really provide useful information. I guess we
> could still use it if there is no better way, but it doesn't seem ideal.
The wakeup setting for USB hubs affects only the following events: port
connect, port disconnect, and port overcurrent. It does not refer to
forwarding wakeup requests from downstream USB devices; that is always
enabled. So maybe your wakeup flag really is accurate and you didn't
realize it.
> Similar for udev->bus->controller, according to sysfs it doesn't even have wakeup
> support. Please let me know if there is a reliable way to check if wakeup is
> enabled on the controller of a device.
The host controller's sysfs wakeup setting should always be correct. If
it isn't, that indicates there is a bug in the host controller driver or
the corresponding platform-specific code. What driver does your system
use?
Alan Stern
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-16 2:14 ` Alan Stern
@ 2020-09-16 19:27 ` Matthias Kaehlcke
0 siblings, 0 replies; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-16 19:27 UTC (permalink / raw)
To: Alan Stern
Cc: Peter Chen, Greg Kroah-Hartman, Rob Herring, Frank Rowand,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
On Tue, Sep 15, 2020 at 10:14:21PM -0400, Alan Stern wrote:
> On Tue, Sep 15, 2020 at 04:03:45PM -0700, Matthias Kaehlcke wrote:
> > Hi Peter,
> >
> > On Tue, Sep 15, 2020 at 07:05:38AM +0000, Peter Chen wrote:
>
> > > Whether or not it is a wakeup_source, it could get through its or its children's
> > > /sys/../power/wakeup value, you have already used usb_wakeup_enabled_descendants
> > > to know it.
> >
> > I conceptually agree, but in practice there are some conflicting details:
> >
> > wakeup for the hubs on my system is by default disabled, yet USB wakeup works
> > regardless, so the flag doesn't really provide useful information. I guess we
> > could still use it if there is no better way, but it doesn't seem ideal.
>
> The wakeup setting for USB hubs affects only the following events: port
> connect, port disconnect, and port overcurrent. It does not refer to
> forwarding wakeup requests from downstream USB devices; that is always
> enabled. So maybe your wakeup flag really is accurate and you didn't
> realize it.
Thanks for the clarification!
> > Similar for udev->bus->controller, according to sysfs it doesn't even have wakeup
> > support. Please let me know if there is a reliable way to check if wakeup is
> > enabled on the controller of a device.
>
> The host controller's sysfs wakeup setting should always be correct. If
> it isn't, that indicates there is a bug in the host controller driver or
> the corresponding platform-specific code.
Good to know :)
> What driver does your system use?
The driver is dwc3-qcom, Peter pointed me to a patch he recently sent to add
the missing wakeup entry (https://patchwork.kernel.org/patch/11717835/). It
seems that should solve the problem, except for some confusion on my side
about the wakeup flag of the xHCI device vs. that of the platform device
(details in my reply to Peter).
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-15 23:03 ` Matthias Kaehlcke
2020-09-16 2:14 ` Alan Stern
@ 2020-09-16 8:19 ` Peter Chen
2020-09-16 19:16 ` Matthias Kaehlcke
1 sibling, 1 reply; 23+ messages in thread
From: Peter Chen @ 2020-09-16 8:19 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
On 20-09-15 16:03:45, Matthias Kaehlcke wrote:
> Hi Peter,
>
> On Tue, Sep 15, 2020 at 07:05:38AM +0000, Peter Chen wrote:
> >
> > > > > + hub->cfg.power_off_in_suspend =
> > > of_property_read_bool(dev->of_node, "power-off-in-suspend");
> > > > > + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node,
> > > > > +"wakeup-source");
> > > >
> > > > Do you really need these two properties? If the device (and its
> > > > children if existed) has wakeup enabled, you keep power in suspend,
> > > > otherwise, you could close it, any exceptions?
> > >
> > > That would work for my use case, but I'm not sure it's a universally good
> > > configuration.
> > >
> > > I don't have a specific USB device in mind, but you could have a device that
> > > shouldn't lose it's context during suspend or keep operating autonomously (e.g.
> > > a sensor with a large buffer collecting samples). Not sure if something like this
> > > exists in the real though.
> > >
> > > I'm not an expert, but it seems there are USB controllers with wakeup support
> > > which is always enabled. A board with such a controller then couldn't have a
> > > policy to power down the hub regardless of wakeup capable devices being
> > > connected.
> > >
> >
> > Whether or not it is a wakeup_source, it could get through its or its children's
> > /sys/../power/wakeup value, you have already used usb_wakeup_enabled_descendants
> > to know it.
>
> I conceptually agree, but in practice there are some conflicting details:
>
> wakeup for the hubs on my system is by default disabled, yet USB wakeup works
> regardless, so the flag doesn't really provide useful information. I guess we
> could still use it if there is no better way, but it doesn't seem ideal.
>
> Similar for udev->bus->controller, according to sysfs it doesn't even have wakeup
> support. Please let me know if there is a reliable way to check if wakeup is
> enabled on the controller of a device.
Then, how could your code work, you use usb_wakeup_enabled_descendants
to get if HUB or the descendants under the HUB has wakeup enabled?
If you use dwc3, you need to enable xhci-plat.c's wakeup entry if your
system needs xHCI connect/disconnect wakeup event. I have one pending
patch to do it:
https://www.spinics.net/lists/linux-usb/msg199406.html
>
> > If the onboard HUB needs to reflect wakeup signal, it should not power off its regulator.
> >
> > For another property power-off-in-suspend, I think it is also a user option,
> > but not a hardware feature.
>
> Ok, I think you are suggesting a sysfs attribute instead of a DT property, that
> sounds good to me.
Yes.
--
Thanks,
Peter Chen
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-16 8:19 ` Peter Chen
@ 2020-09-16 19:16 ` Matthias Kaehlcke
2020-09-17 0:27 ` Peter Chen
0 siblings, 1 reply; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-16 19:16 UTC (permalink / raw)
To: Peter Chen
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
Hi Peter,
On Wed, Sep 16, 2020 at 08:19:07AM +0000, Peter Chen wrote:
> On 20-09-15 16:03:45, Matthias Kaehlcke wrote:
> > Hi Peter,
> >
> > On Tue, Sep 15, 2020 at 07:05:38AM +0000, Peter Chen wrote:
> > >
> > > > > > + hub->cfg.power_off_in_suspend =
> > > > of_property_read_bool(dev->of_node, "power-off-in-suspend");
> > > > > > + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node,
> > > > > > +"wakeup-source");
> > > > >
> > > > > Do you really need these two properties? If the device (and its
> > > > > children if existed) has wakeup enabled, you keep power in suspend,
> > > > > otherwise, you could close it, any exceptions?
> > > >
> > > > That would work for my use case, but I'm not sure it's a universally good
> > > > configuration.
> > > >
> > > > I don't have a specific USB device in mind, but you could have a device that
> > > > shouldn't lose it's context during suspend or keep operating autonomously (e.g.
> > > > a sensor with a large buffer collecting samples). Not sure if something like this
> > > > exists in the real though.
> > > >
> > > > I'm not an expert, but it seems there are USB controllers with wakeup support
> > > > which is always enabled. A board with such a controller then couldn't have a
> > > > policy to power down the hub regardless of wakeup capable devices being
> > > > connected.
> > > >
> > >
> > > Whether or not it is a wakeup_source, it could get through its or its children's
> > > /sys/../power/wakeup value, you have already used usb_wakeup_enabled_descendants
> > > to know it.
> >
> > I conceptually agree, but in practice there are some conflicting details:
> >
> > wakeup for the hubs on my system is by default disabled, yet USB wakeup works
> > regardless, so the flag doesn't really provide useful information. I guess we
> > could still use it if there is no better way, but it doesn't seem ideal.
> >
> > Similar for udev->bus->controller, according to sysfs it doesn't even have wakeup
> > support. Please let me know if there is a reliable way to check if wakeup is
> > enabled on the controller of a device.
>
> Then, how could your code work, you use usb_wakeup_enabled_descendants
> to get if HUB or the descendants under the HUB has wakeup enabled?
Doing just that would not allow to switch the hub off when wakeup enabled
descendants are connected, which might be desirable in some configurations.
> If you use dwc3, you need to enable xhci-plat.c's wakeup entry if your
> system needs xHCI connect/disconnect wakeup event. I have one pending
> patch to do it:
>
> https://www.spinics.net/lists/linux-usb/msg199406.html
Thanks, my system has indeed a dwc3(-qcom) controller, your patch adds
the missing wakeup entry to sysfs. So it seems your patch should solve
my problem (sharp timing!), however you mention specifically the 'xHCI
connect/disconnect wakeup event', so I wonder if the xHCI wakeup flag
isn't applicable to other wakeup events. I know the dwc3-qcom platform
device has its own wakeup flag. The driver currently enables wakeup
interrupts unconditionally, I sent a patch to change that
(https://lore.kernel.org/patchwork/patch/1305894/), however I now wonder
if it should evaluate the xHCI wakeup flag instead of its own.
Thanks
Matthias
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-16 19:16 ` Matthias Kaehlcke
@ 2020-09-17 0:27 ` Peter Chen
2020-09-17 0:47 ` Matthias Kaehlcke
0 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2020-09-17 0:27 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
On 20-09-16 12:16:07, Matthias Kaehlcke wrote:
> Hi Peter,
>
> On Wed, Sep 16, 2020 at 08:19:07AM +0000, Peter Chen wrote:
> > On 20-09-15 16:03:45, Matthias Kaehlcke wrote:
> > > Hi Peter,
> > >
> > > On Tue, Sep 15, 2020 at 07:05:38AM +0000, Peter Chen wrote:
> > > >
> > > > > > > + hub->cfg.power_off_in_suspend =
> > > > > of_property_read_bool(dev->of_node, "power-off-in-suspend");
> > > > > > > + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node,
> > > > > > > +"wakeup-source");
> > > > > >
> > > > > > Do you really need these two properties? If the device (and its
> > > > > > children if existed) has wakeup enabled, you keep power in suspend,
> > > > > > otherwise, you could close it, any exceptions?
> > > > >
> > > > > That would work for my use case, but I'm not sure it's a universally good
> > > > > configuration.
> > > > >
> > > > > I don't have a specific USB device in mind, but you could have a device that
> > > > > shouldn't lose it's context during suspend or keep operating autonomously (e.g.
> > > > > a sensor with a large buffer collecting samples). Not sure if something like this
> > > > > exists in the real though.
> > > > >
> > > > > I'm not an expert, but it seems there are USB controllers with wakeup support
> > > > > which is always enabled. A board with such a controller then couldn't have a
> > > > > policy to power down the hub regardless of wakeup capable devices being
> > > > > connected.
> > > > >
> > > >
> > > > Whether or not it is a wakeup_source, it could get through its or its children's
> > > > /sys/../power/wakeup value, you have already used usb_wakeup_enabled_descendants
> > > > to know it.
> > >
> > > I conceptually agree, but in practice there are some conflicting details:
> > >
> > > wakeup for the hubs on my system is by default disabled, yet USB wakeup works
> > > regardless, so the flag doesn't really provide useful information. I guess we
> > > could still use it if there is no better way, but it doesn't seem ideal.
> > >
> > > Similar for udev->bus->controller, according to sysfs it doesn't even have wakeup
> > > support. Please let me know if there is a reliable way to check if wakeup is
> > > enabled on the controller of a device.
> >
> > Then, how could your code work, you use usb_wakeup_enabled_descendants
> > to get if HUB or the descendants under the HUB has wakeup enabled?
>
> Doing just that would not allow to switch the hub off when wakeup enabled
> descendants are connected, which might be desirable in some configurations.
>
> > If you use dwc3, you need to enable xhci-plat.c's wakeup entry if your
> > system needs xHCI connect/disconnect wakeup event. I have one pending
> > patch to do it:
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.spinics.net%2Flists%2Flinux-usb%2Fmsg199406.html&data=02%7C01%7Cpeter.chen%40nxp.com%7C02c4cc75e26a47d0224d08d85a74f945%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637358805725394858&sdata=cjZhSmQiXVJoLsN5PjFACsLwsikH%2BeRTztPhsckJFNs%3D&reserved=0
>
> Thanks, my system has indeed a dwc3(-qcom) controller, your patch adds
> the missing wakeup entry to sysfs. So it seems your patch should solve
> my problem (sharp timing!), however you mention specifically the 'xHCI
> connect/disconnect wakeup event', so I wonder if the xHCI wakeup flag
> isn't applicable to other wakeup events. I know the dwc3-qcom platform
> device has its own wakeup flag. The driver currently enables wakeup
> interrupts unconditionally, I sent a patch to change that
> (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fpatchwork%2Fpatch%2F1305894%2F&data=02%7C01%7Cpeter.chen%40nxp.com%7C02c4cc75e26a47d0224d08d85a74f945%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637358805725394858&sdata=6IjiiHJql%2FW4vzDla9q3qdfiiOzOQy1Vk7ryUhKOOTc%3D&reserved=0), however I now wonder
> if it should evaluate the xHCI wakeup flag instead of its own.
>
You may need both (glue & xhci), it depends on system design, and
usually, these two kinds of wakeup setting isn't conflict.
--
Thanks,
Peter Chen
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-17 0:27 ` Peter Chen
@ 2020-09-17 0:47 ` Matthias Kaehlcke
2020-09-17 1:24 ` Peter Chen
0 siblings, 1 reply; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-17 0:47 UTC (permalink / raw)
To: Peter Chen
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
On Thu, Sep 17, 2020 at 12:27:29AM +0000, Peter Chen wrote:
> On 20-09-16 12:16:07, Matthias Kaehlcke wrote:
> > Hi Peter,
> >
> > On Wed, Sep 16, 2020 at 08:19:07AM +0000, Peter Chen wrote:
> > > On 20-09-15 16:03:45, Matthias Kaehlcke wrote:
> > > > Hi Peter,
> > > >
> > > > On Tue, Sep 15, 2020 at 07:05:38AM +0000, Peter Chen wrote:
> > > > >
> > > > > > > > + hub->cfg.power_off_in_suspend =
> > > > > > of_property_read_bool(dev->of_node, "power-off-in-suspend");
> > > > > > > > + hub->cfg.wakeup_source = of_property_read_bool(dev->of_node,
> > > > > > > > +"wakeup-source");
> > > > > > >
> > > > > > > Do you really need these two properties? If the device (and its
> > > > > > > children if existed) has wakeup enabled, you keep power in suspend,
> > > > > > > otherwise, you could close it, any exceptions?
> > > > > >
> > > > > > That would work for my use case, but I'm not sure it's a universally good
> > > > > > configuration.
> > > > > >
> > > > > > I don't have a specific USB device in mind, but you could have a device that
> > > > > > shouldn't lose it's context during suspend or keep operating autonomously (e.g.
> > > > > > a sensor with a large buffer collecting samples). Not sure if something like this
> > > > > > exists in the real though.
> > > > > >
> > > > > > I'm not an expert, but it seems there are USB controllers with wakeup support
> > > > > > which is always enabled. A board with such a controller then couldn't have a
> > > > > > policy to power down the hub regardless of wakeup capable devices being
> > > > > > connected.
> > > > > >
> > > > >
> > > > > Whether or not it is a wakeup_source, it could get through its or its children's
> > > > > /sys/../power/wakeup value, you have already used usb_wakeup_enabled_descendants
> > > > > to know it.
> > > >
> > > > I conceptually agree, but in practice there are some conflicting details:
> > > >
> > > > wakeup for the hubs on my system is by default disabled, yet USB wakeup works
> > > > regardless, so the flag doesn't really provide useful information. I guess we
> > > > could still use it if there is no better way, but it doesn't seem ideal.
> > > >
> > > > Similar for udev->bus->controller, according to sysfs it doesn't even have wakeup
> > > > support. Please let me know if there is a reliable way to check if wakeup is
> > > > enabled on the controller of a device.
> > >
> > > Then, how could your code work, you use usb_wakeup_enabled_descendants
> > > to get if HUB or the descendants under the HUB has wakeup enabled?
> >
> > Doing just that would not allow to switch the hub off when wakeup enabled
> > descendants are connected, which might be desirable in some configurations.
> >
> > > If you use dwc3, you need to enable xhci-plat.c's wakeup entry if your
> > > system needs xHCI connect/disconnect wakeup event. I have one pending
> > > patch to do it:
> > >
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.spinics.net%2Flists%2Flinux-usb%2Fmsg199406.html&data=02%7C01%7Cpeter.chen%40nxp.com%7C02c4cc75e26a47d0224d08d85a74f945%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637358805725394858&sdata=cjZhSmQiXVJoLsN5PjFACsLwsikH%2BeRTztPhsckJFNs%3D&reserved=0
> >
> > Thanks, my system has indeed a dwc3(-qcom) controller, your patch adds
> > the missing wakeup entry to sysfs. So it seems your patch should solve
> > my problem (sharp timing!), however you mention specifically the 'xHCI
> > connect/disconnect wakeup event', so I wonder if the xHCI wakeup flag
> > isn't applicable to other wakeup events. I know the dwc3-qcom platform
> > device has its own wakeup flag. The driver currently enables wakeup
> > interrupts unconditionally, I sent a patch to change that
> > (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fpatchwork%2Fpatch%2F1305894%2F&data=02%7C01%7Cpeter.chen%40nxp.com%7C02c4cc75e26a47d0224d08d85a74f945%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637358805725394858&sdata=6IjiiHJql%2FW4vzDla9q3qdfiiOzOQy1Vk7ryUhKOOTc%3D&reserved=0), however I now wonder
> > if it should evaluate the xHCI wakeup flag instead of its own.
> >
>
> You may need both (glue & xhci), it depends on system design, and
> usually, these two kinds of wakeup setting isn't conflict.
Ok, thanks. So if I understand correctly the onboard hub driver should
check the wakeup state of the xHCI to determine if remote wakeup is
enabled for the controller (after all it doesn't know anything about
the platform device). Wakeup might not work properly if it is disabled
for the platform device, but it's the responsability of the board
software/config to make sure it is enabled (possibly this could be done
by making the dwc3-qcom driver understand the 'wakeup-source' property,
as the xhci-mtk driver does).
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-17 0:47 ` Matthias Kaehlcke
@ 2020-09-17 1:24 ` Peter Chen
2020-09-17 15:54 ` Matthias Kaehlcke
0 siblings, 1 reply; 23+ messages in thread
From: Peter Chen @ 2020-09-17 1:24 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
> > >
> >
> > You may need both (glue & xhci), it depends on system design, and
> > usually, these two kinds of wakeup setting isn't conflict.
>
> Ok, thanks. So if I understand correctly the onboard hub driver should check the
> wakeup state of the xHCI to determine if remote wakeup is enabled for the
> controller (after all it doesn't know anything about the platform device).
> Wakeup might not work properly if it is disabled for the platform device, but it's
> the responsability of the board software/config to make sure it is enabled
> (possibly this could be done by making the dwc3-qcom driver understand the
> 'wakeup-source' property, as the xhci-mtk driver does).
No, every level should handle its own wakeup setting. You may have to do this since the USB bus and platform bus
are two different buses, you should not visit device structure across the bus. And you don't need a device tree property
to do it. For platform driver, you could use device_may_wakeup, for onboard hub power driver, you could use
usb_wakeup_enabled_descendants since you need to cover descendants.
The purpose of these two wakeup logic is different, for USB bus, it is used to tell USB devices to enable remote wakeup
and do not power off its regulator; for platform bus, it is used to tell the controller to enable its wakeup setting and keep
the regulator for its USB controller and USB PHY (if needed).
Peter
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] USB: misc: Add onboard_usb_hub driver
2020-09-17 1:24 ` Peter Chen
@ 2020-09-17 15:54 ` Matthias Kaehlcke
0 siblings, 0 replies; 23+ messages in thread
From: Matthias Kaehlcke @ 2020-09-17 15:54 UTC (permalink / raw)
To: Peter Chen
Cc: Greg Kroah-Hartman, Rob Herring, Frank Rowand, Alan Stern,
Krzysztof Kozlowski, Bastien Nocera, Ravi Chandra Sadineni,
linux-usb@vger.kernel.org, Stephen Boyd,
devicetree@vger.kernel.org, Douglas Anderson,
linux-kernel@vger.kernel.org, Alexander A. Klimov,
Masahiro Yamada
On Thu, Sep 17, 2020 at 01:24:30AM +0000, Peter Chen wrote:
> > > >
> > >
> > > You may need both (glue & xhci), it depends on system design, and
> > > usually, these two kinds of wakeup setting isn't conflict.
> >
> > Ok, thanks. So if I understand correctly the onboard hub driver should check the
> > wakeup state of the xHCI to determine if remote wakeup is enabled for the
> > controller (after all it doesn't know anything about the platform device).
> > Wakeup might not work properly if it is disabled for the platform device, but it's
> > the responsability of the board software/config to make sure it is enabled
> > (possibly this could be done by making the dwc3-qcom driver understand the
> > 'wakeup-source' property, as the xhci-mtk driver does).
>
> No, every level should handle its own wakeup setting. You may have to do this since the USB bus and platform bus
> are two different buses, you should not visit device structure across the bus. And you don't need a device tree property
> to do it. For platform driver, you could use device_may_wakeup, for onboard hub power driver, you could use
> usb_wakeup_enabled_descendants since you need to cover descendants.
>
> The purpose of these two wakeup logic is different, for USB bus, it is used to tell USB devices to enable remote wakeup
> and do not power off its regulator; for platform bus, it is used to tell the controller to enable its wakeup setting and keep
> the regulator for its USB controller and USB PHY (if needed).
Sorry, I didn't express myself clearly. With the platform device I was
referring to the dwc3-qcom ('glue') in this case, which could check
it's own 'wakeup-source' attribute to enable wakeup at boot. The driver
currently enables wakeup statically. The onboard_hub driver is agnostic
of this device.
^ permalink raw reply [flat|nested] 23+ messages in thread