net: axienet: make use of axistream-connected attribute optional
authorRobert Hancock <hancock@sedsystems.ca>
Thu, 6 Jun 2019 22:28:23 +0000 (16:28 -0600)
committerDavid S. Miller <davem@davemloft.net>
Thu, 6 Jun 2019 23:24:30 +0000 (16:24 -0700)
Currently the axienet driver requires the use of a second devicetree
node, referenced by an axistream-connected attribute on the Ethernet
device node, which contains the resources for the AXI DMA block used by the
device. This setup is problematic for a use case we have where the Ethernet
and DMA cores are behind a PCIe to AXI bridge and the memory resources for
the nodes are injected into the platform devices using the multifunction
device subsystem - it's not easily possible for the driver to obtain the
platform-level resources from the linked device.

In order to simplify that usage model, and simplify the overall use of
this driver in general, allow for all of the resources to be kept on one
node where the resources are retrieved using platform device APIs rather
than device-tree-specific ones. The previous usage setup is still
supported if the axistream-connected attribute is specified.

Signed-off-by: Robert Hancock <hancock@sedsystems.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/xilinx/xilinx_axienet_main.c

index d138db8d6e7aab79749cf7cff4c320e33a65cf00..898eabffc515eb91b28221b0da4ed5923b49f9c2 100644 (file)
@@ -1580,7 +1580,7 @@ static int axienet_probe(struct platform_device *pdev)
        struct axienet_local *lp;
        struct net_device *ndev;
        const void *mac_addr;
-       struct resource *ethres, dmares;
+       struct resource *ethres;
        u32 value;
 
        ndev = alloc_etherdev(sizeof(*lp));
@@ -1698,28 +1698,41 @@ static int axienet_probe(struct platform_device *pdev)
 
        /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
        np = of_parse_phandle(pdev->dev.of_node, "axistream-connected", 0);
-       if (!np) {
-               dev_err(&pdev->dev, "could not find DMA node\n");
-               ret = -ENODEV;
-               goto free_netdev;
-       }
-       ret = of_address_to_resource(np, 0, &dmares);
-       if (ret) {
-               dev_err(&pdev->dev, "unable to get DMA resource\n");
+       if (np) {
+               struct resource dmares;
+
+               ret = of_address_to_resource(np, 0, &dmares);
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "unable to get DMA resource\n");
+                       of_node_put(np);
+                       goto free_netdev;
+               }
+               lp->dma_regs = devm_ioremap_resource(&pdev->dev,
+                                                    &dmares);
+               lp->rx_irq = irq_of_parse_and_map(np, 1);
+               lp->tx_irq = irq_of_parse_and_map(np, 0);
                of_node_put(np);
-               goto free_netdev;
+               lp->eth_irq = platform_get_irq(pdev, 0);
+       } else {
+               /* Check for these resources directly on the Ethernet node. */
+               struct resource *res = platform_get_resource(pdev,
+                                                            IORESOURCE_MEM, 1);
+               if (!res) {
+                       dev_err(&pdev->dev, "unable to get DMA memory resource\n");
+                       goto free_netdev;
+               }
+               lp->dma_regs = devm_ioremap_resource(&pdev->dev, res);
+               lp->rx_irq = platform_get_irq(pdev, 1);
+               lp->tx_irq = platform_get_irq(pdev, 0);
+               lp->eth_irq = platform_get_irq(pdev, 2);
        }
-       lp->dma_regs = devm_ioremap_resource(&pdev->dev, &dmares);
        if (IS_ERR(lp->dma_regs)) {
                dev_err(&pdev->dev, "could not map DMA regs\n");
                ret = PTR_ERR(lp->dma_regs);
                of_node_put(np);
                goto free_netdev;
        }
-       lp->rx_irq = irq_of_parse_and_map(np, 1);
-       lp->tx_irq = irq_of_parse_and_map(np, 0);
-       lp->eth_irq = irq_of_parse_and_map(np, 2);
-       of_node_put(np);
        if ((lp->rx_irq <= 0) || (lp->tx_irq <= 0)) {
                dev_err(&pdev->dev, "could not determine irqs\n");
                ret = -ENOMEM;