diff options
Diffstat (limited to 'drivers/spi/spi-fsl-spi.c')
| -rw-r--r-- | drivers/spi/spi-fsl-spi.c | 37 | 
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 2129fcd1c31..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; @@ -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;  | 
