diff options
Diffstat (limited to 'drivers/spi/spi-fsl-spi.c')
| -rw-r--r-- | drivers/spi/spi-fsl-spi.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 14e202ee703..98ccd231bf0 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -239,12 +239,6 @@ static int fsl_spi_setup_transfer(struct spi_device *spi, 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; @@ -339,7 +333,7 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, mpc8xxx_spi->tx = t->tx_buf; mpc8xxx_spi->rx = t->rx_buf; - INIT_COMPLETION(mpc8xxx_spi->done); + reinit_completion(&mpc8xxx_spi->done); if (mpc8xxx_spi->flags & SPI_CPM_MODE) ret = fsl_spi_cpm_bufs(mpc8xxx_spi, t, is_dma_mapped); @@ -362,18 +356,28 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, 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) @@ -404,7 +408,8 @@ static void fsl_spi_do_one_msg(struct spi_message *m) } m->status = status; - m->complete(m->context); + if (m->complete) + m->complete(m->context); if (status || !cs_change) { ndelay(nsecs); @@ -426,7 +431,7 @@ static int fsl_spi_setup(struct spi_device *spi) return -EINVAL; if (!cs) { - cs = kzalloc(sizeof *cs, GFP_KERNEL); + cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL); if (!cs) return -ENOMEM; spi->controller_state = cs; @@ -574,7 +579,7 @@ static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on) static void fsl_spi_grlib_probe(struct device *dev) { - struct fsl_spi_platform_data *pdata = dev->platform_data; + struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct spi_master *master = dev_get_drvdata(dev); struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); struct fsl_spi_reg *reg_base = mpc8xxx_spi->reg_base; @@ -600,7 +605,7 @@ static void fsl_spi_grlib_probe(struct device *dev) static struct spi_master * fsl_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) { - struct fsl_spi_platform_data *pdata = dev->platform_data; + struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct spi_master *master; struct mpc8xxx_spi *mpc8xxx_spi; struct fsl_spi_reg *reg_base; @@ -641,6 +646,10 @@ static struct spi_master * fsl_spi_probe(struct device *dev, 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; @@ -700,7 +709,8 @@ err: static void fsl_spi_cs_control(struct spi_device *spi, bool on) { struct device *dev = spi->dev.parent->parent; - struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); + struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); + struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); u16 cs = spi->chip_select; int gpio = pinfo->gpios[cs]; bool alow = pinfo->alow_flags[cs]; @@ -711,7 +721,7 @@ static void fsl_spi_cs_control(struct spi_device *spi, bool on) static int of_fsl_spi_get_chipselects(struct device *dev) { struct device_node *np = dev->of_node; - struct fsl_spi_platform_data *pdata = dev->platform_data; + struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); int ngpios; int i = 0; @@ -790,7 +800,7 @@ err_alloc_flags: static int of_fsl_spi_free_chipselects(struct device *dev) { - struct fsl_spi_platform_data *pdata = dev->platform_data; + struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); int i; @@ -853,7 +863,7 @@ err: static int of_fsl_spi_remove(struct platform_device *ofdev) { - struct spi_master *master = dev_get_drvdata(&ofdev->dev); + struct spi_master *master = platform_get_drvdata(ofdev); struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); int ret; @@ -889,7 +899,7 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev) int irq; struct spi_master *master; - if (!pdev->dev.platform_data) + if (!dev_get_platdata(&pdev->dev)) return -EINVAL; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -901,7 +911,7 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev) return -EINVAL; master = fsl_spi_probe(&pdev->dev, mem, irq); - return PTR_RET(master); + return PTR_ERR_OR_ZERO(master); } static int plat_mpc8xxx_spi_remove(struct platform_device *pdev) |
