wil6210: reorder init sequence
authorVladimir Kondratiev <QCA_vkondrat@QCA.qualcomm.com>
Tue, 9 Jun 2015 11:11:19 +0000 (14:11 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Tue, 9 Jun 2015 11:39:17 +0000 (14:39 +0300)
Need to reorder init sequence to run wil_platform_init
before pci_enable_device. Assumption is platform init
may be required before device may be enabled.
Another issue, platform uninit should be called after
pci_disable_device because platform uninit may render
pci device non-accessible.

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/wil6210/netdev.c
drivers/net/wireless/ath/wil6210/pcie_bus.c
drivers/net/wireless/ath/wil6210/wil6210.h
drivers/net/wireless/ath/wil6210/wil_platform.c

index 6042f61b016c010568c3b9f5903cff8ff668f0eb..8ef18ace110ffffde2e4a954c20c2a0e0632858e 100644 (file)
@@ -132,7 +132,7 @@ static void wil_dev_setup(struct net_device *dev)
        dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
 }
 
-void *wil_if_alloc(struct device *dev, void __iomem *csr)
+void *wil_if_alloc(struct device *dev)
 {
        struct net_device *ndev;
        struct wireless_dev *wdev;
@@ -147,7 +147,6 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
        }
 
        wil = wdev_to_wil(wdev);
-       wil->csr = csr;
        wil->wdev = wdev;
 
        wil_dbg_misc(wil, "%s()\n", __func__);
index a4417d4d302ff9e2d60fc5a2a531590cd7c947f8..aa3ecc607ca31abae2879bea058a2505006e1495 100644 (file)
@@ -163,7 +163,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        struct wil6210_priv *wil;
        struct device *dev = &pdev->dev;
-       void __iomem *csr;
        int rc;
 
        /* check HW */
@@ -178,9 +177,28 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                return -ENODEV;
        }
 
+       wil = wil_if_alloc(dev);
+       if (IS_ERR(wil)) {
+               rc = (int)PTR_ERR(wil);
+               dev_err(dev, "wil_if_alloc failed: %d\n", rc);
+               return rc;
+       }
+       wil->pdev = pdev;
+       pci_set_drvdata(pdev, wil);
+       /* rollback to if_free */
+
+       wil->platform_handle =
+                       wil_platform_init(&pdev->dev, &wil->platform_ops);
+       if (!wil->platform_handle) {
+               rc = -ENODEV;
+               wil_err(wil, "wil_platform_init failed\n");
+               goto if_free;
+       }
+       /* rollback to err_plat */
+
        rc = pci_enable_device(pdev);
        if (rc) {
-               dev_err(&pdev->dev,
+               wil_err(wil,
                        "pci_enable_device failed, retry with MSI only\n");
                /* Work around for platforms that can't allocate IRQ:
                 * retry with MSI only
@@ -188,47 +206,37 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                pdev->msi_enabled = 1;
                rc = pci_enable_device(pdev);
        }
-       if (rc)
-               return -ENODEV;
+       if (rc) {
+               wil_err(wil,
+                       "pci_enable_device failed, even with MSI only\n");
+               goto err_plat;
+       }
        /* rollback to err_disable_pdev */
 
        rc = pci_request_region(pdev, 0, WIL_NAME);
        if (rc) {
-               dev_err(&pdev->dev, "pci_request_region failed\n");
+               wil_err(wil, "pci_request_region failed\n");
                goto err_disable_pdev;
        }
        /* rollback to err_release_reg */
 
-       csr = pci_ioremap_bar(pdev, 0);
-       if (!csr) {
-               dev_err(&pdev->dev, "pci_ioremap_bar failed\n");
+       wil->csr = pci_ioremap_bar(pdev, 0);
+       if (!wil->csr) {
+               wil_err(wil, "pci_ioremap_bar failed\n");
                rc = -ENODEV;
                goto err_release_reg;
        }
        /* rollback to err_iounmap */
-       dev_info(&pdev->dev, "CSR at %pR -> 0x%p\n", &pdev->resource[0], csr);
-
-       wil = wil_if_alloc(dev, csr);
-       if (IS_ERR(wil)) {
-               rc = (int)PTR_ERR(wil);
-               dev_err(dev, "wil_if_alloc failed: %d\n", rc);
-               goto err_iounmap;
-       }
-       /* rollback to if_free */
+       wil_info(wil, "CSR at %pR -> 0x%p\n", &pdev->resource[0], wil->csr);
 
-       pci_set_drvdata(pdev, wil);
-       wil->pdev = pdev;
        wil_set_capabilities(wil);
        wil6210_clear_irq(wil);
 
-       wil->platform_handle =
-                       wil_platform_init(&pdev->dev, &wil->platform_ops);
-
        /* FW should raise IRQ when ready */
        rc = wil_if_pcie_enable(wil);
        if (rc) {
                wil_err(wil, "Enable device failed\n");
-               goto if_free;
+               goto err_iounmap;
        }
        /* rollback to bus_disable */
 
@@ -243,18 +251,19 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        return 0;
 
- bus_disable:
+bus_disable:
        wil_if_pcie_disable(wil);
- if_free:
+err_iounmap:
+       pci_iounmap(pdev, wil->csr);
+err_release_reg:
+       pci_release_region(pdev, 0);
+err_disable_pdev:
+       pci_disable_device(pdev);
+err_plat:
        if (wil->platform_ops.uninit)
                wil->platform_ops.uninit(wil->platform_handle);
+if_free:
        wil_if_free(wil);
- err_iounmap:
-       pci_iounmap(pdev, csr);
- err_release_reg:
-       pci_release_region(pdev, 0);
- err_disable_pdev:
-       pci_disable_device(pdev);
 
        return rc;
 }
@@ -269,12 +278,12 @@ static void wil_pcie_remove(struct pci_dev *pdev)
        wil6210_debugfs_remove(wil);
        wil_if_remove(wil);
        wil_if_pcie_disable(wil);
-       if (wil->platform_ops.uninit)
-               wil->platform_ops.uninit(wil->platform_handle);
-       wil_if_free(wil);
        pci_iounmap(pdev, csr);
        pci_release_region(pdev, 0);
        pci_disable_device(pdev);
+       if (wil->platform_ops.uninit)
+               wil->platform_ops.uninit(wil->platform_handle);
+       wil_if_free(wil);
 }
 
 static const struct pci_device_id wil6210_pcie_ids[] = {
index 78c7536634ddfc1debffac655ef6336879792211..275355d46a36fc8c2ae85585fc7188c0a7e64473 100644 (file)
@@ -686,7 +686,7 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
 void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
                        size_t count);
 
-void *wil_if_alloc(struct device *dev, void __iomem *csr);
+void *wil_if_alloc(struct device *dev);
 void wil_if_free(struct wil6210_priv *wil);
 int wil_if_add(struct wil6210_priv *wil);
 void wil_if_remove(struct wil6210_priv *wil);
index 1db680f0c87fd0210b208a3c2b97daf267e586c8..de15f1422fe9faefe225dd618aecbe688c7a443d 100644 (file)
@@ -35,10 +35,11 @@ void wil_platform_modexit(void)
  */
 void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops)
 {
-       void *handle = NULL;
+       void *handle = ops; /* to return some non-NULL for 'void' impl. */
 
        if (!ops) {
-               dev_err(dev, "Invalid parameter. Cannot init platform module\n");
+               dev_err(dev,
+                       "Invalid parameter. Cannot init platform module\n");
                return NULL;
        }