From patchwork Wed Aug 7 14:36:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 13756380 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89B2284A39 for ; Wed, 7 Aug 2024 14:37:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723041433; cv=none; b=YMgLR6lb7GDnER4g6hMLHRvayCZUQKt4/fWdwpIW1hEfRd7yb/587hRB48spAOWtSYJSv4641tYVwMS+Vu6ABz+WwmNRAYU4lRhnt17AX9zaBgjABTm/4TBjMJF2/+emHlPiZJkerGSzpjurkiIzwwP0LLBiMBX+Kh0+c2y/678= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723041433; c=relaxed/simple; bh=CWJVjRJL3Iy2iDf4saj3FvA/JduymDRbukIlMV/8hK8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qZsYTZPnKVe0x9b0q1HdZfLBmOYEQQbI399wW0RW2GNe9YdnM+73yrzrzc9QRN5j1LYrSp6jgZpDTIIWq38LYxjP2rkKE8u8pphKKz1j+FWg1kKkQKQu/L03RfHJm02LUztZ3dqYdkVyoJBocbHqI527XtAgf0ivU8h53qUvKH0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from dude02.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::28]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1sbhme-0004Iv-Ie; Wed, 07 Aug 2024 16:37:00 +0200 From: Marco Felsch Date: Wed, 07 Aug 2024 16:36:51 +0200 Subject: [PATCH 1/3] usb: hub: add infrastructure to pass onboard_dev port features Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-1-f33ce21353c9@pengutronix.de> References: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de> In-Reply-To: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de> To: Greg Kroah-Hartman , Matthias Kaehlcke , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Fabio Estevam , Liam Girdwood , Mark Brown Cc: kernel@pengutronix.de, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Marco Felsch X-Mailer: b4 0.14.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::28 X-SA-Exim-Mail-From: m.felsch@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org On board devices may require special handling for en-/disable port features due to PCB design decisions e.g. enable/disable the VBUS power on the port. This commit adds the necessary infrastructure to prepare the common code base for such use-cases. Signed-off-by: Marco Felsch --- drivers/usb/core/hub.c | 22 ++++++++++++++++++++-- drivers/usb/misc/onboard_usb_dev.c | 13 +++++++++++++ include/linux/usb/onboard_dev.h | 6 ++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 4b93c0bd1d4b..e639c25a729c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -450,9 +450,18 @@ static int clear_hub_feature(struct usb_device *hdev, int feature) */ int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature) { - return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + int ret; + + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1, NULL, 0, 1000); + if (ret) + return ret; + + if (!is_root_hub(hdev)) + ret = onboard_dev_port_feature(hdev, false, feature, port1); + + return ret; } /* @@ -460,9 +469,18 @@ int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature) */ static int set_port_feature(struct usb_device *hdev, int port1, int feature) { - return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + int ret; + + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1, NULL, 0, 1000); + if (ret) + return ret; + + if (!is_root_hub(hdev)) + ret = onboard_dev_port_feature(hdev, true, feature, port1); + + return ret; } static char *to_led_name(int selector) diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c index f2bcc1a8b95f..f61de2c353d0 100644 --- a/drivers/usb/misc/onboard_usb_dev.c +++ b/drivers/usb/misc/onboard_usb_dev.c @@ -520,6 +520,19 @@ static struct usb_device_driver onboard_dev_usbdev_driver = { .id_table = onboard_dev_id_table, }; +/************************** USB control **************************/ + +int onboard_dev_port_feature(struct usb_device *udev, bool set, + int feature, int port1) +{ + switch (feature) { + default: + return 0; + } +} + +/************************** Kernel module ************************/ + static int __init onboard_dev_init(void) { int ret; diff --git a/include/linux/usb/onboard_dev.h b/include/linux/usb/onboard_dev.h index b79db6d193c8..45e1f7b844d6 100644 --- a/include/linux/usb/onboard_dev.h +++ b/include/linux/usb/onboard_dev.h @@ -9,10 +9,16 @@ struct list_head; #if IS_ENABLED(CONFIG_USB_ONBOARD_DEV) void onboard_dev_create_pdevs(struct usb_device *parent_dev, struct list_head *pdev_list); void onboard_dev_destroy_pdevs(struct list_head *pdev_list); +int onboard_dev_port_feature(struct usb_device *udev, bool set, int feature, int port1); #else static inline void onboard_dev_create_pdevs(struct usb_device *parent_dev, struct list_head *pdev_list) {} static inline void onboard_dev_destroy_pdevs(struct list_head *pdev_list) {} +static inline int onboard_dev_port_feature(struct usb_device *udev, bool set, + int feature, int port1) +{ + return 0; +} #endif #endif /* __LINUX_USB_ONBOARD_DEV_H */ From patchwork Wed Aug 7 14:36:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 13756379 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89B7084A3E for ; Wed, 7 Aug 2024 14:37:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723041432; cv=none; b=XgD+F7tfpEXwX5kfUwbYQraWBmyLhuMKjFS/fh2hO9AnsvNQYpYEpUoGFdgB6jh3OCuRPPoMe7W7vPJRXNez3hCx1LA53c4MuQIHJljvMsPMZdg2/dAQUOYbq8CiMm8LbKvJaS3vrV9nFNBry4Iqp9StMJiE/otXEgixIr29W0k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723041432; c=relaxed/simple; bh=CWu6UEBdQE6dgCfX+/gjSRxyG/gDmW37Og5SPgZMvRc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jVHL0VFGaPNl9wusqw3mVZQVMrx0ngHMN+/Ss6XQzs7m7llt0xREzch95Dwk2IFO5WZWgQCDLt+/Qt85Rxlfy4GD6ONiK6LhtL4nPcqCgzL1zlTksAjv4y055WEB3H9bwErOGxxvvpds31NLDKiz0h1eg3REW0Euj7pKjE5/m2E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from dude02.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::28]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1sbhme-0004Iv-LG; Wed, 07 Aug 2024 16:37:00 +0200 From: Marco Felsch Date: Wed, 07 Aug 2024 16:36:52 +0200 Subject: [PATCH 2/3] dt-bindings: usb: microchip,usb2514: add support for port vbus-supply Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-2-f33ce21353c9@pengutronix.de> References: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de> In-Reply-To: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de> To: Greg Kroah-Hartman , Matthias Kaehlcke , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Fabio Estevam , Liam Girdwood , Mark Brown Cc: kernel@pengutronix.de, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Marco Felsch X-Mailer: b4 0.14.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::28 X-SA-Exim-Mail-From: m.felsch@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org Some PCB designs don't connect the USB hub port power control GPIO and instead make use of an host controllable regulator. Add support for this use-case by introducing an portX-vbus-supply property. Signed-off-by: Marco Felsch --- Documentation/devicetree/bindings/usb/microchip,usb2514.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/microchip,usb2514.yaml b/Documentation/devicetree/bindings/usb/microchip,usb2514.yaml index 783c27591e56..51d02c4b8f2d 100644 --- a/Documentation/devicetree/bindings/usb/microchip,usb2514.yaml +++ b/Documentation/devicetree/bindings/usb/microchip,usb2514.yaml @@ -35,6 +35,13 @@ required: - compatible - reg +patternProperties: + "^port[1-7]-vbus-supply$" + type: object + description: + Regulator controlling the USB VBUS on portX. Only required if the host + controls the portX VBUS. + unevaluatedProperties: false examples: From patchwork Wed Aug 7 14:36:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 13756381 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 074A784A4D for ; Wed, 7 Aug 2024 14:37:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723041433; cv=none; b=Uqj5OlpwoheswcKk+8CaUpnNxloCoU72O2twyd5Ym9LSGRjcxI1niWHLOJKrVFCjlzxmZBhfDGnXZkSFiWb7VvHuS4TSSdsfXr6B3cDTiKxRcRtcKOG7rk5lT/uSjEvgn00Zs3m6MnnE/IHs5TvVdmVHJzTz+z/IlDG3pB0+NYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723041433; c=relaxed/simple; bh=6Ex9JBBQeeumu+5bfMADPiTKVhDkyAOukkLhCDuwNR8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AYzz/BSaYObXDO1q3GxDvZVHf0jM77iqjSv6LA06IP9KOhjlmyMm4yLQz1MQqyIab/jurg9sAVUExFzU7a7xVZSeBvfd14VdIxRpvKjpMXDGQObTeXr2c0GSNIY8RrY6mmfHGMaC0XfZqToodImmewUEfWEAW8+F1CULcgMX5qg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from dude02.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::28]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1sbhme-0004Iv-Nh; Wed, 07 Aug 2024 16:37:00 +0200 From: Marco Felsch Date: Wed, 07 Aug 2024 16:36:53 +0200 Subject: [PATCH 3/3] usb: misc: onboard_dev: add ext-vbus-supply handling Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-3-f33ce21353c9@pengutronix.de> References: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de> In-Reply-To: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de> To: Greg Kroah-Hartman , Matthias Kaehlcke , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Fabio Estevam , Liam Girdwood , Mark Brown Cc: kernel@pengutronix.de, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Marco Felsch X-Mailer: b4 0.14.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::28 X-SA-Exim-Mail-From: m.felsch@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-usb@vger.kernel.org Add support to power the port VBUS via host controlled regulators since some embedded hub PCB designs don't connect the dedicated USB hub port power GPIO accordingly. To support the above use-case the USB_PORT_FEAT_POWER port feature handling must be added. At the moment this feature is limited to the following hubs: - usb424,2412 - usb424,2414 - usb424,2417. Signed-off-by: Marco Felsch --- drivers/usb/misc/onboard_usb_dev.c | 63 ++++++++++++++++++++++++++++++++++++++ drivers/usb/misc/onboard_usb_dev.h | 2 ++ 2 files changed, 65 insertions(+) diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c index f61de2c353d0..f8ca6ef9956b 100644 --- a/drivers/usb/misc/onboard_usb_dev.c +++ b/drivers/usb/misc/onboard_usb_dev.c @@ -36,6 +36,8 @@ static DECLARE_WORK(attach_usb_driver_work, onboard_dev_attach_usb_driver); /************************** Platform driver **************************/ +#define MAX_DOWNSTREAM_PORTS 7 + struct usbdev_node { struct usb_device *udev; struct list_head list; @@ -52,6 +54,7 @@ struct onboard_dev { struct list_head udev_list; struct mutex lock; struct clk *clk; + struct regulator *ext_vbus_supplies[MAX_DOWNSTREAM_PORTS]; }; static int onboard_dev_get_regulators(struct onboard_dev *onboard_dev) @@ -212,6 +215,48 @@ static int onboard_dev_add_usbdev(struct onboard_dev *onboard_dev, return err; } +static int onboard_dev_port_power(struct onboard_dev *onboard_dev, int port1, + bool enable) +{ + struct regulator *vbus_supply; + + vbus_supply = onboard_dev->ext_vbus_supplies[port1 - 1]; + + /* External supplies are optional */ + if (!vbus_supply) + return 0; + + if (enable) + return regulator_enable(vbus_supply); + + return regulator_disable(vbus_supply); +} + +static int onboard_dev_add_ext_vbus_supplies(struct onboard_dev *onboard_dev) +{ + struct device *dev = onboard_dev->dev; + unsigned int i; + + if (!onboard_dev->pdata->support_ext_vbus_supplies) + return 0; + + for (i = 0; i < MAX_DOWNSTREAM_PORTS; i++) { + char *supply_name = "portX-vbus"; + struct regulator *reg; + + sprintf(supply_name, "port%u-vbus", i + 1); + reg = devm_regulator_get_optional(dev, supply_name); + if (!IS_ERR(reg)) { + onboard_dev->ext_vbus_supplies[i] = reg; + } else { + if (PTR_ERR(reg) != -ENODEV) + return PTR_ERR(reg); + } + } + + return 0; +} + static void onboard_dev_remove_usbdev(struct onboard_dev *onboard_dev, const struct usb_device *udev) { @@ -339,6 +384,10 @@ static int onboard_dev_probe(struct platform_device *pdev) if (err) return err; + err = onboard_dev_add_ext_vbus_supplies(onboard_dev); + if (err) + return err; + /* * The USB driver might have been detached from the USB devices by * onboard_dev_remove() (e.g. through an 'unbind' by userspace), @@ -525,7 +574,21 @@ static struct usb_device_driver onboard_dev_usbdev_driver = { int onboard_dev_port_feature(struct usb_device *udev, bool set, int feature, int port1) { + struct device *dev = &udev->dev; + struct onboard_dev *onboard_dev; + + if (!dev->of_node) + return 0; + + onboard_dev = _find_onboard_dev(dev); + if (IS_ERR(onboard_dev)) + return 0; + switch (feature) { + case USB_PORT_FEAT_POWER: + if (!onboard_dev->pdata->is_hub) + return -EINVAL; + return onboard_dev_port_power(onboard_dev, port1, set); default: return 0; } diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h index fbba549c0f47..e828bfe006ba 100644 --- a/drivers/usb/misc/onboard_usb_dev.h +++ b/drivers/usb/misc/onboard_usb_dev.h @@ -13,6 +13,7 @@ struct onboard_dev_pdata { unsigned int num_supplies; /* number of supplies */ const char * const supply_names[MAX_SUPPLIES]; bool is_hub; + bool support_ext_vbus_supplies; }; static const struct onboard_dev_pdata microchip_usb424_data = { @@ -20,6 +21,7 @@ static const struct onboard_dev_pdata microchip_usb424_data = { .num_supplies = 1, .supply_names = { "vdd" }, .is_hub = true, + .support_ext_vbus_supplies = true, }; static const struct onboard_dev_pdata microchip_usb5744_data = {