* [PATCH v2 1/5] usb: dwc3: populate parent of xHCI dev
2023-04-14 14:52 [PATCH v2 0/5] dma: pass physical device to DMA API Ahmad Fatoum
@ 2023-04-14 14:52 ` Ahmad Fatoum
2023-04-14 14:52 ` [PATCH v2 2/5] usb: xhci: pass physical device to DMA API Ahmad Fatoum
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2023-04-14 14:52 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Reparent xHCIs instantiated from DWC3 controllers to their parents
instead of them being direct children of the bus. Apart from improving
devinfo/drvinfo output, this should introduce no functional change.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/base/resource.c | 6 ++++--
drivers/usb/dwc3/host.c | 8 ++++----
include/driver.h | 12 ++++++++++--
3 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/base/resource.c b/drivers/base/resource.c
index 3725c79eb9d4..0d6f200a9d51 100644
--- a/drivers/base/resource.c
+++ b/drivers/base/resource.c
@@ -57,13 +57,15 @@ int device_add_resource(struct device *dev, const char *resname,
return device_add_resources(dev, &res, 1);
}
-struct device *add_generic_device(const char* devname, int id, const char *resname,
+struct device *add_child_device(struct device *parent,
+ const char* devname, int id, const char *resname,
resource_size_t start, resource_size_t size, unsigned int flags,
void *pdata)
{
struct device *dev;
dev = device_alloc(devname, id);
+ dev->parent = parent;
dev->platform_data = pdata;
device_add_resource(dev, resname, start, size, flags);
@@ -71,7 +73,7 @@ struct device *add_generic_device(const char* devname, int id, const char *resna
return dev;
}
-EXPORT_SYMBOL(add_generic_device);
+EXPORT_SYMBOL(add_child_device);
struct device *add_generic_device_res(const char* devname, int id,
struct resource *res, int nb, void *pdata)
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index e377c4068ad2..281d016a86aa 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -24,14 +24,14 @@ int dwc3_host_init(struct dwc3 *dwc)
return PTR_ERR(io);
}
- dwc->xhci = add_generic_device("xHCI", DEVICE_ID_DYNAMIC, NULL,
- io->start, resource_size(io),
- IORESOURCE_MEM, NULL);
+ dwc->xhci = add_child_device(dev, "xHCI", DEVICE_ID_DYNAMIC, NULL,
+ io->start, resource_size(io),
+ IORESOURCE_MEM, NULL);
if (!dwc->xhci) {
dev_err(dev, "Failed to register xHCI device\n");
return -ENODEV;
}
-
+
return 0;
}
diff --git a/include/driver.h b/include/driver.h
index 4b367e31fd78..033b12748c12 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -283,13 +283,21 @@ int device_add_resource(struct device *dev, const char *resname,
int device_add_data(struct device *dev, const void *data, size_t size);
+struct device *add_child_device(struct device *parent,
+ const char* devname, int id, const char *resname,
+ resource_size_t start, resource_size_t size, unsigned int flags,
+ void *pdata);
+
/*
* register a generic device
* with only one resource
*/
-struct device *add_generic_device(const char* devname, int id, const char *resname,
+static inline struct device *add_generic_device(const char* devname, int id, const char *resname,
resource_size_t start, resource_size_t size, unsigned int flags,
- void *pdata);
+ void *pdata)
+{
+ return add_child_device(NULL, devname, id, resname, start, size, flags, pdata);
+}
/*
* register a generic device
--
2.39.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/5] usb: xhci: pass physical device to DMA API
2023-04-14 14:52 [PATCH v2 0/5] dma: pass physical device to DMA API Ahmad Fatoum
2023-04-14 14:52 ` [PATCH v2 1/5] usb: dwc3: populate parent of xHCI dev Ahmad Fatoum
@ 2023-04-14 14:52 ` Ahmad Fatoum
2023-04-14 14:52 ` [PATCH v2 3/5] net: rtl8169: pass physical device for " Ahmad Fatoum
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2023-04-14 14:52 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The xHCI device is just a child of the DWC3 with no DT node assigned.
As such, it lacks all DMA settings that may be set in the DT.
Fix this by using the hardware device instead in case the xHCI lacks
its own DT node.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/usb/host/xhci-ring.c | 8 ++++----
drivers/usb/host/xhci.c | 6 +++++-
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 4654ab14862f..995772f92722 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -594,7 +594,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
memcpy(bounce, buffer, length);
}
- map = addr = dma_map_single(ctrl->dev, bounce, length, direction);
+ map = addr = dma_map_single(ctrl->host.hw_dev, bounce, length, direction);
dev_dbg(&udev->dev, "pipe=0x%lx, buffer=%p, length=%d\n",
pipe, buffer, length);
@@ -740,7 +740,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
record_transfer_result(udev, event, length);
xhci_acknowledge_event(ctrl);
- dma_unmap_single(ctrl->dev, map, length, direction);
+ dma_unmap_single(ctrl->host.hw_dev, map, length, direction);
if (usb_pipein(pipe))
memcpy(buffer, bounce, length);
@@ -895,7 +895,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
if (length > 0) {
if (req->requesttype & USB_DIR_IN)
field |= TRB_DIR_IN;
- map = buf_64 = dma_map_single(ctrl->dev, buffer, length, direction);
+ map = buf_64 = dma_map_single(ctrl->host.hw_dev, buffer, length, direction);
trb_fields[0] = lower_32_bits(buf_64);
trb_fields[1] = upper_32_bits(buf_64);
@@ -947,7 +947,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
/* Invalidate buffer to make it available to usb-core */
if (length > 0)
- dma_unmap_single(ctrl->dev, map, length, direction);
+ dma_unmap_single(ctrl->host.hw_dev, map, length, direction);
if (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len))
== COMP_SHORT_TX) {
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f5cc6dac57d8..f149e784524d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1359,7 +1359,11 @@ int xhci_register(struct xhci_ctrl *ctrl)
*/
host->no_desc_before_addr = true;
- host->hw_dev = dev;
+ /*
+ * If xHCI doesn't have its own DT node, it'll be a child of a
+ * physical USB host controller device that should be used for DMA
+ */
+ host->hw_dev = dev_of_node(dev) ? dev : dev->parent;
host->submit_int_msg = xhci_submit_int_msg;
host->submit_control_msg = xhci_submit_control_msg;
host->submit_bulk_msg = xhci_submit_bulk_msg;
--
2.39.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 3/5] net: rtl8169: pass physical device for DMA API
2023-04-14 14:52 [PATCH v2 0/5] dma: pass physical device to DMA API Ahmad Fatoum
2023-04-14 14:52 ` [PATCH v2 1/5] usb: dwc3: populate parent of xHCI dev Ahmad Fatoum
2023-04-14 14:52 ` [PATCH v2 2/5] usb: xhci: pass physical device to DMA API Ahmad Fatoum
@ 2023-04-14 14:52 ` Ahmad Fatoum
2023-04-14 14:52 ` [PATCH v2 4/5] firmware: zynqmp-fpga: pass physical device to " Ahmad Fatoum
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2023-04-14 14:52 UTC (permalink / raw)
To: barebox; +Cc: Denis Orlov, Ahmad Fatoum
It shouldn't matter for now, but DMA API should always be called for the
physical device, i.e. the struct device underlying the struct pci_device.
This the Ethernet device interface parent, so use that instead.
Cc: Denis Orlov <denorl2009@gmail.com>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/net/rtl8169.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index ffc4ef238b0b..cbcd065980e5 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -216,6 +216,7 @@ static void __set_rx_mode(struct rtl8169_priv *priv)
static void rtl8169_init_ring(struct rtl8169_priv *priv)
{
+ struct eth_device *edev = &priv->edev;
int i;
priv->cur_rx = priv->cur_tx = 0;
@@ -223,13 +224,13 @@ static void rtl8169_init_ring(struct rtl8169_priv *priv)
priv->tx_desc = dma_alloc_coherent(NUM_TX_DESC * sizeof(struct bufdesc),
&priv->tx_desc_phys);
priv->tx_buf = malloc(NUM_TX_DESC * PKT_BUF_SIZE);
- priv->tx_buf_phys = dma_map_single(&priv->edev.dev, priv->tx_buf,
+ priv->tx_buf_phys = dma_map_single(edev->parent, priv->tx_buf,
NUM_TX_DESC * PKT_BUF_SIZE, DMA_TO_DEVICE);
priv->rx_desc = dma_alloc_coherent(NUM_RX_DESC * sizeof(struct bufdesc),
&priv->rx_desc_phys);
priv->rx_buf = malloc(NUM_RX_DESC * PKT_BUF_SIZE);
- priv->rx_buf_phys = dma_map_single(&priv->edev.dev, priv->rx_buf,
+ priv->rx_buf_phys = dma_map_single(edev->parent, priv->rx_buf,
NUM_RX_DESC * PKT_BUF_SIZE, DMA_FROM_DEVICE);
for (i = 0; i < NUM_RX_DESC; i++) {
@@ -479,13 +480,13 @@ static void rtl8169_eth_halt(struct eth_device *edev)
pci_clear_master(priv->pci_dev);
- dma_unmap_single(&edev->dev, priv->tx_buf_phys, NUM_TX_DESC * PKT_BUF_SIZE,
+ dma_unmap_single(edev->parent, priv->tx_buf_phys, NUM_TX_DESC * PKT_BUF_SIZE,
DMA_TO_DEVICE);
free(priv->tx_buf);
dma_free_coherent((void *)priv->tx_desc, priv->tx_desc_phys,
NUM_TX_DESC * sizeof(struct bufdesc));
- dma_unmap_single(&edev->dev, priv->rx_buf_phys, NUM_RX_DESC * PKT_BUF_SIZE,
+ dma_unmap_single(edev->parent, priv->rx_buf_phys, NUM_RX_DESC * PKT_BUF_SIZE,
DMA_FROM_DEVICE);
free(priv->rx_buf);
dma_free_coherent((void *)priv->rx_desc, priv->rx_desc_phys,
--
2.39.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 4/5] firmware: zynqmp-fpga: pass physical device to DMA API
2023-04-14 14:52 [PATCH v2 0/5] dma: pass physical device to DMA API Ahmad Fatoum
` (2 preceding siblings ...)
2023-04-14 14:52 ` [PATCH v2 3/5] net: rtl8169: pass physical device for " Ahmad Fatoum
@ 2023-04-14 14:52 ` Ahmad Fatoum
2023-04-14 14:52 ` [PATCH v2 5/5] net: designware: eqos: " Ahmad Fatoum
2023-04-17 7:05 ` [PATCH v2 0/5] dma: " Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2023-04-14 14:52 UTC (permalink / raw)
To: barebox; +Cc: Michael Tretter, Ahmad Fatoum
The manager device is just a child of the physical device with no
DT node assigned. As such, it lacks all DMA settings that may be
set in the DT. Fix this by using the hardware device instead.
Cc: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/firmware/zynqmp-fpga.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c
index 2544d015d6b7..fe3a7df6d30f 100644
--- a/drivers/firmware/zynqmp-fpga.c
+++ b/drivers/firmware/zynqmp-fpga.c
@@ -197,6 +197,7 @@ static void zynqmp_fpga_show_header(const struct device *dev,
static int fpgamgr_program_finish(struct firmware_handler *fh)
{
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
+ struct device *hw_dev = mgr->dev.parent;
u32 *buf_aligned;
u32 buf_size;
u32 *body;
@@ -254,9 +255,9 @@ static int fpgamgr_program_finish(struct firmware_handler *fh)
memcpy((u32 *)buf_aligned, body, body_length);
buf_aligned[body_length / sizeof(*buf_aligned)] = body_length;
- addr = dma_map_single(&mgr->dev, buf_aligned,
+ addr = dma_map_single(hw_dev, buf_aligned,
body_length + sizeof(buf_size), DMA_TO_DEVICE);
- if (dma_mapping_error(&mgr->dev, addr)) {
+ if (dma_mapping_error(hw_dev, addr)) {
status = -EFAULT;
goto err_free_dma;
}
@@ -267,7 +268,7 @@ static int fpgamgr_program_finish(struct firmware_handler *fh)
buf_size = addr + body_length;
status = mgr->eemi_ops->fpga_load((u64)addr, buf_size, flags);
- dma_unmap_single(&mgr->dev, addr, body_length + sizeof(buf_size),
+ dma_unmap_single(hw_dev, addr, body_length + sizeof(buf_size),
DMA_TO_DEVICE);
if (status < 0)
dev_err(&mgr->dev, "unable to load fpga\n");
--
2.39.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 5/5] net: designware: eqos: pass physical device to DMA API
2023-04-14 14:52 [PATCH v2 0/5] dma: pass physical device to DMA API Ahmad Fatoum
` (3 preceding siblings ...)
2023-04-14 14:52 ` [PATCH v2 4/5] firmware: zynqmp-fpga: pass physical device to " Ahmad Fatoum
@ 2023-04-14 14:52 ` Ahmad Fatoum
2023-04-17 7:05 ` [PATCH v2 0/5] dma: " Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2023-04-14 14:52 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The Ethernet interface device is just a child of the physical device with
no DT node assigned. As such, it lacks all DMA settings that may be
set in the DT. Fix this by using the hardware device instead.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/net/designware_eqos.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/designware_eqos.c b/drivers/net/designware_eqos.c
index ee5a10a007e9..2e2a1cf8bff3 100644
--- a/drivers/net/designware_eqos.c
+++ b/drivers/net/designware_eqos.c
@@ -687,7 +687,6 @@ static void eqos_stop(struct eth_device *edev)
static int eqos_send(struct eth_device *edev, void *packet, int length)
{
struct eqos *eqos = edev->priv;
- struct device *dev = &eqos->netdev.dev;
struct eqos_desc *tx_desc;
dma_addr_t dma;
u32 des3;
@@ -697,8 +696,8 @@ static int eqos_send(struct eth_device *edev, void *packet, int length)
eqos->tx_currdescnum++;
eqos->tx_currdescnum %= EQOS_DESCRIPTORS_TX;
- dma = dma_map_single(dev, packet, length, DMA_TO_DEVICE);
- if (dma_mapping_error(dev, dma))
+ dma = dma_map_single(edev->parent, packet, length, DMA_TO_DEVICE);
+ if (dma_mapping_error(edev->parent, dma))
return -EFAULT;
tx_desc->des0 = (unsigned long)dma;
@@ -717,7 +716,7 @@ static int eqos_send(struct eth_device *edev, void *packet, int length)
!(des3 & EQOS_DESC3_OWN),
100 * USEC_PER_MSEC);
- dma_unmap_single(dev, dma, length, DMA_TO_DEVICE);
+ dma_unmap_single(edev->parent, dma, length, DMA_TO_DEVICE);
if (ret == -ETIMEDOUT)
eqos_dbg(eqos, "TX timeout\n");
@@ -764,7 +763,7 @@ static int eqos_recv(struct eth_device *edev)
static int eqos_init_resources(struct eqos *eqos)
{
- struct device *dev = eqos->netdev.parent;
+ struct eth_device *edev = &eqos->netdev;
int ret = -ENOMEM;
void *descs;
void *p;
@@ -785,8 +784,8 @@ static int eqos_init_resources(struct eqos *eqos)
struct eqos_desc *rx_desc = &eqos->rx_descs[i];
dma_addr_t dma;
- dma = dma_map_single(dev, p, EQOS_MAX_PACKET_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(dev, dma)) {
+ dma = dma_map_single(edev->parent, p, EQOS_MAX_PACKET_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(edev->parent, dma)) {
ret = -EFAULT;
goto err_free_rx_bufs;
}
--
2.39.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/5] dma: pass physical device to DMA API
2023-04-14 14:52 [PATCH v2 0/5] dma: pass physical device to DMA API Ahmad Fatoum
` (4 preceding siblings ...)
2023-04-14 14:52 ` [PATCH v2 5/5] net: designware: eqos: " Ahmad Fatoum
@ 2023-04-17 7:05 ` Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2023-04-17 7:05 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Fri, Apr 14, 2023 at 04:52:54PM +0200, Ahmad Fatoum wrote:
> This splits off the non-contentions parts of my dma-coherency series:
> https://lore.barebox.org/barebox/20230221080524.607241-1-a.fatoum@pengutronix.de/
>
> Only change is a typo fix in a comment, but no other changes.
>
> Ahmad Fatoum (5):
> usb: dwc3: populate parent of xHCI dev
> usb: xhci: pass physical device to DMA API
> net: rtl8169: pass physical device for DMA API
> firmware: zynqmp-fpga: pass physical device to DMA API
> net: designware: eqos: pass physical device to DMA API
Applied, thanks
Sascha
>
> drivers/base/resource.c | 6 ++++--
> drivers/firmware/zynqmp-fpga.c | 7 ++++---
> drivers/net/designware_eqos.c | 13 ++++++-------
> drivers/net/rtl8169.c | 9 +++++----
> drivers/usb/dwc3/host.c | 8 ++++----
> drivers/usb/host/xhci-ring.c | 8 ++++----
> drivers/usb/host/xhci.c | 6 +++++-
> include/driver.h | 12 ++++++++++--
> 8 files changed, 42 insertions(+), 27 deletions(-)
>
> --
> 2.39.2
>
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 7+ messages in thread