diff options
Diffstat (limited to 'drivers/spi/spi-bitbang.c')
| -rw-r--r-- | drivers/spi/spi-bitbang.c | 30 | 
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 8c11355dec2..dc7d2c2d643 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -16,7 +16,6 @@   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */ -#include <linux/init.h>  #include <linux/spinlock.h>  #include <linux/workqueue.h>  #include <linux/interrupt.h> @@ -191,7 +190,7 @@ int spi_bitbang_setup(struct spi_device *spi)  	bitbang = spi_master_get_devdata(spi->master);  	if (!cs) { -		cs = kzalloc(sizeof *cs, GFP_KERNEL); +		cs = kzalloc(sizeof(*cs), GFP_KERNEL);  		if (!cs)  			return -ENOMEM;  		spi->controller_state = cs; @@ -258,7 +257,7 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)  static int spi_bitbang_prepare_hardware(struct spi_master *spi)  { -	struct spi_bitbang 	*bitbang; +	struct spi_bitbang	*bitbang;  	unsigned long		flags;  	bitbang = spi_master_get_devdata(spi); @@ -273,7 +272,7 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi)  static int spi_bitbang_transfer_one(struct spi_master *master,  				    struct spi_message *m)  { -	struct spi_bitbang 	*bitbang; +	struct spi_bitbang	*bitbang;  	unsigned		nsecs;  	struct spi_transfer	*t = NULL;  	unsigned		cs_change; @@ -292,7 +291,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,  	cs_change = 1;  	status = 0; -	list_for_each_entry (t, &m->transfers, transfer_list) { +	list_for_each_entry(t, &m->transfers, transfer_list) {  		/* override speed or wordsize? */  		if (t->speed_hz || t->bits_per_word) @@ -349,7 +348,8 @@ static int spi_bitbang_transfer_one(struct spi_master *master,  		if (t->delay_usecs)  			udelay(t->delay_usecs); -		if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { +		if (cs_change && +		    !list_is_last(&t->transfer_list, &m->transfers)) {  			/* sometimes a short mid-message deselect of the chip  			 * may be needed to terminate a mode or command  			 */ @@ -378,7 +378,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,  static int spi_bitbang_unprepare_hardware(struct spi_master *spi)  { -	struct spi_bitbang 	*bitbang; +	struct spi_bitbang	*bitbang;  	unsigned long		flags;  	bitbang = spi_master_get_devdata(spi); @@ -414,10 +414,16 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi)   * This routine registers the spi_master, which will process requests in a   * dedicated task, keeping IRQs unblocked most of the time.  To stop   * processing those requests, call spi_bitbang_stop(). + * + * On success, this routine will take a reference to master. The caller is + * responsible for calling spi_bitbang_stop() to decrement the reference and + * spi_master_put() as counterpart of spi_alloc_master() to prevent a memory + * leak.   */  int spi_bitbang_start(struct spi_bitbang *bitbang)  {  	struct spi_master *master = bitbang->master; +	int ret;  	if (!master || !bitbang->chipselect)  		return -EINVAL; @@ -449,18 +455,20 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)  	/* driver may get busy before register() returns, especially  	 * if someone registered boardinfo for devices  	 */ -	return spi_register_master(master); +	ret = spi_register_master(spi_master_get(master)); +	if (ret) +		spi_master_put(master); + +	return 0;  }  EXPORT_SYMBOL_GPL(spi_bitbang_start);  /**   * spi_bitbang_stop - stops the task providing spi communication   */ -int spi_bitbang_stop(struct spi_bitbang *bitbang) +void spi_bitbang_stop(struct spi_bitbang *bitbang)  {  	spi_unregister_master(bitbang->master); - -	return 0;  }  EXPORT_SYMBOL_GPL(spi_bitbang_stop);  | 
