X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2F8xx_io%2Ffec.c;h=e6c28fb423b234ba5c8f8892499923e36c1cd92e;hb=refs%2Fheads%2Fvserver;hp=5c7c914f84ea5736704ca457eeb9d8f7a6ed3d57;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 5c7c914f8..e6c28fb42 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -28,7 +28,6 @@ * Thomas Lange, thomas@corelatus.com */ -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #ifdef CONFIG_FEC_PACKETHOOK #include #endif @@ -52,7 +52,6 @@ #include #include #include -#include #include #include @@ -173,7 +172,8 @@ struct fec_enet_private { uint phy_status; uint phy_speed; phy_info_t *phy; - struct tq_struct phy_task; + struct work_struct phy_task; + struct net_device *dev; uint sequence_done; @@ -199,7 +199,7 @@ static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); #ifdef CONFIG_USE_MDIO static void fec_enet_mii(struct net_device *dev); #endif /* CONFIG_USE_MDIO */ -static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); +static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); #ifdef CONFIG_FEC_PACKETHOOK static void fec_enet_tx(struct net_device *dev, __u32 regval); static void fec_enet_rx(struct net_device *dev, __u32 regval); @@ -389,6 +389,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) flush_dcache_range((unsigned long)skb->data, (unsigned long)skb->data + skb->len); + /* disable interrupts while triggering transmit */ spin_lock_irq(&fep->lock); /* Send it on its way. Tell FEC its ready, interrupt when done, @@ -470,8 +471,8 @@ fec_timeout(struct net_device *dev) /* The interrupt handler. * This is called from the MPC core interrupt. */ -static void -fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) +static irqreturn_t +fec_enet_interrupt(int irq, void * dev_id) { struct net_device *dev = dev_id; volatile fec_t *fecp; @@ -524,6 +525,7 @@ printk("%s[%d] %s: unexpected FEC_ENET_MII event\n", __FILE__,__LINE__,__FUNCTIO } } + return IRQ_RETVAL(IRQ_HANDLED); } @@ -539,6 +541,7 @@ fec_enet_tx(struct net_device *dev) struct sk_buff *skb; fep = dev->priv; + /* lock while transmitting */ spin_lock(&fep->lock); bdp = fep->dirty_tx; @@ -799,6 +802,7 @@ fec_enet_mii(struct net_device *dev) if ((mip = mii_head) != NULL) { ep->fec_mii_data = mip->mii_regval; + } } @@ -817,8 +821,8 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 0; - save_flags(flags); - cli(); + /* lock while modifying mii_list */ + spin_lock_irqsave(&fep->lock, flags); if ((mip = mii_free) != NULL) { mii_free = mip->mii_next; @@ -836,7 +840,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 1; } - restore_flags(flags); + spin_unlock_irqrestore(&fep->lock, flags); return(retval); } @@ -1260,9 +1264,11 @@ static void mii_display_status(struct net_device *dev) printk(".\n"); } -static void mii_display_config(struct net_device *dev) +static void mii_display_config(struct work_struct *work) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; volatile uint *s = &(fep->phy_status); printk("%s: config: auto-negotiation ", dev->name); @@ -1291,9 +1297,11 @@ static void mii_display_config(struct net_device *dev) fep->sequence_done = 1; } -static void mii_relink(struct net_device *dev) +static void mii_relink(struct work_struct *work) { - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; int duplex; fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; @@ -1320,18 +1328,18 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - fep->phy_task.routine = (void *)mii_relink; - fep->phy_task.data = dev; - schedule_task(&fep->phy_task); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_relink); + schedule_work(&fep->phy_task); } static void mii_queue_config(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - fep->phy_task.routine = (void *)mii_display_config; - fep->phy_task.data = dev; - schedule_task(&fep->phy_task); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_display_config); + schedule_work(&fep->phy_task); } @@ -1400,11 +1408,11 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) /* This interrupt occurs when the PHY detects a link change. */ -static void +static #ifdef CONFIG_RPXCLASSIC -mii_link_interrupt(void *dev_id) +void mii_link_interrupt(void *dev_id) #else -mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) +irqreturn_t mii_link_interrupt(int irq, void * dev_id) #endif { #ifdef CONFIG_USE_MDIO @@ -1437,6 +1445,9 @@ mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) printk("%s[%d] %s: unexpected Link interrupt\n", __FILE__,__LINE__,__FUNCTION__); #endif /* CONFIG_USE_MDIO */ +#ifndef CONFIG_RPXCLASSIC + return IRQ_RETVAL(IRQ_HANDLED); +#endif /* CONFIG_RPXCLASSIC */ } static int @@ -1572,7 +1583,7 @@ static int __init fec_enet_init(void) struct fec_enet_private *fep; int i, j, k, err; unsigned char *eap, *iap, *ba; - unsigned long mem_addr; + dma_addr_t mem_addr; volatile cbd_t *bdp; cbd_t *cbd_base; volatile immap_t *immap; @@ -1637,7 +1648,8 @@ static int __init fec_enet_init(void) printk("FEC initialization failed.\n"); return 1; } - cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); + cbd_base = (cbd_t *)dma_alloc_coherent(dev->class_dev.dev, PAGE_SIZE, + &mem_addr, GFP_KERNEL); /* Set receive and transmit descriptor base. */ @@ -1654,7 +1666,10 @@ static int __init fec_enet_init(void) /* Allocate a page. */ - ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); + ba = (unsigned char *)dma_alloc_coherent(dev->class_dev.dev, + PAGE_SIZE, + &mem_addr, + GFP_KERNEL); /* BUG: no check for failure */ /* Initialize the BD for every fragment in the page. @@ -1684,7 +1699,7 @@ static int __init fec_enet_init(void) /* Install our interrupt handler. */ - if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0) + if (request_irq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0) panic("Could not allocate FEC IRQ!"); #ifdef CONFIG_RPXCLASSIC @@ -1705,7 +1720,7 @@ static int __init fec_enet_init(void) ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |= (0x80000000 >> PHY_INTERRUPT); - if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0) + if (request_irq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0) panic("Could not allocate MII IRQ!"); #endif @@ -1732,7 +1747,7 @@ static int __init fec_enet_init(void) /* Bits moved from Rev. D onward. */ - if ((mfspr(IMMR) & 0xffff) < 0x0501) + if ((mfspr(SPRN_IMMR) & 0xffff) < 0x0501) immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */ else immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */