Re: [PATCH v5 10/16] usb: hub: Power on connected M.2 E-key connectors with power sequencing API
Chen-Yu Tsai <[email protected]>
| Newsgroups | org.kernel.vger.linux-acpi,dev.linux.lists.driver-core,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-mediatek,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm,org.kernel.vger.linux-usb |
|---|---|
| Message-ID | <CAGXv+5Ed9Cn-NeHiXJ58er7NJs1P2ZUMrjqYac-gSky-TNV8Lw@mail.gmail.com> |
On Wed, Jul 15, 2026 at 9:25 PM Andy Shevchenko <[email protected]> wrote: > > On Wed, Jul 15, 2026 at 04:53:40PM +0800, Chen-Yu Tsai wrote: > > The new M.2 E-key connector can have a USB connection. For the USB device > > on this connector to work, its power must be enabled and the W_DISABLE2# > > signal deasserted. The connector driver handles this and provides a > > toggle over the power sequencing API. > > > > This feature currently only supports a directly connected (no mux in > > between) M.2 E-key connector. Existing USB connector types are not > > covered. The USB A connector was recently added to the onboard devices > > driver. USB B connectors have historically been managed by the USB > > gadget or dual-role device controller drivers. USB C connectors are > > handled by TCPM drivers. > > > > The power sequencing API does not know whether a power sequence provider > > is not needed or not available yet, so we only request it for connectors > > that we know need it, which at this time is just the E-key connector. > > > > On the USB side, the port firmware node (if present) is tied to the > > usb_port device. This device is used to acquire the power sequencing > > descriptor. This allows the provider to tell the different ports on one > > hub apart. > > > > This feature is not implemented in the onboard USB devices driver. The > > power sequencing API expects the consumer device to make the request, > > but there is no device node to instantiate a platform device to tie > > the driver to. The connector is not a child node of the USB host or > > hub, and the graph connection is from a USB port to the connector. > > And the connector itself already has a driver. > > > > Power sequencing is not directly enabled in the connector driver as > > that would completely decouple the timing of it from the USB subsystem. > > It would not be possible for the USB subsystem to toggle the power > > for a power cycle or to disable the port. > > ... > > > static void usb_port_device_release(struct device *dev) > > > fwnode_handle_put(dev_fwnode(dev)); > > + /* usb_hub_create_port_device() could leave an error value */ > > + if (!IS_ERR(port_dev->pwrseq)) > > + pwrseq_put(port_dev->pwrseq); > > Hmm... I would rather make pwrseq_put() NULL and error pointer-aware, so > it will be no-op in such cases. But I think Bart has his own opinion about > this. > > > kfree(port_dev->req); > > kfree(port_dev); > > } > > > put_device(&port_dev->dev); > > + hub->ports[port1 - 1] = NULL; > > return retval; > > } > > ... > > > int usb_hub_create_port_device(struct usb_hub *hub, int port1) > > > + port_dev->pwrseq = usb_hub_port_pwrseq_get(port_dev); > > + if (IS_ERR(port_dev->pwrseq)) { > > + retval = dev_err_probe(&port_dev->dev, PTR_ERR(port_dev->pwrseq), > > + "failed to get power sequencing descriptor\n"); > > + goto err_put_kn; > > OTOH, how pwrseq can be non-NULL and at the same time port be created? I assume by non-NULL you mean returning an error? device_register(&port_dev->dev) is called some lines above this. usb_port is weird in that usb_hub_create_port_device() does a bunch of stuff that is normally done in a driver's probe function. However usb_port's driver is just a stub driver add for userspace compatibility reasons. See commit d99f6b4130877 ("usb: rename usb_port device objects"). So at this point the usb_port device has been added to the driver model. Or we can just zero out port_dev->pwrseq instead? I guess that is cleaner than having some weird check in the release function. ChenYu