int mc_prepare_resume(int ms_time)
{
	int val;
	struct completion done;
	struct modemctl *mc = global_mc;

	if (!mc)
		return -EFAULT;
	/*before do ipc, we should check if modem is on or not.*/
	if(!mc_is_on())
		return -ENODEV;
	val = gpio_get_value(mc->gpio_ipc_slave_wakeup);
	if (val) {
		//gpio_set_value(mc->gpio_ipc_slave_wakeup, 0);
		smm6260_set_slave_wakeup(0);
		dev_info(mc->dev, "svn SLAV_WUP:reset\n");
	}
	val = gpio_get_value(mc->gpio_ipc_host_wakeup);
	if (val == HOST_WUP_LEVEL) {
		dev_info(mc->dev, "svn HOST_WUP:high!\n");
		return MC_HOST_HIGH;
	}

	init_completion(&done);
	mc->l2_done = &done;
	//gpio_set_value(mc->gpio_ipc_slave_wakeup, 1);
	smm6260_set_slave_wakeup(1);
	dev_dbg(mc->dev, "AP>>CP:  SLAV_WUP:1,%d\n",
		gpio_get_value(mc->gpio_ipc_slave_wakeup));

	if (!wait_for_completion_timeout(&done, ms_time)) {
			/*before do ipc, we should check if modem is on or not.*/
			if(!mc_is_on())
				return -ENODEV;
		val = gpio_get_value(mc->gpio_ipc_host_wakeup);
		if (val == HOST_WUP_LEVEL) {
			dev_err(mc->dev, "maybe complete late.. %d\n", ms_time);
			mc->l2_done = NULL;
			return MC_SUCCESS;
		}
		dev_err(mc->dev, "Modem wakeup timeout %d\n", ms_time);
		//gpio_set_value(mc->gpio_ipc_slave_wakeup, 0);
		smm6260_set_slave_wakeup(0);
		dev_dbg(mc->dev, "AP>>CP:  SLAV_WUP:0,%d\n",
			gpio_get_value(mc->gpio_ipc_slave_wakeup));
		mc->l2_done = NULL;
		return MC_HOST_TIMEOUT;
	}
	return MC_SUCCESS;
}
static irqreturn_t modem_resume_thread(int irq, void *dev_id)
{
	struct modemctl *mc = (struct modemctl *)dev_id;
	int val = gpio_get_value(mc->gpio_ipc_host_wakeup);
	int err;

	dev_err(mc->dev, "CP>>AP:  HOST_WUP:%d\n", val);
	//if(mc_get_ignore_cpirq())
		//return IRQ_HANDLED;
	if (val != HOST_WUP_LEVEL) {
		//gpio_set_value(mc->gpio_ipc_slave_wakeup, 0);
		smm6260_set_slave_wakeup(0);
		mc->debug_cnt = 0;
		return IRQ_HANDLED;
	}


	if (val == HOST_WUP_LEVEL) {
		if (mc->l2_done) {
			complete(mc->l2_done);
			mc->l2_done = NULL;
		}
		err = acm_request_resume();
		if (err < 0)
			dev_err(mc->dev, "request resume failed: %d\n", err);
		mc->debug_cnt++;
	}
	if (mc->debug_cnt > 30) {
		dev_err(mc->dev, "Abnormal Host wakeup -- over 30times");
		//disable_irq(irq);
		mc->debug_cnt = 0;
		if(mc->boot_done)
		{
			//mc->cpcrash_flag = 1;
			crash_event(MODEM_EVENT_CRASH);
		}		
		/*crash_event(SVNET_ERROR_CRASH);*/
		/*panic("HSIC Disconnected");*/
		//msleep(1000);
		//enable_irq(irq);
	}


	if (!val
		&& mc->wakeup_flag == HOST_WAKEUP_WAIT_RESET) {
		mc->wakeup_flag = HOST_WAKEUP_LOW;
		dev_err(mc->dev, "%s: wakeup flag (%d)\n",
			__func__, mc->wakeup_flag);
	}

	return IRQ_HANDLED;
}
Exemple #3
0
static int exynos4_usb_phy1_init(struct platform_device *pdev)
{
	struct clk *otg_clk;
	u32 phypwr;
	u32 phyclk;
	u32 rstcon;
	int err;
	struct completion done;
#ifdef CONFIG_USB_EHCI_S5P
	struct modemctl *mc =  global_mc;
#endif

/* add by cym 20120921 */
#ifdef CONFIG_USB_EHCI_S5P	
#ifdef CONFIG_SMM6260_MODEM
/* end add */

printk("[XJ] cp -> ap wakeup host: %d\n",smm6260_is_host_wakeup());

/* add by cym 20120921 */
#endif
#endif
/* end add */
	
#ifdef CONFIG_USB_EHCI_S5P	
#ifdef CONFIG_SMM6260_MODEM

		if (!smm6260_is_host_wakeup()) {
			smm6260_set_slave_wakeup(1);
		}
		
		if((mc != NULL)&&(mc->in_l3_state == 1)){
			init_completion(&done);
			mc->l3_done = &done;
	//		mc->transfer_flag=1;
			printk("---wait for wakeup go low no more than 0.5s\n");   //xujie temp
			if (!wait_for_completion_timeout(&done, 2*HZ)) {
				printk("completion wait timeout\n");
			}

		}


#endif
#endif

	otg_clk = clk_get(&pdev->dev, "usbotg");
	if (IS_ERR(otg_clk)) {
		dev_err(&pdev->dev, "Failed to get otg clock\n");
		return PTR_ERR(otg_clk);
	}

	err = clk_enable(otg_clk);
	if (err) {
		clk_put(otg_clk);
		return err;
	}

	if (soc_is_exynos4210()) {
		exynos4_usb_phy_control(USB_PHY1, PHY_ENABLE);
	} else {
		exynos4_usb_phy_control(USB_PHY
			| USB_PHY_HSIC0
			| USB_PHY_HSIC1,
			PHY_ENABLE);
	}

	atomic_inc(&host_usage);

	if (exynos4_usb_host_phy_is_on()) {
		dev_err(&pdev->dev, "Already power on PHY\n");
		clk_disable(otg_clk);
		clk_put(otg_clk);
		return 0;
	}

	/*
	 *  set XuhostOVERCUR to in-active by controlling ET6PUD[15:14]
	 *  0x0 : pull-up/down disabled
	 *  0x1 : pull-down enabled
	 *  0x2 : reserved
	 *  0x3 : pull-up enabled
	 */
	writel((__raw_readl(ETC6PUD) & ~(0x3 << 14)) | (0x3 << 14),
		ETC6PUD);

	/* set clock frequency for PLL */
	phyclk = exynos4_usb_phy_set_clock(pdev);
	writel(phyclk, EXYNOS4_PHYCLK);

	phypwr = readl(EXYNOS4_PHYPWR);
	/* set to normal HSIC 0 and 1 of PHY1 */
	if (soc_is_exynos4210()) {
		phypwr &= ~(PHY1_STD_NORMAL_MASK
			| EXYNOS4210_HSIC0_NORMAL_MASK
			| EXYNOS4210_HSIC1_NORMAL_MASK);
		writel(phypwr, EXYNOS4_PHYPWR);

		/* floating prevention logic: disable */
		writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);

		/* reset all ports of both PHY and Link */
		rstcon = readl(EXYNOS4_RSTCON)
			| EXYNOS4210_HOST_LINK_PORT_SWRST_MASK
			| EXYNOS4210_PHY1_SWRST_MASK;
		writel(rstcon, EXYNOS4_RSTCON);
		udelay(10);

		rstcon &= ~(EXYNOS4210_HOST_LINK_PORT_SWRST_MASK
			| EXYNOS4210_PHY1_SWRST_MASK);
		writel(rstcon, EXYNOS4_RSTCON);
	} else {
		/* USB MUX change from Device to Host */
		exynos_usb_mux_change(pdev, 1);

		phypwr &= ~(PHY1_STD_NORMAL_MASK
			| EXYNOS4212_HSIC0_NORMAL_MASK
			| EXYNOS4212_HSIC1_NORMAL_MASK);
		writel(phypwr, EXYNOS4_PHYPWR);

		/* reset all ports of both PHY and Link */
		rstcon = readl(EXYNOS4_RSTCON)
			| EXYNOS4212_HOST_LINK_PORT_SWRST_MASK
			| EXYNOS4212_PHY1_SWRST_MASK;
		writel(rstcon, EXYNOS4_RSTCON);
		udelay(10);

		rstcon &= ~(EXYNOS4212_HOST_LINK_PORT_SWRST_MASK
			| EXYNOS4212_PHY1_SWRST_MASK);
		writel(rstcon, EXYNOS4_RSTCON);
	}
	udelay(80);
#ifdef CONFIG_USB_EHCI_S5P
/* modify by cym 20141010 */
#if 0
	usb_hub_gpio_init();// liang
#else
#ifndef CONFIG_USB_EXYNOS_SWITCH
	usb_hub_gpio_init();
#endif
#endif
/* end modify */
#endif

	clk_disable(otg_clk);
	clk_put(otg_clk);
	//exynos_usb_mux_change(pdev, 0);//wjp for device function
	return 0;
}