These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / spi / spi-mpc512x-psc.c
index 965d2bd..c3ec46c 100644 (file)
 #include <linux/gpio.h>
 #include <asm/mpc52xx_psc.h>
 
+enum {
+       TYPE_MPC5121,
+       TYPE_MPC5125,
+};
+
+/*
+ * This macro abstracts the differences in the PSC register layout between
+ * MPC5121 (which uses a struct mpc52xx_psc) and MPC5125 (using mpc5125_psc).
+ */
+#define psc_addr(mps, regname) ({                                      \
+       void *__ret = NULL;                                             \
+       switch (mps->type) {                                            \
+       case TYPE_MPC5121: {                                            \
+                       struct mpc52xx_psc __iomem *psc = mps->psc;     \
+                       __ret = &psc->regname;                          \
+               };                                                      \
+               break;                                                  \
+       case TYPE_MPC5125: {                                            \
+                       struct mpc5125_psc __iomem *psc = mps->psc;     \
+                       __ret = &psc->regname;                          \
+               };                                                      \
+               break;                                                  \
+       }                                                               \
+       __ret; })
+
 struct mpc512x_psc_spi {
        void (*cs_control)(struct spi_device *spi, bool on);
 
        /* driver internal data */
-       struct mpc52xx_psc __iomem *psc;
+       int type;
+       void __iomem *psc;
        struct mpc512x_psc_fifo __iomem *fifo;
        unsigned int irq;
        u8 bits_per_word;
@@ -71,13 +97,12 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
 {
        struct mpc512x_psc_spi_cs *cs = spi->controller_state;
        struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
-       struct mpc52xx_psc __iomem *psc = mps->psc;
        u32 sicr;
        u32 ccr;
        int speed;
        u16 bclkdiv;
 
-       sicr = in_be32(&psc->sicr);
+       sicr = in_be32(psc_addr(mps, sicr));
 
        /* Set clock phase and polarity */
        if (spi->mode & SPI_CPHA)
@@ -94,9 +119,9 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
                sicr |= 0x10000000;
        else
                sicr &= ~0x10000000;
-       out_be32(&psc->sicr, sicr);
+       out_be32(psc_addr(mps, sicr), sicr);
 
-       ccr = in_be32(&psc->ccr);
+       ccr = in_be32(psc_addr(mps, ccr));
        ccr &= 0xFF000000;
        speed = cs->speed_hz;
        if (!speed)
@@ -104,7 +129,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
        bclkdiv = (mps->mclk_rate / speed) - 1;
 
        ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
-       out_be32(&psc->ccr, ccr);
+       out_be32(psc_addr(mps, ccr), ccr);
        mps->bits_per_word = cs->bits_per_word;
 
        if (mps->cs_control && gpio_is_valid(spi->cs_gpio))
@@ -277,11 +302,9 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
        cs_change = 1;
        status = 0;
        list_for_each_entry(t, &m->transfers, transfer_list) {
-               if (t->bits_per_word || t->speed_hz) {
-                       status = mpc512x_psc_spi_transfer_setup(spi, t);
-                       if (status < 0)
-                               break;
-               }
+               status = mpc512x_psc_spi_transfer_setup(spi, t);
+               if (status < 0)
+                       break;
 
                if (cs_change)
                        mpc512x_psc_spi_activate_cs(spi);
@@ -315,16 +338,15 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
 static int mpc512x_psc_spi_prep_xfer_hw(struct spi_master *master)
 {
        struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
-       struct mpc52xx_psc __iomem *psc = mps->psc;
 
        dev_dbg(&master->dev, "%s()\n", __func__);
 
        /* Zero MR2 */
-       in_8(&psc->mode);
-       out_8(&psc->mode, 0x0);
+       in_8(psc_addr(mps, mr2));
+       out_8(psc_addr(mps, mr2), 0x0);
 
        /* enable transmitter/receiver */
-       out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
+       out_8(psc_addr(mps, command), MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
 
        return 0;
 }
@@ -332,13 +354,12 @@ static int mpc512x_psc_spi_prep_xfer_hw(struct spi_master *master)
 static int mpc512x_psc_spi_unprep_xfer_hw(struct spi_master *master)
 {
        struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
-       struct mpc52xx_psc __iomem *psc = mps->psc;
        struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
 
        dev_dbg(&master->dev, "%s()\n", __func__);
 
        /* disable transmitter/receiver and fifo interrupt */
-       out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
+       out_8(psc_addr(mps, command), MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
        out_be32(&fifo->tximr, 0);
 
        return 0;
@@ -388,7 +409,6 @@ static void mpc512x_psc_spi_cleanup(struct spi_device *spi)
 static int mpc512x_psc_spi_port_config(struct spi_master *master,
                                       struct mpc512x_psc_spi *mps)
 {
-       struct mpc52xx_psc __iomem *psc = mps->psc;
        struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
        u32 sicr;
        u32 ccr;
@@ -396,12 +416,12 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
        u16 bclkdiv;
 
        /* Reset the PSC into a known state */
-       out_8(&psc->command, MPC52xx_PSC_RST_RX);
-       out_8(&psc->command, MPC52xx_PSC_RST_TX);
-       out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
+       out_8(psc_addr(mps, command), MPC52xx_PSC_RST_RX);
+       out_8(psc_addr(mps, command), MPC52xx_PSC_RST_TX);
+       out_8(psc_addr(mps, command), MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
 
        /* Disable psc interrupts all useful interrupts are in fifo */
-       out_be16(&psc->isr_imr.imr, 0);
+       out_be16(psc_addr(mps, isr_imr.imr), 0);
 
        /* Disable fifo interrupts, will be enabled later */
        out_be32(&fifo->tximr, 0);
@@ -417,18 +437,18 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master,
                0x00004000 |    /* MSTR = 1   -- SPI master */
                0x00000800;     /* UseEOF = 1 -- SS low until EOF */
 
-       out_be32(&psc->sicr, sicr);
+       out_be32(psc_addr(mps, sicr), sicr);
 
-       ccr = in_be32(&psc->ccr);
+       ccr = in_be32(psc_addr(mps, ccr));
        ccr &= 0xFF000000;
        speed = 1000000;        /* default 1MHz */
        bclkdiv = (mps->mclk_rate / speed) - 1;
        ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
-       out_be32(&psc->ccr, ccr);
+       out_be32(psc_addr(mps, ccr), ccr);
 
        /* Set 2ms DTL delay */
-       out_8(&psc->ctur, 0x00);
-       out_8(&psc->ctlr, 0x82);
+       out_8(psc_addr(mps, ctur), 0x00);
+       out_8(psc_addr(mps, ctlr), 0x82);
 
        /* we don't use the alarms */
        out_be32(&fifo->rxalarm, 0xfff);
@@ -482,6 +502,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
 
        dev_set_drvdata(dev, master);
        mps = spi_master_get_devdata(master);
+       mps->type = (int)of_device_get_match_data(dev);
        mps->irq = irq;
 
        if (pdata == NULL) {
@@ -589,7 +610,8 @@ static int mpc512x_psc_spi_of_remove(struct platform_device *op)
 }
 
 static const struct of_device_id mpc512x_psc_spi_of_match[] = {
-       { .compatible = "fsl,mpc5121-psc-spi", },
+       { .compatible = "fsl,mpc5121-psc-spi", .data = (void *)TYPE_MPC5121 },
+       { .compatible = "fsl,mpc5125-psc-spi", .data = (void *)TYPE_MPC5125 },
        {},
 };