Merge remote-tracking branches 'spi/fix/complete', 'spi/fix/efm32', 'spi/fix/omap2...
authorMark Brown <broonie@linaro.org>
Thu, 10 Apr 2014 22:39:52 +0000 (23:39 +0100)
committerMark Brown <broonie@linaro.org>
Thu, 10 Apr 2014 22:39:52 +0000 (23:39 +0100)
1  2  3  4  5 
drivers/spi/spi-fsl-espi.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-mpc512x-psc.c
drivers/spi/spi-mpc52xx-psc.c
drivers/spi/spi-mpc52xx.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-txx9.c

index 6fb2b75df821e78f80a0f6c1bf4c64e45e4292d5,e8e3d34bab07c4fed001e5dbda5896aae5378f32,6fb2b75df821e78f80a0f6c1bf4c64e45e4292d5,428dc7a6b62e7c173fb9a1dd8b9028ab9ded01b3,6fb2b75df821e78f80a0f6c1bf4c64e45e4292d5..e767f5831b9c7ce3d8ce015e34e67643f69a28df
@@@@@@ -219,8 -219,13 -219,8 -219,13 -219,8 +219,8 @@@@@@ static int fsl_espi_bufs(struct spi_dev
        struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
        struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base;
        unsigned int len = t->len;
 - -    u8 bits_per_word;
        int ret;
     
 - -    bits_per_word = spi->bits_per_word;
 - -    if (t->bits_per_word)
 - -            bits_per_word = t->bits_per_word;
 - - 
        mpc8xxx_spi->len = t->len;
        len = roundup(len, 4) / 4;
     
@@@@@@ -441,7 -446,8 -441,7 -446,7 -441,7 +441,8 @@@@@@ static void fsl_espi_do_one_msg(struct 
     
        m->actual_length = espi_trans.actual_length;
        m->status = espi_trans.status;
- ---   m->complete(m->context);
+ +++   if (m->complete)
+ +++           m->complete(m->context);
     }
     
     static int fsl_espi_setup(struct spi_device *spi)
index f35488ed62a9eaca3c353401d9bf7b935bf4a00c,f2af3eb3ceb72f51e4b6dd57912b0acefbae5067,f35488ed62a9eaca3c353401d9bf7b935bf4a00c,119f7af945374f43a7e1547efbb2f5aa1d9517b0,f35488ed62a9eaca3c353401d9bf7b935bf4a00c..b3e7775034dbd1d660b0ece95a197aea8cb24b54
@@@@@@ -239,6 -239,12 -239,6 -239,12 -239,6 +239,6 @@@@@@ static int fsl_spi_setup_transfer(struc
        if (!bits_per_word)
                bits_per_word = spi->bits_per_word;
     
 - -    /* Make sure its a bit width we support [4..16, 32] */
 - -    if ((bits_per_word < 4)
 - -        || ((bits_per_word > 16) && (bits_per_word != 32))
 - -        || (bits_per_word > mpc8xxx_spi->max_bits_per_word))
 - -            return -EINVAL;
 - - 
        if (!hz)
                hz = spi->max_speed_hz;
     
@@@@@@ -356,28 -362,18 -356,28 -362,18 -356,28 +356,28 @@@@@@ static int fsl_spi_bufs(struct spi_devi
     static void fsl_spi_do_one_msg(struct spi_message *m)
     {
        struct spi_device *spi = m->spi;
 - -    struct spi_transfer *t;
 + +    struct spi_transfer *t, *first;
        unsigned int cs_change;
        const int nsecs = 50;
        int status;
     
 - -    cs_change = 1;
 - -    status = 0;
 + +    /* Don't allow changes if CS is active */
 + +    first = list_first_entry(&m->transfers, struct spi_transfer,
 + +                    transfer_list);
        list_for_each_entry(t, &m->transfers, transfer_list) {
 - -            if (t->bits_per_word || t->speed_hz) {
 - -                    /* Don't allow changes if CS is active */
 + +            if ((first->bits_per_word != t->bits_per_word) ||
 + +                    (first->speed_hz != t->speed_hz)) {
                        status = -EINVAL;
 + +                    dev_err(&spi->dev,
 + +                            "bits_per_word/speed_hz should be same for the same SPI transfer\n");
 + +                    return;
 + +            }
 + +    }
     
 + +    cs_change = 1;
 + +    status = -EINVAL;
 + +    list_for_each_entry(t, &m->transfers, transfer_list) {
 + +            if (t->bits_per_word || t->speed_hz) {
                        if (cs_change)
                                status = fsl_spi_setup_transfer(spi, t);
                        if (status < 0)
        }
     
        m->status = status;
- ---   m->complete(m->context);
+ +++   if (m->complete)
+ +++           m->complete(m->context);
     
        if (status || !cs_change) {
                ndelay(nsecs);
@@@@@@ -645,10 -642,6 -645,10 -641,6 -645,10 +646,10 @@@@@@ static struct spi_master * fsl_spi_prob
        if (mpc8xxx_spi->type == TYPE_GRLIB)
                fsl_spi_grlib_probe(dev);
     
 + +    master->bits_per_word_mask =
 + +            (SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) &
 + +            SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word);
 + + 
        if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)
                mpc8xxx_spi->set_shifts = fsl_spi_qe_cpu_set_shifts;
     
index 3822eef2ef9dacebd723ee2472a33dc04e1865a5,8eee745e847115523fc1aa1115d91b2fc6abb250,3822eef2ef9dacebd723ee2472a33dc04e1865a5,5032141eeeec4ee0cbb46b7d7af7c8a65e76212c,3822eef2ef9dacebd723ee2472a33dc04e1865a5..577d23a12763f79e5c9197aa8a252086c69cf7f2
     
     #include <linux/module.h>
     #include <linux/kernel.h>
 - - #include <linux/init.h>
     #include <linux/errno.h>
     #include <linux/interrupt.h>
     #include <linux/of_address.h>
@@@@@@ -300,7 -301,8 -300,7 -301,7 -300,7 +300,8 @@@@@@ static int mpc512x_psc_spi_msg_xfer(str
        }
     
        m->status = status;
- ---   m->complete(m->context);
+ +++   if (m->complete)
+ +++           m->complete(m->context);
     
        if (status || !cs_change)
                mpc512x_psc_spi_deactivate_cs(spi);
@@@@@@ -465,8 -467,10 -465,8 -466,10 -465,8 +466,8 @@@@@@ static void mpc512x_spi_cs_control(stru
        gpio_set_value(spi->cs_gpio, onoff);
     }
     
 - - /* bus_num is used only for the case dev->platform_data == NULL */
     static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
 - -                                          u32 size, unsigned int irq,
 - -                                          s16 bus_num)
 + +                                          u32 size, unsigned int irq)
     {
        struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
        struct mpc512x_psc_spi *mps;
     
        if (pdata == NULL) {
                mps->cs_control = mpc512x_spi_cs_control;
 - -            master->bus_num = bus_num;
        } else {
                mps->cs_control = pdata->cs_control;
                master->bus_num = pdata->bus_num;
@@@@@@ -570,6 -575,7 -570,6 -574,7 -570,6 +571,6 @@@@@@ static int mpc512x_psc_spi_of_probe(str
     {
        const u32 *regaddr_p;
        u64 regaddr64, size64;
 - -    s16 id = -1;
     
        regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
        if (!regaddr_p) {
        }
        regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);
     
 - -    /* get PSC id (0..11, used by port_config) */
 - -    id = of_alias_get_id(op->dev.of_node, "spi");
 - -    if (id < 0) {
 - -            dev_err(&op->dev, "no alias id for %s\n",
 - -                    op->dev.of_node->full_name);
 - -            return id;
 - -    }
 - - 
        return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64,
 - -                            irq_of_parse_and_map(op->dev.of_node, 0), id);
 + +                            irq_of_parse_and_map(op->dev.of_node, 0));
     }
     
     static int mpc512x_psc_spi_of_remove(struct platform_device *op)
index 3d18d93511854c1aa56fd6b5ebe6d10c65157242,d761bc0dc5ce88faa06dfccbe52baae736f25c93,3d18d93511854c1aa56fd6b5ebe6d10c65157242,00ba910ab3023a2587bc54a700e25e9f4a561438,3d18d93511854c1aa56fd6b5ebe6d10c65157242..de532aa11d34e9f76212e0e4fb74d6c2244d8c18
      */
     
     #include <linux/module.h>
 - - #include <linux/init.h>
     #include <linux/types.h>
     #include <linux/errno.h>
     #include <linux/interrupt.h>
@@@@@@ -247,7 -248,8 -247,7 -248,7 -247,7 +247,8 @@@@@@ static void mpc52xx_psc_spi_work(struc
                }
     
                m->status = status;
- ---           m->complete(m->context);
+ +++           if (m->complete)
+ +++                   m->complete(m->context);
     
                if (status || !cs_change)
                        mpc52xx_psc_spi_deactivate_cs(spi);
index aac2a5ddd964efcf1086263fa1231235aa065141,a0de12ac1debfe5eea2520ed65651087bfdd9014,aac2a5ddd964efcf1086263fa1231235aa065141,7c675fe8310105d255f6f10afc7a2f1c5e576b32,aac2a5ddd964efcf1086263fa1231235aa065141..b07db4b62d80d823804516caaf961d8c57b9bea6
      */
     
     #include <linux/module.h>
 - - #include <linux/init.h>
     #include <linux/errno.h>
     #include <linux/of_platform.h>
     #include <linux/interrupt.h>
@@@@@@ -234,7 -235,8 -234,7 -235,7 -234,7 +234,8 @@@@@@ static int mpc52xx_spi_fsmstate_transfe
                dev_err(&ms->master->dev, "mode fault\n");
                mpc52xx_spi_chipsel(ms, 0);
                ms->message->status = -EIO;
- ---           ms->message->complete(ms->message->context);
+ +++           if (ms->message->complete)
+ +++                   ms->message->complete(ms->message->context);
                ms->state = mpc52xx_spi_fsmstate_idle;
                return FSM_CONTINUE;
        }
@@@@@@ -288,7 -290,8 -288,7 -289,7 -288,7 +289,8 @@@@@@ mpc52xx_spi_fsmstate_wait(int irq, stru
                ms->msg_count++;
                mpc52xx_spi_chipsel(ms, 0);
                ms->message->status = 0;
- ---           ms->message->complete(ms->message->context);
+ +++           if (ms->message->complete)
+ +++                   ms->message->complete(ms->message->context);
                ms->state = mpc52xx_spi_fsmstate_idle;
                return FSM_CONTINUE;
        }
@@@@@@ -356,6 -359,20 -356,6 -357,20 -356,6 +358,6 @@@@@@ static void mpc52xx_spi_wq(struct work_
      * spi_master ops
      */
     
 - - static int mpc52xx_spi_setup(struct spi_device *spi)
 - - {
 - -    if (spi->bits_per_word % 8)
 - -            return -EINVAL;
 - - 
 - -    if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST))
 - -            return -EINVAL;
 - - 
 - -    if (spi->chip_select >= spi->master->num_chipselect)
 - -            return -EINVAL;
 - - 
 - -    return 0;
 - - }
 - - 
     static int mpc52xx_spi_transfer(struct spi_device *spi, struct spi_message *m)
     {
        struct mpc52xx_spi *ms = spi_master_get_devdata(spi->master);
@@@@@@ -418,9 -435,9 -418,9 -433,9 -418,9 +420,9 @@@@@@ static int mpc52xx_spi_probe(struct pla
                goto err_alloc;
        }
     
 - -    master->setup = mpc52xx_spi_setup;
        master->transfer = mpc52xx_spi_transfer;
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
 + +    master->bits_per_word_mask = SPI_BPW_MASK(8);
        master->dev.of_node = op->dev.of_node;
     
        platform_set_drvdata(op, master);
index 2941c5b96ebc2e063c22a4b2fcfea946d55b8849,a72127f08e39faa04d1433094590094ea1ac357d,2941c5b96ebc2e063c22a4b2fcfea946d55b8849,f664212fb4edc403deb81159bea761cc413a684b,2941c5b96ebc2e063c22a4b2fcfea946d55b8849..4dc77df388642601510c41fb02dcb5153d2b2ea3
      */
     
     #include <linux/kernel.h>
 - - #include <linux/init.h>
     #include <linux/interrupt.h>
     #include <linux/module.h>
     #include <linux/device.h>
     #include <linux/platform_data/spi-omap2-mcspi.h>
     
     #define OMAP2_MCSPI_MAX_FREQ               48000000
 + + #define OMAP2_MCSPI_MAX_DIVIDER            4096
     #define OMAP2_MCSPI_MAX_FIFODEPTH  64
     #define OMAP2_MCSPI_MAX_FIFOWCNT   0xFFFF
     #define SPI_AUTOSUSPEND_TIMEOUT            2000
     #define OMAP2_MCSPI_CHCONF_FORCE   BIT(20)
     #define OMAP2_MCSPI_CHCONF_FFET            BIT(27)
     #define OMAP2_MCSPI_CHCONF_FFER            BIT(28)
 + + #define OMAP2_MCSPI_CHCONF_CLKG            BIT(29)
     
     #define OMAP2_MCSPI_CHSTAT_RXS             BIT(0)
     #define OMAP2_MCSPI_CHSTAT_TXS             BIT(1)
     #define OMAP2_MCSPI_CHSTAT_TXFFE   BIT(3)
     
     #define OMAP2_MCSPI_CHCTRL_EN              BIT(0)
 + + #define OMAP2_MCSPI_CHCTRL_EXTCLK_MASK     (0xff << 8)
     
     #define OMAP2_MCSPI_WAKEUPENABLE_WKEN      BIT(0)
     
@@@@@@ -151,7 -149,7 -151,7 -149,7 -151,7 +151,7 @@@@@@ struct omap2_mcspi_cs 
        int                     word_len;
        struct list_head        node;
        /* Context save and restore shadow register */
 - -    u32                     chconf0;
 + +    u32                     chconf0, chctrl0;
     };
     
     static inline void mcspi_write_reg(struct spi_master *master,
@@@@@@ -232,16 -230,10 -232,16 -230,10 -232,16 +232,16 @@@@@@ static void omap2_mcspi_set_dma_req(con
     
     static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)
     {
 + +    struct omap2_mcspi_cs *cs = spi->controller_state;
        u32 l;
     
 - -    l = enable ? OMAP2_MCSPI_CHCTRL_EN : 0;
 - -    mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, l);
 + +    l = cs->chctrl0;
 + +    if (enable)
 + +            l |= OMAP2_MCSPI_CHCTRL_EN;
 + +    else
 + +            l &= ~OMAP2_MCSPI_CHCTRL_EN;
 + +    cs->chctrl0 = l;
 + +    mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0);
        /* Flash post-writes */
        mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
     }
@@@@@@ -848,7 -840,7 -848,7 -840,7 -848,7 +848,7 @@@@@@ static int omap2_mcspi_setup_transfer(s
        struct omap2_mcspi_cs *cs = spi->controller_state;
        struct omap2_mcspi *mcspi;
        struct spi_master *spi_cntrl;
 - -    u32 l = 0, div = 0;
 + +    u32 l = 0, clkd = 0, div, extclk = 0, clkg = 0;
        u8 word_len = spi->bits_per_word;
        u32 speed_hz = spi->max_speed_hz;
     
                speed_hz = t->speed_hz;
     
        speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ);
 - -    div = omap2_mcspi_calc_divisor(speed_hz);
 + +    if (speed_hz < (OMAP2_MCSPI_MAX_FREQ / OMAP2_MCSPI_MAX_DIVIDER)) {
 + +            clkd = omap2_mcspi_calc_divisor(speed_hz);
 + +            speed_hz = OMAP2_MCSPI_MAX_FREQ >> clkd;
 + +            clkg = 0;
 + +    } else {
 + +            div = (OMAP2_MCSPI_MAX_FREQ + speed_hz - 1) / speed_hz;
 + +            speed_hz = OMAP2_MCSPI_MAX_FREQ / div;
 + +            clkd = (div - 1) & 0xf;
 + +            extclk = (div - 1) >> 4;
 + +            clkg = OMAP2_MCSPI_CHCONF_CLKG;
 + +    }
     
        l = mcspi_cached_chconf0(spi);
     
     
        /* set clock divisor */
        l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
 - -    l |= div << 2;
 + +    l |= clkd << 2;
 + + 
 + +    /* set clock granularity */
 + +    l &= ~OMAP2_MCSPI_CHCONF_CLKG;
 + +    l |= clkg;
 + +    if (clkg) {
 + +            cs->chctrl0 &= ~OMAP2_MCSPI_CHCTRL_EXTCLK_MASK;
 + +            cs->chctrl0 |= extclk << 8;
 + +            mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0);
 + +    }
     
        /* set SPI mode 0..3 */
        if (spi->mode & SPI_CPOL)
        mcspi_write_chconf0(spi, l);
     
        dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
 - -                    OMAP2_MCSPI_MAX_FREQ >> div,
 + +                    speed_hz,
                        (spi->mode & SPI_CPHA) ? "trailing" : "leading",
                        (spi->mode & SPI_CPOL) ? "inverted" : "normal");
     
