From: Howard Yen <howardyen@xxxxxxxxxx> Add an overwrite to platform specific callback for setting up the xhci_offload_ops, allow vendor to store the xhci_offload_ops and overwrite them when xhci_plat_probe invoked. Signed-off-by: Howard Yen <howardyen@xxxxxxxxxx> --- Changes in v2: - Use 'offload_ops' instead of 'vendor_ops' drivers/usb/host/xhci-plat.c | 20 ++++++++++++++++++++ drivers/usb/host/xhci-plat.h | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 2f04acb42fa6..11ff89f722b7 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -173,9 +173,26 @@ static const struct of_device_id usb_xhci_of_match[] = { MODULE_DEVICE_TABLE(of, usb_xhci_of_match); #endif +static struct xhci_plat_priv_overwrite xhci_plat_vendor_overwrite; + +int xhci_plat_register_offload_ops(struct xhci_offload_ops *offload_ops) +{ + if (offload_ops == NULL) + return -EINVAL; + + xhci_plat_vendor_overwrite.offload_ops = offload_ops; + + return 0; +} +EXPORT_SYMBOL_GPL(xhci_plat_register_offload_ops); + static int xhci_vendor_init(struct xhci_hcd *xhci) { struct xhci_offload_ops *ops = xhci_offload_get_ops(xhci); + struct xhci_plat_priv *priv = xhci_to_priv(xhci); + + if (xhci_plat_vendor_overwrite.offload_ops) + ops = priv->offload_ops = xhci_plat_vendor_overwrite.offload_ops; if (ops && ops->offload_init) return ops->offload_init(xhci); @@ -185,9 +202,12 @@ static int xhci_vendor_init(struct xhci_hcd *xhci) static void xhci_vendor_cleanup(struct xhci_hcd *xhci) { struct xhci_offload_ops *ops = xhci_offload_get_ops(xhci); + struct xhci_plat_priv *priv = xhci_to_priv(xhci); if (ops && ops->offload_cleanup) ops->offload_cleanup(xhci); + + priv->offload_ops = NULL; } static int xhci_plat_probe(struct platform_device *pdev) diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 5aa0d38fa01a..0656d6daa194 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -22,4 +22,11 @@ struct xhci_plat_priv { #define hcd_to_xhci_priv(h) ((struct xhci_plat_priv *)hcd_to_xhci(h)->priv) #define xhci_to_priv(x) ((struct xhci_plat_priv *)(x)->priv) + +struct xhci_plat_priv_overwrite { + struct xhci_offload_ops *offload_ops; +}; + +int xhci_plat_register_offload_ops(struct xhci_offload_ops *offload_ops); + #endif /* _XHCI_PLAT_H */ -- 2.38.1.431.g37b22c650d-goog