예제 #1
0
int s5p_ehci_bus_resume(struct usb_hcd *hcd)
{
	/* When suspend is failed, re-enable clocks & PHY */
	pm_runtime_resume(hcd->self.controller);

	return bus_resume(hcd);
}
예제 #2
0
/**
 * int root_hub_feature(const u8 port, 
 *		     const u16 type_req, 
 *		     const u16 feature,
 *		     void* buf)
 * 
 * @brief Get port change bitmap information 
 * 
 * @param [IN] port : port number
 *	   [IN] type_req : request type of hub feature as usb 2.0 spec
 *	   [IN] feature : hub feature as usb 2.0 spec
 *	   [OUT] status : buffer to store results
 * 
 * @return USB_ERR_SUCCESS : If success \n
 *         USB_ERR_FAIL : If call fail \n
 *
 * @remark 
 * 
 */
__inline__ int root_hub_feature(const u8 port, 
		     const u16 type_req, 
		     const u16 feature,
		     void *buf)
{
	int retval = USB_ERR_SUCCESS;
	usb_hub_descriptor_t *desc = NULL;
	u32 port_status = 0;
	hprt_t hprt = {.d32 = 0};

	switch (type_req) 
	{
	case ClearHubFeature:
		otg_dbg(OTG_DBG_ROOTHUB,"case ClearHubFeature\n");
		switch (feature) 
		{
			case C_HUB_LOCAL_POWER:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearHubFeature -C_HUB_LOCAL_POWER \n");
				break;
			case C_HUB_OVER_CURRENT:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearHubFeature -C_HUB_OVER_CURRENT \n");
				/* Nothing required here */
				break;
			default:
				retval = USB_ERR_FAIL;
		}
		break;
		
	case ClearPortFeature:
		otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature\n");
		switch (feature) 
		{
			case USB_PORT_FEAT_ENABLE:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_ENABLE \n");
				hprt.b.prtena = 1;
				update_reg_32(HPRT, hprt.d32);
				break;
				
			case USB_PORT_FEAT_SUSPEND:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_SUSPEND \n");
				bus_resume();
				break;
				
			case USB_PORT_FEAT_POWER:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_POWER \n");
				hprt.b.prtpwr = 1;
				clear_reg_32(HPRT, hprt.d32);
				break;
				
			case USB_PORT_FEAT_INDICATOR:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_INDICATOR \n");
				/* Port inidicator not supported */
				break;

			case USB_PORT_FEAT_C_CONNECTION:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_C_CONNECTION \n");
				/* Clears drivers internal connect status change
				 * flag */
				port_flag.b.port_connect_status_change = 0;
				break;
				
			case USB_PORT_FEAT_C_RESET:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_C_RESET \n");
				/* Clears the driver's internal Port Reset Change
				 * flag */
				port_flag.b.port_reset_change = 0;
				break;
				
			case USB_PORT_FEAT_C_ENABLE:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_C_ENABLE \n");
				/* Clears the driver's internal Port
				 * Enable/Disable Change flag */
				port_flag.b.port_enable_change = 0;
				break;
				
			case USB_PORT_FEAT_C_SUSPEND:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_C_SUSPEND \n");
				/* Clears the driver's internal Port Suspend
				 * Change flag, which is set when resume signaling on
				 * the host port is complete */
				port_flag.b.port_suspend_change = 0;
				break;
				
			case USB_PORT_FEAT_C_OVER_CURRENT:
				otg_dbg(OTG_DBG_ROOTHUB,"case ClearPortFeature -USB_PORT_FEAT_C_OVER_CURRENT \n");
				port_flag.b.port_over_current_change = 0;
				break;
				
			default:
				retval = USB_ERR_FAIL;
		}
		break;
		
	case GetHubDescriptor:
		otg_dbg(OTG_DBG_ROOTHUB,"case GetHubDescriptor\n");
		desc = (usb_hub_descriptor_t *)buf;
		desc->desc_length = 9;
		desc->desc_type = 0x29;
		desc->port_number = 1;
		desc->hub_characteristics = 0x08;
		desc->power_on_to_power_good = 1;
		desc->hub_control_current = 0;
		desc->bitmap[0] = 0;
		desc->bitmap[1] = 0xff;
		break;

	case GetHubStatus:
		otg_dbg(OTG_DBG_ROOTHUB,"case GetHubStatus\n");
		otg_mem_set(buf, 0, 4);
		break;

	case GetPortStatus:
		//otg_dbg(OTG_DBG_ROOTHUB_KH,"case GetPortStatus\n");
		

		if (port_flag.b.port_connect_status_change)
			port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);

		if (port_flag.b.port_enable_change)
			port_status |= (1 << USB_PORT_FEAT_C_ENABLE);

		if (port_flag.b.port_suspend_change)
			port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);

		if (port_flag.b.port_reset_change)
			port_status|= (1 << USB_PORT_FEAT_C_RESET);

		if (port_flag.b.port_over_current_change) 
			port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
			

		if (!port_flag.b.port_connect_status) 
		{
			//
			// The port is disconnected, which means the core is
			// either in device mode or it soon will be. Just
			// return 0's for the remainder of the port status
			// since the port register can't be read if the core
			// is in device mode.
			
			 *((__le32*)buf) = cpu_to_le32(port_status);
			break;
		}
		
		
		hprt.d32 = read_reg_32(HPRT);

		if (hprt.b.prtconnsts) 
			port_status|= (1 << USB_PORT_FEAT_CONNECTION);

		if (hprt.b.prtena)
			port_status |= (1 << USB_PORT_FEAT_ENABLE);

		if (hprt.b.prtsusp)
			port_status |= (1 << USB_PORT_FEAT_SUSPEND);

		if (hprt.b.prtovrcurract)
			port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);

		if (hprt.b.prtrst)
			port_status |= (1 << USB_PORT_FEAT_RESET);

		if (hprt.b.prtpwr)
			port_status |= (1 << USB_PORT_FEAT_POWER);

		if (hprt.b.prtspd == 0)
			port_status |= (1 << USB_PORT_FEAT_HIGHSPEED);
		
		else if (hprt.b.prtspd == 2)
			port_status |= (1 << USB_PORT_FEAT_LOWSPEED);

		if (hprt.b.prttstctl)
			port_status |= (1 << USB_PORT_FEAT_TEST);

		*((__le32*)buf) = cpu_to_le32(port_status);
		break;
		
	case SetHubFeature:
		otg_dbg(OTG_DBG_ROOTHUB,"case SetHubFeature\n");
		/* No HUB features supported */
		break;
		
	case SetPortFeature:
		otg_dbg(OTG_DBG_ROOTHUB,"case SetPortFeature\n");
		if (!port_flag.b.port_connect_status) {
			/*
			 * The port is disconnected, which means the core is
			 * either in device mode or it soon will be. Just
			 * return without doing anything since the port
			 * register can't be written if the core is in device
			 * mode.
			 */
			break;
		}

		switch (feature) 
		{
			case USB_PORT_FEAT_SUSPEND:
				otg_dbg(OTG_DBG_ROOTHUB,"case SetPortFeature -USB_PORT_FEAT_SUSPEND \n");
				bus_suspend();
				break;
				
			case USB_PORT_FEAT_POWER:
				otg_dbg(OTG_DBG_ROOTHUB,"case SetPortFeature -USB_PORT_FEAT_POWER \n");
				hprt.d32 = read_reg_32(HPRT);		
				if(!hprt.b.prtpwr)
				{
					//hprt.d32 = 0;
					hprt.b.prtpwr = 1;
					write_reg_32(HPRT, hprt.d32);
				}
				break;

			case USB_PORT_FEAT_RESET:
				otg_dbg(OTG_DBG_ROOTHUB,"case SetPortFeature -USB_PORT_FEAT_RESET \n");
				retval = reset_and_enable_port(port);
				break;
				
			case USB_PORT_FEAT_INDICATOR:
				otg_dbg(OTG_DBG_ROOTHUB,"case USB_PORT_FEAT_INDICATOR\n");
				break;

			default : 
				retval = USB_ERR_FAIL;
				break;
		}		
		break;
	
	default:
		retval = USB_ERR_FAIL;
		otg_dbg(OTG_DBG_ROOTHUB,"root_hub_feature() Function Error\n");
		break;
	}
	if(retval != USB_ERR_SUCCESS)
		retval = USB_ERR_FAIL;
	return retval;
}

/**
 * void bus_suspend(void)
 * 
 * @brief Make suspend status when this platform support PM Mode
 * 
 * @param None
 * 
 * @return None
 *
 * @remark 
 * 
 */	
void bus_suspend(void)
{
	hprt_t	hprt;
	pcgcctl_t	pcgcctl;
	
	hprt.d32 = 0;
	pcgcctl.d32 = 0;

	hprt.b.prtsusp = 1;
	update_reg_32(HPRT, hprt.d32);

	pcgcctl.b.pwrclmp = 1;
	update_reg_32(PCGCCTL,pcgcctl.d32);
	udelay(1);

	pcgcctl.b.rstpdwnmodule = 1;
	update_reg_32(PCGCCTL,pcgcctl.d32);
	udelay(1);
	
	pcgcctl.b.stoppclk = 1;
	update_reg_32(PCGCCTL,pcgcctl.d32);
	udelay(1);
}