示例#1
0
static int __init alarm_dev_init(void)
{
	int err;
	int i;

	err = misc_register(&alarm_device);
	if (err)
		return err;

	alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm,
			ALARM_REALTIME, devalarm_alarmhandler);
	hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt,
			CLOCK_REALTIME, HRTIMER_MODE_ABS);
	alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm,
			ALARM_BOOTTIME, devalarm_alarmhandler);
	hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt,
			CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
	hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
			CLOCK_MONOTONIC, HRTIMER_MODE_ABS);

	for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
		alarms[i].type = i;
		if (!is_wakeup(i))
			alarms[i].u.hrt.function = devalarm_hrthandler;
	}

	wakeup_source_init(&alarm_wake_lock, "alarm");
	wakeup_source_init(&temp_wake_lock, "alarm_temp");
	return 0;
}
示例#2
0
/* acipc_init is used to register interrupt call-back function */
int acipc_init(u32 lpm_qos)
{
	wakeup_source_init(&acipc_wakeup, "acipc_wakeup");

	/* we do not check any return value */
	acipc_event_bind(ACIPC_MODEM_DDR_UPDATE_REQ, acipc_cb_event_notify,
		       ACIPC_CB_NORMAL, NULL);

	acipc_event_bind(ACIPC_IPM, acipc_cb_block_cpuidle_axi,
		       ACIPC_CB_NORMAL, NULL);

	pm_qos_cpuidle_block_axi = lpm_qos;
	pm_qos_add_request(&cp_block_cpuidle_axi, PM_QOS_CPUIDLE_BLOCK,
		PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE);

#ifdef CONFIG_DDR_DEVFREQ
	pm_qos_add_request(&modem_ddr_cons, PM_QOS_DDR_DEVFREQ_MIN,
		PM_QOS_DEFAULT_VALUE);
	INIT_WORK(&acipc_modem_ddr_freq_update,
		acipc_modem_ddr_freq_update_handler);
	acipc_wq = alloc_workqueue("ACIPC_WQ", WQ_HIGHPRI, 0);
#endif

	return 0;
}
INT32 wmt_plat_init(UINT32 co_clock_type)
{
	CMB_STUB_CB stub_cb;
	INT32 iret;
	/*init wmt function ctrl wakelock if wake lock is supported by host platform */

	wmt_plat_soc_co_clock_flag_set(co_clock_type);

	stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl;
	stub_cb.func_ctrl_cb = wmt_plat_func_ctrl;
	stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl;
	stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl;
	stub_cb.wmt_do_reset_cb = NULL;
	stub_cb.size = sizeof(stub_cb);

	/* register to cmb_stub */
	iret = mtk_wcn_cmb_stub_reg(&stub_cb);
#ifdef CFG_WMT_WAKELOCK_SUPPORT
#ifdef CONFIG_PM_WAKELOCKS
	wakeup_source_init(&wmtWakeLock, "wmtFuncCtrl");
#else
	wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl");
#endif
	mutex_init(&gOsSLock);
#endif

#if CONSYS_BT_WIFI_SHARE_V33
	gBtWifiV33.counter = 0;
	spin_lock_init(&gBtWifiV33.lock);
#endif

	iret += mtk_wcn_consys_hw_init();

	spin_lock_init(&gbgfIrqBle.lock);
	WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret);

	return 0;
}
static int __devinit pm80x_onkey_probe(struct platform_device *pdev)
{

	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct pm80x_onkey_info *info;
	int irq, err;

	info = kzalloc(sizeof(struct pm80x_onkey_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->pm80x = chip;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "No IRQ resource!\n");
		err = -EINVAL;
		goto out;
	}

	info->irq = irq + chip->irq_base;
	info->map = info->pm80x->regmap;
	if (!info->map) {
		dev_err(&pdev->dev, "no regmap!\n");
		err = -EINVAL;
		goto out;
	}

	info->idev = input_allocate_device();
	if (!info->idev) {
		dev_err(&pdev->dev, "Failed to allocate input dev\n");
		err = -ENOMEM;
		goto out;
	}

	info->idev->name = "88pm80x_on";
	info->idev->phys = "88pm80x_on/input0";
	info->idev->id.bustype = BUS_I2C;
	info->idev->dev.parent = &pdev->dev;
	info->idev->evbit[0] = BIT_MASK(EV_KEY);
	__set_bit(KEY_POWER, info->idev->keybit);

	err = pm80x_request_irq(info->pm80x, info->irq, pm80x_onkey_handler,
				IRQF_ONESHOT, "onkey", info);
	if (err < 0) {
		dev_err(&pdev->dev, "Failed to request IRQ: #%d: %d\n",
			info->irq, err);
		goto out_reg;
	}

	err = input_register_device(info->idev);
	if (err) {
		dev_err(&pdev->dev, "Can't register input device: %d\n", err);
		goto out_irq;
	}

	platform_set_drvdata(pdev, info);

	/* Enable long onkey detection */
	regmap_update_bits(info->map, PM800_RTC_MISC4, PM800_LONG_ONKEY_EN,
			   PM800_LONG_ONKEY_EN);
	/* Set 8-second interval */
	regmap_update_bits(info->map, PM800_RTC_MISC3,
			   PM800_LONKEY_PRESS_TIME_MASK,
			   PM800_LONKEY_PRESS_TIME);

	device_init_wakeup(&pdev->dev, 1);
#ifdef CONFIG_FAKE_SYSTEMOFF
	pm8xxx_info = info;
	atomic_set(&longpress_work_state, 0);
	wakeup_source_init(&suspend_longkey_lock, "longkey_suspend");
#endif
#if 1
	{struct device *dev_t;
	
	dev_t = device_create(sec_class, NULL, 0, "%s", "sec_power_key");
	
	if(device_create_file(dev_t, &dev_attr_sec_power_key_pressed) < 0)
		 printk("Failed to create device file(%s)!\n", dev_attr_sec_power_key_pressed.attr.name);
	}
#endif
	return 0;

out_irq:
	pm80x_free_irq(info->pm80x, info->irq, info);
out_reg:
	input_free_device(info->idev);
out:
	kfree(info);
	return err;
}
static enum MHI_STATUS mhi_init_wakelock(struct mhi_device_ctxt *mhi_dev_ctxt)
{
	wakeup_source_init(&mhi_dev_ctxt->w_lock, "mhi_wakeup_source");
	return MHI_STATUS_SUCCESS;
}
static int ehci_msm2_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct resource *res;
	struct msm_hcd *mhcd;
	struct pinctrl_state *set_state;
	const struct msm_usb_host_platform_data *pdata;
	char pdev_name[PDEV_NAME_LEN];
	int ret;

	dev_dbg(&pdev->dev, "ehci_msm2 probe\n");

	/*
	 * Fail probe in case of uicc till userspace activates driver through
	 * sysfs entry.
	 */
	if (!uicc_card_present && pdev->dev.of_node && of_property_read_bool(
				pdev->dev.of_node, "qcom,usb2-enable-uicc"))
		return -ENODEV;

	hcd = usb_create_hcd(&ehci_msm2_hc_driver, &pdev->dev,
				dev_name(&pdev->dev));
	if (!hcd) {
		dev_err(&pdev->dev, "Unable to create HCD\n");
		return  -ENOMEM;
	}

	mhcd = hcd_to_mhcd(hcd);
	mhcd->dev = &pdev->dev;

	mhcd->xo_clk = clk_get(&pdev->dev, "xo");
	if (IS_ERR(mhcd->xo_clk)) {
		ret = PTR_ERR(mhcd->xo_clk);
		mhcd->xo_clk = NULL;
		if (ret == -EPROBE_DEFER)
			goto put_hcd;
	}

	ret = msm_ehci_init_clocks(mhcd, 1);
	if (ret)
		goto xo_put;

	if (pdev->dev.of_node) {
		dev_dbg(&pdev->dev, "device tree enabled\n");
		pdev->dev.platform_data = ehci_msm2_dt_to_pdata(pdev);
	}

	if (!pdev->dev.platform_data)
		dev_dbg(&pdev->dev, "No platform data given\n");

	pdata = pdev->dev.platform_data;

	if (!pdev->dev.dma_mask)
		pdev->dev.dma_mask = &ehci_msm_dma_mask;
	if (!pdev->dev.coherent_dma_mask)
		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

	hcd_to_bus(hcd)->skip_resume = true;

	hcd->irq = platform_get_irq(pdev, 0);
	if (hcd->irq < 0) {
		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
		ret = hcd->irq;
		goto deinit_clocks;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Unable to get memory resource\n");
		ret = -ENODEV;
		goto deinit_clocks;
	}

	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, "ioremap failed\n");
		ret = -ENOMEM;
		goto deinit_clocks;
	}


	spin_lock_init(&mhcd->wakeup_lock);

	mhcd->async_irq = platform_get_irq_byname(pdev, "async_irq");
	if (mhcd->async_irq < 0) {
		dev_dbg(&pdev->dev, "platform_get_irq for async_int failed\n");
		mhcd->async_irq = 0;
	} else {
		ret = request_irq(mhcd->async_irq, msm_async_irq,
				IRQF_TRIGGER_RISING, "msm_ehci_host", mhcd);
		if (ret) {
			dev_err(&pdev->dev, "request irq failed (ASYNC INT)\n");
			goto unmap;
		}
		disable_irq(mhcd->async_irq);
	}

	snprintf(pdev_name, PDEV_NAME_LEN, "%s.%d", pdev->name, pdev->id);
	if (mhcd->xo_clk)
		ret = clk_prepare_enable(mhcd->xo_clk);
	if (ret) {
		dev_err(&pdev->dev, "%s failed to vote for TCXO %d\n",
								__func__, ret);
		goto free_xo_handle;
	}

	/* Get pinctrl if target uses pinctrl */
	mhcd->hsusb_pinctrl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(mhcd->hsusb_pinctrl)) {
		if (of_property_read_bool(pdev->dev.of_node, "pinctrl-names")) {
			dev_err(&pdev->dev, "Error encountered while getting pinctrl");
			ret = PTR_ERR(mhcd->hsusb_pinctrl);
			goto devote_xo_handle;
		}
		pr_debug("Target does not use pinctrl\n");
		mhcd->hsusb_pinctrl = NULL;
	}

	if (mhcd->hsusb_pinctrl) {
		set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl,
				"ehci_active");
		if (IS_ERR(set_state)) {
			pr_err("cannot get hsusb pinctrl active state\n");
			ret = PTR_ERR(set_state);
			goto devote_xo_handle;
		}
		ret = pinctrl_select_state(mhcd->hsusb_pinctrl, set_state);
		if (ret) {
			pr_err("cannot set hsusb pinctrl active state\n");
			goto devote_xo_handle;
		}
	}

	if (pdata && gpio_is_valid(pdata->resume_gpio)) {
		mhcd->resume_gpio = pdata->resume_gpio;
		ret = devm_gpio_request(&pdev->dev, mhcd->resume_gpio,
							"hsusb_resume");
		if (ret) {
			dev_err(&pdev->dev,
				"resume gpio(%d) request failed:%d\n",
				mhcd->resume_gpio, ret);
			mhcd->resume_gpio = -EINVAL;
		} else {
			/* to override ehci_bus_resume from ehci-hcd library */
			ehci_bus_resume_func = ehci_msm2_hc_driver.bus_resume;
			ehci_msm2_hc_driver.bus_resume =
				msm_ehci_bus_resume_with_gpio;
		}
	}

	if (pdata && gpio_is_valid(pdata->ext_hub_reset_gpio)) {
		ret = devm_gpio_request(&pdev->dev, pdata->ext_hub_reset_gpio,
							"hsusb_reset");
		if (ret) {
			dev_err(&pdev->dev,
				"reset gpio(%d) request failed:%d\n",
				pdata->ext_hub_reset_gpio, ret);
			goto pinctrl_sleep;
		} else {
			/* reset external hub */
			gpio_direction_output(pdata->ext_hub_reset_gpio, 0);
			/*
			 * Hub reset should be asserted for minimum 5microsec
			 * before deasserting.
			 */
			usleep_range(5, 1000);
			gpio_direction_output(pdata->ext_hub_reset_gpio, 1);
		}
	}

	spin_lock_init(&mhcd->wakeup_lock);

	ret = msm_ehci_init_vddcx(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize VDDCX\n");
		ret = -ENODEV;
		goto pinctrl_sleep;
	}

	ret = msm_ehci_config_vddcx(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "hsusb vddcx configuration failed\n");
		goto deinit_vddcx;
	}

	ret = msm_ehci_ldo_init(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "hsusb vreg configuration failed\n");
		goto deinit_vddcx;
	}

	ret = msm_ehci_ldo_enable(mhcd, 1);
	if (ret) {
		dev_err(&pdev->dev, "hsusb vreg enable failed\n");
		goto deinit_ldo;
	}

	ret = msm_ehci_init_vbus(mhcd, 1);
	if (ret)
		goto disable_ldo;

	hcd->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
	if (IS_ERR(hcd->phy)) {
		if (PTR_ERR(hcd->phy) == -EPROBE_DEFER) {
			dev_dbg(&pdev->dev, "usb-phy not probed yet\n");
			ret = -EPROBE_DEFER;
			goto vbus_deinit;
		}
		hcd->phy = NULL;
	}

	if (hcd->phy)
		usb_phy_init(hcd->phy);
	else if (pdata && pdata->use_sec_phy)
		mhcd->usb_phy_ctrl_reg = USB_PHY_CTRL2;
	else
		mhcd->usb_phy_ctrl_reg = USB_PHY_CTRL;

	ret = msm_hsusb_reset(mhcd);
	if (ret) {
		dev_err(&pdev->dev, "hsusb PHY initialization failed\n");
		goto vbus_deinit;
	}

	ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
	if (ret) {
		dev_err(&pdev->dev, "unable to register HCD\n");
		goto vbus_deinit;
	}

	pdata = mhcd->dev->platform_data;
	if (pdata && (!pdata->dock_connect_irq ||
				!irq_read_line(pdata->dock_connect_irq)))
		msm_ehci_vbus_power(mhcd, 1);

	/* For peripherals directly conneted to downstream port of root hub
	 * and require to drive suspend and resume by controller driver instead
	 * of root hub.
	 */
	if (pdata)
		mhcd->ehci.no_selective_suspend = pdata->no_selective_suspend;

	mhcd->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq");
	if (mhcd->wakeup_irq > 0) {
		dev_dbg(&pdev->dev, "wakeup irq:%d\n", mhcd->wakeup_irq);

		irq_set_status_flags(mhcd->wakeup_irq, IRQ_NOAUTOEN);
		ret = request_irq(mhcd->wakeup_irq, msm_hsusb_wakeup_irq,
				IRQF_TRIGGER_HIGH,
				"msm_hsusb_wakeup", mhcd);
		if (ret) {
			dev_err(&pdev->dev, "request_irq(%d) failed:%d\n",
					mhcd->wakeup_irq, ret);
			mhcd->wakeup_irq = 0;
		}
	} else {
		mhcd->wakeup_irq = 0;
	}

	device_init_wakeup(&pdev->dev, 1);
	wakeup_source_init(&mhcd->ws, dev_name(&pdev->dev));
	pm_stay_awake(mhcd->dev);
	INIT_WORK(&mhcd->phy_susp_fail_work, msm_ehci_phy_susp_fail_work);
	/*
	 * This pdev->dev is assigned parent of root-hub by USB core,
	 * hence, runtime framework automatically calls this driver's
	 * runtime APIs based on root-hub's state.
	 */
	/* configure pmic_gpio_irq for D+ change */
	if (pdata && pdata->pmic_gpio_dp_irq)
		mhcd->pmic_gpio_dp_irq = pdata->pmic_gpio_dp_irq;
	if (mhcd->pmic_gpio_dp_irq) {
		ret = request_threaded_irq(mhcd->pmic_gpio_dp_irq, NULL,
				msm_ehci_host_wakeup_irq,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"msm_ehci_host_wakeup", mhcd);
		if (!ret) {
			disable_irq_nosync(mhcd->pmic_gpio_dp_irq);
		} else {
			dev_err(&pdev->dev, "request_irq(%d) failed: %d\n",
					mhcd->pmic_gpio_dp_irq, ret);
			mhcd->pmic_gpio_dp_irq = 0;
		}
	}
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	if (ehci_debugfs_init(mhcd) < 0)
		dev_err(mhcd->dev, "%s: debugfs init failed\n", __func__);

	return 0;

