Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc
[pandora-kernel.git] / drivers / net / sungem.c
index 55f3b85..b70bbd7 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/workqueue.h>
 #include <linux/if_vlan.h>
 #include <linux/bitops.h>
+#include <linux/mutex.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1653,40 +1654,36 @@ static void gem_init_rings(struct gem *gp)
 /* Init PHY interface and start link poll state machine */
 static void gem_init_phy(struct gem *gp)
 {
-       u32 mif_cfg;
+       u32 mifcfg;
 
        /* Revert MIF CFG setting done on stop_phy */
-       mif_cfg = readl(gp->regs + MIF_CFG);
-       mif_cfg &= ~(MIF_CFG_PSELECT|MIF_CFG_POLL|MIF_CFG_BBMODE|MIF_CFG_MDI1);
-       mif_cfg |= MIF_CFG_MDI0;
-       writel(mif_cfg, gp->regs + MIF_CFG);
-       writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE);
-       writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG);
+       mifcfg = readl(gp->regs + MIF_CFG);
+       mifcfg &= ~MIF_CFG_BBMODE;
+       writel(mifcfg, gp->regs + MIF_CFG);
        
        if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
                int i;
-               u16 ctrl;
 
+               /* Those delay sucks, the HW seem to love them though, I'll
+                * serisouly consider breaking some locks here to be able
+                * to schedule instead
+                */
+               for (i = 0; i < 3; i++) {
 #ifdef CONFIG_PPC_PMAC
-               pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0);
+                       pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0);
+                       msleep(20);
 #endif
-
-               /* Some PHYs used by apple have problem getting back
-                * to us, we do an additional reset here
-                */
-               phy_write(gp, MII_BMCR, BMCR_RESET);
-               for (i = 0; i < 50; i++) {
-                       if ((phy_read(gp, MII_BMCR) & BMCR_RESET) == 0)
+                       /* Some PHYs used by apple have problem getting back to us,
+                        * we do an additional reset here
+                        */
+                       phy_write(gp, MII_BMCR, BMCR_RESET);
+                       msleep(20);
+                       if (phy_read(gp, MII_BMCR) != 0xffff)
                                break;
-                       msleep(10);
+                       if (i == 2)
+                               printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
+                                      gp->dev->name);
                }
-               if (i == 50)
-                       printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
-                              gp->dev->name);
-               /* Make sure isolate is off */
-               ctrl = phy_read(gp, MII_BMCR);
-               if (ctrl & BMCR_ISOLATE)
-                       phy_write(gp, MII_BMCR, ctrl & ~BMCR_ISOLATE);
        }
 
        if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
@@ -2123,7 +2120,7 @@ static void gem_reinit_chip(struct gem *gp)
 /* Must be invoked with no lock held. */
 static void gem_stop_phy(struct gem *gp, int wol)
 {
-       u32 mif_cfg;
+       u32 mifcfg;
        unsigned long flags;
 
        /* Let the chip settle down a bit, it seems that helps
@@ -2134,9 +2131,9 @@ static void gem_stop_phy(struct gem *gp, int wol)
        /* Make sure we aren't polling PHY status change. We
         * don't currently use that feature though
         */
-       mif_cfg = readl(gp->regs + MIF_CFG);
-       mif_cfg &= ~MIF_CFG_POLL;
-       writel(mif_cfg, gp->regs + MIF_CFG);
+       mifcfg = readl(gp->regs + MIF_CFG);
+       mifcfg &= ~MIF_CFG_POLL;
+       writel(mifcfg, gp->regs + MIF_CFG);
 
        if (wol && gp->has_wol) {
                unsigned char *e = &gp->dev->dev_addr[0];
@@ -2186,8 +2183,7 @@ static void gem_stop_phy(struct gem *gp, int wol)
                /* According to Apple, we must set the MDIO pins to this begnign
                 * state or we may 1) eat more current, 2) damage some PHYs
                 */
-               mif_cfg = 0;
-               writel(mif_cfg | MIF_CFG_BBMODE, gp->regs + MIF_CFG);
+               writel(mifcfg | MIF_CFG_BBMODE, gp->regs + MIF_CFG);
                writel(0, gp->regs + MIF_BBCLK);
                writel(0, gp->regs + MIF_BBDATA);
                writel(0, gp->regs + MIF_BBOENAB);
@@ -2224,7 +2220,7 @@ static int gem_do_start(struct net_device *dev)
        spin_unlock_irqrestore(&gp->lock, flags);
 
        if (request_irq(gp->pdev->irq, gem_interrupt,
-                                  SA_SHIRQ, dev->name, (void *)dev)) {
+                                  IRQF_SHARED, dev->name, (void *)dev)) {
                printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
 
                spin_lock_irqsave(&gp->lock, flags);
@@ -2289,7 +2285,7 @@ static void gem_reset_task(void *data)
 {
        struct gem *gp = (struct gem *) data;
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
        netif_poll_disable(gp->dev);
 
@@ -2316,7 +2312,7 @@ static void gem_reset_task(void *data)
 
        netif_poll_enable(gp->dev);
 
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 }
 
 
@@ -2325,14 +2321,14 @@ static int gem_open(struct net_device *dev)
        struct gem *gp = dev->priv;
        int rc = 0;
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
        /* We need the cell enabled */
        if (!gp->asleep)
                rc = gem_do_start(dev);
        gp->opened = (rc == 0);
 
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        return rc;
 }
@@ -2345,13 +2341,13 @@ static int gem_close(struct net_device *dev)
         * our caller (dev_close) already did it for us
         */
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
        gp->opened = 0; 
        if (!gp->asleep)
                gem_do_stop(dev, 0);
 
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
        
        return 0;
 }
@@ -2363,7 +2359,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
        struct gem *gp = dev->priv;
        unsigned long flags;
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
        netif_poll_disable(dev);
 
@@ -2396,11 +2392,11 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
        /* Stop the link timer */
        del_timer_sync(&gp->link_timer);
 
-       /* Now we release the semaphore to not block the reset task who
+       /* Now we release the mutex to not block the reset task who
         * can take it too. We are marked asleep, so there will be no
         * conflict here
         */
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        /* Wait for a pending reset task to complete */
        while (gp->reset_task_pending)
@@ -2429,7 +2425,7 @@ static int gem_resume(struct pci_dev *pdev)
 
        printk(KERN_INFO "%s: resuming\n", dev->name);
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
        /* Keep the cell enabled during the entire operation, no need to
         * take a lock here tho since nothing else can happen while we are
@@ -2445,7 +2441,7 @@ static int gem_resume(struct pci_dev *pdev)
                 * still asleep, a new sleep cycle may bring it back
                 */
                gem_put_cell(gp);
-               up(&gp->pm_sem);
+               mutex_unlock(&gp->pm_mutex);
                return 0;
        }
        pci_set_master(gp->pdev);
@@ -2491,7 +2487,7 @@ static int gem_resume(struct pci_dev *pdev)
 
        netif_poll_enable(dev);
        
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        return 0;
 }
@@ -2596,7 +2592,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
                return 0;
        }
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
        spin_lock_irq(&gp->lock);
        spin_lock(&gp->tx_lock);
        dev->mtu = new_mtu;
@@ -2607,7 +2603,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
        }
        spin_unlock(&gp->tx_lock);
        spin_unlock_irq(&gp->lock);
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        return 0;
 }
@@ -2776,10 +2772,10 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        int rc = -EOPNOTSUPP;
        unsigned long flags;
 
-       /* Hold the PM semaphore while doing ioctl's or we may collide
+       /* Hold the PM mutex while doing ioctl's or we may collide
         * with power management.
         */
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
                
        spin_lock_irqsave(&gp->lock, flags);
        gem_get_cell(gp);
@@ -2817,7 +2813,7 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        gem_put_cell(gp);
        spin_unlock_irqrestore(&gp->lock, flags);
 
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
        
        return rc;
 }
@@ -2884,17 +2880,20 @@ static int __devinit gem_get_device_address(struct gem *gp)
 #if defined(__sparc__)
        struct pci_dev *pdev = gp->pdev;
        struct pcidev_cookie *pcp = pdev->sysdata;
-       int node = -1;
+       int use_idprom = 1;
 
        if (pcp != NULL) {
-               node = pcp->prom_node;
-               if (prom_getproplen(node, "local-mac-address") == 6)
-                       prom_getproperty(node, "local-mac-address",
-                                        dev->dev_addr, 6);
-               else
-                       node = -1;
+               unsigned char *addr;
+               int len;
+
+               addr = of_get_property(pcp->prom_node, "local-mac-address",
+                                      &len);
+               if (addr && len == 6) {
+                       use_idprom = 0;
+                       memcpy(dev->dev_addr, addr, 6);
+               }
        }
-       if (node == -1)
+       if (use_idprom)
                memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
 #elif defined(CONFIG_PPC_PMAC)
        unsigned char *addr;
@@ -3038,7 +3037,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
        spin_lock_init(&gp->lock);
        spin_lock_init(&gp->tx_lock);
-       init_MUTEX(&gp->pm_sem);
+       mutex_init(&gp->pm_mutex);
 
        init_timer(&gp->link_timer);
        gp->link_timer.function = gem_link_timer;