Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
[sfrench/cifs-2.6.git] / drivers / net / fs_enet / mac-scc.c
index 7540966687ec24a84cc2064b9cb8b752e7c37947..48f2f30059359f4a6a45e5d7b697fb33874c70d4 100644 (file)
@@ -1,14 +1,14 @@
 /*
  * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx.
  *
- * Copyright (c) 2003 Intracom S.A. 
+ * Copyright (c) 2003 Intracom S.A.
  *  by Pantelis Antoniou <panto@intracom.gr>
- * 
- * 2005 (c) MontaVista Software, Inc. 
+ *
+ * 2005 (c) MontaVista Software, Inc.
  * Vitaly Bordug <vbordug@ru.mvista.com>
  *
- * This file is licensed under the terms of the GNU General Public License 
- * version 2. This program is licensed "as is" without any warranty of any 
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
  * kind, whether express or implied.
  */
 
 #include <asm/commproc.h>
 #endif
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
+
 #include "fs_enet.h"
 
 /*************************************************/
 #define SCC_MAX_MULTICAST_ADDRS        64
 
 /*
- * Delay to wait for SCC reset command to complete (in us) 
+ * Delay to wait for SCC reset command to complete (in us)
  */
 #define SCC_RESET_DELAY                50
 #define MAX_CR_CMD_LOOPS       10000
 
 static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
 {
-       cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm;
-       u32 v, ch;
-       int i = 0;
+       const struct fs_platform_info *fpi = fep->fpi;
+       int i;
 
-       ch = fep->scc.idx << 2;
-       v = mk_cr_cmd(ch, op);
-       W16(cpmp, cp_cpcr, v | CPM_CR_FLG);
+       W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8));
        for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
                if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
-                       break;
+                       return 0;
 
-       if (i >= MAX_CR_CMD_LOOPS) {
-               printk(KERN_ERR "%s(): Not able to issue CPM command\n",
-                       __FUNCTION__);
-               return 1;
-       }
-       return 0;
+       printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+               __FUNCTION__);
+       return 1;
 }
 
 static int do_pd_setup(struct fs_enet_private *fep)
 {
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+       struct of_device *ofdev = to_of_device(fep->dev);
+
+       fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
+       if (fep->interrupt == NO_IRQ)
+               return -EINVAL;
+
+       fep->scc.sccp = of_iomap(ofdev->node, 0);
+       if (!fep->scc.sccp)
+               return -EINVAL;
+
+       fep->scc.ep = of_iomap(ofdev->node, 1);
+       if (!fep->scc.ep) {
+               iounmap(fep->scc.sccp);
+               return -EINVAL;
+       }
+#else
        struct platform_device *pdev = to_platform_device(fep->dev);
        struct resource *r;
 
@@ -129,6 +144,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
 
        if (fep->scc.ep == NULL)
                return -EINVAL;
+#endif
 
        return 0;
 }
@@ -141,12 +157,17 @@ static int do_pd_setup(struct fs_enet_private *fep)
 static int setup_data(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       const struct fs_platform_info *fpi = fep->fpi;
+
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
+       struct fs_platform_info *fpi = fep->fpi;
 
        fep->scc.idx = fs_get_scc_index(fpi->fs_no);
-       if ((unsigned int)fep->fcc.idx > 4)     /* max 4 SCCs */
+       if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */
                return -EINVAL;
 
+       fpi->cp_command = fep->fcc.idx << 6;
+#endif
+
        do_pd_setup(fep);
 
        fep->scc.hthi = 0;
@@ -154,7 +175,7 @@ static int setup_data(struct net_device *dev)
 
        fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
        fep->ev_rx = SCC_RX_EVENT;
-       fep->ev_tx = SCC_TX_EVENT;
+       fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE;
        fep->ev_err = SCC_ERR_EVENT_MSK;
 
        return 0;
@@ -170,7 +191,8 @@ static int allocate_bd(struct net_device *dev)
        if (IS_ERR_VALUE(fep->ring_mem_addr))
                return -ENOMEM;
 
-       fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr);
+       fep->ring_base = (void __iomem __force*)
+               cpm_dpram_addr(fep->ring_mem_addr);
 
        return 0;
 }
@@ -189,9 +211,9 @@ static void cleanup_data(struct net_device *dev)
 }
 
 static void set_promiscuous_mode(struct net_device *dev)
-{                              
+{
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
+       scc_t __iomem *sccp = fep->scc.sccp;
 
        S16(sccp, scc_psmr, SCC_PSMR_PRO);
 }
@@ -199,7 +221,7 @@ static void set_promiscuous_mode(struct net_device *dev)
 static void set_multicast_start(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_enet_t *ep = fep->scc.ep;
+       scc_enet_t __iomem *ep = fep->scc.ep;
 
        W16(ep, sen_gaddr1, 0);
        W16(ep, sen_gaddr2, 0);
@@ -210,7 +232,7 @@ static void set_multicast_start(struct net_device *dev)
 static void set_multicast_one(struct net_device *dev, const u8 * mac)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_enet_t *ep = fep->scc.ep;
+       scc_enet_t __iomem *ep = fep->scc.ep;
        u16 taddrh, taddrm, taddrl;
 
        taddrh = ((u16) mac[5] << 8) | mac[4];
@@ -226,8 +248,8 @@ static void set_multicast_one(struct net_device *dev, const u8 * mac)
 static void set_multicast_finish(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
-       scc_enet_t *ep = fep->scc.ep;
+       scc_t __iomem *sccp = fep->scc.sccp;
+       scc_enet_t __iomem *ep = fep->scc.ep;
 
        /* clear promiscuous always */
        C16(sccp, scc_psmr, SCC_PSMR_PRO);
@@ -264,8 +286,8 @@ static void set_multicast_list(struct net_device *dev)
 static void restart(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
-       scc_enet_t *ep = fep->scc.ep;
+       scc_t __iomem *sccp = fep->scc.sccp;
+       scc_enet_t __iomem *ep = fep->scc.ep;
        const struct fs_platform_info *fpi = fep->fpi;
        u16 paddrh, paddrm, paddrl;
        const unsigned char *mac;
@@ -275,7 +297,7 @@ static void restart(struct net_device *dev)
 
        /* clear everything (slow & steady does it) */
        for (i = 0; i < sizeof(*ep); i++)
-               __fs_out8((char *)ep + i, 0);
+               __fs_out8((u8 __iomem *)ep + i, 0);
 
        /* point to bds */
        W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr);
@@ -323,7 +345,7 @@ static void restart(struct net_device *dev)
        W16(ep, sen_iaddr3, 0);
        W16(ep, sen_iaddr4, 0);
 
-       /* set address 
+       /* set address
         */
        mac = dev->dev_addr;
        paddrh = ((u16) mac[5] << 8) | mac[4];
@@ -345,7 +367,7 @@ static void restart(struct net_device *dev)
 
        W16(sccp, scc_scce, 0xffff);
 
-       /* Enable interrupts we wish to service. 
+       /* Enable interrupts we wish to service.
         */
        W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
 
@@ -373,10 +395,10 @@ static void restart(struct net_device *dev)
        S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
 }
 
-static void stop(struct net_device *dev)       
+static void stop(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
+       scc_t __iomem *sccp = fep->scc.sccp;
        int i;
 
        for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++)
@@ -420,7 +442,7 @@ static void post_free_irq(struct net_device *dev, int irq)
 static void napi_clear_rx_event(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
+       scc_t __iomem *sccp = fep->scc.sccp;
 
        W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
 }
@@ -428,7 +450,7 @@ static void napi_clear_rx_event(struct net_device *dev)
 static void napi_enable_rx(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
+       scc_t __iomem *sccp = fep->scc.sccp;
 
        S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
 }
@@ -436,7 +458,7 @@ static void napi_enable_rx(struct net_device *dev)
 static void napi_disable_rx(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
+       scc_t __iomem *sccp = fep->scc.sccp;
 
        C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
 }
@@ -454,7 +476,7 @@ static void tx_kickstart(struct net_device *dev)
 static u32 get_int_events(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
+       scc_t __iomem *sccp = fep->scc.sccp;
 
        return (u32) R16(sccp, scc_scce);
 }
@@ -462,7 +484,7 @@ static u32 get_int_events(struct net_device *dev)
 static void clear_int_events(struct net_device *dev, u32 int_events)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-       scc_t *sccp = fep->scc.sccp;
+       scc_t __iomem *sccp = fep->scc.sccp;
 
        W16(sccp, scc_scce, int_events & 0xffff);
 }
@@ -477,20 +499,20 @@ static int get_regs(struct net_device *dev, void *p, int *sizep)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
 
-       if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t))
+       if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t __iomem *))
                return -EINVAL;
 
        memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t));
        p = (char *)p + sizeof(scc_t);
 
-       memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t));
+       memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t __iomem *));
 
        return 0;
 }
 
 static int get_regs_len(struct net_device *dev)
 {
-       return sizeof(scc_t) + sizeof(scc_enet_t);
+       return sizeof(scc_t) + sizeof(scc_enet_t __iomem *);
 }
 
 static void tx_restart(struct net_device *dev)