Commit c132cd8e authored by David S. Miller's avatar David S. Miller

Merge branch 'r8169-device-managed'

Heiner Kallweit says:

====================
r8169: extend PCI core and switch to device-managed functions in probe

Probe error path and remove callback can be significantly simplified
by using device-managed functions. To be able to do this in the r8169
driver we need a device-managed version of pci_set_mwi first.

v2:
Change patch 1 based on Björn's review comments and add his Acked-by.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ec94c269 4cf964af
...@@ -4643,16 +4643,6 @@ static void rtl8169_phy_timer(struct timer_list *t) ...@@ -4643,16 +4643,6 @@ static void rtl8169_phy_timer(struct timer_list *t)
rtl_schedule_task(tp, RTL_FLAG_TASK_PHY_PENDING); rtl_schedule_task(tp, RTL_FLAG_TASK_PHY_PENDING);
} }
static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
void __iomem *ioaddr)
{
iounmap(ioaddr);
pci_release_regions(pdev);
pci_clear_mwi(pdev);
pci_disable_device(pdev);
free_netdev(dev);
}
DECLARE_RTL_COND(rtl_phy_reset_cond) DECLARE_RTL_COND(rtl_phy_reset_cond)
{ {
return tp->phy_reset_pending(tp); return tp->phy_reset_pending(tp);
...@@ -4784,14 +4774,6 @@ static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data ...@@ -4784,14 +4774,6 @@ static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
{
if (tp->features & RTL_FEATURE_MSI) {
pci_disable_msi(pdev);
tp->features &= ~RTL_FEATURE_MSI;
}
}
static void rtl_init_mdio_ops(struct rtl8169_private *tp) static void rtl_init_mdio_ops(struct rtl8169_private *tp)
{ {
struct mdio_ops *ops = &tp->mdio_ops; struct mdio_ops *ops = &tp->mdio_ops;
...@@ -8256,9 +8238,6 @@ static void rtl_remove_one(struct pci_dev *pdev) ...@@ -8256,9 +8238,6 @@ static void rtl_remove_one(struct pci_dev *pdev)
unregister_netdev(dev); unregister_netdev(dev);
dma_free_coherent(&tp->pci_dev->dev, sizeof(*tp->counters),
tp->counters, tp->counters_phys_addr);
rtl_release_firmware(tp); rtl_release_firmware(tp);
if (pci_dev_run_wake(pdev)) if (pci_dev_run_wake(pdev))
...@@ -8266,9 +8245,6 @@ static void rtl_remove_one(struct pci_dev *pdev) ...@@ -8266,9 +8245,6 @@ static void rtl_remove_one(struct pci_dev *pdev)
/* restore original MAC address */ /* restore original MAC address */
rtl_rar_set(tp, dev->perm_addr); rtl_rar_set(tp, dev->perm_addr);
rtl_disable_msi(pdev, tp);
rtl8169_release_board(pdev, dev, tp->mmio_addr);
} }
static const struct net_device_ops rtl_netdev_ops = { static const struct net_device_ops rtl_netdev_ops = {
...@@ -8445,11 +8421,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8445,11 +8421,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
MODULENAME, RTL8169_VERSION); MODULENAME, RTL8169_VERSION);
} }
dev = alloc_etherdev(sizeof (*tp)); dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
if (!dev) { if (!dev)
rc = -ENOMEM; return -ENOMEM;
goto out;
}
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
dev->netdev_ops = &rtl_netdev_ops; dev->netdev_ops = &rtl_netdev_ops;
...@@ -8472,13 +8446,13 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8472,13 +8446,13 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
PCIE_LINK_STATE_CLKPM); PCIE_LINK_STATE_CLKPM);
/* enable device (incl. PCI PM wakeup and hotplug setup) */ /* enable device (incl. PCI PM wakeup and hotplug setup) */
rc = pci_enable_device(pdev); rc = pcim_enable_device(pdev);
if (rc < 0) { if (rc < 0) {
netif_err(tp, probe, dev, "enable failure\n"); netif_err(tp, probe, dev, "enable failure\n");
goto err_out_free_dev_1; return rc;
} }
if (pci_set_mwi(pdev) < 0) if (pcim_set_mwi(pdev) < 0)
netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n"); netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n");
/* make sure PCI base addr 1 is MMIO */ /* make sure PCI base addr 1 is MMIO */
...@@ -8486,30 +8460,28 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8486,30 +8460,28 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_err(tp, probe, dev, netif_err(tp, probe, dev,
"region #%d not an MMIO resource, aborting\n", "region #%d not an MMIO resource, aborting\n",
region); region);
rc = -ENODEV; return -ENODEV;
goto err_out_mwi_2;
} }
/* check for weird/broken PCI region reporting */ /* check for weird/broken PCI region reporting */
if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) { if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
netif_err(tp, probe, dev, netif_err(tp, probe, dev,
"Invalid PCI region size(s), aborting\n"); "Invalid PCI region size(s), aborting\n");
rc = -ENODEV; return -ENODEV;
goto err_out_mwi_2;
} }
rc = pci_request_regions(pdev, MODULENAME); rc = pci_request_regions(pdev, MODULENAME);
if (rc < 0) { if (rc < 0) {
netif_err(tp, probe, dev, "could not request regions\n"); netif_err(tp, probe, dev, "could not request regions\n");
goto err_out_mwi_2; return rc;
} }
/* ioremap MMIO region */ /* ioremap MMIO region */
ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE); ioaddr = devm_ioremap(&pdev->dev, pci_resource_start(pdev, region),
R8169_REGS_SIZE);
if (!ioaddr) { if (!ioaddr) {
netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n"); netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
rc = -EIO; return -EIO;
goto err_out_free_res_3;
} }
tp->mmio_addr = ioaddr; tp->mmio_addr = ioaddr;
...@@ -8535,7 +8507,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8535,7 +8507,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) { if (rc < 0) {
netif_err(tp, probe, dev, "DMA configuration failed\n"); netif_err(tp, probe, dev, "DMA configuration failed\n");
goto err_out_unmap_4; return rc;
} }
} }
...@@ -8697,16 +8669,15 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8697,16 +8669,15 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->rtl_fw = RTL_FIRMWARE_UNKNOWN; tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
tp->counters = dma_alloc_coherent (&pdev->dev, sizeof(*tp->counters), tp->counters = dmam_alloc_coherent (&pdev->dev, sizeof(*tp->counters),
&tp->counters_phys_addr, GFP_KERNEL); &tp->counters_phys_addr,
if (!tp->counters) { GFP_KERNEL);
rc = -ENOMEM; if (!tp->counters)
goto err_out_msi_5; return -ENOMEM;
}
rc = register_netdev(dev); rc = register_netdev(dev);
if (rc < 0) if (rc < 0)
goto err_out_cnt_6; return rc;
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
...@@ -8735,25 +8706,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -8735,25 +8706,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_carrier_off(dev); netif_carrier_off(dev);
out: return 0;
return rc;
err_out_cnt_6:
dma_free_coherent(&pdev->dev, sizeof(*tp->counters), tp->counters,
tp->counters_phys_addr);
err_out_msi_5:
netif_napi_del(&tp->napi);
rtl_disable_msi(pdev, tp);
err_out_unmap_4:
iounmap(ioaddr);
err_out_free_res_3:
pci_release_regions(pdev);
err_out_mwi_2:
pci_clear_mwi(pdev);
pci_disable_device(pdev);
err_out_free_dev_1:
free_netdev(dev);
goto out;
} }
static struct pci_driver rtl8169_pci_driver = { static struct pci_driver rtl8169_pci_driver = {
......
...@@ -1458,6 +1458,7 @@ struct pci_devres { ...@@ -1458,6 +1458,7 @@ struct pci_devres {
unsigned int pinned:1; unsigned int pinned:1;
unsigned int orig_intx:1; unsigned int orig_intx:1;
unsigned int restore_intx:1; unsigned int restore_intx:1;
unsigned int mwi:1;
u32 region_mask; u32 region_mask;
}; };
...@@ -1476,6 +1477,9 @@ static void pcim_release(struct device *gendev, void *res) ...@@ -1476,6 +1477,9 @@ static void pcim_release(struct device *gendev, void *res)
if (this->region_mask & (1 << i)) if (this->region_mask & (1 << i))
pci_release_region(dev, i); pci_release_region(dev, i);
if (this->mwi)
pci_clear_mwi(dev);
if (this->restore_intx) if (this->restore_intx)
pci_intx(dev, this->orig_intx); pci_intx(dev, this->orig_intx);
...@@ -3760,6 +3764,27 @@ int pci_set_mwi(struct pci_dev *dev) ...@@ -3760,6 +3764,27 @@ int pci_set_mwi(struct pci_dev *dev)
} }
EXPORT_SYMBOL(pci_set_mwi); EXPORT_SYMBOL(pci_set_mwi);
/**
* pcim_set_mwi - a device-managed pci_set_mwi()
* @dev: the PCI device for which MWI is enabled
*
* Managed pci_set_mwi().
*
* RETURNS: An appropriate -ERRNO error value on error, or zero for success.
*/
int pcim_set_mwi(struct pci_dev *dev)
{
struct pci_devres *dr;
dr = find_pci_dr(dev);
if (!dr)
return -ENOMEM;
dr->mwi = 1;
return pci_set_mwi(dev);
}
EXPORT_SYMBOL(pcim_set_mwi);
/** /**
* pci_try_set_mwi - enables memory-write-invalidate PCI transaction * pci_try_set_mwi - enables memory-write-invalidate PCI transaction
* @dev: the PCI device for which MWI is enabled * @dev: the PCI device for which MWI is enabled
......
...@@ -1072,6 +1072,7 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); ...@@ -1072,6 +1072,7 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
int pci_set_cacheline_size(struct pci_dev *dev); int pci_set_cacheline_size(struct pci_dev *dev);
#define HAVE_PCI_SET_MWI #define HAVE_PCI_SET_MWI
int __must_check pci_set_mwi(struct pci_dev *dev); int __must_check pci_set_mwi(struct pci_dev *dev);
int __must_check pcim_set_mwi(struct pci_dev *dev);
int pci_try_set_mwi(struct pci_dev *dev); int pci_try_set_mwi(struct pci_dev *dev);
void pci_clear_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev);
void pci_intx(struct pci_dev *dev, int enable); void pci_intx(struct pci_dev *dev, int enable);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment