示例#1
0
static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct ucc_geth_private *ugeth = netdev_priv(netdev);
	struct phy_device *phydev = ugeth->phydev;

	if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
		return -EINVAL;
	else if (wol->wolopts & WAKE_PHY && (!phydev || !phydev->irq))
		return -EINVAL;
	else if (wol->wolopts & WAKE_MAGIC && !qe_alive_during_sleep())
		return -EINVAL;

	ugeth->wol_en = wol->wolopts;
	device_set_wakeup_enable(&netdev->dev, ugeth->wol_en);

	return 0;
}
示例#2
0
static int hcd_pci_suspend_noirq(struct device *dev)
{
	struct pci_dev		*pci_dev = to_pci_dev(dev);
	struct usb_hcd		*hcd = pci_get_drvdata(pci_dev);
	int			retval;

	retval = check_root_hub_suspended(dev);
	if (retval)
		return retval;

	pci_save_state(pci_dev);

	/* If the root hub is HALTed rather than SUSPENDed,
	 * disallow remote wakeup.
	 */
	if (hcd->state == HC_STATE_HALT)
		device_set_wakeup_enable(dev, 0);
	dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev));

	/* Possibly enable remote wakeup,
	 * choose the appropriate low-power state, and go to that state.
	 */
	retval = pci_prepare_to_sleep(pci_dev);
	if (retval == -EIO) {		/* Low-power not supported */
		dev_dbg(dev, "--> PCI D0 legacy\n");
		retval = 0;
	} else if (retval == 0) {
		dev_dbg(dev, "--> PCI %s\n",
				pci_power_name(pci_dev->current_state));
	} else {
		suspend_report_result(pci_prepare_to_sleep, retval);
		return retval;
	}

#ifdef CONFIG_PPC_PMAC
	/* Disable ASIC clocks for USB */
	if (machine_is(powermac)) {
		struct device_node	*of_node;

		of_node = pci_device_to_OF_node(pci_dev);
		if (of_node)
			pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
	}
#endif
	return retval;
}
示例#3
0
文件: phy-am335x.c 项目: 3null/linux
static int am335x_phy_probe(struct platform_device *pdev)
{
	struct am335x_phy *am_phy;
	struct device *dev = &pdev->dev;
	int ret;

	am_phy = devm_kzalloc(dev, sizeof(*am_phy), GFP_KERNEL);
	if (!am_phy)
		return -ENOMEM;

	am_phy->phy_ctrl = am335x_get_phy_control(dev);
	if (!am_phy->phy_ctrl)
		return -EPROBE_DEFER;
	am_phy->id = of_alias_get_id(pdev->dev.of_node, "phy");
	if (am_phy->id < 0) {
		dev_err(&pdev->dev, "Missing PHY id: %d\n", am_phy->id);
		return am_phy->id;
	}

	ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL);
	if (ret)
		return ret;

	ret = usb_add_phy_dev(&am_phy->usb_phy_gen.phy);
	if (ret)
		return ret;
	am_phy->usb_phy_gen.phy.init = am335x_init;
	am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown;

	platform_set_drvdata(pdev, am_phy);
	device_init_wakeup(dev, true);

	/*
	 * If we leave PHY wakeup enabled then AM33XX wakes up
	 * immediately from DS0. To avoid this we mark dev->power.can_wakeup
	 * to false. The same is checked in suspend routine to decide
	 * on whether to enable PHY wakeup or not.
	 * PHY wakeup works fine in standby mode, there by allowing us to
	 * handle remote wakeup, wakeup on disconnect and connect.
	 */

	device_set_wakeup_enable(dev, false);
	phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false);

	return 0;
}
static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct atl1c_adapter *adapter = netdev_priv(netdev);

	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
			    WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
		return -EOPNOTSUPP;
	/* these settings will always override what we currently have */
	adapter->wol = 0;

	if (wol->wolopts & WAKE_MAGIC)
		adapter->wol |= AT_WUFC_MAG;
	if (wol->wolopts & WAKE_PHY)
		adapter->wol |= AT_WUFC_LNKC;

	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);

	return 0;
}
示例#5
0
static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct atl1e_adapter *adapter = netdev_priv(netdev);

	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
			    WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
		return -EOPNOTSUPP;
	
	adapter->wol = 0;

	if (wol->wolopts & WAKE_MAGIC)
		adapter->wol |= AT_WUFC_MAG;
	if (wol->wolopts & WAKE_PHY)
		adapter->wol |= AT_WUFC_LNKC;

	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);

	return 0;
}
示例#6
0
static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
	struct gfar_private *priv = netdev_priv(dev);
	unsigned long flags;

	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
	    wol->wolopts != 0)
		return -EINVAL;

	if (wol->wolopts & ~WAKE_MAGIC)
		return -EINVAL;

	spin_lock_irqsave(&priv->bflock, flags);
	priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
	device_set_wakeup_enable(&dev->dev, priv->wol_en);
	spin_unlock_irqrestore(&priv->bflock, flags);

	return 0;
}
int __init n1_sdhci_init(void)
{
	if(system_rev >= BOARD_REV08)
#if defined CONFIG_MACH_BOSE_ATT
		tegra_sdhci_platform_data2.cd_gpio = 0xffff;
#else
		tegra_sdhci_platform_data2.cd_gpio = -1;
#endif
	platform_device_register(&tegra_sdhci_device3);
	platform_device_register(&tegra_sdhci_device2);
	platform_device_register(&tegra_sdhci_device0);

	device_init_wakeup(&tegra_sdhci_device0.dev, 1);
	device_set_wakeup_enable(&tegra_sdhci_device0.dev, 0);

	tegra_sdhci_device0_ptr = &tegra_sdhci_device0;

	n1_wifi_init();
	return 0;
}
示例#8
0
static int stm_sbc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
	int ret = 0;
	unsigned long lpt;
	struct stm_sbc_rtc *rtc = dev_get_drvdata(dev);

	rtc_tm_to_time(&t->time, &lpt);
	lpt = lpt - get_time_in_sec();
	rtc_time_to_tm(lpt, &t->time);

	memcpy(&rtc->alarm, t, sizeof(struct rtc_wkalrm));

	ret = stm_lpm_set_wakeup_time(lpt);
	if (ret < 0)
		return ret;

	device_set_wakeup_enable(dev, true);

	return 0;
}
示例#9
0
static int __init gtablet_wifi_init(void)
{
        wifi_32k_clk = clk_get_sys(NULL, "blink");
        if (IS_ERR(wifi_32k_clk)) {
                pr_err("%s: unable to get blink clock\n", __func__);
                return PTR_ERR(wifi_32k_clk);
        }
        tegra_gpio_enable(GTABLET_WLAN_POWER);
        tegra_gpio_enable(GTABLET_WLAN_RESET);

	gpio_request(GTABLET_WLAN_POWER, "wifi_power");
	gpio_request(GTABLET_WLAN_RESET, "wifi_reset");
        gpio_direction_output(GTABLET_WLAN_POWER, 0);
        gpio_direction_output(GTABLET_WLAN_RESET, 0);

        platform_device_register(&gtablet_wifi_device);

        device_init_wakeup(&gtablet_wifi_device.dev, 1);
        device_set_wakeup_enable(&gtablet_wifi_device.dev, 0);

        return 0;
}
static int __init ventana_wifi_init(void)
{
	wifi_32k_clk = clk_get_sys(NULL, "blink");
	if (IS_ERR(wifi_32k_clk)) {
		pr_err("%s: unable to get blink clock\n", __func__);
		return PTR_ERR(wifi_32k_clk);
	}

#if defined(CONFIG_BCM4329_HW_OOB) || defined(CONFIG_BCM4329_OOB_INTR_ONLY)
       gpio_request(VENTANA_WLAN_IRQ,"oob irq");
       tegra_gpio_enable(VENTANA_WLAN_IRQ);
       gpio_direction_input(VENTANA_WLAN_IRQ);
#endif //CONFIG_BCM4329_HW_OOB || CONFIG_BCM4329_OOB_INTR_ONLY


	gpio_request(VENTANA_WLAN_PWR, "wlan_power");
	gpio_request(VENTANA_WLAN_RST, "wlan_rst");

	tegra_gpio_enable(VENTANA_WLAN_PWR);
	tegra_gpio_enable(VENTANA_WLAN_RST);

	gpio_direction_output(VENTANA_WLAN_PWR, 0);
	gpio_direction_output(VENTANA_WLAN_RST, 0);

#if defined(CONFIG_MACH_ACER_PICASSO_E)
	gpio_request(VENTANA_BCM_VDD, "bcm_vdd");
	tegra_gpio_enable(VENTANA_BCM_VDD);
	gpio_direction_output(VENTANA_BCM_VDD, 0);
#endif
	platform_device_register(&ventana_wifi_device);

	device_init_wakeup(&ventana_wifi_device.dev, 1);
	device_set_wakeup_enable(&ventana_wifi_device.dev, 0);

#if defined(CONFIG_MACH_ACER_PICASSO_E)
	disable_wifi_sdio_func();
#endif
	return 0;
}
示例#11
0
static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct ixgbe_adapter *adapter = netdev_priv(netdev);

	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
		return -EOPNOTSUPP;

	adapter->wol = 0;

	if (wol->wolopts & WAKE_UCAST)
		adapter->wol |= IXGBE_WUFC_EX;
	if (wol->wolopts & WAKE_MCAST)
		adapter->wol |= IXGBE_WUFC_MC;
	if (wol->wolopts & WAKE_BCAST)
		adapter->wol |= IXGBE_WUFC_BC;
	if (wol->wolopts & WAKE_MAGIC)
		adapter->wol |= IXGBE_WUFC_MAG;

	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);

	return 0;
}
示例#12
0
static int __init picasso_wifi_init(void)
{
	wifi_32k_clk = clk_get_sys(NULL, "blink");
	if (IS_ERR(wifi_32k_clk)) {
		pr_err("%s: unable to get blink clock\n", __func__);
		return PTR_ERR(wifi_32k_clk);
	}

	gpio_request(VENTANA_WLAN_PWR, "wlan_power");
	gpio_request(VENTANA_WLAN_RST, "wlan_rst");
	gpio_request(VENTANA_WLAN_WOW, "bcmsdh_sdmmc");

	gpio_direction_output(VENTANA_WLAN_PWR, 0);
	gpio_direction_output(VENTANA_WLAN_RST, 0);
	gpio_direction_input(VENTANA_WLAN_WOW);

	platform_device_register(&picasso_wifi_device);

	device_init_wakeup(&picasso_wifi_device.dev, 1);
	device_set_wakeup_enable(&picasso_wifi_device.dev, 0);

	return 0;
}
示例#13
0
static int i40e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_pf *pf = np->vsi->back;
	struct i40e_hw *hw = &pf->hw;
	u16 wol_nvm_bits;

	/* NVM bit on means WoL disabled for the port */
	i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
	if (((1 << hw->port) & wol_nvm_bits))
		return -EOPNOTSUPP;

	/* only magic packet is supported */
	if (wol->wolopts && (wol->wolopts != WAKE_MAGIC))
		return -EOPNOTSUPP;

	/* is this a new value? */
	if (pf->wol_en != !!wol->wolopts) {
		pf->wol_en = !!wol->wolopts;
		device_set_wakeup_enable(&pf->pdev->dev, pf->wol_en);
	}

	return 0;
}
static int __init p3_wifi_init(void)
{
	printk(KERN_INFO "%s: start\n", __func__);
	wifi_32k_clk = clk_get_sys(NULL, "blink");
	if (IS_ERR(wifi_32k_clk)) {
		pr_err("%s: unable to get blink clock\n", __func__);
		return PTR_ERR(wifi_32k_clk);
	}

	gpio_request(GPIO_WLAN_EN, "wlan_power");
	tegra_gpio_enable(GPIO_WLAN_EN);
	gpio_direction_output(GPIO_WLAN_EN, 0);

#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
	brcm_init_wlan_mem();
#endif

	platform_device_register(&p3_wifi_device);

	device_init_wakeup(&p3_wifi_device.dev, 1);
	device_set_wakeup_enable(&p3_wifi_device.dev, 0);

	return 0;
}
示例#15
0
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;
	unsigned int		i, unet_id, rdev_cnt, n = 0;
	bool			mux;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	mux = test_bit(info->data, &mux_enabled);
	
	if (prod->idProduct == 0x908a)
		mux = true;
	else
		mux = false;

	mux_enabled_per_pid = mux;
	
	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;
	info->in = 0;

	for (n = 0; n < rdev_cnt; n++) {

		info->in++;
		status = usbnet_probe(iface, prod);
		if (status < 0) {
			dev_err(&iface->dev, "usbnet_probe failed %d\n",
					status);
			goto out;
		}

		unet_id = n + info->data * no_rmnet_insts_per_dev;

		unet_list[unet_id] = unet = usb_get_intfdata(iface);

		
		unet->data[3] = n;

		
		unet->data[1] = unet->data[4] = mux;

		
		set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

		
		rmnet_usb_setup(unet->net, mux);

		
		status = device_create_file(&unet->net->dev,
				&dev_attr_dbg_mask);
		if (status) {
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
				&unet->data[1]);
		if (status) {
			device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_data_debugfs_init(unet);
		if (status)
			dev_dbg(&iface->dev,
					"mode debugfs file is not available\n");
	}
	
	

	if (udev->parent && !udev->parent->parent) {
		
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);

		
		pm_runtime_set_autosuspend_delay(&udev->dev, 1000);
		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);

		#if defined(CONFIG_MONITOR_STREAMING_PORT_SOCKET) && defined(CONFIG_MSM_NONSMD_PACKET_FILTER)
		original_autosuspend_timer = udev->dev.power.autosuspend_delay;
		dev_info(&udev->dev, "original_autosuspend_timer:%d\n", original_autosuspend_timer);
		#endif 
	}

	return 0;

out:
	for (i = 0; i < n; i++) {
		
		unet_id = i + info->data * no_rmnet_insts_per_dev;
		unet = unet_list[unet_id];
		dev = (struct rmnet_ctrl_dev *)unet->data[1];

		rmnet_usb_data_debugfs_cleanup(unet);
		rmnet_usb_ctrl_disconnect(dev);
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usb_set_intfdata(iface, unet_list[unet_id]);
		usbnet_disconnect(iface);
		unet_list[unet_id] = NULL;
	}

	return status;
}
示例#16
0
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info;
	struct usb_device	*udev;
	unsigned int		iface_num;
	static int		first_rmnet_iface_num = -EINVAL;
	int			status = 0;

	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	info = (struct driver_info *)prod->driver_info;
	if (!test_bit(iface_num, &info->data))
		return -ENODEV;

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&iface->dev, "usbnet_probe failed %d\n", status);
		goto out;
	}
	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
	if (status)
		goto out;

	if (first_rmnet_iface_num == -EINVAL)
		first_rmnet_iface_num = iface_num;

	/*save control device intstance */
	unet->data[1] = (unsigned long)ctrl_dev	\
			[iface_num - first_rmnet_iface_num];

	status = rmnet_usb_ctrl_probe(iface, unet->status,
		(struct rmnet_ctrl_dev *)unet->data[1]);
	if (status)
		goto out;

//ASUS_BSP+++ BennyCheng "fix rmnet driver probe fail with user build"
#ifdef CONFIG_DEBUG_FS
	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&iface->dev, "mode debugfs file is not available\n");
#endif
//ASUS_BSP--- BennyCheng "fix rmnet driver probe fail with user build"

	udev = unet->udev;

	usb_enable_autosuspend(udev);

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);

		/* set default autosuspend timeout for modem and roothub */
		//ASUS_BSP+++ BennyCheng "extend hsic autosuspend delay time from 1s to 2s"
		pm_runtime_set_autosuspend_delay(&udev->dev, 2000);
		//ASUS_BSP--- BennyCheng "extend hsic autosuspend delay time from 1s to 2s"
		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);
	}

out:
	return status;
}
/*
 * We need to register our own PCI probe function (instead of the USB core's
 * function) in order to create a second roothub under xHCI.
 */
static int xhci_ush_pci_probe(struct pci_dev *dev,
		const struct pci_device_id *id)
{
	int retval;
	struct xhci_hcd *xhci;
	struct hc_driver *driver;
	struct usb_hcd *hcd;

	driver = (struct hc_driver *)id->driver_data;
	pci_dev = dev;

	/* AUX GPIO init */
	retval = hsic_aux_gpio_init();
	if (retval < 0) {
		dev_err(&dev->dev, "AUX GPIO init fail\n");
		retval = -ENODEV;
	}

	/* AUX GPIO init */
	retval = hsic_wakeup_gpio_init();
	if (retval < 0) {
		dev_err(&dev->dev, "Wakeup GPIO init fail\n");
		retval = -ENODEV;
	}

	/* Register the USB 2.0 roothub.
	 * FIXME: USB core must know to register the USB 2.0 roothub first.
	 * This is sort of silly, because we could just set the HCD driver flags
	 * to say USB 2.0, but I'm not sure what the implications would be in
	 * the other parts of the HCD code.
	 */
	retval = usb_hcd_pci_probe(dev, id);
	if (retval)
		return retval;

	/* USB 2.0 roothub is stored in the PCI device now. */
	hcd = dev_get_drvdata(&dev->dev);
	xhci = hcd_to_xhci(hcd);
	xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev,
				pci_name(dev), hcd);
	if (!xhci->shared_hcd) {
		retval = -ENOMEM;
		goto dealloc_usb2_hcd;
	}

	/* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset)
	 * is called by usb_add_hcd().
	 */
	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;

	if (hsic.hsic_enable_created == 0) {
		retval = create_device_files();
		if (retval < 0) {
			dev_dbg(&dev->dev, "error create device files\n");
			goto dealloc_usb2_hcd;
		}

		hsic.hsic_enable_created = 1;
	}

	if (hsic.hsic_mutex_init == 0) {
		mutex_init(&hsic.hsic_mutex);
		hsic.hsic_mutex_init = 1;
	}

	if (hsic.aux_wq_init == 0) {
		init_waitqueue_head(&hsic.aux_wq);
		hsic.aux_wq_init = 1;
	}

	hsic.work_queue = create_singlethread_workqueue("hsic");
	INIT_WORK(&hsic.wakeup_work, wakeup_work);
	INIT_DELAYED_WORK(&(hsic.hsic_aux), hsic_aux_work);

	retval = usb_add_hcd(xhci->shared_hcd, dev->irq,
			IRQF_SHARED);
	if (retval)
		goto put_usb3_hcd;
	/* Roothub already marked as USB 3.0 speed */

	/* Enable Controller wakeup capability */
	device_set_wakeup_enable(&dev->dev, true);

	/* Enable runtime pm ability */
	hcd->rpm_control = 1;
	hcd->rpm_resume = 0;
	pm_runtime_set_active(&dev->dev);

	/* Check here to avoid to call pm_runtime_put_noidle() twice */
	if (!pci_dev_run_wake(dev))
		pm_runtime_put_noidle(&dev->dev);

	pm_runtime_allow(&dev->dev);
	hsic.hsic_stopped = 0;
	hsic_enable = 1;
	return 0;

put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);
dealloc_usb2_hcd:
	usb_hcd_pci_remove(dev);
	return retval;
}
示例#18
0
/* ==========================================================================*/
static void __init ambarella_init_boss(void)
{
	int					i;
	int					use_bub_default = 1;
	int					wm8994_inited = 0;
	ambarella_init_machine("Boss");
	if (AMBARELLA_BOARD_TYPE(system_rev) == AMBARELLA_BOARD_TYPE_EVK) {
		switch (AMBARELLA_BOARD_REV(system_rev)) {
			case 'C':
				wm8994_inited = 1;
			case 'B':
#if !defined(CONFIG_AMBARELLA_IPC)
				ambarella_platform_sd_controller1.slot[0].ext_power.gpio_id = GPIO(111);
#endif
				ambarella_platform_sd_controller1.slot[0].ext_power.active_level = GPIO_HIGH;
				ambarella_platform_sd_controller1.slot[0].ext_power.active_delay = 300;
				if(0 == wm8994_inited) {
					/* the cs_pin of spi0.1 is used to determine wm8994's
					 * I2C address, and the cs_pin of spi0.4, spi0,5, spi0.6
					 * spi0.7 are used as I2S signals, so we need to prevent
					 * them from be modified by SPI driver */
					ambarella_spi0_cs_pins[1] = -1;
					ambarella_spi0_cs_pins[4] = -1;
					ambarella_spi0_cs_pins[5] = -1;
					ambarella_spi0_cs_pins[6] = -1;
					ambarella_spi0_cs_pins[7] = -1;
					ambarella_init_wm8994();
				}
			case 'A':
				ambarella_board_generic.touch_panel_irq.irq_gpio = GPIO(44);
				ambarella_board_generic.touch_panel_irq.irq_line = gpio_to_irq(44);
				ambarella_board_generic.touch_panel_irq.irq_type = IRQF_TRIGGER_FALLING;
				ambarella_board_generic.touch_panel_irq.irq_gpio_val = GPIO_LOW;
				ambarella_board_generic.touch_panel_irq.irq_gpio_mode = GPIO_FUNC_SW_INPUT;

				ambarella_board_generic.wifi_power.gpio_id = GPIO(109);
				ambarella_board_generic.wifi_power.active_level = GPIO_HIGH;
				ambarella_board_generic.wifi_power.active_delay = 300;
				ambarella_board_generic.wifi_sd_bus = 0;
				ambarella_board_generic.wifi_sd_slot = 1;

				ambarella_board_generic.pmic_irq.irq_gpio = GPIO(54);
				ambarella_board_generic.pmic_irq.irq_line = gpio_to_irq(54);
				ambarella_board_generic.pmic_irq.irq_type = IRQF_TRIGGER_FALLING;
				ambarella_board_generic.pmic_irq.irq_gpio_val = GPIO_LOW;
				ambarella_board_generic.pmic_irq.irq_gpio_mode = GPIO_FUNC_SW_INPUT;

				ambarella_board_generic.power_control.gpio_id = GPIO(120);
				ambarella_board_generic.power_control.active_level = GPIO_LOW;

				memcpy(ambarella_spi_devices[12].modalias, "wm8310", 6);
				ambarella_spi_devices[12].max_speed_hz = 500000;
				ambarella_spi_devices[12].platform_data = &boss_wm8310_pdata;

				ambarella_platform_sd_controller0.clk_limit = 24000000;
				ambarella_platform_sd_controller0.slot[0].use_bounce_buffer = 1;
				ambarella_platform_sd_controller0.slot[0].max_blk_sz = SD_BLK_SZ_128KB;
				ambarella_platform_sd_controller0.slot[0].cd_delay = 100;
				ambarella_platform_sd_controller0.slot[0].fixed_cd = 0;
				ambarella_platform_sd_controller0.slot[0].gpio_cd.irq_gpio = -1;
				ambarella_platform_sd_controller0.slot[0].gpio_cd.irq_line = -1;
				ambarella_platform_sd_controller0.slot[0].fixed_wp = 0;
				ambarella_platform_sd_controller0.slot[0].gpio_wp.gpio_id = -1;
				ambarella_platform_sd_controller0.slot[0].ext_power.gpio_id = GPIO(157);
				ambarella_platform_sd_controller0.slot[0].ext_power.active_level = GPIO_HIGH;
				ambarella_platform_sd_controller0.slot[0].ext_power.active_delay = 300;
				ambarella_platform_sd_controller0.slot[1].use_bounce_buffer = 1;
				ambarella_platform_sd_controller0.slot[1].max_blk_sz = SD_BLK_SZ_128KB;
				ambarella_platform_sd_controller0.slot[1].cd_delay = 100;
				ambarella_platform_sd_controller0.slot[1].fixed_cd = 0;
				ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_gpio = -1;
				ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_line = -1;
				ambarella_platform_sd_controller0.slot[1].fixed_wp = 0;
				ambarella_platform_sd_controller0.slot[1].gpio_wp.gpio_id = -1;
				ambarella_platform_sd_controller1.clk_limit = 25000000;
				ambarella_platform_sd_controller1.slot[0].cd_delay = 100;
				ambarella_platform_sd_controller1.slot[0].use_bounce_buffer = 1;
				ambarella_platform_sd_controller1.slot[0].max_blk_sz = SD_BLK_SZ_128KB;
				ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_gpio = GPIO(129);
				ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_line = gpio_to_irq(129);
				ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_type = IRQ_TYPE_EDGE_BOTH;
				ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_gpio_val  = GPIO_LOW,
				ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_gpio_mode = GPIO_FUNC_SW_INPUT,
				ambarella_platform_sd_controller1.slot[0].gpio_wp.gpio_id = GPIO(128);

				boss_board_input_info.pkeymap = boss_keymap_evk;
				ambarella_tm1726_board_info.irq = ambarella_board_generic.touch_panel_irq.irq_line;
				i2c_register_board_info(2, &ambarella_tm1726_board_info, 1);

				use_bub_default = 0;
				break;
			default:
				pr_warn("%s: Unknown EVK Rev[%d]\n", __func__, AMBARELLA_BOARD_REV(system_rev));
				break;
		}
		platform_add_devices(ambarella_devices, ARRAY_SIZE(ambarella_devices));
		for (i = 0; i < ARRAY_SIZE(ambarella_devices); i++) {
			device_set_wakeup_capable(&ambarella_devices[i]->dev, 1);
			device_set_wakeup_enable(&ambarella_devices[i]->dev, 0);
		}
	}

	if (use_bub_default) {
		/* Config SD*/
		ambarella_platform_sd_controller0.clk_limit = 25000000;
		ambarella_platform_sd_controller0.slot[0].use_bounce_buffer = 1;
		ambarella_platform_sd_controller0.slot[0].max_blk_sz = SD_BLK_SZ_128KB;
		ambarella_platform_sd_controller0.slot[0].cd_delay = 1000;
		ambarella_platform_sd_controller0.slot[0].gpio_cd.irq_gpio = GPIO(67);
		ambarella_platform_sd_controller0.slot[0].gpio_cd.irq_line = gpio_to_irq(67);
		ambarella_platform_sd_controller0.slot[0].gpio_cd.irq_type = IRQ_TYPE_EDGE_BOTH;
		ambarella_platform_sd_controller0.slot[0].gpio_cd.irq_gpio_val	= GPIO_LOW,
		ambarella_platform_sd_controller0.slot[0].gpio_cd.irq_gpio_mode	= GPIO_FUNC_SW_INPUT,
		ambarella_platform_sd_controller0.slot[0].gpio_wp.gpio_id = GPIO(68);
		ambarella_platform_sd_controller0.slot[1].use_bounce_buffer = 1;
		ambarella_platform_sd_controller0.slot[1].max_blk_sz = SD_BLK_SZ_128KB;
		ambarella_platform_sd_controller0.slot[1].cd_delay = 1000;
		ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_gpio = GPIO(75);
		ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_line = gpio_to_irq(75);
		ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_type = IRQ_TYPE_EDGE_BOTH;
		ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_gpio_val	= GPIO_LOW,
		ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_gpio_mode	= GPIO_FUNC_SW_INPUT,
		ambarella_platform_sd_controller0.slot[1].gpio_wp.gpio_id = GPIO(76);
		ambarella_platform_sd_controller1.clk_limit = 25000000;
		ambarella_platform_sd_controller1.slot[0].cd_delay = 100;
		ambarella_platform_sd_controller1.slot[0].use_bounce_buffer = 1;
		ambarella_platform_sd_controller1.slot[0].max_blk_sz = SD_BLK_SZ_128KB;
#if !defined(CONFIG_AMBARELLA_IPC)
		ambarella_platform_sd_controller1.slot[0].ext_power.gpio_id = GPIO(106);
#endif
		ambarella_platform_sd_controller1.slot[0].ext_power.active_level = GPIO_HIGH;
		ambarella_platform_sd_controller1.slot[0].ext_power.active_delay = 300;
		ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_gpio = GPIO(129);
		ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_line = gpio_to_irq(129);
		ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_type = IRQ_TYPE_EDGE_BOTH;
		ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_gpio_val	= GPIO_LOW,
		ambarella_platform_sd_controller1.slot[0].gpio_cd.irq_gpio_mode	= GPIO_FUNC_SW_INPUT,
		ambarella_platform_sd_controller1.slot[0].gpio_wp.gpio_id = GPIO(128);
#if defined(CONFIG_AMBARELLA_IPC)
		ambarella_platform_sd_controller0.slot[0].caps |= MMC_CAP_8_BIT_DATA;
		ambarella_platform_sd_controller1.slot[0].caps |= MMC_CAP_8_BIT_DATA;

		ambarella_platform_sd_controller0.slot[0].caps |= MMC_CAP_BUS_WIDTH_TEST;
		ambarella_platform_sd_controller0.slot[1].caps |= MMC_CAP_BUS_WIDTH_TEST;
		ambarella_platform_sd_controller1.slot[0].caps |= MMC_CAP_BUS_WIDTH_TEST;
#endif

		platform_add_devices(ambarella_devices, ARRAY_SIZE(ambarella_devices));
		for (i = 0; i < ARRAY_SIZE(ambarella_devices); i++) {
			device_set_wakeup_capable(&ambarella_devices[i]->dev, 1);
			device_set_wakeup_enable(&ambarella_devices[i]->dev, 0);
		}
	}
	spi_register_board_info(ambarella_spi_devices, ARRAY_SIZE(ambarella_spi_devices));
	platform_device_register(&boss_board_input);
	platform_device_register(&boss_bt_rfkill);  // for BT
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;
	unsigned int		i, unet_id, rdev_cnt, n = 0;
	bool			mux;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	mux = test_bit(info->data, &mux_enabled);
	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;
	info->in = 0;

	for (n = 0; n < rdev_cnt; n++) {

		/* Use this filed to increment device count this will be
		 * used by bind to determin the forward link and reverse
		 * link network interface names.
		 */
		info->in++;
		status = usbnet_probe(iface, prod);
		if (status < 0) {
			dev_err(&iface->dev, "usbnet_probe failed %d\n",
					status);
			goto out;
		}

		unet_id = n + info->data * no_rmnet_insts_per_dev;

		unet_list[unet_id] = unet = usb_get_intfdata(iface);

		/*store mux id for later access*/
		unet->data[3] = n;

		/*save mux info for control and usbnet devices*/
		unet->data[1] = unet->data[4] = mux;

		/*set rmnet operation mode to eth by default*/
		set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

		/*update net device*/
		rmnet_usb_setup(unet->net, mux);

		/*create /sys/class/net/rmnet_usbx/dbg_mask*/
		status = device_create_file(&unet->net->dev,
				&dev_attr_dbg_mask);
		if (status) {
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
				&unet->data[1]);
		if (status) {
			device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_data_debugfs_init(unet);
		if (status)
			dev_dbg(&iface->dev,
					"mode debugfs file is not available\n");
	}

	usb_enable_autosuspend(udev);

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);
	}

	return 0;

out:
	for (i = 0; i < n; i++) {
		/* This cleanup happens only for MUX case */
		unet_id = i + info->data * no_rmnet_insts_per_dev;
		unet = unet_list[unet_id];
		dev = (struct rmnet_ctrl_dev *)unet->data[1];

		rmnet_usb_data_debugfs_cleanup(unet);
		rmnet_usb_ctrl_disconnect(dev);
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usb_set_intfdata(iface, unet_list[unet_id]);
		usbnet_disconnect(iface);
		unet_list[unet_id] = NULL;
	}

	return status;
}
示例#20
0
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		return -EINVAL;
	}

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&iface->dev, "usbnet_probe failed %d\n",
				status);
		return status;
	}

	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev,
			&dev_attr_dbg_mask);
	if (status) {
		usbnet_disconnect(iface);
		return status;
	}

	status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
			&unet->data[1]);
	if (status) {
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usbnet_disconnect(iface);
		return status;
	}

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&iface->dev,
				"mode debugfs file is not available\n");

	usb_enable_autosuspend(udev);

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);
	}

	return 0;
}
static int ehci_mid_probe(struct pci_dev *pdev,
				const struct pci_device_id *id)
{
	struct hc_driver *driver;
	struct usb_phy *otg;
	struct intel_mid_otg_xceiv *iotg;
	struct intel_mid_otg_pdata *otg_pdata;
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	int irq;
	int retval;

	pr_debug("initializing Intel MID USB OTG Host Controller\n");

	/* we need not call pci_enable_dev since otg transceiver already take
	 * the control of this device and this probe actaully gets called by
	 * otg transceiver driver with HNP protocol.
	 */
	irq = pdev->irq;

	if (!id)
		return -EINVAL;
	driver = (struct hc_driver *)id->driver_data;
	if (!driver)
		return -EINVAL;

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto err1;
	}

	ehci = hcd_to_ehci(hcd);
	/* this will be called in ehci_bus_suspend and ehci_bus_resume */
	ehci->otg_suspend = usb_otg_suspend;
	ehci->otg_resume = usb_otg_resume;
	/* this will be called by root hub code */
	hcd->otg_notify = otg_notify;
	otg = usb_get_transceiver();
	if (otg == NULL) {
		printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__);
		retval = -EINVAL;
		goto err1;
	}

	iotg = otg_to_mid_xceiv(otg);
	hcd->regs = iotg->base;

	hcd->rsrc_start = pci_resource_start(pdev, 0);
	hcd->rsrc_len = pci_resource_len(pdev, 0);

	if (hcd->regs == NULL) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto err2;
	}

	otg_pdata = pdev->dev.platform_data;
	if (otg_pdata == NULL) {
		dev_err(&pdev->dev, "Failed to get OTG platform data.\n");
		retval = -ENODEV;
		goto err2;
	}
	hcd->power_budget = otg_pdata->power_budget;

	/* Mandatorily set the controller as remote-wakeup enabled */
	device_set_wakeup_enable(&pdev->dev, true);

	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (retval != 0)
		goto err2;
	retval = otg_set_host(otg->otg, &hcd->self);
	if (!otg->otg->default_a)
		hcd->self.is_b_host = 1;
	usb_put_transceiver(otg);
	return retval;

err2:
	usb_put_hcd(hcd);
err1:
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
	return retval;
}
示例#22
0
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info;
	struct usb_device	*udev;
	unsigned int		iface_num;
	static int		first_rmnet_iface_num = -EINVAL;
	int			status = 0;

	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	info = (struct driver_info *)prod->driver_info;
	if (!test_bit(iface_num, &info->data))
		return -ENODEV;

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&iface->dev, "usbnet_probe failed %d\n", status);
		goto out;
	}
	unet = usb_get_intfdata(iface);

	
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	
	rmnet_usb_setup(unet->net);

	
	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
	if (status)
		goto out;

	if (first_rmnet_iface_num == -EINVAL)
		first_rmnet_iface_num = iface_num;

	
	unet->data[1] = (unsigned long)ctrl_dev	\
			[iface_num - first_rmnet_iface_num];

	status = rmnet_usb_ctrl_probe(iface, unet->status,
		(struct rmnet_ctrl_dev *)unet->data[1]);
	if (status)
		goto out;

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&iface->dev, "mode debugfs file is not available\n");

	udev = unet->udev;

	if (udev->parent && !udev->parent->parent) {
		
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);

		
		pm_runtime_set_autosuspend_delay(&udev->dev, 1000);
		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);
	}

out:
	return status;
}
/* called during probe() after chip reset completes */
static int ehci_pci_setup(struct usb_hcd *hcd)
{
	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
	struct pci_dev		*p_smbus;
	u8			rev;
	u32			temp;
	int			retval;
	int			force_otg_hc_mode = 0;

	switch (pdev->vendor) {
	case PCI_VENDOR_ID_TOSHIBA_2:
		/* celleb's companion chip */
		if (pdev->device == 0x01b5) {
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
			ehci->big_endian_mmio = 1;
#else
			ehci_warn(ehci,
				  "unsupported big endian Toshiba quirk\n");
#endif
		}
		break;
	case PCI_VENDOR_ID_INTEL:
		if (pdev->device == 0x0811 || pdev->device == 0x0829 ||
				pdev->device == 0xE006) {
			ehci_info(ehci, "Detected Intel MID OTG HC\n");
			hcd->has_tt = 1;
			ehci->has_hostpc = 1;
#ifdef CONFIG_USB_OTG
			ehci->has_otg = 1;
#endif
			force_otg_hc_mode = 1;

			hcd->has_sram = 1;
			/*
			 * Disable SRAM for CLVP A0 due to the silicon issue.
			 */
			if (pdev->device == 0xE006 && pdev->revision < 0xC) {
				ehci_info(ehci, "Disable SRAM for CLVP A0\n");
				hcd->has_sram = 0;
			}

			hcd->sram_no_payload = 1;
			sram_init(hcd);
		} else if (pdev->device == 0x0806) {
			ehci_info(ehci, "Detected Langwell MPH\n");
			hcd->has_tt = 1;
			ehci->has_hostpc = 1;
			hcd->has_sram = 1;
			hcd->sram_no_payload = 1;
			sram_init(hcd);
		} else if (pdev->device == 0x0829) {
			ehci_info(ehci, "Detected Penwell OTG HC\n");
			hcd->has_tt = 1;
			ehci->has_hostpc = 1;
		} else if (pdev->device == 0x08F2) {
#ifdef CONFIG_USB_EHCI_HCD_SPH
			struct ehci_sph_pdata   *sph_pdata;
			sph_pdata = pdev->dev.platform_data;
			if (!sph_pdata) {
				ehci_err(ehci, "get SPH platform data failed\n");
				retval = -ENODEV;
				return retval;
			}

			/* All need to bypass tll mode  */
			temp = ehci_readl(ehci, hcd->regs + CLV_SPHCFG);
			temp &= ~CLV_SPHCFG_ULPI1TYPE;
			ehci_writel(ehci, temp, hcd->regs + CLV_SPHCFG);

			sph_pdata->enabled = sph_enabled();

			/* Check SPH enabled or not */
			if (sph_pdata->enabled == 0) {
				/* ULPI 1 ref-clock switch off */
				temp = ehci_readl(ehci, hcd->regs + CLV_SPHCFG);
				temp |= CLV_SPHCFG_REFCKDIS;
				ehci_writel(ehci, temp, hcd->regs + CLV_SPHCFG);

				/* Set Power state */
				retval = pci_set_power_state(pdev, PCI_D1);
				if (retval < 0)
					ehci_err(ehci,
						"Set SPH to D1 failed, retval = %d\n",
						retval);

				ehci_info(ehci, "USB SPH is disabled\n");
				return -ENODEV;
			}

			ehci_info(ehci, "Detected SPH HC\n");
			hcd->has_tt = 1;
			ehci->has_hostpc = 1;

			temp = ehci_readl(ehci, hcd->regs + CLV_SPH_HOSTPC);
			temp |= CLV_SPH_HOSTPC_PTS;
			ehci_writel(ehci, temp, hcd->regs + CLV_SPH_HOSTPC);

			device_set_wakeup_enable(&pdev->dev, true);

			/* Set Runtime-PM flags for SPH */
			hcd->rpm_control = 1;
			hcd->rpm_resume = 0;
			pm_runtime_set_active(&pdev->dev);
#endif
		} else if (pdev->device == 0x119C) {
			ehci_info(ehci, "Detected Merr USB2 HC\n");
			hcd->has_tt = 1;
			ehci->has_hostpc = 1;
		} else if (pdev->device == 0x119D) {
			ehci_info(ehci, "Detected HSIC HC\n");
			hcd->has_tt = 1;
			ehci->has_hostpc = 1;
			ehci->has_lpm = 0;
			hcd->has_sram = 1;
			hcd->sram_no_payload = 1;
			sram_init(hcd);

			device_set_wakeup_enable(&pdev->dev, true);
			/* Set Runtime-PM flags for SPH */
			hcd->rpm_control = 1;
			hcd->rpm_resume = 0;
			pm_runtime_set_active(&pdev->dev);
		}
	}

	ehci->caps = hcd->regs;
	ehci->regs = hcd->regs +
		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));

	dbg_hcs_params(ehci, "reset");
	dbg_hcc_params(ehci, "reset");

        /* ehci_init() causes memory for DMA transfers to be
         * allocated.  Thus, any vendor-specific workarounds based on
         * limiting the type of memory used for DMA transfers must
         * happen before ehci_init() is called. */
	switch (pdev->vendor) {
	case PCI_VENDOR_ID_NVIDIA:
		/* NVidia reports that certain chips don't handle
		 * QH, ITD, or SITD addresses above 2GB.  (But TD,
		 * data buffer, and periodic schedule are normal.)
		 */
		switch (pdev->device) {
		case 0x003c:	/* MCP04 */
		case 0x005b:	/* CK804 */
		case 0x00d8:	/* CK8 */
		case 0x00e8:	/* CK8S */
			if (pci_set_consistent_dma_mask(pdev,
						DMA_BIT_MASK(31)) < 0)
				ehci_warn(ehci, "can't enable NVidia "
					"workaround for >2GB RAM\n");
			break;
		}
		break;
	}

	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
	if (force_otg_hc_mode)
		ehci_reset(ehci);

	retval = ehci_halt(ehci);
	if (retval)
		return retval;

	if ((pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x7808) ||
	    (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x4396)) {
		/* EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may
		 * read/write memory space which does not belong to it when
		 * there is NULL pointer with T-bit set to 1 in the frame list
		 * table. To avoid the issue, the frame list link pointer
		 * should always contain a valid pointer to a inactive qh.
		 */
		ehci->use_dummy_qh = 1;
		ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI "
				"dummy qh workaround\n");
	}

	/* data structure init */
	retval = ehci_init(hcd);
	if (retval)
		return retval;

	switch (pdev->vendor) {
	case PCI_VENDOR_ID_NEC:
		ehci->need_io_watchdog = 0;
		break;
	case PCI_VENDOR_ID_INTEL:
		ehci->need_io_watchdog = 0;
		ehci->fs_i_thresh = 1;
		if (pdev->device == 0x27cc) {
			ehci->broken_periodic = 1;
			ehci_info(ehci, "using broken periodic workaround\n");
		}
		if (pdev->device == 0x0806 || pdev->device == 0x0811
			|| pdev->device == 0x0829 || pdev->device == 0xE006) {
			ehci_info(ehci, "disable lpm for langwell/penwell\n");
			ehci->has_lpm = 0;
		}
		if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) {
			hcd->has_tt = 1;
			tdi_reset(ehci);
		}
		break;
	case PCI_VENDOR_ID_TDI:
		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
			hcd->has_tt = 1;
			tdi_reset(ehci);
		}
		break;
	case PCI_VENDOR_ID_AMD:
		/* AMD PLL quirk */
		if (usb_amd_find_chipset_info())
			ehci->amd_pll_fix = 1;
		/* AMD8111 EHCI doesn't work, according to AMD errata */
		if (pdev->device == 0x7463) {
			ehci_info(ehci, "ignoring AMD8111 (errata)\n");
			retval = -EIO;
			goto done;
		}
		break;
	case PCI_VENDOR_ID_NVIDIA:
		switch (pdev->device) {
		/* Some NForce2 chips have problems with selective suspend;
		 * fixed in newer silicon.
		 */
		case 0x0068:
			if (pdev->revision < 0xa4)
				ehci->no_selective_suspend = 1;
			break;

		/* MCP89 chips on the MacBookAir3,1 give EPROTO when
		 * fetching device descriptors unless LPM is disabled.
		 * There are also intermittent problems enumerating
		 * devices with PPCD enabled.
		 */
		case 0x0d9d:
			ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
			ehci->has_lpm = 0;
			ehci->has_ppcd = 0;
			ehci->command &= ~CMD_PPCEE;
			break;
		}
		break;
	case PCI_VENDOR_ID_VIA:
		if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x60) {
			u8 tmp;

			/* The VT6212 defaults to a 1 usec EHCI sleep time which
			 * hogs the PCI bus *badly*. Setting bit 5 of 0x4B makes
			 * that sleep time use the conventional 10 usec.
			 */
			pci_read_config_byte(pdev, 0x4b, &tmp);
			if (tmp & 0x20)
				break;
			pci_write_config_byte(pdev, 0x4b, tmp | 0x20);
		}
		break;
	case PCI_VENDOR_ID_ATI:
		/* AMD PLL quirk */
		if (usb_amd_find_chipset_info())
			ehci->amd_pll_fix = 1;
		/* SB600 and old version of SB700 have a bug in EHCI controller,
		 * which causes usb devices lose response in some cases.
		 */
		if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) {
			p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
						 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
						 NULL);
			if (!p_smbus)
				break;
			rev = p_smbus->revision;
			if ((pdev->device == 0x4386) || (rev == 0x3a)
			    || (rev == 0x3b)) {
				u8 tmp;
				ehci_info(ehci, "applying AMD SB600/SB700 USB "
					"freeze workaround\n");
				pci_read_config_byte(pdev, 0x53, &tmp);
				pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
			}
			pci_dev_put(p_smbus);
		}
		break;
	case PCI_VENDOR_ID_NETMOS:
		/* MosChip frame-index-register bug */
		ehci_info(ehci, "applying MosChip frame-index workaround\n");
		ehci->frame_index_bug = 1;
		break;
	}

	/* optional debug port, normally in the first BAR */
	temp = pci_find_capability(pdev, 0x0a);
	if (temp) {
		pci_read_config_dword(pdev, temp, &temp);
		temp >>= 16;
		if ((temp & (3 << 13)) == (1 << 13)) {
			temp &= 0x1fff;
			ehci->debug = ehci_to_hcd(ehci)->regs + temp;
			temp = ehci_readl(ehci, &ehci->debug->control);
			ehci_info(ehci, "debug port %d%s\n",
				HCS_DEBUG_PORT(ehci->hcs_params),
				(temp & DBGP_ENABLED)
					? " IN USE"
					: "");
			if (!(temp & DBGP_ENABLED))
				ehci->debug = NULL;
		}
	}

	ehci_reset(ehci);

	/* at least the Genesys GL880S needs fixup here */
	temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
	temp &= 0x0f;
	if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
		ehci_dbg(ehci, "bogus port configuration: "
			"cc=%d x pcc=%d < ports=%d\n",
			HCS_N_CC(ehci->hcs_params),
			HCS_N_PCC(ehci->hcs_params),
			HCS_N_PORTS(ehci->hcs_params));

		switch (pdev->vendor) {
		case 0x17a0:		/* GENESYS */
			/* GL880S: should be PORTS=2 */
			temp |= (ehci->hcs_params & ~0xf);
			ehci->hcs_params = temp;
			break;
		case PCI_VENDOR_ID_NVIDIA:
			/* NF4: should be PCC=10 */
			break;
		}
	}

	/* Serial Bus Release Number is at PCI 0x60 offset */
	pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
	if (pdev->vendor == PCI_VENDOR_ID_STMICRO
	    && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST)
		ehci->sbrn = 0x20; /* ConneXT has no sbrn register */

	/* Keep this around for a while just in case some EHCI
	 * implementation uses legacy PCI PM support.  This test
	 * can be removed on 17 Dec 2009 if the dev_warn() hasn't
	 * been triggered by then.
	 */
	if (!device_can_wakeup(&pdev->dev)) {
		u16	port_wake;

		pci_read_config_word(pdev, 0x62, &port_wake);
		if (port_wake & 0x0001) {
			dev_warn(&pdev->dev, "Enabling legacy PCI PM\n");
			device_set_wakeup_capable(&pdev->dev, 1);
		}
	}

