]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/spi/mpc52xx_psc_spi.c
spi: fix platform driver hotplug/coldplug
[linux-2.6-omap-h63xx.git] / drivers / spi / mpc52xx_psc_spi.c
index d2a4b2bdb07b6cbae5f2a4b4d51727a813ed2596..90729469d481dced3ae3e70d1c284df22e385acf 100644 (file)
@@ -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;
@@ -181,7 +183,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
                }
 
 
-               /* enable interupts and wait for wake up
+               /* enable interrupts and wait for wake up
                 * if just one byte is expected the Rx FIFO genererates no
                 * FFULL interrupt, so activate the RxRDY interrupt
                 */
@@ -190,11 +192,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,75 +332,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 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)
-       cdm = mpc52xx_find_and_map("mpc5200-cdm");
-       gpio = mpc52xx_find_and_map("mpc5200-gpio");
-#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);
@@ -408,7 +349,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 */
@@ -422,12 +363,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;
 }
 
@@ -487,6 +422,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);
@@ -503,7 +440,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
        INIT_LIST_HEAD(&mps->queue);
 
        mps->workqueue = create_singlethread_workqueue(
-               master->cdev.dev->bus_id);
+               master->dev.parent->bus_id);
        if (mps->workqueue == NULL) {
                ret = -EBUSY;
                goto free_irq;
@@ -563,6 +500,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 = {
@@ -623,8 +563,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);