diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index e4c99a1c4047..8e7a846ae688 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2257,6 +2257,30 @@ int usb_hcd_sec_event_ring_cleanup(struct usb_device *udev,
 
 /*-------------------------------------------------------------------------*/
 
+dma_addr_t
+usb_hcd_get_sec_event_ring_dma_addr(struct usb_device *udev,
+	unsigned int intr_num)
+{
+	struct usb_hcd	*hcd = bus_to_hcd(udev->bus);
+
+	if (!HCD_RH_RUNNING(hcd))
+		return 0;
+
+	return hcd->driver->get_sec_event_ring_dma_addr(hcd, intr_num);
+}
+
+dma_addr_t
+usb_hcd_get_xfer_ring_dma_addr(struct usb_device *udev,
+	unsigned int intr_num)
+{
+	struct usb_hcd	*hcd = bus_to_hcd(udev->bus);
+
+	if (!HCD_RH_RUNNING(hcd))
+		return 0;
+
+	return hcd->driver->get_xfer_ring_dma_addr(hcd, udev, ep);
+}
+
 int usb_hcd_get_controller_id(struct usb_device *udev)
 {
 	struct usb_hcd	*hcd = bus_to_hcd(udev->bus);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7e58698f0931..7822b8b44ffd 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -842,6 +842,27 @@ int usb_sec_event_ring_cleanup(struct usb_device *dev,
 }
 EXPORT_SYMBOL(usb_sec_event_ring_cleanup);
 
+dma_addr_t
+usb_get_sec_event_ring_dma_addr(struct usb_device *dev,
+	unsigned int intr_num)
+{
+	if (dev->state == USB_STATE_NOTATTACHED)
+		return 0;
+
+	return usb_hcd_get_sec_event_ring_dma_addr(dev, intr_num);
+}
+EXPORT_SYMBOL_GPL(usb_get_sec_event_ring_dma_addr);
+
+dma_addr_t usb_get_xfer_ring_dma_addr(struct usb_device *dev,
+	struct usb_host_endpoint *ep)
+{
+	if (dev->state == USB_STATE_NOTATTACHED)
+		return 0;
+
+	return usb_hcd_get_xfer_ring_dma_addr(dev, ep);
+}
+EXPORT_SYMBOL_GPL(usb_get_xfer_ring_dma_addr);
+
 /**
  * usb_get_controller_id - returns the host controller id.
  * @dev: the device whose host controller id is being queried.
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ce23d2dc9714..f8ea67ac9c84 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5183,6 +5183,50 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 }
 EXPORT_SYMBOL_GPL(xhci_gen_setup);
 
+dma_addr_t xhci_get_sec_event_ring_dma_addr(struct usb_hcd *hcd,
+	unsigned int intr_num)
+{
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+	if (intr_num > xhci->max_interrupters) {
+		xhci_err(xhci, "intr num %d > max intrs %d\n", intr_num,
+			xhci->max_interrupters);
+		return 0;
+	}
+
+	if (!(xhci->xhc_state & XHCI_STATE_HALTED) &&
+		xhci->sec_event_ring && xhci->sec_event_ring[intr_num]
+		&& xhci->sec_event_ring[intr_num]->first_seg)
+		return xhci->sec_event_ring[intr_num]->first_seg->dma;
+
+	return 0;
+}
+
+dma_addr_t xhci_get_xfer_ring_dma_addr(struct usb_hcd *hcd,
+	struct usb_device *udev, struct usb_host_endpoint *ep)
+{
+	int ret;
+	unsigned int ep_index;
+	struct xhci_virt_device *virt_dev;
+
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+	ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
+	if (ret <= 0) {
+		xhci_err(xhci, "%s: invalid args\n", __func__);
+		return 0;
+	}
+
+	virt_dev = xhci->devs[udev->slot_id];
+	ep_index = xhci_get_endpoint_index(&ep->desc);
+
+	if (virt_dev->eps[ep_index].ring &&
+		virt_dev->eps[ep_index].ring->first_seg)
+		return virt_dev->eps[ep_index].ring->first_seg->dma;
+
+	return 0;
+}
+
 static int  xhci_stop_endpoint(struct usb_hcd *hcd,
 	struct usb_device *udev, struct usb_host_endpoint *ep)
 {
@@ -5302,6 +5346,8 @@ static const struct hc_driver xhci_hc_driver = {
 	.find_raw_port_number =	xhci_find_raw_port_number,
 	.sec_event_ring_setup =		xhci_sec_event_ring_setup,
 	.sec_event_ring_cleanup =	xhci_sec_event_ring_cleanup,
+	.get_sec_event_ring_dma_addr =	xhci_get_sec_event_ring_dma_addr,
+	.get_xfer_ring_dma_addr =	xhci_get_xfer_ring_dma_addr,
 	.stop_endpoint =		xhci_stop_endpoint,
 };
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 987bb203e766..25a8cb676ba2 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -837,6 +837,11 @@ extern int usb_sec_event_ring_setup(struct usb_device *dev,
 	unsigned int intr_num);
 extern int usb_sec_event_ring_cleanup(struct usb_device *dev,
 	unsigned int intr_num);
+
+extern dma_addr_t usb_get_sec_event_ring_dma_addr(struct usb_device *dev,
+	unsigned int intr_num);
+extern dma_addr_t usb_get_xfer_ring_dma_addr(struct usb_device *dev,
+	struct usb_host_endpoint *ep);
 extern int usb_get_controller_id(struct usb_device *dev);
 
 extern int usb_stop_endpoint(struct usb_device *dev,
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 24b33e9e9b86..59584fe85c1c 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -410,7 +410,11 @@ struct hc_driver {
 	int (*sec_event_ring_setup)(struct usb_hcd *hcd, unsigned int intr_num);
 	int (*sec_event_ring_cleanup)(struct usb_hcd *hcd,
 			unsigned int intr_num);
-	int	(*get_core_id)(struct usb_hcd *hcd);
+	dma_addr_t (*get_sec_event_ring_dma_addr)(struct usb_hcd *hcd,
+			unsigned int intr_num);
+	dma_addr_t (*get_xfer_ring_dma_addr)(struct usb_hcd *hcd,
+			struct usb_device *udev, struct usb_host_endpoint *ep);
+	int (*get_core_id)(struct usb_hcd *hcd);
 	int (*stop_endpoint)(struct usb_hcd *hcd, struct usb_device *udev,
 			struct usb_host_endpoint *ep);
 };
@@ -455,6 +459,10 @@ extern int usb_hcd_sec_event_ring_setup(struct usb_device *udev,
 	unsigned int intr_num);
 extern int usb_hcd_sec_event_ring_cleanup(struct usb_device *udev,
 	unsigned int intr_num);
+extern dma_addr_t usb_hcd_get_sec_event_ring_dma_addr(struct usb_device *udev,
+		unsigned int intr_num);
+extern dma_addr_t usb_hcd_get_xfer_ring_dma_addr(struct usb_device *udev,
+	struct usb_host_endpoint *ep);
 extern int usb_hcd_get_controller_id(struct usb_device *udev);
 extern int usb_hcd_stop_endpoint(struct usb_device *udev,
 	struct usb_host_endpoint *ep);