#ifdef	CONFIG_USB_SUSPEND
	/* REVISIT: the controller works fine for wakeup iff the root hub
	 * itself is "globally" suspended, but usbcore currently doesn't
	 * understand such things.
	 *
	 * System suspend currently expects to be able to suspend the entire
	 * device tree, device-at-a-time.  If we failed selective suspend
	 * reports, system suspend would fail; so the root hub code must claim
	 * success.  That's lying to usbcore, and it matters for runtime
	 * PM scenarios with selective suspend and remote wakeup...
	 */
	if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev))
		ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
#endif

	ehci_port_power(ehci, 1);
	retval = ehci_pci_reinit(ehci, pdev);
done:
	return retval;
}
示例#24
0
/* ==========================================================================*/
static void __init ambarella_init_filbert(void)
{
	int					i;
	struct ambarella_spi_platform_info	*spi2_pdata;

	ambarella_init_machine("Filbert");

	platform_add_devices(ambarella_devices, ARRAY_SIZE(ambarella_devices));
	for (i = 0; i < ARRAY_SIZE(ambarella_devices); i++) {
		device_set_wakeup_capable(&ambarella_devices[i]->dev, 1);
		device_set_wakeup_enable(&ambarella_devices[i]->dev, 0);
	}

	/* config board */
	ambarella_board_generic.power_detect.irq_gpio = GPIO(135);
	ambarella_board_generic.power_detect.irq_line = gpio_to_irq(135);
	ambarella_board_generic.power_detect.irq_type = IRQF_TRIGGER_RISING;
	ambarella_board_generic.power_detect.irq_gpio_val = GPIO_LOW;
	ambarella_board_generic.power_detect.irq_gpio_mode = GPIO_FUNC_SW_INPUT;

	/* config LCD */
	ambarella_board_generic.lcd_backlight.gpio_id = GPIO(85);
	ambarella_board_generic.lcd_backlight.active_level = GPIO_HIGH;
	ambarella_board_generic.lcd_backlight.active_delay = 1;

	ambarella_board_generic.lcd_spi_hw.bus_id = 2;
	ambarella_board_generic.lcd_spi_hw.cs_id = 4;

	/* config audio */
	ambarella_board_generic.audio_reset.gpio_id = GPIO(12);
	ambarella_board_generic.audio_reset.active_level = GPIO_LOW;

	/* Config Eth0 */
	ambarella_eth0_platform_info.mii_reset.gpio_id = GPIO(124);

	/* Config Eth1 */
	ambarella_eth1_platform_info.mii_reset.gpio_id = GPIO(125);

	/* Config Vin */
	ambarella_board_generic.vin0_reset.gpio_id = GPIO(127);
	ambarella_board_generic.vin0_reset.active_level = GPIO_LOW;
	ambarella_board_generic.vin0_reset.active_delay = 200;

	/* Config SD */
	fio_default_owner = SELECT_FIO_SDIO;
	ambarella_platform_sd_controller0.max_blk_mask = SD_BLK_SZ_512KB;
	ambarella_platform_sd_controller0.slot[1].ext_power.gpio_id = GPIO(54);
	ambarella_platform_sd_controller0.slot[1].ext_power.active_level = GPIO_HIGH;
	ambarella_platform_sd_controller0.slot[1].ext_power.active_delay = 300;
	ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_gpio = GPIO(SMIO_44);
	ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_line = gpio_to_irq(SMIO_44);
	ambarella_platform_sd_controller0.slot[1].gpio_cd.irq_type = IRQ_TYPE_EDGE_BOTH;
	ambarella_platform_sd_controller0.slot[1].gpio_wp.gpio_id = GPIO(SMIO_45);

	spi2_pdata = (struct ambarella_spi_platform_info *)ambarella_spi2.dev.platform_data;
	spi2_pdata->cs_num = 7;
	spi2_pdata->cs_pins[7] = -1;
	spi_register_board_info(ambarella_spi_devices,
		ARRAY_SIZE(ambarella_spi_devices));

#if defined(CONFIG_TOUCH_AMBARELLA_TM1510)
	ambarella_tm1510_board_info.irq =
		ambarella_board_generic.touch_panel_irq.irq_line;
	ambarella_tm1510_board_info.flags = 0;
	i2c_register_board_info(0, &ambarella_tm1510_board_info, 1);
#endif

	i2c_register_board_info(0, ambarella_board_vin_infos,
		ARRAY_SIZE(ambarella_board_vin_infos));

#if (IDC_SUPPORT_PIN_MUXING_FOR_HDMI == 1)
	i2c_register_board_info(0, &ambarella_board_hdmi_info, 1);
#else
	i2c_register_board_info(1, &ambarella_board_hdmi_info, 1);
#endif

	platform_device_register(&filbert_board_input);
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct usb_device	*udev;
	struct driver_info	*info;
	unsigned int		iface_num;
	static int		first_rmnet_iface_num = -EINVAL;
	int			status = 0;

	udev = interface_to_usbdev(iface);
	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	if (iface->num_altsetting != 1) {
		dev_err(&udev->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	info = (struct driver_info *)prod->driver_info;
	if (!test_bit(iface_num, &info->data))
		return -ENODEV;

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&udev->dev, "usbnet_probe failed %d\n", status);
		goto out;
	}
	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
	if (status)
		goto out;

	if (first_rmnet_iface_num == -EINVAL)
		first_rmnet_iface_num = iface_num;

	/*save control device intstance */
	unet->data[1] = (unsigned long)ctrl_dev	\
			[iface_num - first_rmnet_iface_num];

	status = rmnet_usb_ctrl_probe(iface, unet->status,
		(struct rmnet_ctrl_dev *)unet->data[1]);
	if (status)
		goto out;

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&udev->dev, "mode debugfs file is not available\n");

	/* allow modem to wake up suspended system */
	device_set_wakeup_enable(&udev->dev, 1);
out:
	return status;
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;
	unsigned int		i, unet_id, rdev_cnt, n = 0;
	bool			mux;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	mux = test_bit(info->data, &mux_enabled);
	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;
	info->in = 0;

	for (n = 0; n < rdev_cnt; n++) {

		/*                                                      
                                                          
                                  
   */
		info->in++;
		status = usbnet_probe(iface, prod);
		if (status < 0) {
			dev_err(&iface->dev, "usbnet_probe failed %d\n",
					status);
			goto out;
		}

		unet_id = n + info->data * no_rmnet_insts_per_dev;

		unet_list[unet_id] = unet = usb_get_intfdata(iface);

		/*                             */
		unet->data[3] = n;

		/*                                            */
		unet->data[1] = unet->data[4] = mux;

		/*                                          */
		set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

		/*                 */
		rmnet_usb_setup(unet->net, mux);

		/*                                         */
		status = device_create_file(&unet->net->dev,
				&dev_attr_dbg_mask);
		if (status) {
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
				&unet->data[1]);
		if (status) {
			device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_data_debugfs_init(unet);
		if (status)
			dev_dbg(&iface->dev,
					"mode debugfs file is not available\n");
	}

	usb_enable_autosuspend(udev);

	if (udev->parent && !udev->parent->parent) {
		/*                                                     */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);
	}

	return 0;

out:
	for (i = 0; i < n; i++) {
		/*                                        */
		unet_id = i + info->data * no_rmnet_insts_per_dev;
		unet = unet_list[unet_id];
		dev = (struct rmnet_ctrl_dev *)unet->data[1];

		rmnet_usb_data_debugfs_cleanup(unet);
		rmnet_usb_ctrl_disconnect(dev);
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usb_set_intfdata(iface, unet_list[unet_id]);
		usbnet_disconnect(iface);
		unet_list[unet_id] = NULL;
	}

	return status;
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info;
	struct usb_device	*udev;
	unsigned int		iface_num;
	static int		first_rmnet_iface_num = -EINVAL;
	int			status = 0;

//++SSD_RIL:20120731: For tx/rx enable_hlt/disable_hlt
	if( machine_is_evitareul() ) {
		rnmet_usb_hlt_enabled = 1;
		pr_info("%s:rnmet_usb_hlt_enabled = 1\n", __func__);
	}
//--SSD_RIL
//++SSD_RIL:20120814: For CPU/Freq min default value
	if ( rnmet_usb_hlt_enabled == 1 && get_radio_flag() & 0x0002 ) {
		rnmet_usb_cpu_freq_enabled = 1;
	}
//--SSD_RIL

	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	info = (struct driver_info *)prod->driver_info;
	if (!test_bit(iface_num, &info->data))
		return -ENODEV;

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&iface->dev, "usbnet_probe failed %d\n", status);
		goto out;
	}
	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
	if (status)
		goto out;

	if (first_rmnet_iface_num == -EINVAL)
		first_rmnet_iface_num = iface_num;

	/*save control device intstance */
	unet->data[1] = (unsigned long)ctrl_dev	\
			[iface_num - first_rmnet_iface_num];

	status = rmnet_usb_ctrl_probe(iface, unet->status,
		(struct rmnet_ctrl_dev *)unet->data[1]);
	if (status)
		goto out;

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&iface->dev, "mode debugfs file is not available\n");

	udev = unet->udev;

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);

		/* set default autosuspend timeout for modem and roothub */
		pm_runtime_set_autosuspend_delay(&udev->dev, 1000);
		dev_err(&udev->dev, "pm_runtime_set_autosuspend_delay 1000\n");
		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);
		dev_err(&udev->parent->dev, "pm_runtime_set_autosuspend_delay 200\n");
	}

out:
//++SSD_RIL:20120814: For CPU/Freq min default value
	if ( rnmet_usb_cpu_freq_enabled == 1 ) {
		rmnet_usb_freq_request();
	}
//--SSD_RIL


//++SSD_RIL:20121017: get -71 but already register rmnet netdev
if (status == -EPROTO && already_register_rmNET  ) {
	pr_info("%s fail ,status = %d,unregister_netdev \n", __func__,status);
	//unregister_netdev(unet->net);
	//usb_put_dev(unet->udev);
	usbnet_disconnect(iface);
}
//--SSD_RIL:20121017: get -71 but already register rmnet netdev

	return status;
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct usb_device	*udev;
	struct driver_info	*info;
	unsigned int		iface_num;
	static int		first_rmnet_iface_num = -EINVAL;
	int			status = 0;
	int			ret = 0;

	udev = interface_to_usbdev(iface);
	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	if (iface->num_altsetting != 1) {
		dev_err(&udev->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	info = (struct driver_info *)prod->driver_info;
	if (!test_bit(iface_num, &info->data))
		return -ENODEV;

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&udev->dev, "usbnet_probe failed %d\n", status);
		goto out;
	}
	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
	if (status)
		goto out;

	if (first_rmnet_iface_num == -EINVAL)
		first_rmnet_iface_num = iface_num;

	/*save control device intstance */
	unet->data[1] = (unsigned long)ctrl_dev	\
			[iface_num - first_rmnet_iface_num];

	status = rmnet_usb_ctrl_probe(iface, unet->status,
		(struct rmnet_ctrl_dev *)unet->data[1]);
	if (status) {
		if (status == -EPIPE) {
			ret = set_qmicm_mode(rmnet_pm_dev);
			if (ret < 0)
				goto out;
			return status;
		}
		else
			goto out;
	}

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&udev->dev, "mode debugfs file is not available\n");

#ifdef CONFIG_MDM_HSIC_PM
	status = register_udev_to_pm_dev(rmnet_pm_dev, udev);
	if (status) {
		dev_err(&udev->dev,
			"%s: fail to register to hsic pm device\n", __func__);
		goto out;
	}
#endif
	/* allow modem to wake up suspended system */
	device_set_wakeup_enable(&udev->dev, 1);
out:
#ifdef CONFIG_MDM_HSIC_PM
	/* make reset or dump at 2nd enumeration fail */
	if (status < 0)
		mdm_force_fatal();
#endif
	return status;
}
示例#29
0
/**
 * ehci_hcd_omap_probe - initialize TI-based HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int ehci_hcd_omap_probe(struct platform_device *pdev)
{
	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
	struct ehci_hcd_omap *omap;
	struct resource *res;
	struct usb_hcd *hcd;

	int irq = platform_get_irq(pdev, 0);
	int ret = -ENODEV;
	int i;
	char supply[7];
	char supply_aux[11];

	if (!pdata) {
		dev_dbg(&pdev->dev, "missing platform_data\n");
		goto err_pdata;
	}

	if (usb_disabled())
		goto err_disabled;

	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
	if (!omap) {
		ret = -ENOMEM;
		goto err_disabled;
	}

	/* Electrical test support
	 * Interface is /sys/devices/platform/ehci-omap.0/portn
	 */
	if (pdata->port_mode[0] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port1);
	if (pdata->port_mode[1] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port2);
	if (pdata->port_mode[2] != EHCI_HCD_OMAP_MODE_UNKNOWN)
		ret = device_create_file(&pdev->dev, &dev_attr_port3);

	ghcd = hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
			dev_name(&pdev->dev));
	if (!hcd) {
		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
		ret = -ENOMEM;
		goto err_create_hcd;
	}

	platform_set_drvdata(pdev, omap);
	omap->dev		= &pdev->dev;
	omap->phy_reset		= pdata->phy_reset;
	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
	omap->port_mode[0]		= pdata->port_mode[0];
	omap->port_mode[1]		= pdata->port_mode[1];
	omap->port_mode[2]		= pdata->port_mode[2];
	omap->aux[0]			= pdata->aux[0];
	omap->aux[1]			= pdata->aux[1];
	omap->aux[2]			= pdata->aux[2];
	omap->ehci		= hcd_to_ehci(hcd);
	omap->ehci->sbrn	= 0x20;
	gb_omap = omap;
	omap->suspended = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "EHCI ioremap failed\n");
		ret = -ENOMEM;
		goto err_ioremap;
	}

	/* we know this is the memory we want, no need to ioremap again */
	omap->ehci->caps = hcd->regs;
	omap->ehci_base = hcd->regs;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	omap->uhh_base = ioremap(res->start, resource_size(res));
	if (!omap->uhh_base) {
		dev_err(&pdev->dev, "UHH ioremap failed\n");
		ret = -ENOMEM;
		goto err_uhh_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	omap->tll_base = ioremap(res->start, resource_size(res));
	if (!omap->tll_base) {
		dev_err(&pdev->dev, "TLL ioremap failed\n");
		ret = -ENOMEM;
		goto err_tll_ioremap;
	}

	/* get ehci regulator and enable */
	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
		if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) {
			omap->regulator[i] = NULL;
			continue;
		}
		snprintf(supply, 7, "hsusb%d", i);
		omap->regulator[i] = regulator_get(omap->dev, supply);
		if (IS_ERR(omap->regulator[i])) {
			dev_dbg(&pdev->dev,
			"failed to get ehci port%d regulator\n", i);
			omap->regulator[i] = NULL;
		} else {
			regulator_enable(omap->regulator[i]);
		}

		/* enable auxiliary supply if required */
		if (omap->aux[i]) {
			snprintf(supply_aux, 11, "hsusb%d-aux", i);
			omap->regulator_aux[i] =
				regulator_get(omap->dev, supply_aux);
			if (IS_ERR(omap->regulator_aux[i])) {
				dev_dbg(&pdev->dev,
				"failed to get ehci port%d aux regulator\n", i);
				omap->regulator[i] = NULL;
			} else {
				regulator_enable(omap->regulator_aux[i]);
			}
		}
	}

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to start ehci\n");
		goto err_start;
	}

	omap->ehci->regs = hcd->regs
		+ HC_LENGTH(readl(&omap->ehci->caps->hc_capbase));

	dbg_hcs_params(omap->ehci, "reset");
	dbg_hcc_params(omap->ehci, "reset");

	/* cache this readonly data; minimize chip reads */
	omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params);

	/* SET 1 micro-frame Interrupt interval */
	writel(readl(&omap->ehci->regs->command) | (1 << 16),
			&omap->ehci->regs->command);

	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret) {
		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
		goto err_add_hcd;
	}

	if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) &&
			gpio_is_valid(omap->reset_gpio_port[0])) {
		gpio_request(omap->reset_gpio_port[0], "HSUSB0 reset");
		gpio_direction_output(omap->reset_gpio_port[0], 0);
	}

	if ((omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) &&
			gpio_is_valid(omap->reset_gpio_port[1])) {
		gpio_request(omap->reset_gpio_port[1], "HSUSB1 reset");
		gpio_direction_output(omap->reset_gpio_port[1], 0);
	}

	/* reset the USB PHY */
	if (omap->phy_reset)
		ehci_omap_phy_reset(omap);

	/* root ports should always stay powered */
	ehci_port_power(omap->ehci, 1);

#ifdef CONFIG_LOGIC_OMAP3530_USB3320_HACK
	{
		struct usb_device *rdev = hcd->self.root_hub;

		omap->ehci->no_selective_suspend = 1;
		
		// Kill the auto suspend delay for the root hub
		// Since we only have one port used, it's better
		// if we go down right away.
		if(rdev)
		{
		    rdev->autosuspend_delay = 0;
		}
	}
#endif

#ifdef CONFIG_LOGIC_OMAP3530_USB3320_HACK
	usb3320_hack_init(ehci_hcd_omap_hack_handler, &pdev->dev);
#endif

        // Default wakeup enable should be off.
        device_init_wakeup(&pdev->dev, 1);
        device_set_wakeup_enable(&pdev->dev, 0);

	return 0;

err_add_hcd:
	omap_stop_ehc(omap, hcd);

err_start:
	for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
		if (omap->regulator[i]) {
			regulator_disable(omap->regulator[i]);
			regulator_put(omap->regulator[i]);
		}
	}
	iounmap(omap->tll_base);

err_tll_ioremap:
	iounmap(omap->uhh_base);

err_uhh_ioremap:
	iounmap(hcd->regs);

err_ioremap:
	usb_put_hcd(hcd);
	kfree(omap);

err_create_hcd:
	kfree(omap);
err_disabled:
err_pdata:
	return ret;
}