vbus_deinit:
	msm_ehci_init_vbus(mhcd, 0);
disable_ldo:
	msm_ehci_ldo_enable(mhcd, 0);
deinit_ldo:
	msm_ehci_ldo_init(mhcd, 0);
deinit_vddcx:
	msm_ehci_init_vddcx(mhcd, 0);
pinctrl_sleep:
	if (mhcd->hsusb_pinctrl) {
		set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl,
				"ehci_sleep");
		if (IS_ERR(set_state))
			pr_err("cannot get hsusb pinctrl sleep state\n");
		else
			pinctrl_select_state(mhcd->hsusb_pinctrl, set_state);
	}
devote_xo_handle:
	if (mhcd->xo_clk)
		clk_disable_unprepare(mhcd->xo_clk);
free_xo_handle:
	if (mhcd->xo_clk) {
		clk_put(mhcd->xo_clk);
		mhcd->xo_clk = NULL;
	}
	if (mhcd->async_irq)
		free_irq(mhcd->async_irq, mhcd);
unmap:
	iounmap(hcd->regs);
deinit_clocks:
	msm_ehci_init_clocks(mhcd, 0);
xo_put:
	if (mhcd->xo_clk)
		clk_put(mhcd->xo_clk);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
static int __devinit sm5502_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct sm5502_usbsw *usbsw;
	struct device *switch_dev;

	int ret = 0;

	dev_info(&client->dev, "probe start\n");
	probing = 1;

	/* For AT Command FactoryTest */
	wakeup_source_init(&jig_suspend_wake, "JIG_UART Connect suspend wake");

	usbsw = kzalloc(sizeof(struct sm5502_usbsw), GFP_KERNEL);
	if (!usbsw) {
		dev_err(&client->dev, "failed to allocate driver data\n");
		return -ENOMEM;
	}

	chip = usbsw;
	usbsw->client = client;
	usbsw->pdata = client->dev.platform_data;

	i2c_set_clientdata(client, usbsw);

	mutex_init(&usbsw->mutex);

	/* DeskTop Dock  */
	usbsw->dock_dev.name = "dock";
	ret = switch_dev_register(&usbsw->dock_dev);
	if (ret < 0)
		dev_err(&client->dev, "dock_dev_register error !!\n");

	switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
	if (device_create_file(switch_dev, &dev_attr_adc) < 0)
		dev_err(&client->dev, "Failed to create device file(%s)!\n",
		       dev_attr_adc.attr.name);
	if (device_create_file(switch_dev, &dev_attr_usb_state) < 0)
		dev_err(&client->dev, "Failed to create device file(%s)!\n",
		       dev_attr_usb_state.attr.name);
	if (device_create_file(switch_dev, &dev_attr_usb_sel) < 0)
		dev_err(&client->dev, "Failed to create device file(%s)!\n",
		       dev_attr_usb_sel.attr.name);
	if (device_create_file(switch_dev, &dev_attr_uart_sel) < 0)
		dev_err(&client->dev, "Failed to create device file(%s)!\n",
		       dev_attr_uart_sel.attr.name);
	dev_set_drvdata(switch_dev, usbsw);

	ret = sysfs_create_group(&client->dev.kobj, &sm5502_group);
	if (ret) {
		dev_err(&client->dev, "Creating sm5502 attribute group failed\n");
		goto sm5502_probe_fail2;
	}

	usbsw->qos_idle.name = "Jig driver";
	pm_qos_add_request(&usbsw->qos_idle, PM_QOS_CPUIDLE_BLOCK,
			   PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE);

	ret = sm5502_reg_init(usbsw);
	if (ret)
		goto sm5502_probe_fail;

	/* device detection */
	dev_info(&client->dev, "First Detection\n");
	detect_dev_sm5502(usbsw, ATTACHED, REV_ACCE, &first_acce);

	ret = sm5502_int_init(usbsw);
	if (ret)
		goto sm5502_probe_fail;

	probing = 0;
	dev_info(&client->dev, "PROBE Done.\n");

	return 0;

sm5502_probe_fail2:
	if (client->irq)
		free_irq(client->irq, NULL);
sm5502_probe_fail:
	i2c_set_clientdata(client, NULL);
	kfree(usbsw);
	return ret;
}
static int mxhci_hsic_probe(struct platform_device *pdev)
{
	struct hc_driver *driver;
	struct device_node *node = pdev->dev.of_node;
	struct mxhci_hsic_hcd *mxhci;
	struct xhci_hcd		*xhci;
	struct resource *res;
	struct usb_hcd *hcd;
	unsigned int reg;
	int ret;
	int irq;
	u32 tmp[3];

	if (usb_disabled())
		return -ENODEV;

	driver = &mxhci_hsic_hc_driver;

	pdev->dev.dma_mask = &dma_mask;

	/* dbg log event settings */
	dbg_hsic.log_events =  enable_dbg_log;
	dbg_hsic.log_payload = enable_payload_log;
	dbg_hsic.inep_log_mask = ep_addr_rxdbg_mask;
	dbg_hsic.outep_log_mask = ep_addr_rxdbg_mask;

	/* usb2.0 root hub */
	driver->hcd_priv_size =	sizeof(struct mxhci_hsic_hcd);
	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd)
		return -ENOMEM;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = -ENODEV;
		goto put_hcd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		ret = -ENODEV;
		goto put_hcd;
	}

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

	hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "error mapping memory\n");
		ret = -EFAULT;
		goto put_hcd;
	}

	mxhci = hcd_to_hsic(hcd);
	mxhci->dev = &pdev->dev;

	mxhci->strobe = of_get_named_gpio(node, "hsic,strobe-gpio", 0);
	if (mxhci->strobe < 0) {
		ret = -EINVAL;
		goto put_hcd;
	}

	mxhci->data  = of_get_named_gpio(node, "hsic,data-gpio", 0);
	if (mxhci->data < 0) {
		ret = -EINVAL;
		goto put_hcd;
	}

	ret = of_property_read_u32_array(node, "qcom,vdd-voltage-level",
							tmp, ARRAY_SIZE(tmp));
	if (!ret) {
		mxhci->vdd_no_vol_level = tmp[0];
		mxhci->vdd_low_vol_level = tmp[1];
		mxhci->vdd_high_vol_level = tmp[2];
	} else {
		dev_err(&pdev->dev,
			"failed to read qcom,vdd-voltage-level property\n");
		ret = -EINVAL;
		goto put_hcd;
	}

	ret = mxhci_msm_config_gdsc(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to configure hsic gdsc\n");
		goto put_hcd;
	}

	ret = mxhci_hsic_init_clocks(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize clocks\n");
		goto put_hcd;
	}

	ret = mxhci_hsic_init_vddcx(mxhci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize vddcx\n");
		goto deinit_clocks;
	}

	mxhci_hsic_reset(mxhci);

	/* HSIC phy caliberation:set periodic caliberation interval ~2.048sec */
	mxhci_hsic_ulpi_write(mxhci, 0xFF, MSM_HSIC_IO_CAL_PER);

	/* Enable periodic IO calibration in HSIC_CFG register */
	mxhci_hsic_ulpi_write(mxhci, 0xA8, MSM_HSIC_CFG);

	/* Configure Strobe and Data GPIOs to enable HSIC */
	ret = mxhci_hsic_config_gpios(mxhci);
	if (ret) {
		dev_err(mxhci->dev, " gpio configuarion failed\n");
		goto deinit_vddcx;
	}

	/* enable STROBE_PAD_CTL */
	reg = readl_relaxed(TLMM_GPIO_HSIC_STROBE_PAD_CTL);
	writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_STROBE_PAD_CTL);

	/* enable DATA_PAD_CTL */
	reg = readl_relaxed(TLMM_GPIO_HSIC_DATA_PAD_CTL);
	writel_relaxed(reg | 0x2000000, TLMM_GPIO_HSIC_DATA_PAD_CTL);

	mb();

	/* Enable LPM in Sleep mode and suspend mode */
	reg = readl_relaxed(MSM_HSIC_CTRL_REG);
	reg |= CTRLREG_PLL_CTRL_SLEEP | CTRLREG_PLL_CTRL_SUSP;
	writel_relaxed(reg, MSM_HSIC_CTRL_REG);

	if (of_property_read_bool(node, "qti,disable-hw-clk-gating")) {
		reg = readl_relaxed(MSM_HSIC_GCTL);
		writel_relaxed((reg | GCTL_DSBLCLKGTNG), MSM_HSIC_GCTL);
	}

	/* enable pwr event irq for LPM_IN_L2_IRQ */
	writel_relaxed(LPM_IN_L2_IRQ_MASK, MSM_HSIC_PWR_EVNT_IRQ_MASK);

	mxhci->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq");
	if (mxhci->wakeup_irq < 0) {
		mxhci->wakeup_irq = 0;
		dev_err(&pdev->dev, "failed to init wakeup_irq\n");
	} else {
		/* enable wakeup irq only when entering lpm */
		irq_set_status_flags(mxhci->wakeup_irq, IRQ_NOAUTOEN);
		ret = devm_request_irq(&pdev->dev, mxhci->wakeup_irq,
			mxhci_hsic_wakeup_irq, 0, "mxhci_hsic_wakeup", mxhci);
		if (ret) {
			dev_err(&pdev->dev,
					"request irq failed (wakeup irq)\n");
			goto deinit_vddcx;
		}
	}

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto deinit_vddcx;

	hcd = dev_get_drvdata(&pdev->dev);
	xhci = hcd_to_xhci(hcd);

	/* USB 3.0 roothub */

	/* no need for another instance of mxhci */
	driver->hcd_priv_size = sizeof(struct xhci_hcd *);

	xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
			dev_name(&pdev->dev), hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto remove_usb2_hcd;
	}

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

	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
	if (ret)
		goto put_usb3_hcd;

	spin_lock_init(&mxhci->wakeup_lock);

	mxhci->pwr_event_irq = platform_get_irq_byname(pdev, "pwr_event_irq");
	if (mxhci->pwr_event_irq < 0) {
		dev_err(&pdev->dev,
				"platform_get_irq for pwr_event_irq failed\n");
		goto remove_usb3_hcd;
	}

	ret = devm_request_irq(&pdev->dev, mxhci->pwr_event_irq,
				mxhci_hsic_pwr_event_irq,
				0, "mxhci_hsic_pwr_evt", mxhci);
	if (ret) {
		dev_err(&pdev->dev, "request irq failed (pwr event irq)\n");
		goto remove_usb3_hcd;
	}

	init_completion(&mxhci->phy_in_lpm);

	mxhci->wq = create_singlethread_workqueue("mxhci_wq");
	if (!mxhci->wq) {
		dev_err(&pdev->dev, "unable to create workqueue\n");
		ret = -ENOMEM;
		goto remove_usb3_hcd;
	}

	INIT_WORK(&mxhci->bus_vote_w, mxhci_hsic_bus_vote_w);

	mxhci->bus_scale_table = msm_bus_cl_get_pdata(pdev);
	if (!mxhci->bus_scale_table) {
		dev_dbg(&pdev->dev, "bus scaling is disabled\n");
	} else {
		mxhci->bus_perf_client =
			msm_bus_scale_register_client(mxhci->bus_scale_table);
		/* Configure BUS performance parameters for MAX bandwidth */
		if (mxhci->bus_perf_client) {
			mxhci->bus_vote = true;
			queue_work(mxhci->wq, &mxhci->bus_vote_w);
		} else {
			dev_err(&pdev->dev, "%s: bus scaling client reg err\n",
					__func__);
			ret = -ENODEV;
			goto delete_wq;
		}
	}

	ret = device_create_file(&pdev->dev, &dev_attr_config_imod);
	if (ret)
		dev_dbg(&pdev->dev, "%s: unable to create imod sysfs entry\n",
					__func__);

	/* Enable HSIC PHY */
	mxhci_hsic_ulpi_write(mxhci, 0x01, MSM_HSIC_CFG_SET);

	device_init_wakeup(&pdev->dev, 1);
	wakeup_source_init(&mxhci->ws, dev_name(&pdev->dev));
	pm_stay_awake(mxhci->dev);

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

delete_wq:
	destroy_workqueue(mxhci->wq);
remove_usb3_hcd:
	usb_remove_hcd(xhci->shared_hcd);
put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);
remove_usb2_hcd:
	usb_remove_hcd(hcd);
deinit_vddcx:
	mxhci_hsic_init_vddcx(mxhci, 0);
deinit_clocks:
	mxhci_hsic_init_clocks(mxhci, 0);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
示例#9
0
void cnss_pm_wake_lock_init(struct wakeup_source *ws, const char *name)
{
    wakeup_source_init(ws, name);
}
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs,
	struct gpio_event_info *info, void **data, int func)
{
	int i;
	int err;
	int key_count;
	struct gpio_kp *kp;
	struct gpio_event_matrix_info *mi;

	mi = container_of(info, struct gpio_event_matrix_info, info);
	if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
		/* TODO: disable scanning */
		return 0;
	}

	if (func == GPIO_EVENT_FUNC_INIT) {
		if (mi->keymap == NULL ||
		   mi->input_gpios == NULL ||
		   mi->output_gpios == NULL) {
			err = -ENODEV;
			pr_err("gpiomatrix: Incomplete pdata\n");
			goto err_invalid_platform_data;
		}
		key_count = mi->ninputs * mi->noutputs;

		*data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
				     BITS_TO_LONGS(key_count), GFP_KERNEL);
		if (kp == NULL) {
			err = -ENOMEM;
			pr_err("gpiomatrix: Failed to allocate private data\n");
			goto err_kp_alloc_failed;
		}
		kp->input_devs = input_devs;
		kp->keypad_info = mi;
		for (i = 0; i < key_count; i++) {
			unsigned short keyentry = mi->keymap[i];
			unsigned short keycode = keyentry & MATRIX_KEY_MASK;
			unsigned short dev = keyentry >> MATRIX_CODE_BITS;
			if (dev >= input_devs->count) {
				pr_err("gpiomatrix: bad device index %d >= "
					"%d for key code %d\n",
					dev, input_devs->count, keycode);
				err = -EINVAL;
				goto err_bad_keymap;
			}
			if (keycode && keycode <= KEY_MAX)
				input_set_capability(input_devs->dev[dev],
							EV_KEY, keycode);
		}

		for (i = 0; i < mi->noutputs; i++) {
			err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
			if (err) {
				pr_err("gpiomatrix: gpio_request failed for "
					"output %d\n", mi->output_gpios[i]);
				goto err_request_output_gpio_failed;
			}
			if (gpio_cansleep(mi->output_gpios[i])) {
				pr_err("gpiomatrix: unsupported output gpio %d,"
					" can sleep\n", mi->output_gpios[i]);
				err = -EINVAL;
				goto err_output_gpio_configure_failed;
			}
			if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
				err = gpio_direction_output(mi->output_gpios[i],
					!(mi->flags & GPIOKPF_ACTIVE_HIGH));
			else
				err = gpio_direction_input(mi->output_gpios[i]);
			if (err) {
				pr_err("gpiomatrix: gpio_configure failed for "
					"output %d\n", mi->output_gpios[i]);
				goto err_output_gpio_configure_failed;
			}
		}
		for (i = 0; i < mi->ninputs; i++) {
			err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
			if (err) {
				pr_err("gpiomatrix: gpio_request failed for "
					"input %d\n", mi->input_gpios[i]);
				goto err_request_input_gpio_failed;
			}
			err = gpio_direction_input(mi->input_gpios[i]);
			if (err) {
				pr_err("gpiomatrix: gpio_direction_input failed"
					" for input %d\n", mi->input_gpios[i]);
				goto err_gpio_direction_input_failed;
			}
		}
		kp->current_output = mi->noutputs;
		kp->key_state_changed = 1;

		hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		kp->timer.function = gpio_keypad_timer_func;
		wakeup_source_init(&kp->wakeup_source,"gpio_kp");
		err = gpio_keypad_request_irqs(kp);
		kp->use_irq = err == 0;

		pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for "
			"%s%s in %s mode\n", input_devs->dev[0]->name,
			(input_devs->count > 1) ? "..." : "",
			kp->use_irq ? "interrupt" : "polling");

		if (kp->use_irq)
			__pm_stay_awake(&kp->wakeup_source);
		hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);

		return 0;
	}

	err = 0;
	kp = *data;

	if (kp->use_irq)
		for (i = mi->noutputs - 1; i >= 0; i--)
			free_irq(gpio_to_irq(mi->input_gpios[i]), kp);

	hrtimer_cancel(&kp->timer);
	wakeup_source_trash(&kp->wakeup_source);
	for (i = mi->noutputs - 1; i >= 0; i--) {
err_gpio_direction_input_failed:
		gpio_free(mi->input_gpios[i]);
err_request_input_gpio_failed:
		;
	}
	for (i = mi->noutputs - 1; i >= 0; i--) {
err_output_gpio_configure_failed:
		gpio_free(mi->output_gpios[i]);
err_request_output_gpio_failed:
		;
	}
