diff options
Diffstat (limited to 'drivers/net/ethernet/micrel')
| -rw-r--r-- | drivers/net/ethernet/micrel/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/micrel/ks8695net.c | 49 | ||||
| -rw-r--r-- | drivers/net/ethernet/micrel/ks8842.c | 29 | ||||
| -rw-r--r-- | drivers/net/ethernet/micrel/ks8851.c | 221 | ||||
| -rw-r--r-- | drivers/net/ethernet/micrel/ks8851.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/micrel/ks8851_mll.c | 111 | ||||
| -rw-r--r-- | drivers/net/ethernet/micrel/ksz884x.c | 95 |
7 files changed, 275 insertions, 236 deletions
diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig index fe42fc00d8d..d16b11ed2e5 100644 --- a/drivers/net/ethernet/micrel/Kconfig +++ b/drivers/net/ethernet/micrel/Kconfig @@ -22,7 +22,6 @@ if NET_VENDOR_MICREL config ARM_KS8695_ETHER tristate "KS8695 Ethernet support" depends on ARM && ARCH_KS8695 - select NET_CORE select MII ---help--- If you wish to compile a kernel for the KS8695 and want to @@ -39,7 +38,6 @@ config KS8842 config KS8851 tristate "Micrel KS8851 SPI" depends on SPI - select NET_CORE select MII select CRC32 select EEPROM_93CX6 @@ -49,7 +47,6 @@ config KS8851 config KS8851_MLL tristate "Micrel KS8851 MLL" depends on HAS_IOMEM - select NET_CORE select MII ---help--- This platform driver is for Micrel KS8851 Address/data bus @@ -58,7 +55,6 @@ config KS8851_MLL config KSZ884X_PCI tristate "Micrel KSZ8841/2 PCI" depends on PCI - select NET_CORE select MII select CRC32 ---help--- diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c index ab81c0dc96e..6c7c78baedc 100644 --- a/drivers/net/ethernet/micrel/ks8695net.c +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -21,7 +21,6 @@ #include <linux/ioport.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/skbuff.h> #include <linux/spinlock.h> @@ -278,7 +277,8 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp) for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) { if (!ksp->rx_buffers[buff_n].skb) { - struct sk_buff *skb = dev_alloc_skb(MAX_RXBUF_SIZE); + struct sk_buff *skb = + netdev_alloc_skb(ksp->ndev, MAX_RXBUF_SIZE); dma_addr_t mapping; ksp->rx_buffers[buff_n].skb = skb; @@ -299,7 +299,6 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp) break; } ksp->rx_buffers[buff_n].dma_ptr = mapping; - skb->dev = ksp->ndev; ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE; /* Record this into the DMA ring */ @@ -1249,9 +1248,6 @@ ks8695_open(struct net_device *ndev) struct ks8695_priv *ksp = netdev_priv(ndev); int ret; - if (!is_valid_ether_addr(ndev->dev_addr)) - return -EADDRNOTAVAIL; - ks8695_reset(ksp); ks8695_update_mac(ksp); @@ -1277,7 +1273,7 @@ ks8695_open(struct net_device *ndev) * This initialises the LAN switch in the KS8695 to a known-good * set of defaults. */ -static void __devinit +static void ks8695_init_switch(struct ks8695_priv *ksp) { u32 ctrl; @@ -1305,7 +1301,7 @@ ks8695_init_switch(struct ks8695_priv *ksp) * This initialises a KS8695's WAN phy to sensible values for * autonegotiation etc. */ -static void __devinit +static void ks8695_init_wan_phy(struct ks8695_priv *ksp) { u32 ctrl; @@ -1349,7 +1345,7 @@ static const struct net_device_ops ks8695_netdev_ops = { * wan ports, and an IORESOURCE_IRQ for the link IRQ for the wan * port. */ -static int __devinit +static int ks8695_probe(struct platform_device *pdev) { struct ks8695_priv *ksp; @@ -1362,10 +1358,8 @@ ks8695_probe(struct platform_device *pdev) /* Initialise a net_device */ ndev = alloc_etherdev(sizeof(struct ks8695_priv)); - if (!ndev) { - dev_err(&pdev->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } SET_NETDEV_DEV(ndev, &pdev->dev); @@ -1510,15 +1504,15 @@ ks8695_probe(struct platform_device *pdev) if (ksp->phyiface_regs && ksp->link_irq == -1) { ks8695_init_switch(ksp); ksp->dtype = KS8695_DTYPE_LAN; - SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); + ndev->ethtool_ops = &ks8695_ethtool_ops; } else if (ksp->phyiface_regs && ksp->link_irq != -1) { ks8695_init_wan_phy(ksp); ksp->dtype = KS8695_DTYPE_WAN; - SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops); + ndev->ethtool_ops = &ks8695_wan_ethtool_ops; } else { /* No initialisation since HPNA does not have a PHY */ ksp->dtype = KS8695_DTYPE_HPNA; - SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); + ndev->ethtool_ops = &ks8695_ethtool_ops; } /* And bring up the net_device with the net core */ @@ -1599,13 +1593,12 @@ ks8695_drv_resume(struct platform_device *pdev) * * This unregisters and releases a KS8695 ethernet device. */ -static int __devexit +static int ks8695_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct ks8695_priv *ksp = netdev_priv(ndev); - platform_set_drvdata(pdev, NULL); netif_napi_del(&ksp->napi); unregister_netdev(ndev); @@ -1622,30 +1615,12 @@ static struct platform_driver ks8695_driver = { .owner = THIS_MODULE, }, .probe = ks8695_probe, - .remove = __devexit_p(ks8695_drv_remove), + .remove = ks8695_drv_remove, .suspend = ks8695_drv_suspend, .resume = ks8695_drv_resume, }; -/* Module interface */ - -static int __init -ks8695_init(void) -{ - printk(KERN_INFO "%s Ethernet driver, V%s\n", - MODULENAME, MODULEVERSION); - - return platform_driver_register(&ks8695_driver); -} - -static void __exit -ks8695_cleanup(void) -{ - platform_driver_unregister(&ks8695_driver); -} - -module_init(ks8695_init); -module_exit(ks8695_cleanup); +module_platform_driver(ks8695_driver); MODULE_AUTHOR("Simtec Electronics"); MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c index 0a85690a132..822616e3c37 100644 --- a/drivers/net/ethernet/micrel/ks8842.c +++ b/drivers/net/ethernet/micrel/ks8842.c @@ -458,9 +458,8 @@ static int ks8842_tx_frame_dma(struct sk_buff *skb, struct net_device *netdev) if (sg_dma_len(&ctl->sg) % 4) sg_dma_len(&ctl->sg) += 4 - sg_dma_len(&ctl->sg) % 4; - ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan, - &ctl->sg, 1, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); + ctl->adesc = dmaengine_prep_slave_sg(ctl->chan, + &ctl->sg, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); if (!ctl->adesc) return NETDEV_TX_BUSY; @@ -570,9 +569,8 @@ static int __ks8842_start_new_rx_dma(struct net_device *netdev) sg_dma_len(sg) = DMA_BUFFER_SIZE; - ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan, - sg, 1, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); + ctl->adesc = dmaengine_prep_slave_sg(ctl->chan, + sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); if (!ctl->adesc) goto out; @@ -705,7 +703,8 @@ static void ks8842_rx_frame(struct net_device *netdev, ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR); } -void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter) +static void ks8842_handle_rx(struct net_device *netdev, + struct ks8842_adapter *adapter) { u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; netdev_dbg(netdev, "%s Entry - rx_data: %d\n", __func__, rx_data); @@ -715,7 +714,8 @@ void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter) } } -void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter) +static void ks8842_handle_tx(struct net_device *netdev, + struct ks8842_adapter *adapter) { u16 sr = ks8842_read16(adapter, 16, REG_TXSR); netdev_dbg(netdev, "%s - entry, sr: %x\n", __func__, sr); @@ -724,7 +724,7 @@ void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter) netif_wake_queue(netdev); } -void ks8842_handle_rx_overrun(struct net_device *netdev, +static void ks8842_handle_rx_overrun(struct net_device *netdev, struct ks8842_adapter *adapter) { netdev_dbg(netdev, "%s: entry\n", __func__); @@ -732,7 +732,7 @@ void ks8842_handle_rx_overrun(struct net_device *netdev, netdev->stats.rx_fifo_errors++; } -void ks8842_tasklet(unsigned long arg) +static void ks8842_tasklet(unsigned long arg) { struct net_device *netdev = (struct net_device *)arg; struct ks8842_adapter *adapter = netdev_priv(netdev); @@ -1140,13 +1140,13 @@ static const struct ethtool_ops ks8842_ethtool_ops = { .get_link = ethtool_op_get_link, }; -static int __devinit ks8842_probe(struct platform_device *pdev) +static int ks8842_probe(struct platform_device *pdev) { int err = -ENOMEM; struct resource *iomem; struct net_device *netdev; struct ks8842_adapter *adapter; - struct ks8842_platform_data *pdata = pdev->dev.platform_data; + struct ks8842_platform_data *pdata = dev_get_platdata(&pdev->dev); u16 id; unsigned i; @@ -1211,7 +1211,7 @@ static int __devinit ks8842_probe(struct platform_device *pdev) ks8842_read_mac_addr(adapter, netdev->dev_addr); if (!is_valid_ether_addr(netdev->dev_addr)) - random_ether_addr(netdev->dev_addr); + eth_hw_addr_random(netdev); } id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE); @@ -1239,7 +1239,7 @@ err_mem_region: return err; } -static int __devexit ks8842_remove(struct platform_device *pdev) +static int ks8842_remove(struct platform_device *pdev) { struct net_device *netdev = platform_get_drvdata(pdev); struct ks8842_adapter *adapter = netdev_priv(netdev); @@ -1250,7 +1250,6 @@ static int __devexit ks8842_remove(struct platform_device *pdev) iounmap(adapter->hw_addr); free_netdev(netdev); release_mem_region(iomem->start, resource_size(iomem)); - platform_set_drvdata(pdev, NULL); return 0; } diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 0c3e4005224..66d4ab703f4 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1,4 +1,4 @@ -/* drivers/net/ks8851.c +/* drivers/net/ethernet/micrel/ks8851.c * * Copyright 2009 Simtec Electronics * http://www.simtec.co.uk/ @@ -23,8 +23,11 @@ #include <linux/crc32.h> #include <linux/mii.h> #include <linux/eeprom_93cx6.h> +#include <linux/regulator/consumer.h> #include <linux/spi/spi.h> +#include <linux/gpio.h> +#include <linux/of_gpio.h> #include "ks8851.h" @@ -69,7 +72,6 @@ union ks8851_tx_hdr { * @mii: The MII state information for the mii calls. * @rxctrl: RX settings for @rxctrl_work. * @tx_work: Work queue for tx packets - * @irq_work: Work queue for servicing interrupts * @rxctrl_work: Work queue for updating RX mode and multicast lists * @txq: Queue of packets for transmission. * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. @@ -84,6 +86,9 @@ union ks8851_tx_hdr { * @rc_rxqcr: Cached copy of KS_RXQCR. * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM. + * @vdd_reg: Optional regulator supplying the chip + * @vdd_io: Optional digital power supply for IO + * @gpio: Optional reset_n gpio * * The @lock ensures that the chip is protected when certain operations are * in progress. When the read or write packet transfer is in progress, most @@ -121,7 +126,6 @@ struct ks8851_net { struct ks8851_rxctrl rxctrl; struct work_struct tx_work; - struct work_struct irq_work; struct work_struct rxctrl_work; struct sk_buff_head txq; @@ -132,6 +136,9 @@ struct ks8851_net { struct spi_transfer spi_xfer2[2]; struct eeprom_93cx6 eeprom; + struct regulator *vdd_reg; + struct regulator *vdd_io; + int gpio; }; static int msg_enable; @@ -422,7 +429,7 @@ static void ks8851_read_mac_addr(struct net_device *dev) * * Get or create the initial mac address for the device and then set that * into the station address register. If there is an EEPROM present, then - * we try that. If no valid mac address is found we use random_ether_addr() + * we try that. If no valid mac address is found we use eth_random_addr() * to create a new one. */ static void ks8851_init_mac(struct ks8851_net *ks) @@ -439,28 +446,11 @@ static void ks8851_init_mac(struct ks8851_net *ks) dev->dev_addr); } - random_ether_addr(dev->dev_addr); + eth_hw_addr_random(dev); ks8851_write_mac_addr(dev); } /** - * ks8851_irq - device interrupt handler - * @irq: Interrupt number passed from the IRQ hnalder. - * @pw: The private word passed to register_irq(), our struct ks8851_net. - * - * Disable the interrupt from happening again until we've processed the - * current status by scheduling ks8851_irq_work(). - */ -static irqreturn_t ks8851_irq(int irq, void *pw) -{ - struct ks8851_net *ks = pw; - - disable_irq_nosync(irq); - schedule_work(&ks->irq_work); - return IRQ_HANDLED; -} - -/** * ks8851_rdfifo - read data from the receive fifo * @ks: The device state. * @buff: The buffer address @@ -547,7 +537,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) for (; rxfc != 0; rxfc--) { rxh = ks8851_rdreg32(ks, KS_RXFHSR); rxstat = rxh & 0xffff; - rxlen = rxh >> 16; + rxlen = (rxh >> 16) & 0xfff; netif_dbg(ks, rx_status, ks->netdev, "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); @@ -595,19 +585,20 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) } /** - * ks8851_irq_work - work queue handler for dealing with interrupt requests - * @work: The work structure that was scheduled by schedule_work() + * ks8851_irq - IRQ handler for dealing with interrupt requests + * @irq: IRQ number + * @_ks: cookie * - * This is the handler invoked when the ks8851_irq() is called to find out - * what happened, as we cannot allow ourselves to sleep whilst waiting for - * anything other process has the chip's lock. + * This handler is invoked when the IRQ line asserts to find out what happened. + * As we cannot allow ourselves to sleep in HARDIRQ context, this handler runs + * in thread context. * * Read the interrupt status, work out what needs to be done and then clear * any of the interrupts that are not needed. */ -static void ks8851_irq_work(struct work_struct *work) +static irqreturn_t ks8851_irq(int irq, void *_ks) { - struct ks8851_net *ks = container_of(work, struct ks8851_net, irq_work); + struct ks8851_net *ks = _ks; unsigned status; unsigned handled = 0; @@ -618,10 +609,8 @@ static void ks8851_irq_work(struct work_struct *work) netif_dbg(ks, intr, ks->netdev, "%s: status 0x%04x\n", __func__, status); - if (status & IRQ_LCI) { - /* should do something about checking link status */ + if (status & IRQ_LCI) handled |= IRQ_LCI; - } if (status & IRQ_LDI) { u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); @@ -684,10 +673,13 @@ static void ks8851_irq_work(struct work_struct *work) mutex_unlock(&ks->lock); + if (status & IRQ_LCI) + mii_check_link(&ks->mii); + if (status & IRQ_TXI) netif_wake_queue(ks->netdev); - enable_irq(ks->netdev->irq); + return IRQ_HANDLED; } /** @@ -889,16 +881,16 @@ static int ks8851_net_stop(struct net_device *dev) netif_stop_queue(dev); mutex_lock(&ks->lock); + /* turn off the IRQs and ack any outstanding */ + ks8851_wrreg16(ks, KS_IER, 0x0000); + ks8851_wrreg16(ks, KS_ISR, 0xffff); + mutex_unlock(&ks->lock); /* stop any outstanding work */ - flush_work(&ks->irq_work); flush_work(&ks->tx_work); flush_work(&ks->rxctrl_work); - /* turn off the IRQs and ack any outstanding */ - ks8851_wrreg16(ks, KS_IER, 0x0000); - ks8851_wrreg16(ks, KS_ISR, 0xffff); - + mutex_lock(&ks->lock); /* shutdown RX process */ ks8851_wrreg16(ks, KS_RXCR1, 0x0000); @@ -907,6 +899,7 @@ static int ks8851_net_stop(struct net_device *dev) /* set powermode to soft power down to save power */ ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); + mutex_unlock(&ks->lock); /* ensure any queued tx buffers are dumped */ while (!skb_queue_empty(&ks->txq)) { @@ -918,7 +911,6 @@ static int ks8851_net_stop(struct net_device *dev) dev_kfree_skb(txb); } - mutex_unlock(&ks->lock); return 0; } @@ -1381,48 +1373,48 @@ static int ks8851_read_selftest(struct ks8851_net *ks) /* driver bus management functions */ -#ifdef CONFIG_PM -static int ks8851_suspend(struct spi_device *spi, pm_message_t state) +#ifdef CONFIG_PM_SLEEP + +static int ks8851_suspend(struct device *dev) { - struct ks8851_net *ks = dev_get_drvdata(&spi->dev); - struct net_device *dev = ks->netdev; + struct ks8851_net *ks = dev_get_drvdata(dev); + struct net_device *netdev = ks->netdev; - if (netif_running(dev)) { - netif_device_detach(dev); - ks8851_net_stop(dev); + if (netif_running(netdev)) { + netif_device_detach(netdev); + ks8851_net_stop(netdev); } return 0; } -static int ks8851_resume(struct spi_device *spi) +static int ks8851_resume(struct device *dev) { - struct ks8851_net *ks = dev_get_drvdata(&spi->dev); - struct net_device *dev = ks->netdev; + struct ks8851_net *ks = dev_get_drvdata(dev); + struct net_device *netdev = ks->netdev; - if (netif_running(dev)) { - ks8851_net_open(dev); - netif_device_attach(dev); + if (netif_running(netdev)) { + ks8851_net_open(netdev); + netif_device_attach(netdev); } return 0; } -#else -#define ks8851_suspend NULL -#define ks8851_resume NULL #endif -static int __devinit ks8851_probe(struct spi_device *spi) +static SIMPLE_DEV_PM_OPS(ks8851_pm_ops, ks8851_suspend, ks8851_resume); + +static int ks8851_probe(struct spi_device *spi) { struct net_device *ndev; struct ks8851_net *ks; int ret; + unsigned cider; + int gpio; ndev = alloc_etherdev(sizeof(struct ks8851_net)); - if (!ndev) { - dev_err(&spi->dev, "failed to alloc ethernet device\n"); + if (!ndev) return -ENOMEM; - } spi->bits_per_word = 8; @@ -1432,11 +1424,58 @@ static int __devinit ks8851_probe(struct spi_device *spi) ks->spidev = spi; ks->tx_space = 6144; + gpio = of_get_named_gpio_flags(spi->dev.of_node, "reset-gpios", + 0, NULL); + if (gpio == -EPROBE_DEFER) { + ret = gpio; + goto err_gpio; + } + + ks->gpio = gpio; + if (gpio_is_valid(gpio)) { + ret = devm_gpio_request_one(&spi->dev, gpio, + GPIOF_OUT_INIT_LOW, "ks8851_rst_n"); + if (ret) { + dev_err(&spi->dev, "reset gpio request failed\n"); + goto err_gpio; + } + } + + ks->vdd_io = devm_regulator_get(&spi->dev, "vdd-io"); + if (IS_ERR(ks->vdd_io)) { + ret = PTR_ERR(ks->vdd_io); + goto err_reg_io; + } + + ret = regulator_enable(ks->vdd_io); + if (ret) { + dev_err(&spi->dev, "regulator vdd_io enable fail: %d\n", + ret); + goto err_reg_io; + } + + ks->vdd_reg = devm_regulator_get(&spi->dev, "vdd"); + if (IS_ERR(ks->vdd_reg)) { + ret = PTR_ERR(ks->vdd_reg); + goto err_reg; + } + + ret = regulator_enable(ks->vdd_reg); + if (ret) { + dev_err(&spi->dev, "regulator vdd enable fail: %d\n", + ret); + goto err_reg; + } + + if (gpio_is_valid(gpio)) { + usleep_range(10000, 11000); + gpio_set_value(gpio, 1); + } + mutex_init(&ks->lock); spin_lock_init(&ks->statelock); INIT_WORK(&ks->tx_work, ks8851_tx_work); - INIT_WORK(&ks->irq_work, ks8851_irq_work); INIT_WORK(&ks->rxctrl_work, ks8851_rxctrl_work); /* initialise pre-made spi transfer messages */ @@ -1472,10 +1511,10 @@ static int __devinit ks8851_probe(struct spi_device *spi) skb_queue_head_init(&ks->txq); - SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops); + ndev->ethtool_ops = &ks8851_ethtool_ops; SET_NETDEV_DEV(ndev, &spi->dev); - dev_set_drvdata(&spi->dev, ks); + spi_set_drvdata(spi, ks); ndev->if_port = IF_PORT_100BASET; ndev->netdev_ops = &ks8851_netdev_ops; @@ -1485,8 +1524,8 @@ static int __devinit ks8851_probe(struct spi_device *spi) ks8851_soft_reset(ks, GRR_GSR); /* simple check for a valid chip being connected to the bus */ - - if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { + cider = ks8851_rdreg16(ks, KS_CIDER); + if ((cider & ~CIDER_REV_MASK) != CIDER_ID) { dev_err(&spi->dev, "failed to read device ID\n"); ret = -ENODEV; goto err_id; @@ -1503,8 +1542,9 @@ static int __devinit ks8851_probe(struct spi_device *spi) ks8851_read_selftest(ks); ks8851_init_mac(ks); - ret = request_irq(spi->irq, ks8851_irq, IRQF_TRIGGER_LOW, - ndev->name, ks); + ret = request_threaded_irq(spi->irq, NULL, ks8851_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + ndev->name, ks); if (ret < 0) { dev_err(&spi->dev, "failed to get irq\n"); goto err_irq; @@ -1517,59 +1557,62 @@ static int __devinit ks8851_probe(struct spi_device *spi) } netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n", - CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), - ndev->dev_addr, ndev->irq, + CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq, ks->rc_ccr & CCR_EEPROM ? "has" : "no"); return 0; err_netdev: - free_irq(ndev->irq, ndev); + free_irq(ndev->irq, ks); -err_id: err_irq: + if (gpio_is_valid(gpio)) + gpio_set_value(gpio, 0); +err_id: + regulator_disable(ks->vdd_reg); +err_reg: + regulator_disable(ks->vdd_io); +err_reg_io: +err_gpio: free_netdev(ndev); return ret; } -static int __devexit ks8851_remove(struct spi_device *spi) +static int ks8851_remove(struct spi_device *spi) { - struct ks8851_net *priv = dev_get_drvdata(&spi->dev); + struct ks8851_net *priv = spi_get_drvdata(spi); if (netif_msg_drv(priv)) dev_info(&spi->dev, "remove\n"); unregister_netdev(priv->netdev); free_irq(spi->irq, priv); + if (gpio_is_valid(priv->gpio)) + gpio_set_value(priv->gpio, 0); + regulator_disable(priv->vdd_reg); + regulator_disable(priv->vdd_io); free_netdev(priv->netdev); return 0; } +static const struct of_device_id ks8851_match_table[] = { + { .compatible = "micrel,ks8851" }, + { } +}; + static struct spi_driver ks8851_driver = { .driver = { .name = "ks8851", + .of_match_table = ks8851_match_table, .owner = THIS_MODULE, + .pm = &ks8851_pm_ops, }, .probe = ks8851_probe, - .remove = __devexit_p(ks8851_remove), - .suspend = ks8851_suspend, - .resume = ks8851_resume, + .remove = ks8851_remove, }; - -static int __init ks8851_init(void) -{ - return spi_register_driver(&ks8851_driver); -} - -static void __exit ks8851_exit(void) -{ - spi_unregister_driver(&ks8851_driver); -} - -module_init(ks8851_init); -module_exit(ks8851_exit); +module_spi_driver(ks8851_driver); MODULE_DESCRIPTION("KS8851 Network driver"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h index b0fae86aaca..852256ef1f2 100644 --- a/drivers/net/ethernet/micrel/ks8851.h +++ b/drivers/net/ethernet/micrel/ks8851.h @@ -1,4 +1,4 @@ -/* drivers/net/ks8851.h +/* drivers/net/ethernet/micrel/ks8851.h * * Copyright 2009 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 2784bc706f1..c83d16dc7cd 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1,5 +1,5 @@ /** - * drivers/net/ks8851_mll.c + * drivers/net/ethernet/micrel/ks8851_mll.c * Copyright (c) 2009 Micrel Inc. * * This program is free software; you can redistribute it and/or modify @@ -16,8 +16,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/** - * Supports: +/* Supports: * KS8851 16bit MLL chip from Micrel Inc. */ @@ -35,12 +34,15 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/slab.h> -#include <asm/io.h> +#include <linux/ks8851_mll.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_net.h> #define DRV_NAME "ks8851_mll" static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; -#define MAX_RECV_FRAMES 32 +#define MAX_RECV_FRAMES 255 #define MAX_BUF_SIZE 2048 #define TX_BUF_SIZE 2000 #define RX_BUF_SIZE 2000 @@ -465,8 +467,7 @@ static int msg_enable; #define BE1 0x2000 /* Byte Enable 1 */ #define BE0 0x1000 /* Byte Enable 0 */ -/** - * register read/write calls. +/* register read/write calls. * * All these calls issue transactions to access the chip's registers. They * all require that the necessary lock is held to prevent accesses when the @@ -687,7 +688,7 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op) } -void ks_enable_qmu(struct ks_net *ks) +static void ks_enable_qmu(struct ks_net *ks) { u16 w; @@ -794,20 +795,35 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev) frame_hdr = ks->frame_head_info; while (ks->frame_cnt--) { - skb = dev_alloc_skb(frame_hdr->len + 16); - if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) && - (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { + if (unlikely(!(frame_hdr->sts & RXFSHR_RXFV) || + frame_hdr->len >= RX_BUF_SIZE || + frame_hdr->len <= 0)) { + + /* discard an invalid packet */ + ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF)); + netdev->stats.rx_dropped++; + if (!(frame_hdr->sts & RXFSHR_RXFV)) + netdev->stats.rx_frame_errors++; + else + netdev->stats.rx_length_errors++; + frame_hdr++; + continue; + } + + skb = netdev_alloc_skb(netdev, frame_hdr->len + 16); + if (likely(skb)) { skb_reserve(skb, 2); /* read data block including CRC 4 bytes */ ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len); - skb_put(skb, frame_hdr->len); + skb_put(skb, frame_hdr->len - 4); skb->protocol = eth_type_trans(skb, netdev); netif_rx(skb); + /* exclude CRC size */ + netdev->stats.rx_bytes += frame_hdr->len - 4; + netdev->stats.rx_packets++; } else { - pr_err("%s: err:skb alloc\n", __func__); ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF)); - if (skb) - dev_kfree_skb_irq(skb); + netdev->stats.rx_dropped++; } frame_hdr++; } @@ -837,7 +853,7 @@ static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks) /** * ks_irq - device interrupt handler - * @irq: Interrupt number passed from the IRQ hnalder. + * @irq: Interrupt number passed from the IRQ handler. * @pw: The private word passed to register_irq(), our struct ks_net. * * This is the handler invoked to find out what happened @@ -879,6 +895,8 @@ static irqreturn_t ks_irq(int irq, void *pw) ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); } + if (unlikely(status & IRQ_RXOI)) + ks->netdev->stats.rx_over_errors++; /* this should be the last in IRQ handler*/ ks_restore_cmd_reg(ks); return IRQ_HANDLED; @@ -897,7 +915,7 @@ static int ks_net_open(struct net_device *netdev) struct ks_net *ks = netdev_priv(netdev); int err; -#define KS_INT_FLAGS (IRQF_DISABLED|IRQF_TRIGGER_LOW) +#define KS_INT_FLAGS IRQF_TRIGGER_LOW /* lock the card, even if we may not actually do anything * else at the moment. */ @@ -1017,6 +1035,9 @@ static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) { ks_write_qmu(ks, skb->data, skb->len); + /* add tx statistics */ + netdev->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; dev_kfree_skb(skb); } else retv = NETDEV_TX_BUSY; @@ -1103,7 +1124,7 @@ static void ks_set_grpaddr(struct ks_net *ks) } } /* ks_set_grpaddr */ -/* +/** * ks_clear_mcast - clear multicast information * * @ks : The chip information @@ -1227,7 +1248,7 @@ static void ks_set_mac(struct ks_net *ks, u8 *data) w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF); ks_wrreg16(ks, KS_MARL, w); - memcpy(ks->mac_addr, data, 6); + memcpy(ks->mac_addr, data, ETH_ALEN); if (ks->enabled) ks_start_rx(ks); @@ -1499,23 +1520,29 @@ static int ks_hw_init(struct ks_net *ks) ks->mcast_lst_size = 0; ks->frame_head_info = kmalloc(MHEADER_SIZE, GFP_KERNEL); - if (!ks->frame_head_info) { - pr_err("Error: Fail to allocate frame memory\n"); + if (!ks->frame_head_info) return false; - } ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS); return true; } +#if defined(CONFIG_OF) +static const struct of_device_id ks8851_ml_dt_ids[] = { + { .compatible = "micrel,ks8851-mll" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ks8851_ml_dt_ids); +#endif -static int __devinit ks8851_probe(struct platform_device *pdev) +static int ks8851_probe(struct platform_device *pdev) { int err = -ENOMEM; struct resource *io_d, *io_c; struct net_device *netdev; struct ks_net *ks; u16 id, data; + const char *mac; io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0); io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -1597,17 +1624,35 @@ static int __devinit ks8851_probe(struct platform_device *pdev) ks_disable_qmu(ks); ks_setup(ks); ks_setup_int(ks); - memcpy(netdev->dev_addr, ks->mac_addr, 6); data = ks_rdreg16(ks, KS_OBCR); ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA); - /** - * If you want to use the default MAC addr, - * comment out the 2 functions below. - */ + /* overwriting the default MAC address */ + if (pdev->dev.of_node) { + mac = of_get_mac_address(pdev->dev.of_node); + if (mac) + memcpy(ks->mac_addr, mac, ETH_ALEN); + } else { + struct ks8851_mll_platform_data *pdata; + + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + netdev_err(netdev, "No platform data\n"); + err = -ENODEV; + goto err_pdata; + } + memcpy(ks->mac_addr, pdata->mac_addr, ETH_ALEN); + } + if (!is_valid_ether_addr(ks->mac_addr)) { + /* Use random MAC address if none passed */ + eth_random_addr(ks->mac_addr); + netdev_info(netdev, "Using random mac address\n"); + } + netdev_info(netdev, "Mac address is: %pM\n", ks->mac_addr); + + memcpy(netdev->dev_addr, ks->mac_addr, ETH_ALEN); - random_ether_addr(netdev->dev_addr); ks_set_mac(ks, netdev->dev_addr); id = ks_rdreg16(ks, KS_CIDER); @@ -1616,6 +1661,8 @@ static int __devinit ks8851_probe(struct platform_device *pdev) (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); return 0; +err_pdata: + unregister_netdev(netdev); err_register: err_get_irq: iounmap(ks->hw_addr_cmd); @@ -1631,7 +1678,7 @@ err_mem_region: return err; } -static int __devexit ks8851_remove(struct platform_device *pdev) +static int ks8851_remove(struct platform_device *pdev) { struct net_device *netdev = platform_get_drvdata(pdev); struct ks_net *ks = netdev_priv(netdev); @@ -1642,7 +1689,6 @@ static int __devexit ks8851_remove(struct platform_device *pdev) iounmap(ks->hw_addr); free_netdev(netdev); release_mem_region(iomem->start, resource_size(iomem)); - platform_set_drvdata(pdev, NULL); return 0; } @@ -1651,9 +1697,10 @@ static struct platform_driver ks8851_platform_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ks8851_ml_dt_ids), }, .probe = ks8851_probe, - .remove = __devexit_p(ks8851_remove), + .remove = ks8851_remove, }; module_platform_driver(ks8851_platform_driver); diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index e52cd310ae7..064a48d0c36 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -1,5 +1,5 @@ /** - * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver + * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver * * Copyright (c) 2009-2010 Micrel, Inc. * Tristram Ha <Tristram.Ha@micrel.com> @@ -1487,7 +1487,7 @@ struct dev_priv { #define DRV_VERSION "1.0.0" #define DRV_RELDATE "Feb 8, 2010" -static char version[] __devinitdata = +static char version[] = "Micrel " DEVICE_NAME " " DRV_VERSION " (" DRV_RELDATE ")"; static u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x88, 0x42, 0x01 }; @@ -3913,7 +3913,7 @@ static void hw_start_rx(struct ksz_hw *hw) hw->rx_stop = 2; } -/* +/** * hw_stop_rx - stop receiving * @hw: The hardware instance. * @@ -4128,10 +4128,10 @@ static int hw_add_addr(struct ksz_hw *hw, u8 *mac_addr) int i; int j = ADDITIONAL_ENTRIES; - if (!memcmp(hw->override_addr, mac_addr, ETH_ALEN)) + if (ether_addr_equal(hw->override_addr, mac_addr)) return 0; for (i = 0; i < hw->addr_list_size; i++) { - if (!memcmp(hw->address[i], mac_addr, ETH_ALEN)) + if (ether_addr_equal(hw->address[i], mac_addr)) return 0; if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i])) j = i; @@ -4149,7 +4149,7 @@ static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr) int i; for (i = 0; i < hw->addr_list_size; i++) { - if (!memcmp(hw->address[i], mac_addr, ETH_ALEN)) { + if (ether_addr_equal(hw->address[i], mac_addr)) { memset(hw->address[i], 0, ETH_ALEN); writel(0, hw->io + ADD_ADDR_INCR * i + KS_ADD_ADDR_0_HI); @@ -4480,14 +4480,12 @@ static void ksz_init_rx_buffers(struct dev_info *adapter) dma_buf->len = adapter->mtu; if (!dma_buf->skb) dma_buf->skb = alloc_skb(dma_buf->len, GFP_ATOMIC); - if (dma_buf->skb && !dma_buf->dma) { - dma_buf->skb->dev = adapter->dev; + if (dma_buf->skb && !dma_buf->dma) dma_buf->dma = pci_map_single( adapter->pdev, skb_tail_pointer(dma_buf->skb), dma_buf->len, PCI_DMA_FROMDEVICE); - } /* Set descriptor. */ set_rx_buf(desc, dma_buf->dma); @@ -4763,7 +4761,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal) struct ksz_dma_buf *dma_buf; struct net_device *dev = NULL; - spin_lock(&hw_priv->hwlock); + spin_lock_irq(&hw_priv->hwlock); last = info->last; while (info->avail < info->alloc) { @@ -4797,7 +4795,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal) info->avail++; } info->last = last; - spin_unlock(&hw_priv->hwlock); + spin_unlock_irq(&hw_priv->hwlock); /* Notify the network subsystem that the packet has been sent. */ if (dev) @@ -4834,7 +4832,7 @@ static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb) skb->csum = old->csum; skb_set_network_header(skb, ETH_HLEN); - dev_kfree_skb(old); + dev_consume_skb_any(old); } /** @@ -4863,7 +4861,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) memset(&skb->data[skb->len], 0, 50 - skb->len); skb->len = 50; } else { - skb = dev_alloc_skb(50); + skb = netdev_alloc_skb(dev, 50); if (!skb) return NETDEV_TX_BUSY; memcpy(skb->data, org_skb->data, org_skb->len); @@ -4881,11 +4879,11 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) left = hw_alloc_pkt(hw, skb->len, num); if (left) { if (left < num || - ((CHECKSUM_PARTIAL == skb->ip_summed) && - (ETH_P_IPV6 == htons(skb->protocol)))) { + (CHECKSUM_PARTIAL == skb->ip_summed && + skb->protocol == htons(ETH_P_IPV6))) { struct sk_buff *org_skb = skb; - skb = dev_alloc_skb(org_skb->len); + skb = netdev_alloc_skb(dev, org_skb->len); if (!skb) { rc = NETDEV_TX_BUSY; goto unlock; @@ -4932,7 +4930,7 @@ static void netdev_tx_timeout(struct net_device *dev) * Only reset the hardware if time between calls is long * enough. */ - if (jiffies - last_reset <= dev->watchdog_timeo) + if (time_before_eq(jiffies, last_reset + dev->watchdog_timeo)) hw_priv = NULL; } @@ -5019,7 +5017,7 @@ static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw, do { /* skb->data != skb->head */ - skb = dev_alloc_skb(packet_len + 2); + skb = netdev_alloc_skb(dev, packet_len + 2); if (!skb) { dev->stats.rx_dropped++; return -ENOMEM; @@ -5261,11 +5259,15 @@ static irqreturn_t netdev_intr(int irq, void *dev_id) struct dev_info *hw_priv = priv->adapter; struct ksz_hw *hw = &hw_priv->hw; + spin_lock(&hw_priv->hwlock); + hw_read_intr(hw, &int_enable); /* Not our interrupt! */ - if (!int_enable) + if (!int_enable) { + spin_unlock(&hw_priv->hwlock); return IRQ_NONE; + } do { hw_ack_intr(hw, int_enable); @@ -5312,6 +5314,8 @@ static irqreturn_t netdev_intr(int irq, void *dev_id) hw_ena_intr(hw); + spin_unlock(&hw_priv->hwlock); + return IRQ_HANDLED; } @@ -5409,8 +5413,8 @@ static int netdev_close(struct net_device *dev) /* Delay for receive task to stop scheduling itself. */ msleep(2000 / HZ); - tasklet_disable(&hw_priv->rx_tasklet); - tasklet_disable(&hw_priv->tx_tasklet); + tasklet_kill(&hw_priv->rx_tasklet); + tasklet_kill(&hw_priv->tx_tasklet); free_irq(dev->irq, hw_priv->dev); transmit_cleanup(hw_priv, 0); @@ -5461,8 +5465,10 @@ static int prepare_hardware(struct net_device *dev) rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); if (rc) return rc; - tasklet_enable(&hw_priv->rx_tasklet); - tasklet_enable(&hw_priv->tx_tasklet); + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, + (unsigned long) hw_priv); + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, + (unsigned long) hw_priv); hw->promiscuous = 0; hw->all_multi = 0; @@ -5675,7 +5681,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr) memcpy(hw->override_addr, mac->sa_data, ETH_ALEN); } - memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); + memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN); interrupt = hw_block_intr(hw); @@ -5847,15 +5853,12 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct dev_info *hw_priv = priv->adapter; struct ksz_hw *hw = &hw_priv->hw; struct ksz_port *port = &priv->port; - int rc; int result = 0; struct mii_ioctl_data *data = if_mii(ifr); if (down_interruptible(&priv->proc_sem)) return -ERESTARTSYS; - /* assume success */ - rc = 0; switch (cmd) { /* Get address of MII PHY in use. */ case SIOCGMIIPHY: @@ -6769,7 +6772,7 @@ static int stp; /* * This enables fast aging in the KSZ8842 switch. Not sure what situation * needs that. However, fast aging is used to flush the dynamic MAC table when - * STP suport is enabled. + * STP support is enabled. */ static int fast_aging; @@ -6919,8 +6922,7 @@ static void read_other_addr(struct ksz_hw *hw) #define PCI_VENDOR_ID_MICREL_KS 0x16c6 #endif -static int __devinit pcidev_init(struct pci_dev *pdev, - const struct pci_device_id *id) +static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *dev; struct dev_priv *priv; @@ -7035,16 +7037,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev, spin_lock_init(&hw_priv->hwlock); mutex_init(&hw_priv->lock); - /* tasklet is enabled. */ - tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, - (unsigned long) hw_priv); - tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, - (unsigned long) hw_priv); - - /* tasklet_enable will decrement the atomic counter. */ - tasklet_disable(&hw_priv->rx_tasklet); - tasklet_disable(&hw_priv->tx_tasklet); - for (i = 0; i < TOTAL_PORT_NUM; i++) init_waitqueue_head(&hw_priv->counter[i].counter); @@ -7080,6 +7072,7 @@ static int __devinit pcidev_init(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct dev_priv)); if (!dev) goto pcidev_init_reg_err; + SET_NETDEV_DEV(dev, &pdev->dev); info->netdev[i] = dev; priv = netdev_priv(dev); @@ -7109,13 +7102,12 @@ static int __devinit pcidev_init(struct pci_dev *pdev, ETH_ALEN); else { memcpy(dev->dev_addr, sw->other_addr, ETH_ALEN); - if (!memcmp(sw->other_addr, hw->override_addr, - ETH_ALEN)) + if (ether_addr_equal(sw->other_addr, hw->override_addr)) dev->dev_addr[5] += port->first_port; } dev->netdev_ops = &netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); + dev->ethtool_ops = &netdev_ethtool_ops; if (register_netdev(dev)) goto pcidev_init_reg_err; port_set_power_saving(port, true); @@ -7155,8 +7147,6 @@ static void pcidev_exit(struct pci_dev *pdev) struct platform_info *info = pci_get_drvdata(pdev); struct dev_info *hw_priv = &info->dev_info; - pci_set_drvdata(pdev, NULL); - release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); for (i = 0; i < hw_priv->hw.dev_count; i++) { @@ -7232,7 +7222,7 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state) static char pcidev_name[] = "ksz884xp"; -static struct pci_device_id pcidev_table[] = { +static DEFINE_PCI_DEVICE_TABLE(pcidev_table) = { { PCI_VENDOR_ID_MICREL_KS, 0x8841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_MICREL_KS, 0x8842, @@ -7253,18 +7243,7 @@ static struct pci_driver pci_device_driver = { .remove = pcidev_exit }; -static int __init ksz884x_init_module(void) -{ - return pci_register_driver(&pci_device_driver); -} - -static void __exit ksz884x_cleanup_module(void) -{ - pci_unregister_driver(&pci_device_driver); -} - -module_init(ksz884x_init_module); -module_exit(ksz884x_cleanup_module); +module_pci_driver(pci_device_driver); MODULE_DESCRIPTION("KSZ8841/2 PCI network driver"); MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>"); |
