diff options
Diffstat (limited to 'drivers/usb/phy/phy-fsl-usb.c')
| -rw-r--r-- | drivers/usb/phy/phy-fsl-usb.c | 104 | 
1 files changed, 79 insertions, 25 deletions
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index fa7c9f9628b..2b0f968d932 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -27,7 +27,6 @@  #include <linux/slab.h>  #include <linux/proc_fs.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/timer.h> @@ -134,7 +133,7 @@ int write_ulpi(u8 addr, u8 data)  /* Operations that will be called from OTG Finite State Machine */  /* Charge vbus for vbus pulsing in SRP */ -void fsl_otg_chrg_vbus(int on) +void fsl_otg_chrg_vbus(struct otg_fsm *fsm, int on)  {  	u32 tmp; @@ -170,7 +169,7 @@ void fsl_otg_dischrg_vbus(int on)  }  /* A-device driver vbus, controlled through PP bit in PORTSC */ -void fsl_otg_drv_vbus(int on) +void fsl_otg_drv_vbus(struct otg_fsm *fsm, int on)  {  	u32 tmp; @@ -188,7 +187,7 @@ void fsl_otg_drv_vbus(int on)   * Pull-up D+, signalling connect by periperal. Also used in   * data-line pulsing in SRP   */ -void fsl_otg_loc_conn(int on) +void fsl_otg_loc_conn(struct otg_fsm *fsm, int on)  {  	u32 tmp; @@ -207,7 +206,7 @@ void fsl_otg_loc_conn(int on)   * port.  In host mode, controller will automatically send SOF.   * Suspend will block the data on the port.   */ -void fsl_otg_loc_sof(int on) +void fsl_otg_loc_sof(struct otg_fsm *fsm, int on)  {  	u32 tmp; @@ -222,7 +221,7 @@ void fsl_otg_loc_sof(int on)  }  /* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ -void fsl_otg_start_pulse(void) +void fsl_otg_start_pulse(struct otg_fsm *fsm)  {  	u32 tmp; @@ -235,7 +234,7 @@ void fsl_otg_start_pulse(void)  	fsl_otg_loc_conn(1);  #endif -	fsl_otg_add_timer(b_data_pulse_tmr); +	fsl_otg_add_timer(fsm, b_data_pulse_tmr);  }  void b_data_pulse_end(unsigned long foo) @@ -252,14 +251,14 @@ void b_data_pulse_end(unsigned long foo)  void fsl_otg_pulse_vbus(void)  {  	srp_wait_done = 0; -	fsl_otg_chrg_vbus(1); +	fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 1);  	/* start the timer to end vbus charge */ -	fsl_otg_add_timer(b_vbus_pulse_tmr); +	fsl_otg_add_timer(&fsl_otg_dev->fsm, b_vbus_pulse_tmr);  }  void b_vbus_pulse_end(unsigned long foo)  { -	fsl_otg_chrg_vbus(0); +	fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 0);  	/*  	 * As USB3300 using the same a_sess_vld and b_sess_vld voltage @@ -267,7 +266,7 @@ void b_vbus_pulse_end(unsigned long foo)  	 * residual voltage of vbus pulsing and A device pull up  	 */  	fsl_otg_dischrg_vbus(1); -	fsl_otg_add_timer(b_srp_wait_tmr); +	fsl_otg_add_timer(&fsl_otg_dev->fsm, b_srp_wait_tmr);  }  void b_srp_end(unsigned long foo) @@ -289,7 +288,7 @@ void a_wait_enum(unsigned long foo)  {  	VDBG("a_wait_enum timeout\n");  	if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) -		fsl_otg_add_timer(a_wait_enum_tmr); +		fsl_otg_add_timer(&fsl_otg_dev->fsm, a_wait_enum_tmr);  	else  		otg_statemachine(&fsl_otg_dev->fsm);  } @@ -375,8 +374,42 @@ void fsl_otg_uninit_timers(void)  	kfree(b_vbus_pulse_tmr);  } +static struct fsl_otg_timer *fsl_otg_get_timer(enum otg_fsm_timer t) +{ +	struct fsl_otg_timer *timer; + +	/* REVISIT: use array of pointers to timers instead */ +	switch (t) { +	case A_WAIT_VRISE: +		timer = a_wait_vrise_tmr; +		break; +	case A_WAIT_BCON: +		timer = a_wait_vrise_tmr; +		break; +	case A_AIDL_BDIS: +		timer = a_wait_vrise_tmr; +		break; +	case B_ASE0_BRST: +		timer = a_wait_vrise_tmr; +		break; +	case B_SE0_SRP: +		timer = a_wait_vrise_tmr; +		break; +	case B_SRP_FAIL: +		timer = a_wait_vrise_tmr; +		break; +	case A_WAIT_ENUM: +		timer = a_wait_vrise_tmr; +		break; +	default: +		timer = NULL; +	} + +	return timer; +} +  /* Add timer to timer list */ -void fsl_otg_add_timer(void *gtimer) +void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer)  {  	struct fsl_otg_timer *timer = gtimer;  	struct fsl_otg_timer *tmp_timer; @@ -394,8 +427,19 @@ void fsl_otg_add_timer(void *gtimer)  	list_add_tail(&timer->list, &active_timers);  } +static void fsl_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) +{ +	struct fsl_otg_timer *timer; + +	timer = fsl_otg_get_timer(t); +	if (!timer) +		return; + +	fsl_otg_add_timer(fsm, timer); +} +  /* Remove timer from the timer list; clear timeout status */ -void fsl_otg_del_timer(void *gtimer) +void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer)  {  	struct fsl_otg_timer *timer = gtimer;  	struct fsl_otg_timer *tmp_timer, *del_tmp; @@ -405,6 +449,17 @@ void fsl_otg_del_timer(void *gtimer)  			list_del(&timer->list);  } +static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) +{ +	struct fsl_otg_timer *timer; + +	timer = fsl_otg_get_timer(t); +	if (!timer) +		return; + +	fsl_otg_del_timer(fsm, timer); +} +  /*   * Reduce timer count by 1, and find timeout conditions.   * Called by fsl_otg 1ms timer interrupt @@ -468,7 +523,7 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on)  				retval = dev->driver->pm->resume(dev);  				if (fsm->id) {  					/* default-b */ -					fsl_otg_drv_vbus(1); +					fsl_otg_drv_vbus(fsm, 1);  					/*  					 * Workaround: b_host can't driver  					 * vbus, but PP in PORTSC needs to @@ -493,7 +548,7 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on)  					retval = dev->driver->pm->suspend(dev);  				if (fsm->id)  					/* default-b */ -					fsl_otg_drv_vbus(0); +					fsl_otg_drv_vbus(fsm, 0);  			}  			otg_dev->host_working = 0;  		} @@ -757,8 +812,8 @@ static struct otg_fsm_ops fsl_otg_ops = {  	.loc_sof = fsl_otg_loc_sof,  	.start_pulse = fsl_otg_start_pulse, -	.add_timer = fsl_otg_add_timer, -	.del_timer = fsl_otg_del_timer, +	.add_timer = fsl_otg_fsm_add_timer, +	.del_timer = fsl_otg_fsm_del_timer,  	.start_host = fsl_otg_start_host,  	.start_gadget = fsl_otg_start_gadget, @@ -792,7 +847,7 @@ static int fsl_otg_conf(struct platform_device *pdev)  		pr_info("Couldn't init OTG timers\n");  		goto err;  	} -	spin_lock_init(&fsl_otg_tc->fsm.lock); +	mutex_init(&fsl_otg_tc->fsm.lock);  	/* Set OTG state machine operations */  	fsl_otg_tc->fsm.ops = &fsl_otg_ops; @@ -961,10 +1016,9 @@ static int show_fsl_usb2_otg_state(struct device *dev,  	struct otg_fsm *fsm = &fsl_otg_dev->fsm;  	char *next = buf;  	unsigned size = PAGE_SIZE; -	unsigned long flags;  	int t; -	spin_lock_irqsave(&fsm->lock, flags); +	mutex_lock(&fsm->lock);  	/* basic driver infomation */  	t = scnprintf(next, size, @@ -1011,7 +1065,7 @@ static int show_fsl_usb2_otg_state(struct device *dev,  			"b_bus_suspend: %d\n"  			"b_conn: %d\n"  			"b_se0_srp: %d\n" -			"b_sess_end: %d\n" +			"b_ssend_srp: %d\n"  			"b_sess_vld: %d\n"  			"id: %d\n",  			fsm->a_bus_req, @@ -1026,13 +1080,13 @@ static int show_fsl_usb2_otg_state(struct device *dev,  			fsm->b_bus_suspend,  			fsm->b_conn,  			fsm->b_se0_srp, -			fsm->b_sess_end, +			fsm->b_ssend_srp,  			fsm->b_sess_vld,  			fsm->id);  	size -= t;  	next += t; -	spin_unlock_irqrestore(&fsm->lock, flags); +	mutex_unlock(&fsm->lock);  	return PAGE_SIZE - size;  } @@ -1057,7 +1111,7 @@ static long fsl_otg_ioctl(struct file *file, unsigned int cmd,  		break;  	case SET_A_SUSPEND_REQ: -		fsl_otg_dev->fsm.a_suspend_req = arg; +		fsl_otg_dev->fsm.a_suspend_req_inf = arg;  		break;  	case SET_A_BUS_DROP:  | 