err_bad_keymap:
	kfree(kp);
err_kp_alloc_failed:
err_invalid_platform_data:
	return err;
}
示例#11
0
static int smd_tty_port_activate(struct tty_port *tport,
				 struct tty_struct *tty)
{
	int res = 0;
	unsigned int n = tty->index;
	struct smd_tty_info *info;
	const char *peripheral = NULL;


	if (n >= MAX_SMD_TTYS || !smd_tty[n].ch_name)
		return -ENODEV;

	info = smd_tty + n;

	mutex_lock(&info->open_lock_lha1);
	tty->driver_data = info;

	peripheral = smd_edge_to_subsystem(smd_tty[n].edge);
	if (peripheral) {
		info->pil = subsystem_get(peripheral);
		if (IS_ERR(info->pil)) {
			SMD_TTY_INFO(
				"%s failed on smd_tty device :%s subsystem_get failed for %s",
				__func__, info->ch_name,
				peripheral);

			/*
			 * Sleep, inorder to reduce the frequency of
			 * retry by user-space modules and to avoid
			 * possible watchdog bite.
			 */
			msleep((smd_tty[n].open_wait * 1000));
			res = PTR_ERR(info->pil);
			goto out;
		}

		/* Wait for the modem SMSM to be inited for the SMD
		 * Loopback channel to be allocated at the modem. Since
		 * the wait need to be done atmost once, using msleep
		 * doesn't degrade the performance.
		 */
		if (n == LOOPBACK_IDX) {
			if (!is_modem_smsm_inited())
				msleep(5000);
			smsm_change_state(SMSM_APPS_STATE,
					  0, SMSM_SMD_LOOPBACK);
			msleep(100);
		}

		/*
		 * Wait for a channel to be allocated so we know
		 * the modem is ready enough.
		 */
		if (smd_tty[n].open_wait) {
			res = wait_for_completion_interruptible_timeout(
					&info->ch_allocated,
					msecs_to_jiffies(smd_tty[n].open_wait *
									1000));

			if (res == 0) {
				SMD_TTY_INFO(
					"Timed out waiting for SMD channel %s",
					info->ch_name);
				res = -ETIMEDOUT;
				goto release_pil;
			} else if (res < 0) {
				SMD_TTY_INFO(
					"Error waiting for SMD channel %s : %d\n",
					info->ch_name, res);
				goto release_pil;
			}
		}
#ifdef CONFIG_LGE_USES_SMD_DS_TTY
		/*           
                                                     
                               
   */
		if (n == DS_IDX) {
			/* wait for open ready status in seconds */
			pr_info("%s: checking DS modem status\n", __func__);
			res = wait_event_interruptible_timeout(
					info->ch_opened_wait_queue,
					info->is_dsmodem_ready, (lge_ds_modem_wait * HZ));
			if (res == 0) {
				res = -ETIMEDOUT;
				pr_err("%s: timeout to wait for %s modem: %d\n",
						__func__, info->ch_name, res);
				goto release_pil;
			}
			if (res < 0) {
				pr_err("%s: timeout to wait for %s modem: %d\n",
						__func__, info->ch_name, res);
				goto release_pil;
			}
			pr_info("%s: DS modem is OK, open smd0..\n", __func__);
		}
#endif

	}

