diff options
Diffstat (limited to 'drivers/misc/ti-st/st_kim.c')
| -rw-r--r-- | drivers/misc/ti-st/st_kim.c | 33 | 
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 38fd2f04c07..3a3580566df 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -68,6 +68,7 @@ void validate_firmware_response(struct kim_data_s *kim_gdata)  	if (unlikely(skb->data[5] != 0)) {  		pr_err("no proper response during fw download");  		pr_err("data6 %x", skb->data[5]); +		kfree_skb(skb);  		return;		/* keep waiting for the proper response */  	}  	/* becos of all the script being downloaded */ @@ -210,6 +211,7 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)  		pr_err(" waiting for ver info- timed out ");  		return -ETIMEDOUT;  	} +	INIT_COMPLETION(kim_gdata->kim_rcvd);  	version =  		MAKEWORD(kim_gdata->resp_buffer[13], @@ -298,6 +300,7 @@ static long download_firmware(struct kim_data_s *kim_gdata)  		switch (((struct bts_action *)ptr)->type) {  		case ACTION_SEND_COMMAND:	/* action send */ +			pr_debug("S");  			action_ptr = &(((struct bts_action *)ptr)->data[0]);  			if (unlikely  			    (((struct hci_command *)action_ptr)->opcode == @@ -335,6 +338,10 @@ static long download_firmware(struct kim_data_s *kim_gdata)  				release_firmware(kim_gdata->fw_entry);  				return -ETIMEDOUT;  			} +			/* reinit completion before sending for the +			 * relevant wait +			 */ +			INIT_COMPLETION(kim_gdata->kim_rcvd);  			/*  			 * Free space found in uart buffer, call st_int_write @@ -361,6 +368,7 @@ static long download_firmware(struct kim_data_s *kim_gdata)  			}  			break;  		case ACTION_WAIT_EVENT:  /* wait */ +			pr_debug("W");  			if (!wait_for_completion_timeout  					(&kim_gdata->kim_rcvd,  					 msecs_to_jiffies(CMD_RESP_TIME))) { @@ -434,11 +442,17 @@ long st_kim_start(void *kim_data)  {  	long err = 0;  	long retry = POR_RETRY_COUNT; +	struct ti_st_plat_data	*pdata;  	struct kim_data_s	*kim_gdata = (struct kim_data_s *)kim_data;  	pr_info(" %s", __func__); +	pdata = kim_gdata->kim_pdev->dev.platform_data;  	do { +		/* platform specific enabling code here */ +		if (pdata->chip_enable) +			pdata->chip_enable(kim_gdata); +  		/* Configure BT nShutdown to HIGH state */  		gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);  		mdelay(5);	/* FIXME: a proper toggle */ @@ -460,6 +474,12 @@ long st_kim_start(void *kim_data)  			pr_info("ldisc_install = 0");  			sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,  					NULL, "install"); +			/* the following wait is never going to be completed, +			 * since the ldisc was never installed, hence serving +			 * as a mdelay of LDISC_TIME msecs */ +			err = wait_for_completion_timeout +				(&kim_gdata->ldisc_installed, +				 msecs_to_jiffies(LDISC_TIME));  			err = -ETIMEDOUT;  			continue;  		} else { @@ -472,6 +492,13 @@ long st_kim_start(void *kim_data)  				pr_info("ldisc_install = 0");  				sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,  						NULL, "install"); +				/* this wait might be completed, though in the +				 * tty_close() since the ldisc is already +				 * installed */ +				err = wait_for_completion_timeout +					(&kim_gdata->ldisc_installed, +					 msecs_to_jiffies(LDISC_TIME)); +				err = -EINVAL;  				continue;  			} else {	/* on success don't retry */  				break; @@ -489,6 +516,8 @@ long st_kim_stop(void *kim_data)  {  	long err = 0;  	struct kim_data_s	*kim_gdata = (struct kim_data_s *)kim_data; +	struct ti_st_plat_data	*pdata = +		kim_gdata->kim_pdev->dev.platform_data;  	INIT_COMPLETION(kim_gdata->ldisc_installed); @@ -515,6 +544,10 @@ long st_kim_stop(void *kim_data)  	gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);  	mdelay(1);  	gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); + +	/* platform specific disable */ +	if (pdata->chip_disable) +		pdata->chip_disable(kim_gdata);  	return err;  }  |