bnx2x: WoL capability
[safe/jmp/linux-2.6] / drivers / spi / mpc52xx_psc_spi.c
index d398c93..25eda71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * MPC52xx SPC in SPI mode driver.
+ * MPC52xx PSC in SPI mode driver.
  *
  * Maintainer: Dragos Carp
  *
@@ -17,7 +17,7 @@
 #include <linux/interrupt.h>
 
 #if defined(CONFIG_PPC_MERGE)
-#include <asm/of_platform.h>
+#include <linux/of_platform.h>
 #else
 #include <linux/platform_device.h>
 #endif
@@ -42,6 +42,7 @@ struct mpc52xx_psc_spi {
 
        /* driver internal data */
        struct mpc52xx_psc __iomem *psc;
+       struct mpc52xx_psc_fifo __iomem *fifo;
        unsigned int irq;
        u8 bits_per_word;
        u8 busy;
@@ -139,6 +140,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
 {
        struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
        struct mpc52xx_psc __iomem *psc = mps->psc;
+       struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
        unsigned rb = 0;        /* number of bytes receieved */
        unsigned sb = 0;        /* number of bytes sent */
        unsigned char *rx_buf = (unsigned char *)t->rx_buf;
@@ -146,7 +148,6 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
        unsigned rfalarm;
        unsigned send_at_once = MPC52xx_PSC_BUFSIZE;
        unsigned recv_at_once;
-       unsigned bpw = mps->bits_per_word / 8;
 
        if (!t->tx_buf && !t->rx_buf && t->len)
                return -EINVAL;
@@ -162,22 +163,15 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
                }
 
                dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once);
-               if (tx_buf) {
-                       for (; send_at_once; sb++, send_at_once--) {
-                               /* set EOF flag */
-                               if (mps->bits_per_word
-                                               && (sb + 1) % bpw == 0)
-                                       out_8(&psc->ircr2, 0x01);
+               for (; send_at_once; sb++, send_at_once--) {
+                       /* set EOF flag before the last word is sent */
+                       if (send_at_once == 1)
+                               out_8(&psc->ircr2, 0x01);
+
+                       if (tx_buf)
                                out_8(&psc->mpc52xx_psc_buffer_8, tx_buf[sb]);
-                       }
-               } else {
-                       for (; send_at_once; sb++, send_at_once--) {
-                               /* set EOF flag */
-                               if (mps->bits_per_word
-                                               && ((sb + 1) % bpw) == 0)
-                                       out_8(&psc->ircr2, 0x01);
+                       else
                                out_8(&psc->mpc52xx_psc_buffer_8, 0);
-                       }
                }
 
 
@@ -190,11 +184,11 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
                        out_8(&psc->mode, 0);
                } else {
                        out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
-                       out_be16(&psc->rfalarm, rfalarm);
+                       out_be16(&fifo->rfalarm, rfalarm);
                }
                out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY);
                wait_for_completion(&mps->done);
-               recv_at_once = in_be16(&psc->rfnum);
+               recv_at_once = in_be16(&fifo->rfnum);
                dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once);
 
                send_at_once = recv_at_once;
@@ -330,80 +324,14 @@ static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)
 
 static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
 {
-       struct device_node *np;
-       struct mpc52xx_cdm __iomem *cdm;
-       struct mpc52xx_gpio __iomem *gpio;
        struct mpc52xx_psc __iomem *psc = mps->psc;
-       u32 ul;
+       struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
        u32 mclken_div;
        int ret = 0;
 
-#if defined(CONFIG_PPC_MERGE)
-       np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm");
-       cdm = of_iomap(np, 0);
-       of_node_put(np);
-       np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio");
-       gpio = of_iomap(np, 0);
-       of_node_put(np);
-#else
-       cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
-       gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
-#endif
-       if (!cdm || !gpio) {
-               printk(KERN_ERR "Error mapping CDM/GPIO\n");
-               ret = -EFAULT;
-               goto unmap_regs;
-       }
-
        /* default sysclk is 512MHz */
-       mclken_div = 0x8000 |
-               (((mps->sysclk ? mps->sysclk : 512000000) / MCLK) & 0x1FF);
-
-       switch (psc_id) {
-       case 1:
-               ul = in_be32(&gpio->port_config);
-               ul &= 0xFFFFFFF8;
-               ul |= 0x00000006;
-               out_be32(&gpio->port_config, ul);
-               out_be16(&cdm->mclken_div_psc1, mclken_div);
-               ul = in_be32(&cdm->clk_enables);
-               ul |= 0x00000020;
-               out_be32(&cdm->clk_enables, ul);
-               break;
-       case 2:
-               ul = in_be32(&gpio->port_config);
-               ul &= 0xFFFFFF8F;
-               ul |= 0x00000060;
-               out_be32(&gpio->port_config, ul);
-               out_be16(&cdm->mclken_div_psc2, mclken_div);
-               ul = in_be32(&cdm->clk_enables);
-               ul |= 0x00000040;
-               out_be32(&cdm->clk_enables, ul);
-               break;
-       case 3:
-               ul = in_be32(&gpio->port_config);
-               ul &= 0xFFFFF0FF;
-               ul |= 0x00000600;
-               out_be32(&gpio->port_config, ul);
-               out_be16(&cdm->mclken_div_psc3, mclken_div);
-               ul = in_be32(&cdm->clk_enables);
-               ul |= 0x00000080;
-               out_be32(&cdm->clk_enables, ul);
-               break;
-       case 6:
-               ul = in_be32(&gpio->port_config);
-               ul &= 0xFF8FFFFF;
-               ul |= 0x00700000;
-               out_be32(&gpio->port_config, ul);
-               out_be16(&cdm->mclken_div_psc6, mclken_div);
-               ul = in_be32(&cdm->clk_enables);
-               ul |= 0x00000010;
-               out_be32(&cdm->clk_enables, ul);
-               break;
-       default:
-               ret = -EINVAL;
-               goto unmap_regs;
-       }
+       mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
+       mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
 
        /* Reset the PSC into a known state */
        out_8(&psc->command, MPC52xx_PSC_RST_RX);
@@ -413,7 +341,7 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
        /* Disable interrupts, interrupts are based on alarm level */
        out_be16(&psc->mpc52xx_psc_imr, 0);
        out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
-       out_8(&psc->rfcntl, 0);
+       out_8(&fifo->rfcntl, 0);
        out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
 
        /* Configure 8bit codec mode as a SPI master and use EOF flags */
@@ -427,12 +355,6 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
 
        mps->bits_per_word = 8;
 
-unmap_regs:
-       if (cdm)
-               iounmap(cdm);
-       if (gpio)
-               iounmap(gpio);
-
        return ret;
 }
 
@@ -492,6 +414,8 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
                ret = -EFAULT;
                goto free_master;
        }
+       /* On the 5200, fifo regs are immediately ajacent to the psc regs */
+       mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc);
 
        ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi",
                                mps);
@@ -568,6 +492,9 @@ static int __exit mpc52xx_psc_spi_remove(struct platform_device *dev)
        return mpc52xx_psc_spi_do_remove(&dev->dev);
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:mpc52xx-psc-spi");
+
 static struct platform_driver mpc52xx_psc_spi_platform_driver = {
        .remove = __exit_p(mpc52xx_psc_spi_remove),
        .driver = {
@@ -628,8 +555,9 @@ static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op)
 }
 
 static struct of_device_id mpc52xx_psc_spi_of_match[] = {
-       { .type = "spi", .compatible = "mpc5200-psc-spi", },
-       {},
+       { .compatible = "fsl,mpc5200-psc-spi", },
+       { .compatible = "mpc5200-psc-spi", }, /* old */
+       {}
 };
 
 MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match);