Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Chen-Yu Tsai <wenst@chromium.org>
Cc: Bartosz Golaszewski <brgl@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Daniel Scally <djrscally@gmail.com>,
	Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Sakari Ailus <sakari.ailus@linux.intel.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Danilo Krummrich <dakr@kernel.org>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	Alan Stern <stern@rowland.harvard.edu>,
	linux-acpi@vger.kernel.org, driver-core@lists.linux.dev,
	linux-pm@vger.kernel.org, linux-usb@vger.kernel.org,
	devicetree@vger.kernel.org, linux-mediatek@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Manivannan Sadhasivam <mani@kernel.org>
Subject: Re: [PATCH v2 07/16] usb: hub: Power on connected M.2 E-key connectors
Date: Wed, 10 Jun 2026 17:31:56 +0300	[thread overview]
Message-ID: <ail1XLTIkU7YVvs1@ashevche-desk.local> (raw)
In-Reply-To: <20260610084053.2059858-8-wenst@chromium.org>

On Wed, Jun 10, 2026 at 04:40:41PM +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.
> 
> This change depends on another change to make the power sequencing
> framework bool instead of tristate. The USB core and hub driver are
> bool, so if the power sequencing framework is built as a module, the
> kernel will fail to link.

>  int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub,
>  			   int port1, bool set)
>  {
> -	int ret;
> +	struct usb_port *pwrseq_port = hub->ports[port1 - 1];
> +	int ret = 0;

Don't touch ret here. It's easier to maintain when assignment is closer to it's
first user (because it's getting validated there).

> +	/* non-SuperSpeed USB port holds pwrseq descriptor reference. */
> +	if (hub->ports[port1 - 1]->is_superspeed && hub->ports[port1 - 1]->peer)
> +		pwrseq_port = hub->ports[port1 - 1]->peer;

	ret = 0;

> +	if (set && !pwrseq_port->pwrseq_on)
> +		ret = pwrseq_power_on(pwrseq_port->pwrseq);
> +	else if (!set && pwrseq_port->pwrseq_on)
> +		ret = pwrseq_power_off(pwrseq_port->pwrseq);
> +	if (ret)
> +		return ret;
>  
>  	if (set)
>  		ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
>  	else
>  		ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
>  
> -	if (ret)
> +	if (ret) {
> +		if (set && !pwrseq_port->pwrseq_on)
> +			pwrseq_power_off(pwrseq_port->pwrseq);
> +		else if (!set && pwrseq_port->pwrseq_on)
> +			pwrseq_power_on(pwrseq_port->pwrseq);
>  		return ret;

Can we rather have a couple of helpers? It might be hard to follow all this.
In such a case you won't even need the ret assignment here.


> +	}
>  
> -	if (set)
> +	if (set) {
>  		set_bit(port1, hub->power_bits);
> -	else
> +		pwrseq_port->pwrseq_on = 1;
> +	} else {
>  		clear_bit(port1, hub->power_bits);
> +		pwrseq_port->pwrseq_on = 0;
> +	}

Just

	pwrseq_port->pwrseq_on = set; // or explicit comparison
	assign_bit(port1, hub->power_bits, pwrseq_port->pwrseq_on);

>  	return 0;
>  }

...

> +static bool port_pwrseq_is_supported(struct usb_port *port_dev)
> +{
> +	struct device *dev = &port_dev->dev;
> +	struct fwnode_handle *port = dev->fwnode;

+ blank line here, because for RAII we assume the C99 definitions inside
the code, so one can insert the code in between. Doing it before ep validation
may lead to interesting errors in the future.

> +	struct fwnode_handle *ep __free(fwnode_handle) =
> +			fwnode_graph_get_next_port_endpoint(port, NULL);
> +	if (!ep)
> +		return false;
> +
> +	struct fwnode_handle *remote __free(fwnode_handle) =
> +			fwnode_graph_get_remote_port_parent(ep);
> +	if (!remote)
> +		return false;
> +
> +	if (!fwnode_device_is_compatible(remote, "pcie-m2-e-connector")) {
> +		dev_dbg(dev, "remote endpoint %pfw is not a supported connector", remote);
> +		return false;
> +	}
> +
> +	return true;
> +}

...

> +	if (IS_ERR(port_dev->pwrseq)) {
> +		retval = PTR_ERR(port_dev->pwrseq);
> +		dev_err_probe(&port_dev->dev, retval,
> +			      "failed to get power sequencing descriptor\n");

		retval = dev_err_probe(PTR_ERR(...));

> +		goto err_put_kn;
> +	}

...

>  	retval = component_add(&port_dev->dev, &connector_ops);
>  	if (retval) {
>  		dev_warn(&port_dev->dev, "failed to add component\n");

dev_warn_probe() // however it's not in your patch and was before...

> -		goto err_put_kn;
> +		goto err_pwrseq_off;
>  	}

...

> +err_pwrseq_off:
> +	if (port_dev->pwrseq_on)
> +		pwrseq_power_off(port_dev->pwrseq);

Hmm... I would rather see pwrseq framework to provide something like
_is_powered_on().

	if (pwrseq_is_powered_on())
		_power_off();

...

> +	if (port_dev->pwrseq_on)
> +		pwrseq_power_off(port_dev->pwrseq);

Ditto.

And perhaps even _power_off_if_on() that combines the check and the call.

However it seems that is reference counted and this _power_off() calls won't
guarantee actual power off.

-- 
With Best Regards,
Andy Shevchenko




  reply	other threads:[~2026-06-10 14:32 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10  8:40 [PATCH v2 00/16] arm64: mediatek: Add M.2 E-key slot on Chromebooks Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 01/16] device property: Add fwnode_graph_get_port_by_id() Chen-Yu Tsai
2026-06-10 13:57   ` Andy Shevchenko
2026-06-11  8:15   ` Bartosz Golaszewski
2026-06-10  8:40 ` [PATCH v2 02/16] device property: Add fwnode_graph_get_next_port_endpoint() Chen-Yu Tsai
2026-06-10 14:08   ` Andy Shevchenko
2026-06-10  8:40 ` [PATCH v2 03/16] power: sequencing: Change CONFIG_POWER_SEQUENCING to bool Chen-Yu Tsai
2026-06-10  9:00   ` Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 04/16] usb: hub: Return actual error from hub_configure() in hub_probe() Chen-Yu Tsai
2026-06-10 14:20   ` Andy Shevchenko
2026-06-11  8:17   ` Bartosz Golaszewski
2026-06-10  8:40 ` [PATCH v2 05/16] usb: hub: Associate port@ fwnode with USB port device Chen-Yu Tsai
2026-06-10 14:16   ` Andy Shevchenko
2026-06-11  8:20     ` Bartosz Golaszewski
2026-06-10  8:40 ` [PATCH v2 06/16] usb: hub: Pass |struct usb_port*| to usb_port_is_power_on() Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 07/16] usb: hub: Power on connected M.2 E-key connectors Chen-Yu Tsai
2026-06-10 14:31   ` Andy Shevchenko [this message]
2026-06-10  8:40 ` [PATCH v2 08/16] Revert "dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP" Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 09/16] dt-bindings: usb: mediatek,mtk-xhci: Allow ports for USB connections Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 10/16] power: sequencing: pcie-m2: support matching on remote "port" node Chen-Yu Tsai
2026-06-10 14:33   ` Andy Shevchenko
2026-06-10  8:40 ` [PATCH v2 11/16] power: sequencing: pcie-m2: Add usb and sdio targets for E-key connector Chen-Yu Tsai
2026-06-10 14:36   ` Andy Shevchenko
2026-06-10  8:40 ` [PATCH v2 12/16] arm64: dts: mediatek: mt8192-asurada: Add USB type-A connector Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 13/16] arm64: dts: mediatek: mt8192-asurada: Add M.2 E-key slot Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 14/16] arm64: dts: mediatek: mt8195-cherry: " Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 15/16] arm64: dts: mediatek: mt8195-cherry: Add USB type-A connector Chen-Yu Tsai
2026-06-10  8:40 ` [PATCH v2 16/16] arm64: dts: mediatek: mt8188-geralt: Add WiFi/BT as M.2 E-key slot Chen-Yu Tsai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ail1XLTIkU7YVvs1@ashevche-desk.local \
    --to=andriy.shevchenko@linux.intel.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=brgl@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=dakr@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=djrscally@gmail.com \
    --cc=driver-core@lists.linux.dev \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mani@kernel.org \
    --cc=matthias.bgg@gmail.com \
    --cc=rafael@kernel.org \
    --cc=robh@kernel.org \
    --cc=sakari.ailus@linux.intel.com \
    --cc=stern@rowland.harvard.edu \
    --cc=wenst@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox