]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
usb: dwc3: core: Introduce glue callbacks for flattened implementations
authorKrishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Sun, 7 Sep 2025 18:14:11 +0000 (23:44 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Sep 2025 12:04:20 +0000 (14:04 +0200)
In certain situations like role switching, the glue layers need to be
informed of these events, so that they can take any necessary action.
But in non-flattened implementations, the glue drivers have no data on
when the core driver probe was successful post invoking of_platform_
populate. Now that the core driver supports flattened implementations
as well, introduce vendor callbacks that can be passed on from glue to
core before invoking dwc3_core_probe.

Introduce callbacks to notify glue layer of role_switch and run_stop
changes. These can be used by flattened implementation of Qualcomm
glue layer to generate connect/disconnect events in controller during
cable connect and run stop modifications by udc in device mode.

Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250907181412.2174616-2-krishna.kurapati@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/drd.c
drivers/usb/dwc3/gadget.c

index 370fc524a468eb8377e69a36ae689b4b05f4f0de..ae140c356295c03df3982ff4fa95f8638296e52d 100644 (file)
@@ -2352,6 +2352,7 @@ static int dwc3_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        dwc->dev = &pdev->dev;
+       dwc->glue_ops = NULL;
 
        probe_data.dwc = dwc;
        probe_data.res = res;
index d5b985fa12f4d9ee3f318ea5cce7c1b225cd3623..a5fc92c4ffa3bc280960e81594ae5cfb401f233a 100644 (file)
@@ -992,6 +992,17 @@ struct dwc3_scratchpad_array {
        __le64  dma_adr[DWC3_MAX_HIBER_SCRATCHBUFS];
 };
 
+/**
+ * struct dwc3_glue_ops - The ops indicate the notifications that
+ *                             need to be passed on to glue layer
+ * @pre_set_role: Notify glue of role switch notifications
+ * @pre_run_stop: Notify run stop enable/disable information to glue
+ */
+struct dwc3_glue_ops {
+       void    (*pre_set_role)(struct dwc3 *dwc, enum usb_role role);
+       void    (*pre_run_stop)(struct dwc3 *dwc, bool is_on);
+};
+
 /**
  * struct dwc3 - representation of our controller
  * @drd_work: workqueue used for role swapping
@@ -1012,6 +1023,7 @@ struct dwc3_scratchpad_array {
  * @eps: endpoint array
  * @gadget: device side representation of the peripheral controller
  * @gadget_driver: pointer to the gadget driver
+ * @glue_ops: Vendor callbacks for flattened device implementations.
  * @bus_clk: clock for accessing the registers
  * @ref_clk: reference clock
  * @susp_clk: clock used when the SS phy is in low power (S3) state
@@ -1197,6 +1209,8 @@ struct dwc3 {
        struct usb_gadget       *gadget;
        struct usb_gadget_driver *gadget_driver;
 
+       const struct dwc3_glue_ops      *glue_ops;
+
        struct clk              *bus_clk;
        struct clk              *ref_clk;
        struct clk              *susp_clk;
@@ -1614,6 +1628,18 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc);
 int dwc3_core_soft_reset(struct dwc3 *dwc);
 void dwc3_enable_susphy(struct dwc3 *dwc, bool enable);
 
+static inline void dwc3_pre_set_role(struct dwc3 *dwc, enum usb_role role)
+{
+       if (dwc->glue_ops && dwc->glue_ops->pre_set_role)
+               dwc->glue_ops->pre_set_role(dwc, role);
+}
+
+static inline void dwc3_pre_run_stop(struct dwc3 *dwc, bool is_on)
+{
+       if (dwc->glue_ops && dwc->glue_ops->pre_run_stop)
+               dwc->glue_ops->pre_run_stop(dwc, is_on);
+}
+
 #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
 int dwc3_host_init(struct dwc3 *dwc);
 void dwc3_host_exit(struct dwc3 *dwc);
index 7977860932b142924edd19f859f7c4041d11eda6..4c91240eb4299a034d7f777cb33f538f551e9330 100644 (file)
@@ -464,6 +464,7 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
                break;
        }
 
+       dwc3_pre_set_role(dwc, role);
        dwc3_set_mode(dwc, mode);
        return 0;
 }
index 554f997eb8c4fb5c64d4262298ffb753558c4cbb..6f18b4840a25d176abb4134581ad0ce68ba19ffc 100644 (file)
@@ -2662,6 +2662,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
                dwc->pullups_connected = false;
        }
 
+       dwc3_pre_run_stop(dwc, is_on);
        dwc3_gadget_dctl_write_safe(dwc, reg);
 
        do {