@@@@@@ -999,7 -972,6 -999,7 -972,6 -999,7 +999,7 @@@@@@ static int omap2_mcspi_setup(struct spi
                cs->base = mcspi->base + spi->chip_select * 0x14;
                cs->phys = mcspi->phys + spi->chip_select * 0x14;
                cs->chconf0 = 0;
 + +            cs->chctrl0 = 0;
                spi->controller_state = cs;
                /* Link this to context save list */
                list_add_tail(&cs->node, &ctx->cs);
@@@@@@ -1085,15 -1057,12 -1085,15 -1057,12 -1085,15 +1085,15 @@@@@@ static void omap2_mcspi_work(struct oma
                        status = -EINVAL;
                        break;
                }
 - -            if (par_override || t->speed_hz || t->bits_per_word) {
 + +            if (par_override ||
 + +                (t->speed_hz != spi->max_speed_hz) ||
 + +                (t->bits_per_word != spi->bits_per_word)) {
                        par_override = 1;
                        status = omap2_mcspi_setup_transfer(spi, t);
                        if (status < 0)
                                break;
 - -                    if (!t->speed_hz && !t->bits_per_word)
 + +                    if (t->speed_hz == spi->max_speed_hz &&
 + +                        t->bits_per_word == spi->bits_per_word)
                                par_override = 0;
                }
                if (cd && cd->cs_per_word) {
@@@@@@ -1207,12 -1176,16 -1207,12 -1176,16 -1207,12 +1207,12 @@@@@@ static int omap2_mcspi_transfer_one_mes
        m->actual_length = 0;
        m->status = 0;
     
 - -    /* reject invalid messages and transfers */
 - -    if (list_empty(&m->transfers))
 - -            return -EINVAL;
        list_for_each_entry(t, &m->transfers, transfer_list) {
                const void      *tx_buf = t->tx_buf;
                void            *rx_buf = t->rx_buf;
                unsigned        len = t->len;
     
 - -            if (t->speed_hz > OMAP2_MCSPI_MAX_FREQ
 - -                            || (len && !(rx_buf || tx_buf))) {
 + +            if ((len && !(rx_buf || tx_buf))) {
                        dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
                                        t->speed_hz,
                                        len,
                                        t->bits_per_word);
                        return -EINVAL;
                }
 - -            if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) {
 - -                    dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n",
 - -                                    t->speed_hz,
 - -                                    OMAP2_MCSPI_MAX_FREQ >> 15);
 - -                    return -EINVAL;
 - -            }
     
                if (m->is_dma_mapped || len < DMA_MIN_BYTES)
                        continue;
@@@@@@ -1332,8 -1311,6 -1332,8 -1311,6 -1332,8 +1332,8 @@@@@@ static int omap2_mcspi_probe(struct pla
        master->transfer_one_message = omap2_mcspi_transfer_one_message;
        master->cleanup = omap2_mcspi_cleanup;
        master->dev.of_node = node;
 + +    master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ;
 + +    master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15;
     
        platform_set_drvdata(pdev, master);
     
     
        INIT_LIST_HEAD(&mcspi->ctx.cs);
     
--- -   mcspi->dma_channels = kcalloc(master->num_chipselect,
--- -                   sizeof(struct omap2_mcspi_dma),
--- -                   GFP_KERNEL);
--- -
--- -   if (mcspi->dma_channels == NULL)
+++ +   mcspi->dma_channels = devm_kcalloc(&pdev->dev, master->num_chipselect,
+++ +                                      sizeof(struct omap2_mcspi_dma),
+++ +                                      GFP_KERNEL);
+++ +   if (mcspi->dma_channels == NULL) {
+++ +           status = -ENOMEM;
                goto free_master;
+++ +   }
     
        for (i = 0; i < master->num_chipselect; i++) {
                char *dma_rx_ch_name = mcspi->dma_channels[i].dma_rx_ch_name;
        }
     
        if (status < 0)
--- -           goto dma_chnl_free;
+++ +           goto free_master;
     
        pm_runtime_use_autosuspend(&pdev->dev);
        pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
     
     disable_pm:
        pm_runtime_disable(&pdev->dev);
--- -dma_chnl_free:
--- -   kfree(mcspi->dma_channels);
     free_master:
        spi_master_put(master);
        return status;
     
     static int omap2_mcspi_remove(struct platform_device *pdev)
     {
--- -   struct spi_master       *master;
--- -   struct omap2_mcspi      *mcspi;
--- -   struct omap2_mcspi_dma  *dma_channels;
--- -
--- -   master = platform_get_drvdata(pdev);
--- -   mcspi = spi_master_get_devdata(master);
--- -   dma_channels = mcspi->dma_channels;
+++ +   struct spi_master *master = platform_get_drvdata(pdev);
+++ +   struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
     
        pm_runtime_put_sync(mcspi->dev);
        pm_runtime_disable(&pdev->dev);
     
--- -   kfree(dma_channels);
--- -
        return 0;
     }
     
diff --combined drivers/spi/spi-txx9.c
index 820b499816f8ebfb6bc45a56026dbe05b9b4311f,57a14977101c4ec77cbecc53befbedcde3659a50,820b499816f8ebfb6bc45a56026dbe05b9b4311f,6191ced514b2e71538926983ecc341ce7be75718,820b499816f8ebfb6bc45a56026dbe05b9b4311f..5f183baa91a98bb343747eced81ae6f4e09c4536
@@@@@@ -80,6 -80,7 -80,6 -80,7 -80,6 +80,6 @@@@@@ struct txx9spi 
        void __iomem *membase;
        int baseclk;
        struct clk *clk;
 - -    u32 max_speed_hz, min_speed_hz;
        int last_chipselect;
        int last_chipselect_val;
     };
@@@@@@ -116,7 -117,9 -116,7 -117,9 -116,7 +116,7 @@@@@@ static int txx9spi_setup(struct spi_dev
     {
        struct txx9spi *c = spi_master_get_devdata(spi->master);
     
 - -    if (!spi->max_speed_hz
 - -                    || spi->max_speed_hz > c->max_speed_hz
 - -                    || spi->max_speed_hz < c->min_speed_hz)
 + +    if (!spi->max_speed_hz)
                return -EINVAL;
     
        if (gpio_direction_output(spi->chip_select,
@@@@@@ -262,7 -265,8 -262,7 -265,7 -262,7 +262,8 @@@@@@ static void txx9spi_work_one(struct txx
     
     exit:
        m->status = status;
- ---   m->complete(m->context);
+ +++   if (m->complete)
+ +++           m->complete(m->context);
     
        /* normally deactivate chipselect ... unless no error and
         * cs_change has hinted that the next message will probably
@@@@@@ -306,8 -310,15 -306,8 -309,15 -306,8 +307,8 @@@@@@ static int txx9spi_transfer(struct spi_
     
        /* check each transfer's parameters */
        list_for_each_entry(t, &m->transfers, transfer_list) {
 - -            u32 speed_hz = t->speed_hz ? : spi->max_speed_hz;
 - -            u8 bits_per_word = t->bits_per_word;
 - - 
                if (!t->tx_buf && !t->rx_buf && t->len)
                        return -EINVAL;
 - -            if (t->len & ((bits_per_word >> 3) - 1))
 - -                    return -EINVAL;
 - -            if (speed_hz < c->min_speed_hz || speed_hz > c->max_speed_hz)
 - -                    return -EINVAL;
        }
     
        spin_lock_irqsave(&c->lock, flags);
@@@@@@ -350,12 -361,17 -350,12 -360,17 -350,12 +351,12 @@@@@@ static int txx9spi_probe(struct platfor
                goto exit;
        }
        c->baseclk = clk_get_rate(c->clk);
 - -    c->min_speed_hz = DIV_ROUND_UP(c->baseclk, SPI_MAX_DIVIDER + 1);
 - -    c->max_speed_hz = c->baseclk / (SPI_MIN_DIVIDER + 1);
 + +    master->min_speed_hz = DIV_ROUND_UP(c->baseclk, SPI_MAX_DIVIDER + 1);
 + +    master->max_speed_hz = c->baseclk / (SPI_MIN_DIVIDER + 1);
     
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 - -    if (!res)
 - -            goto exit_busy;
 - -    if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res),
 - -                                 "spi_txx9"))
 - -            goto exit_busy;
 - -    c->membase = devm_ioremap(&dev->dev, res->start, resource_size(res));
 - -    if (!c->membase)
 + +    c->membase = devm_ioremap_resource(&dev->dev, res);
 + +    if (IS_ERR(c->membase))
                goto exit_busy;
     
        /* enter config mode */