	tasklet_init(&info->tty_tsklt, smd_tty_read, (unsigned long)info);
	wakeup_source_init(&info->pending_ws, info->ch_name);
	scnprintf(info->ra_wakeup_source_name, MAX_RA_WAKE_LOCK_NAME_LEN,
		  "SMD_TTY_%s_RA", info->ch_name);
	wakeup_source_init(&info->ra_wakeup_source,
			info->ra_wakeup_source_name);

	res = smd_named_open_on_edge(info->ch_name,
				     smd_tty[n].edge, &info->ch, info,
				     smd_tty_notify);
	if (res < 0) {
		SMD_TTY_INFO("%s: %s open failed %d\n",
			      __func__, info->ch_name, res);
		goto release_wl_tl;
	}

	res = wait_event_interruptible_timeout(info->ch_opened_wait_queue,
					       info->is_open, (2 * HZ));
	if (res == 0)
		res = -ETIMEDOUT;
	if (res < 0) {
		SMD_TTY_INFO("%s: wait for %s smd_open failed %d\n",
			      __func__, info->ch_name, res);
		goto close_ch;
	}
	SMD_TTY_INFO("%s with PID %u opened port %s",
		      current->comm, current->pid, info->ch_name);
	smd_disable_read_intr(info->ch);
	mutex_unlock(&info->open_lock_lha1);
	return 0;

close_ch:
	smd_close(info->ch);
	info->ch = NULL;

release_wl_tl:
	tasklet_kill(&info->tty_tsklt);
	wakeup_source_trash(&info->pending_ws);
	wakeup_source_trash(&info->ra_wakeup_source);

release_pil:
	subsystem_put(info->pil);
out:
	mutex_unlock(&info->open_lock_lha1);

	return res;
}