[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240807-b4-v6-10-topic-usb-onboard-dev-v1-1-f33ce21353c9@pengutronix.de>
Date: Wed, 07 Aug 2024 16:36:51 +0200
From: Marco Felsch <m.felsch@...gutronix.de>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Matthias Kaehlcke <mka@...omium.org>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>, Fabio Estevam <festevam@...il.com>,
Liam Girdwood <lgirdwood@...il.com>, Mark Brown <broonie@...nel.org>
Cc: kernel@...gutronix.de, linux-usb@...r.kernel.org,
linux-kernel@...r.kernel.org, devicetree@...r.kernel.org,
Marco Felsch <m.felsch@...gutronix.de>
Subject: [PATCH 1/3] usb: hub: add infrastructure to pass onboard_dev port
features
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 <m.felsch@...gutronix.de>
---
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 */
--
2.39.2
Powered by blists - more mailing lists