示例#1
0
static int tty_ldisc_halt(struct tty_struct *tty)
{
	clear_bit(TTY_LDISC, &tty->flags);
	return cancel_delayed_work_sync(&tty->buf.work);
}
void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
{
	clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);

	/*
	 * Stop rfkill polling.
	 */
	if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
		rt2x00rfkill_unregister(rt2x00dev);

	/*
	 * Disable radio.
	 */
	rt2x00lib_disable_radio(rt2x00dev);

	/*
	 * Stop all work.
	 */
	cancel_work_sync(&rt2x00dev->intf_work);
	cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
	cancel_work_sync(&rt2x00dev->sleep_work);
	if (rt2x00_is_usb(rt2x00dev)) {
		hrtimer_cancel(&rt2x00dev->txstatus_timer);
		cancel_work_sync(&rt2x00dev->rxdone_work);
		cancel_work_sync(&rt2x00dev->txdone_work);
	}
	if (rt2x00dev->workqueue)
		destroy_workqueue(rt2x00dev->workqueue);

	/*
	 * Free the tx status fifo.
	 */
	kfifo_free(&rt2x00dev->txstatus_fifo);

	/*
	 * Kill the tx status tasklet.
	 */
	tasklet_kill(&rt2x00dev->txstatus_tasklet);
	tasklet_kill(&rt2x00dev->pretbtt_tasklet);
	tasklet_kill(&rt2x00dev->tbtt_tasklet);
	tasklet_kill(&rt2x00dev->rxdone_tasklet);
	tasklet_kill(&rt2x00dev->autowake_tasklet);

	/*
	 * Uninitialize device.
	 */
	rt2x00lib_uninitialize(rt2x00dev);

	/*
	 * Free extra components
	 */
	rt2x00debug_deregister(rt2x00dev);
	rt2x00leds_unregister(rt2x00dev);

	/*
	 * Free ieee80211_hw memory.
	 */
	rt2x00lib_remove_hw(rt2x00dev);

	/*
	 * Free firmware image.
	 */
	rt2x00lib_free_firmware(rt2x00dev);

	/*
	 * Free queue structures.
	 */
	rt2x00queue_free(rt2x00dev);

	/*
	 * Free the driver data.
	 */
	if (rt2x00dev->drv_data)
		kfree(rt2x00dev->drv_data);
}
/**
 * dwc3_otg_init - Initializes otg related registers
 * @dwc: Pointer to out controller context structure
 *
 * Returns 0 on success otherwise negative errno.
 */
int dwc3_otg_init(struct dwc3 *dwc)
{
	u32	reg;
	int ret = 0;
	struct dwc3_otg *dotg;

	dev_dbg(dwc->dev, "dwc3_otg_init\n");

	/* Allocate and init otg instance */
	dotg = devm_kzalloc(dwc->dev, sizeof(struct dwc3_otg), GFP_KERNEL);
	if (!dotg) {
		dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
		return -ENOMEM;
	}

	dotg->otg.phy = devm_kzalloc(dwc->dev, sizeof(struct usb_phy),
							GFP_KERNEL);
	if (!dotg->otg.phy) {
		dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
		return -ENOMEM;
	}

	dotg->otg.phy->otg = &dotg->otg;
	dotg->otg.phy->dev = dwc->dev;
	dotg->otg.phy->set_power = dwc3_otg_set_power;
	dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
	dotg->otg.set_host = dwc3_otg_set_host;
	dotg->otg.phy->state = OTG_STATE_UNDEFINED;

	/*
	 * GHWPARAMS6[10] bit is SRPSupport.
	 * This bit also reflects DWC_USB3_EN_OTG
	 */
	reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
	if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
		/*
		 * No OTG support in the HW core.
		 * We return 0 to indicate no error, since this is acceptable
		 * situation, just continue probe the dwc3 driver without otg.
		 */
		dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
		return 0;
	}


	/* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
	dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
								"otg_irq");
	if (dotg->irq < 0) {
		dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
		return -ENODEV;
	}

	dotg->regs = dwc->regs;

	/* This reference is used by dwc3 modules for checking otg existance */
	dwc->dotg = dotg;
	dotg->dwc = dwc;
	dotg->otg.phy->dev = dwc->dev;

	init_completion(&dotg->dwc3_xcvr_vbus_init);
	INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work);

	ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
				"dwc3_otg", dotg);
	if (ret) {
		dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
				dotg->irq, ret);
		goto err1;
	}

	pm_runtime_get(dwc->dev);

	return 0;

err1:
	cancel_delayed_work_sync(&dotg->sm_work);
	dwc->dotg = NULL;

	return ret;
}
void blk_sync_queue(struct request_queue *q)
{
	del_timer_sync(&q->timeout);
	cancel_delayed_work_sync(&q->delay_work);
}
/*Charger Module Initialization*/
static int max8903_charger_probe(struct platform_device *pdev)
{

	struct max8903_charger *mc;
	int ret;
	struct resource *r;

	/*allocate mem*/
	mc = kzalloc(sizeof(*mc), GFP_KERNEL);
	if (!mc)
		return -ENOMEM;

	platform_set_drvdata(pdev, mc);

	printk("MAX8903: Charger Initializing...\n");
	//INIT_DELAYED_WORK(&mc->max8903_charger_detect_work, max8903_charger_detect);
	/* Create power supplies for WALL/USB which are the only 2 ext supplies*/
	mc->adapter.name            = "ac";
	mc->adapter.type            = POWER_SUPPLY_TYPE_MAINS;
	mc->adapter.properties      = power_props;
	mc->adapter.num_properties  = ARRAY_SIZE(power_props);
	mc->adapter.get_property    = &adapter_get_property;

	mc->usb.name            = "usb";
	mc->usb.type            = POWER_SUPPLY_TYPE_USB;
	mc->usb.properties      = power_props;
	mc->usb.num_properties  = ARRAY_SIZE(power_props);
	mc->usb.get_property    = usb_get_property;

	mc->adapter_online = 0;
	mc->adapter_active = 0;
	mc->adapter_curr_limit = USB_CURRENT_LIMIT_HIGH; /* default limit is high limit */
	mc->usb_online = 0;
	mc->usb_active = 0;

	ret = power_supply_register(&pdev->dev, &mc->adapter);
	if (ret) {
		printk("MAX8903: Failed to register WALL CHARGER\n");
		goto exit0;
	}

	ret = power_supply_register(&pdev->dev, &mc->usb);
	if (ret) {
		printk("MAX8903: Failed to register USB CHARGER\n");
		goto exit1;
	}

	/*****************/
	/* Get resources */
	/*****************/
	r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_EN);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_EN);
		goto exit1;
	}
	mc->max8903_gpio_chg_en = r->start;
	r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_FLT);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_FLT);
		goto exit1;
	}
	mc->max8903_gpio_chg_flt = r->start;
	r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_IUSB);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_IUSB);
		goto exit1;
	}
	mc->max8903_gpio_chg_iusb = r->start;
	r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_USUS);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_USUS);
		goto exit1;
	}
	mc->max8903_gpio_chg_usus = r->start;
	r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_ILM);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_ILM);
		goto exit1;
	}
	mc->max8903_gpio_chg_ilm = r->start;
	r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_UOK);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_UOK);
		goto exit1;
	}
	mc->max8903_gpio_chg_uok = r->start;
	r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_DOK);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_DOK);
		goto exit1;
	}
	mc->max8903_gpio_chg_dok = r->start;

	/******************************/
	/* Control pins configuration */
	/******************************/

	/*~DOK Status*/
	if (gpio_request(mc->max8903_gpio_chg_dok, MAX8903_TOKEN_GPIO_CHG_DOK) < 0) {
		printk(KERN_ERR "Can't get GPIO for max8903 chg_dok\n");
		goto exit2;
	}
	gpio_direction_input(mc->max8903_gpio_chg_dok);
	/*~UOK Status*/
	if (gpio_request(mc->max8903_gpio_chg_uok, MAX8903_TOKEN_GPIO_CHG_UOK) < 0) {
		printk(KERN_ERR "Can't get GPIO for max8903 chg_uok\n");
		goto exit3;
	}
	gpio_direction_input(mc->max8903_gpio_chg_uok);
	/*IUSB control*/
	if (gpio_request(mc->max8903_gpio_chg_iusb,  MAX8903_TOKEN_GPIO_CHG_IUSB) < 0) {
		printk(KERN_ERR "Can't get GPIO for max8903 chg_iusb\n");
		goto exit5;
	}
	gpio_direction_output(mc->max8903_gpio_chg_iusb, CHG_IUSB_SELECT_500mA);

	/*USUS control*/
	if (gpio_request(mc->max8903_gpio_chg_usus, MAX8903_TOKEN_GPIO_CHG_USUS) < 0) {
		printk(KERN_ERR "Can't get GPIO for max8903 chg_usus\n");
		goto exit6;
	}
	gpio_direction_output(mc->max8903_gpio_chg_usus, DISABLED); // leave USUS disabled until we connect

	/*~CEN control */
	if (gpio_request(mc->max8903_gpio_chg_en, MAX8903_TOKEN_GPIO_CHG_EN) < 0) {
		printk(KERN_ERR "Can't get GPIO for max8903 chg_en\n");
		goto exit7;
	}
	gpio_direction_output(mc->max8903_gpio_chg_en, DISABLED);

	if (gpio_request(mc->max8903_gpio_chg_ilm, MAX8903_TOKEN_GPIO_CHG_ILM) < 0) {
		printk(KERN_ERR "Can't get GPIO for max8903 chg_ilm\n");
		goto exit8;
	}
	gpio_direction_output(mc->max8903_gpio_chg_ilm, CHG_ILM_SELECT_USB);    /* set to USB  current limit by default */

	if (gpio_request(mc->max8903_gpio_chg_flt, MAX8903_TOKEN_GPIO_CHG_FLT) < 0) {
		printk(KERN_ERR "Can't get GPIO for max8903 chg_flt\n");
		goto exit9;
	}
	gpio_direction_input(mc->max8903_gpio_chg_flt);

	/*~FLT status*/
	mc->flt_irq= gpio_to_irq(mc->max8903_gpio_chg_flt) ;
	ret  = request_irq( mc->flt_irq,
			max8903_fault_interrupt,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_DISABLED,
			"max8903-fault-irq",
			mc);

	printk("MAX8903: Request CHARGER FLT IRQ successfully!\n");
	if (ret < 0) {
		printk(KERN_ERR "MAX8903: Can't Request IRQ for max8903 flt_irq\n");
		goto exita;
	}

	/*
	   create sysfs for manufacture testing coverage on charging
	   the operator should be able to write 1 to turn on the charging and 0 to
	   turn off the charging to verify the charging circuit is functioning
	   */
	ret = sysfs_create_group(&pdev->dev.kobj, &max8903_attr_group);

	if (ret){
		printk(KERN_ERR "MAX8903: Can't Create Sysfs Entry for FTM\n");
		goto exitd;
	}

	// Register charger work and notification callback.
	INIT_DELAYED_WORK_DEFERRABLE(&mc->usb_work, max8903_usb_charger_work);
	mc->nb.notifier_call = twl6030_usb_notifier_call;
	mc->otg = otg_get_transceiver();
	if (!mc->otg) {
		dev_err(&pdev->dev, "otg_get_transceiver() failed\n");
		goto exitn;
	}
	ret = otg_register_notifier(mc->otg, &mc->nb);
	if (ret) {
		dev_err(&pdev->dev, "otg register notifier failed %d\n", ret);
		goto exitn;
	}

	max8903_usb_charger_atboot(mc);

	return 0;

exitn:
	cancel_delayed_work_sync(&mc->usb_work);
	sysfs_remove_group(&pdev->dev.kobj, &max8903_attr_group);

exitd:
	free_irq(mc->flt_irq,mc);
exita:
	gpio_free(mc->max8903_gpio_chg_flt);
exit9:
	gpio_free(mc->max8903_gpio_chg_ilm);
exit8:
	gpio_free(mc->max8903_gpio_chg_en);
exit7:
	gpio_free(mc->max8903_gpio_chg_usus);
exit6:
	gpio_free(mc->max8903_gpio_chg_iusb);
exit5:
	gpio_free(mc->max8903_gpio_chg_uok);
exit3:
	gpio_free(mc->max8903_gpio_chg_dok);
exit2:
	power_supply_unregister(&mc->usb);
exit1:
	power_supply_unregister(&mc->adapter);
exit0:
	kfree(mc);
	return ret;
}
int isert_conn_alloc(struct iscsi_session *session,
		     struct iscsi_kern_conn_info *info,
		     struct iscsi_conn **new_conn,
		     struct iscsit_transport *t)
{
	int res = 0;
	struct isert_conn_dev *dev;
	struct iscsi_conn *conn;
	struct iscsi_cmnd *cmnd;
	struct file *filp = fget(info->fd);

	TRACE_ENTRY();

	lockdep_assert_held(&session->target->target_mutex);

	if (unlikely(!filp)) {
		res = -EBADF;
		goto out;
	}

	dev = filp->private_data;

	cmnd = dev->login_rsp;

	sBUG_ON(cmnd == NULL);
	dev->login_rsp = NULL;

	*new_conn = dev->conn;
	res = isert_set_session_params(dev->conn, &session->sess_params,
				       &session->tgt_params);

	if (!res)
		set_bit(ISERT_CONN_PASSED, &dev->flags);

	fput(filp);

	conn = *new_conn;

	if (unlikely(res))
		goto cleanup_conn;

	conn->transport = t;

	res = iscsi_init_conn(session, info, conn);
	if (unlikely(res))
		goto cleanup_conn;

	conn->rd_state = 1;
	isert_del_timer(dev);
	isert_dev_release(dev);
	isert_set_priv(conn, NULL);

	res = isert_login_rsp_tx(cmnd, true, false);
	vunmap(dev->sg_virt);
	dev->sg_virt = NULL;

	if (unlikely(res))
		goto cleanup_iscsi_conn;

#ifndef CONFIG_SCST_PROC
	res = conn_sysfs_add(conn);
	if (unlikely(res))
		goto cleanup_iscsi_conn;
#endif

	list_add_tail(&conn->conn_list_entry, &session->conn_list);

	goto out;

cleanup_iscsi_conn:
	conn->rd_state = 0;
	if (conn->nop_in_interval > 0)
		cancel_delayed_work_sync(&conn->nop_in_delayed_work);
cleanup_conn:
	conn->session = NULL;
	isert_close_connection(conn);
out:
	TRACE_EXIT_RES(res);
	return res;
}
示例#7
0
static int da9055_onkey_probe(struct platform_device *pdev)
{
	struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
	struct da9055_onkey *onkey;
	struct input_dev *input_dev;
	int irq, err;

	irq = platform_get_irq_byname(pdev, "ONKEY");
	if (irq < 0) {
		dev_err(&pdev->dev,
			"Failed to get an IRQ for input device, %d\n", irq);
		return -EINVAL;
	}

	onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
	if (!onkey) {
		dev_err(&pdev->dev, "Failed to allocate memory\n");
		return -ENOMEM;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&pdev->dev, "Failed to allocate memory\n");
		return -ENOMEM;
	}

	onkey->input = input_dev;
	onkey->da9055 = da9055;
	input_dev->name = "da9055-onkey";
	input_dev->phys = "da9055-onkey/input0";
	input_dev->dev.parent = &pdev->dev;

	input_dev->evbit[0] = BIT_MASK(EV_KEY);
	__set_bit(KEY_POWER, input_dev->keybit);

	INIT_DELAYED_WORK(&onkey->work, da9055_onkey_work);

	err = request_threaded_irq(irq, NULL, da9055_onkey_irq,
				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
				   "ONKEY", onkey);
	if (err < 0) {
		dev_err(&pdev->dev,
			"Failed to register ONKEY IRQ %d, error = %d\n",
			irq, err);
		goto err_free_input;
	}

	err = input_register_device(input_dev);
	if (err) {
		dev_err(&pdev->dev, "Unable to register input device, %d\n",
			err);
		goto err_free_irq;
	}

	platform_set_drvdata(pdev, onkey);

	return 0;

err_free_irq:
	free_irq(irq, onkey);
	cancel_delayed_work_sync(&onkey->work);
err_free_input:
	input_free_device(input_dev);

	return err;
}
static int boost_mig_sync_thread(void *data)
{
	int dest_cpu = (int) data;
	int src_cpu, ret;
	struct cpu_sync *s = &per_cpu(sync_info, dest_cpu);
	struct cpufreq_policy dest_policy;
	struct cpufreq_policy src_policy;
	unsigned long flags;

	while (1) {
		wait_event_interruptible(s->sync_wq,
					s->pending || kthread_should_stop());

		if (kthread_should_stop())
			break;

		spin_lock_irqsave(&s->lock, flags);
		s->pending = false;
		src_cpu = s->src_cpu;
		spin_unlock_irqrestore(&s->lock, flags);

		ret = cpufreq_get_policy(&src_policy, src_cpu);
		if (ret)
			continue;

		ret = cpufreq_get_policy(&dest_policy, dest_cpu);
		if (ret)
			continue;

		if (src_policy.cur == src_policy.cpuinfo.min_freq) {
			pr_debug("No sync. Source CPU%d@%dKHz at min freq\n",
				 src_cpu, src_policy.cur);
			continue;
		}

		cancel_delayed_work_sync(&s->boost_rem);
		if (sync_threshold) {
			if (src_policy.cur >= sync_threshold)
				s->boost_min = sync_threshold;
			else
				s->boost_min = src_policy.cur;
		} else {
			s->boost_min = src_policy.cur;
		}
		/* Force policy re-evaluation to trigger adjust notifier. */
		get_online_cpus();
		if (cpu_online(src_cpu))
			/*
			 * Send an unchanged policy update to the source
			 * CPU. Even though the policy isn't changed from
			 * its existing boosted or non-boosted state
			 * notifying the source CPU will let the governor
			 * know a boost happened on another CPU and that it
			 * should re-evaluate the frequency at the next timer
			 * event without interference from a min sample time.
			 */
			cpufreq_update_policy(src_cpu);
		if (cpu_online(dest_cpu)) {
			cpufreq_update_policy(dest_cpu);
			queue_delayed_work_on(dest_cpu, cpu_boost_wq,
				&s->boost_rem, msecs_to_jiffies(boost_ms));
		} else {
			s->boost_min = 0;
		}
		put_online_cpus();
	}

	return 0;
}
示例#9
0
void smp_suspend(struct early_suspend *h)
{
	cancel_delayed_work_sync(&cpuup_work);
	if (num_online_cpus() > 1)
		disable_nonboot_cpus();
}
示例#10
0
static void tm6000_ir_stop(void *priv)
{
	struct tm6000_IR *ir = priv;

	cancel_delayed_work_sync(&ir->work);
}
/**
 * exynos_drd_switch_init - Initializes DRD role switch.
 *
 * @drd: Pointer to DRD controller structure.
 *
 * Returns 0 on success otherwise negative errno.
 */
int exynos_drd_switch_init(struct exynos_drd *drd)
{
	struct dwc3_exynos_data *pdata = drd->pdata;
	struct exynos_drd_switch *drd_switch;
	int ret = 0;
	unsigned long irq_flags = 0;

	dev_dbg(drd->dev, "%s\n", __func__);

	drd_switch = devm_kzalloc(drd->dev, sizeof(struct exynos_drd_switch),
				  GFP_KERNEL);
	if (!drd_switch) {
		dev_err(drd->dev, "not enough memory for DRD switch\n");
		return -ENOMEM;
	}

	drd_switch->core = &drd->core;
	atomic_set(&drd_switch->sm_reset, 0);

	/* ID pin gpio IRQ */
	drd_switch->id_irq = pdata->id_irq;
	if (drd_switch->id_irq < 0)
		dev_dbg(drd->dev, "cannot find ID irq\n");

	init_timer(&drd_switch->id_db_timer);
	drd_switch->id_db_timer.data = (unsigned long) drd_switch;
	drd_switch->id_db_timer.function = exynos_drd_switch_debounce;

	/* VBus pin gpio IRQ */
	drd_switch->vbus_irq = pdata->vbus_irq;
	if (drd_switch->vbus_irq < 0)
		dev_dbg(drd->dev, "cannot find VBUS irq\n");

	init_timer(&drd_switch->vbus_db_timer);
	drd_switch->vbus_db_timer.data = (unsigned long) drd_switch;
	drd_switch->vbus_db_timer.function = exynos_drd_switch_debounce;

	irq_flags = pdata->irq_flags;

	drd_switch->otg.set_peripheral = exynos_drd_switch_set_peripheral;
	drd_switch->otg.set_host = exynos_drd_switch_set_host;

	/* Save for using by host and peripheral */
	drd->core.otg = &drd_switch->otg;

	drd_switch->otg.phy = devm_kzalloc(drd->dev, sizeof(struct usb_phy),
					   GFP_KERNEL);
	if (!drd_switch->otg.phy) {
		dev_err(drd->dev, "cannot allocate OTG phy\n");
		return -ENOMEM;
	}

	drd_switch->otg.phy->otg = &drd_switch->otg;
	drd_switch->otg.phy->dev = drd->dev;
#if 0
	/*
	 * TODO: we need to have support for multiple transceivers here.
	 * Kernel > 3.5 should already have it. Now it works only for one
	 * drd channel.
	 */
	ret = usb_set_transceiver(drd_switch->otg.phy);
	if (ret) {
		dev_err(drd->dev,
			"failed to set transceiver, already exists\n",
			__func__);
		goto err2;
	}
#endif
	spin_lock_init(&drd_switch->lock);

	wake_lock_init(&drd_switch->wakelock,
		WAKE_LOCK_SUSPEND, "drd_switch");

	exynos_drd_switch_reset(drd, 0);

	drd_switch->wq = create_freezable_workqueue("drd_switch");
	if (!drd_switch->wq) {
		dev_err(drd->dev, "cannot create workqueue\n");
		ret = -ENOMEM;
		goto err_wq;
	}

	INIT_DELAYED_WORK(&drd_switch->work, exynos_drd_switch_work);

	if (drd_switch->id_irq >= 0) {
		ret = devm_request_irq(drd->dev, drd_switch->id_irq,
				  exynos_drd_switch_id_interrupt, irq_flags,
				  "drd_switch_id", drd_switch);
		if (ret) {
			dev_err(drd->dev, "cannot claim ID irq\n");
			goto err_irq;
		}
	}

	if (drd_switch->vbus_irq >= 0) {
		ret = devm_request_irq(drd->dev, drd_switch->vbus_irq,
				  exynos_drd_switch_vbus_interrupt, irq_flags,
				  "drd_switch_vbus", drd_switch);
		if (ret) {
			dev_err(drd->dev, "cannot claim VBUS irq\n");
			goto err_irq;
		}
	}

	ret = sysfs_create_group(&drd->dev->kobj, &exynos_drd_switch_attr_group);
	if (ret) {
		dev_err(drd->dev, "cannot create switch attributes\n");
		goto err_irq;
	}

	dev_dbg(drd->dev, "DRD switch initialization finished normally\n");

	return 0;

err_irq:
	cancel_delayed_work_sync(&drd_switch->work);
	destroy_workqueue(drd_switch->wq);
err_wq:
	wake_lock_destroy(&drd_switch->wakelock);

	return ret;
}
示例#12
0
int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
{
	struct smp_cmd_pairing *req, *rsp;
	struct smp_chan *smp = conn->smp_chan;
	__u8 *keydist;

	BT_DBG("conn %p force %d", conn, force);

	if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
		return 0;

	rsp = (void *) &smp->prsp[1];

	/* The responder sends its keys first */
	if (!force && conn->hcon->out && (rsp->resp_key_dist & 0x07))
		return 0;

	req = (void *) &smp->preq[1];

	if (conn->hcon->out) {
		keydist = &rsp->init_key_dist;
		*keydist &= req->init_key_dist;
	} else {
		keydist = &rsp->resp_key_dist;
		*keydist &= req->resp_key_dist;
	}


	BT_DBG("keydist 0x%x", *keydist);

	if (*keydist & SMP_DIST_ENC_KEY) {
		struct smp_cmd_encrypt_info enc;
		struct smp_cmd_master_ident ident;
		struct hci_conn *hcon = conn->hcon;
		u8 authenticated;
		__le16 ediv;

		get_random_bytes(enc.ltk, sizeof(enc.ltk));
		get_random_bytes(&ediv, sizeof(ediv));
		get_random_bytes(ident.rand, sizeof(ident.rand));

		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);

		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
		hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
			    HCI_SMP_LTK_SLAVE, 1, authenticated,
			    enc.ltk, smp->enc_key_size, ediv, ident.rand);

		ident.ediv = ediv;

		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);

		*keydist &= ~SMP_DIST_ENC_KEY;
	}

	if (*keydist & SMP_DIST_ID_KEY) {
		struct smp_cmd_ident_addr_info addrinfo;
		struct smp_cmd_ident_info idinfo;

		/* Send a dummy key */
		get_random_bytes(idinfo.irk, sizeof(idinfo.irk));

		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);

		/* Just public address */
		memset(&addrinfo, 0, sizeof(addrinfo));
		bacpy(&addrinfo.bdaddr, conn->src);

		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
								&addrinfo);

		*keydist &= ~SMP_DIST_ID_KEY;
	}

	if (*keydist & SMP_DIST_SIGN) {
		struct smp_cmd_sign_info sign;

		/* Send a dummy key */
		get_random_bytes(sign.csrk, sizeof(sign.csrk));

		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);

		*keydist &= ~SMP_DIST_SIGN;
	}

	if (conn->hcon->out || force) {
		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
		cancel_delayed_work_sync(&conn->security_timer);
		smp_chan_destroy(conn);
	}

	return 0;
}
static void msm_otg_sm_work(struct work_struct *w)
{
	struct msm_otg *motg = container_of(w, struct msm_otg, sm_work);
	struct usb_otg *otg = motg->phy.otg;

	switch (otg->state) {
	case OTG_STATE_UNDEFINED:
		dev_dbg(otg->phy->dev, "OTG_STATE_UNDEFINED state\n");
		msm_otg_reset(otg->phy);
		msm_otg_init_sm(motg);
		otg->state = OTG_STATE_B_IDLE;
		/* FALL THROUGH */
	case OTG_STATE_B_IDLE:
		dev_dbg(otg->phy->dev, "OTG_STATE_B_IDLE state\n");
		if (!test_bit(ID, &motg->inputs) && otg->host) {
			/* disable BSV bit */
			writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
			msm_otg_start_host(otg->phy, 1);
			otg->state = OTG_STATE_A_HOST;
		} else if (test_bit(B_SESS_VLD, &motg->inputs)) {
			switch (motg->chg_state) {
			case USB_CHG_STATE_UNDEFINED:
				msm_chg_detect_work(&motg->chg_work.work);
				break;
			case USB_CHG_STATE_DETECTED:
				switch (motg->chg_type) {
				case USB_DCP_CHARGER:
					msm_otg_notify_charger(motg,
							IDEV_CHG_MAX);
					break;
				case USB_CDP_CHARGER:
					msm_otg_notify_charger(motg,
							IDEV_CHG_MAX);
					msm_otg_start_peripheral(otg->phy, 1);
					otg->state
						= OTG_STATE_B_PERIPHERAL;
					break;
				case USB_SDP_CHARGER:
					msm_otg_notify_charger(motg, IUNIT);
					msm_otg_start_peripheral(otg->phy, 1);
					otg->state
						= OTG_STATE_B_PERIPHERAL;
					break;
				default:
					break;
				}
				break;
			default:
				break;
			}
		} else {
			/*
			 * If charger detection work is pending, decrement
			 * the pm usage counter to balance with the one that
			 * is incremented in charger detection work.
			 */
			if (cancel_delayed_work_sync(&motg->chg_work)) {
				pm_runtime_put_sync(otg->phy->dev);
				msm_otg_reset(otg->phy);
			}
			msm_otg_notify_charger(motg, 0);
			motg->chg_state = USB_CHG_STATE_UNDEFINED;
			motg->chg_type = USB_INVALID_CHARGER;
		}

		if (otg->state == OTG_STATE_B_IDLE)
			pm_runtime_put_sync(otg->phy->dev);
		break;
	case OTG_STATE_B_PERIPHERAL:
		dev_dbg(otg->phy->dev, "OTG_STATE_B_PERIPHERAL state\n");
		if (!test_bit(B_SESS_VLD, &motg->inputs) ||
				!test_bit(ID, &motg->inputs)) {
			msm_otg_notify_charger(motg, 0);
			msm_otg_start_peripheral(otg->phy, 0);
			motg->chg_state = USB_CHG_STATE_UNDEFINED;
			motg->chg_type = USB_INVALID_CHARGER;
			otg->state = OTG_STATE_B_IDLE;
			msm_otg_reset(otg->phy);
			schedule_work(w);
		}
		break;
	case OTG_STATE_A_HOST:
		dev_dbg(otg->phy->dev, "OTG_STATE_A_HOST state\n");
		if (test_bit(ID, &motg->inputs)) {
			msm_otg_start_host(otg->phy, 0);
			otg->state = OTG_STATE_B_IDLE;
			msm_otg_reset(otg->phy);
			schedule_work(w);
		}
		break;
	default:
		break;
	}
}
示例#14
0
int smp_distribute_keys(struct l2cap_conn *conn)
{
	struct smp_cmd_pairing *req, *rsp;
	struct smp_chan *smp = conn->smp_chan;
	struct hci_conn *hcon = conn->hcon;
	struct hci_dev *hdev = hcon->hdev;
	__u8 *keydist;

	BT_DBG("conn %p", conn);

	if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
		return 0;

	rsp = (void *) &smp->prsp[1];

	/* The responder sends its keys first */
	if (hcon->out && (smp->remote_key_dist & 0x07))
		return 0;

	req = (void *) &smp->preq[1];

	if (hcon->out) {
		keydist = &rsp->init_key_dist;
		*keydist &= req->init_key_dist;
	} else {
		keydist = &rsp->resp_key_dist;
		*keydist &= req->resp_key_dist;
	}

	BT_DBG("keydist 0x%x", *keydist);

	if (*keydist & SMP_DIST_ENC_KEY) {
		struct smp_cmd_encrypt_info enc;
		struct smp_cmd_master_ident ident;
		struct smp_ltk *ltk;
		u8 authenticated;
		__le16 ediv;
		__le64 rand;

		get_random_bytes(enc.ltk, sizeof(enc.ltk));
		get_random_bytes(&ediv, sizeof(ediv));
		get_random_bytes(&rand, sizeof(rand));

		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);

		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
				  HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
				  smp->enc_key_size, ediv, rand);
		smp->slave_ltk = ltk;

		ident.ediv = ediv;
		ident.rand = rand;

		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);

		*keydist &= ~SMP_DIST_ENC_KEY;
	}

	if (*keydist & SMP_DIST_ID_KEY) {
		struct smp_cmd_ident_addr_info addrinfo;
		struct smp_cmd_ident_info idinfo;

		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));

		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);

		/* The hci_conn contains the local identity address
		 * after the connection has been established.
		 *
		 * This is true even when the connection has been
		 * established using a resolvable random address.
		 */
		bacpy(&addrinfo.bdaddr, &hcon->src);
		addrinfo.addr_type = hcon->src_type;

		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
			     &addrinfo);

		*keydist &= ~SMP_DIST_ID_KEY;
	}

	if (*keydist & SMP_DIST_SIGN) {
		struct smp_cmd_sign_info sign;
		struct smp_csrk *csrk;

		/* Generate a new random key */
		get_random_bytes(sign.csrk, sizeof(sign.csrk));

		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
		if (csrk) {
			csrk->master = 0x00;
			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
		}
		smp->slave_csrk = csrk;

		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);

		*keydist &= ~SMP_DIST_SIGN;
	}

	/* If there are still keys to be received wait for them */
	if ((smp->remote_key_dist & 0x07))
		return 0;

	clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
	cancel_delayed_work_sync(&conn->security_timer);
	set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
	smp_notify_keys(conn);

	smp_chan_destroy(conn);

	return 0;
}
示例#15
0
static int tps6507x_ts_probe(struct platform_device *pdev)
{
	int error;
	struct tps6507x_ts *tsc;
	struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
	struct touchscreen_init_data *init_data;
	struct input_dev *input_dev;
	struct tps6507x_board *tps_board;
	int schd;

	/**
	 * tps_board points to pmic related constants
	 * coming from the board-evm file.
	 */

	tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data;

	if (!tps_board) {
		dev_err(tps6507x_dev->dev,
			"Could not find tps6507x platform data\n");
		return -EIO;
	}

	/**
	 * init_data points to array of regulator_init structures
	 * coming from the board-evm file.
	 */

	init_data = tps_board->tps6507x_ts_init_data;

	tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL);
	if (!tsc) {
		dev_err(tps6507x_dev->dev, "failed to allocate driver data\n");
		error = -ENOMEM;
		goto err0;
	}

	tps6507x_dev->ts = tsc;
	tsc->mfd = tps6507x_dev;
	tsc->dev = tps6507x_dev->dev;
	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(tsc->dev, "Failed to allocate input device.\n");
		error = -ENOMEM;
		goto err1;
	}

	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

	input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0);

	input_dev->name = "TPS6507x Touchscreen";
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = tsc->dev;

	snprintf(tsc->phys, sizeof(tsc->phys),
		 "%s/input0", dev_name(tsc->dev));
	input_dev->phys = tsc->phys;

	dev_dbg(tsc->dev, "device: %s\n", input_dev->phys);

	input_set_drvdata(input_dev, tsc);

	tsc->input_dev = input_dev;

	INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler);

	if (init_data) {
		tsc->poll_period = init_data->poll_period;
		tsc->vref = init_data->vref;
		tsc->min_pressure = init_data->min_pressure;
		input_dev->id.vendor = init_data->vendor;
		input_dev->id.product = init_data->product;
		input_dev->id.version = init_data->version;
	} else {
		tsc->poll_period = TSC_DEFAULT_POLL_PERIOD;
		tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE;
	}

	error = tps6507x_adc_standby(tsc);
	if (error)
		goto err2;

	error = input_register_device(input_dev);
	if (error)
		goto err2;

	schd = schedule_delayed_work(&tsc->work,
				     msecs_to_jiffies(tsc->poll_period));

	if (schd)
		tsc->polling = 1;
	else {
		tsc->polling = 0;
		dev_err(tsc->dev, "schedule failed");
		goto err2;
	 }
	platform_set_drvdata(pdev, tps6507x_dev);

	return 0;

err2:
	cancel_delayed_work_sync(&tsc->work);
	input_free_device(input_dev);
err1:
	kfree(tsc);
	tps6507x_dev->ts = NULL;
err0:
	return error;
}
示例#16
0
/**
 * dwc3_otg_sm_work - workqueue function.
 *
 * @w: Pointer to the dwc3 otg workqueue
 *
 * NOTE: After any change in phy->state,
 * we must reschdule the state machine.
 */
static void dwc3_otg_sm_work(struct work_struct *w)
{
	struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work.work);
	struct usb_phy *phy = dotg->otg.phy;
	struct dwc3_charger *charger = dotg->charger;
	bool work = 0;
	int ret = 0;
	unsigned long delay = 0;

	pm_runtime_resume(phy->dev);
	dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));

	/* Check OTG state */
	switch (phy->state) {
	case OTG_STATE_UNDEFINED:
		dwc3_otg_init_sm(dotg);
		if (!dotg->psy) {
			dotg->psy = power_supply_get_by_name("usb");

			if (!dotg->psy)
				dev_err(phy->dev,
					 "couldn't get usb power supply\n");
		}

		/* Switch to A or B-Device according to ID / BSV */
		if (!test_bit(ID, &dotg->inputs)) {
			dev_dbg(phy->dev, "!id\n");
			phy->state = OTG_STATE_A_IDLE;
			work = 1;
		} else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
			dev_dbg(phy->dev, "b_sess_vld\n");
			phy->state = OTG_STATE_B_IDLE;
			work = 1;
		} else {
			phy->state = OTG_STATE_B_IDLE;
			dev_dbg(phy->dev, "No device, trying to suspend\n");
			pm_runtime_put_sync(phy->dev);
		}
		break;

	case OTG_STATE_B_IDLE:
		if (!test_bit(ID, &dotg->inputs)) {
			dev_dbg(phy->dev, "!id\n");
			phy->state = OTG_STATE_A_IDLE;
			work = 1;
			dotg->charger_retry_count = 0;
			if (charger) {
				if (charger->chg_type == DWC3_INVALID_CHARGER)
					charger->start_detection(dotg->charger,
									false);
				else
					charger->chg_type =
							DWC3_INVALID_CHARGER;
			}
		} else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
			dev_dbg(phy->dev, "b_sess_vld\n");
			if (charger) {
				/* Has charger been detected? If no detect it */
				switch (charger->chg_type) {
				case DWC3_DCP_CHARGER:
				case DWC3_PROPRIETARY_CHARGER:
					dev_dbg(phy->dev, "lpm, DCP charger\n");
					dwc3_otg_set_power(phy,
							DWC3_IDEV_CHG_MAX);
					pm_runtime_put_sync(phy->dev);
					break;
				case DWC3_CDP_CHARGER:
					dwc3_otg_set_power(phy,
							DWC3_IDEV_CHG_MAX);
					dwc3_otg_start_peripheral(&dotg->otg,
									1);
					phy->state = OTG_STATE_B_PERIPHERAL;
					work = 1;
					break;
				case DWC3_SDP_CHARGER:
					dwc3_otg_start_peripheral(&dotg->otg,
									1);
					phy->state = OTG_STATE_B_PERIPHERAL;
					pr_info("DWC3_SDP_CHARGER\n");
					work = 1;
					break;
				case DWC3_FLOATED_CHARGER:
					if (dotg->charger_retry_count <
							max_chgr_retry_count)
						dotg->charger_retry_count++;
					/*
					 * In case of floating charger, if
					 * retry count equal to max retry count
					 * notify PMIC about floating charger
					 * and put Hw in low power mode. Else
					 * perform charger detection again by
					 * calling start_detection() with false
					 * and then with true argument.
					 */
					if (dotg->charger_retry_count ==
						max_chgr_retry_count) {
						dwc3_otg_set_power(phy, 0);
						pm_runtime_put_sync(phy->dev);
						break;
					}
					charger->start_detection(dotg->charger,
									false);

				default:
					dev_dbg(phy->dev, "chg_det started\n");
					charger->start_detection(charger, true);
					break;
				}
			} else {
				/* no charger registered, start peripheral */
				if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
					/*
					 * Probably set_peripheral not called
					 * yet. We will re-try as soon as it
					 * will be called
					 */
					dev_err(phy->dev, "enter lpm as\n"
						"unable to start B-device\n");
					phy->state = OTG_STATE_UNDEFINED;
					pm_runtime_put_sync(phy->dev);
					return;
				}
			}
		} else {
			if (charger)
				charger->start_detection(dotg->charger, false);

			dotg->charger_retry_count = 0;
			dwc3_otg_set_power(phy, 0);
			dev_dbg(phy->dev, "No device, trying to suspend\n");
			pm_runtime_put_sync(phy->dev);
		}
		break;

	case OTG_STATE_B_PERIPHERAL:
#ifdef CONFIG_PANTECH_USB_BLOCKING_MDMSTATE
		if (get_pantech_mdm_state())
			dwc3_otg_set_power(phy, DWC3_BLOCKING_USB_MDMSTATE_MAX);
#endif
#ifndef CONFIG_PANTECH_SIO_BUG_FIX
		if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
				!test_bit(ID, &dotg->inputs)) {
#else
		if (!test_bit(B_SESS_VLD, &dotg->inputs)) {
		
#endif
			dev_dbg(phy->dev, "!id || !bsv\n");
			dwc3_otg_start_peripheral(&dotg->otg, 0);
			phy->state = OTG_STATE_B_IDLE;
			if (charger)
				charger->chg_type = DWC3_INVALID_CHARGER;
			work = 1;
		}
		break;

	case OTG_STATE_A_IDLE:
		/* Switch to A-Device*/
		if (test_bit(ID, &dotg->inputs)) {
			dev_dbg(phy->dev, "id\n");
			phy->state = OTG_STATE_B_IDLE;
			dotg->vbus_retry_count = 0;
			work = 1;
		} else {
			phy->state = OTG_STATE_A_HOST;
			ret = dwc3_otg_start_host(&dotg->otg, 1);
			if ((ret == -EPROBE_DEFER) &&
						dotg->vbus_retry_count < 3) {
				/*
				 * Get regulator failed as regulator driver is
				 * not up yet. Will try to start host after 1sec
				 */
				phy->state = OTG_STATE_A_IDLE;
				dev_dbg(phy->dev, "Unable to get vbus regulator. Retrying...\n");
				delay = VBUS_REG_CHECK_DELAY;
				work = 1;
				dotg->vbus_retry_count++;
			} else if (ret) {
				/*
				 * Probably set_host was not called yet.
				 * We will re-try as soon as it will be called
				 */
				dev_dbg(phy->dev, "enter lpm as\n"
					"unable to start A-device\n");
				phy->state = OTG_STATE_A_IDLE;
				pm_runtime_put_sync(phy->dev);
				return;
			}
		}
		break;

	case OTG_STATE_A_HOST:
		if (test_bit(ID, &dotg->inputs)) {
			dev_dbg(phy->dev, "id\n");
#ifdef CONFIG_PANTECH_SIO_BUG_FIX
			/* FIXME : If OTG cable is disconnecting, below process is must completed 
			 * before pm_runtime_suspend.
			 * So we are ignored pm_runtime_suspend request.
			 * LS4-USB tarial
			 */
			pm_runtime_get_noresume(phy->dev);
#endif
			dwc3_otg_start_host(&dotg->otg, 0);
			phy->state = OTG_STATE_B_IDLE;
			dotg->vbus_retry_count = 0;
			work = 1;
#ifdef CONFIG_PANTECH_SIO_BUG_FIX
			pm_runtime_put_noidle(phy->dev);
#endif
		}
		break;

	default:
		dev_err(phy->dev, "%s: invalid otg-state\n", __func__);

	}

	if (work)
		queue_delayed_work(system_nrt_wq, &dotg->sm_work, delay);
}


/**
 * dwc3_otg_reset - reset dwc3 otg registers.
 *
 * @w: Pointer to the dwc3 otg workqueue
 */
static void dwc3_otg_reset(struct dwc3_otg *dotg)
{
	static int once;
	struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;

	/*
	 * OCFG[2] - OTG-Version = 1
	 * OCFG[1] - HNPCap = 0
	 * OCFG[0] - SRPCap = 0
	 */
	if (ext_xceiv && !ext_xceiv->otg_capability)
		dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);

	/*
	 * OCTL[6] - PeriMode = 1
	 * OCTL[5] - PrtPwrCtl = 0
	 * OCTL[4] - HNPReq = 0
	 * OCTL[3] - SesReq = 0
	 * OCTL[2] - TermSelDLPulse = 0
	 * OCTL[1] - DevSetHNPEn = 0
	 * OCTL[0] - HstSetHNPEn = 0
	 */
	if (!once) {
		if (ext_xceiv && !ext_xceiv->otg_capability)
			dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
		once++;
	}

	/* Clear all otg events (interrupts) indications  */
	dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);

	/* Enable ID/BSV StsChngEn event*/
	if (ext_xceiv && !ext_xceiv->otg_capability)
		dwc3_writel(dotg->regs, DWC3_OEVTEN,
				DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
				DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
}

/**
 * dwc3_otg_init - Initializes otg related registers
 * @dwc: Pointer to out controller context structure
 *
 * Returns 0 on success otherwise negative errno.
 */
int dwc3_otg_init(struct dwc3 *dwc)
{
	u32	reg;
	int ret = 0;
	struct dwc3_otg *dotg;

	dev_dbg(dwc->dev, "dwc3_otg_init\n");

	/*
	 * GHWPARAMS6[10] bit is SRPSupport.
	 * This bit also reflects DWC_USB3_EN_OTG
	 */
	reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
	if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
		/*
		 * No OTG support in the HW core.
		 * We return 0 to indicate no error, since this is acceptable
		 * situation, just continue probe the dwc3 driver without otg.
		 */
		dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
		return 0;
	}

	/* Allocate and init otg instance */
	dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
	if (!dotg) {
		dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
		return -ENOMEM;
	}

	/* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
	dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
								"otg_irq");
	if (dotg->irq < 0) {
		dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
		ret = -ENODEV;
		goto err1;
	}

	dotg->regs = dwc->regs;

	dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
	dotg->otg.set_host = dwc3_otg_set_host;

	/* This reference is used by dwc3 modules for checking otg existance */
	dwc->dotg = dotg;

	dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
	if (!dotg->otg.phy) {
		dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
		ret = -ENOMEM;
		goto err1;
	}

	dotg->dwc = dwc;
	dotg->otg.phy->otg = &dotg->otg;
	dotg->otg.phy->dev = dwc->dev;
	dotg->otg.phy->set_power = dwc3_otg_set_power;
	dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;

	ret = usb_set_transceiver(dotg->otg.phy);
	if (ret) {
		dev_err(dotg->otg.phy->dev,
			"%s: failed to set transceiver, already exists\n",
			__func__);
		goto err2;
	}

	dotg->otg.phy->state = OTG_STATE_UNDEFINED;

	init_completion(&dotg->dwc3_xcvr_vbus_init);
	INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work);

	ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
				"dwc3_otg", dotg);
	if (ret) {
		dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
				dotg->irq, ret);
		goto err3;
	}

	pm_runtime_get(dwc->dev);

	return 0;

err3:
	cancel_delayed_work_sync(&dotg->sm_work);
	usb_set_transceiver(NULL);
err2:
	kfree(dotg->otg.phy);
err1:
	dwc->dotg = NULL;
	kfree(dotg);

	return ret;
}
int close_send_current(void)
{
	if (atomic_cmpxchg(&enabled, 1, 0))
				cancel_delayed_work_sync(&read_current_work);
	return 0;
}
示例#18
0
void hv_kvp_deinit(void)
{
	cn_del_callback(&kvp_id);
	cancel_delayed_work_sync(&kvp_work);
	cancel_work_sync(&kvp_sendkey_work);
}
static int hdmi_streamon(struct hdmi_device *hdev)
{
    const struct hdmi_timings *conf = hdev->cur_conf;
    struct device *dev = hdev->dev;
    int ret;
    u32 val0, val1, val2;

    dev_dbg(dev, "%s\n", __func__);

    /* 3D test */
    hdmi_set_infoframe(hdev);

    /* set packets for audio */
    hdmi_set_packets(hdev);

    /* init audio */
#if defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_I2S)
    hdmi_reg_i2s_audio_init(hdev);
#elif defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_SPDIF)
    hdmi_reg_spdif_audio_init(hdev);
#endif
    /* enbale HDMI audio */
    if (hdev->audio_enable)
        hdmi_audio_enable(hdev, 1);

    hdmi_set_dvi_mode(hdev);

    /* controls the pixel value limitation */
    hdmi_reg_set_limits(hdev);

    /* setting core registers */
    hdmi_timing_apply(hdev, conf);

    /* enable HDMI and timing generator */
    hdmi_enable(hdev, 1);
    hdmi_tg_enable(hdev, 1);

    hdev->streaming = HDMI_STREAMING;

    /* change the HPD interrupt: External -> Internal */
    disable_irq(hdev->ext_irq);
    cancel_delayed_work_sync(&hdev->hpd_work_ext);
    hdmi_reg_set_int_hpd(hdev);
    enable_irq(hdev->int_irq);
    dev_info(hdev->dev, "HDMI interrupt changed to internal\n");

    /* start HDCP if enabled */
    if (hdev->hdcp_info.hdcp_enable) {
        ret = hdcp_start(hdev);
        if (ret)
            return ret;
    }

    val0 = hdmi_read(hdev, HDMI_ACR_MCTS0);
    val1 = hdmi_read(hdev, HDMI_ACR_MCTS1);
    val2 = hdmi_read(hdev, HDMI_ACR_MCTS2);
    dev_dbg(dev, "HDMI_ACR_MCTS0 : 0x%08x\n", val0);
    dev_dbg(dev, "HDMI_ACR_MCTS1 : 0x%08x\n", val1);
    dev_dbg(dev, "HDMI_ACR_MCTS2 : 0x%08x\n", val2);

    hdmi_dumpregs(hdev, "streamon");
    return 0;
}
示例#20
0
int
zfsctl_mount_snapshot(struct path *path, int flags)
{
	struct dentry *dentry = path->dentry;
	struct inode *ip = dentry->d_inode;
	zfs_sb_t *zsb = ITOZSB(ip);
	char *full_name, *full_path;
	zfs_snapentry_t *sep;
	zfs_snapentry_t search;
	char *argv[] = { "/bin/sh", "-c", NULL, NULL };
	char *envp[] = { NULL };
	int error;

	ZFS_ENTER(zsb);

	full_name = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
	full_path = kmem_zalloc(PATH_MAX, KM_SLEEP);

	error = zfsctl_snapshot_zname(ip, dname(dentry), MAXNAMELEN, full_name);
	if (error)
		goto error;

	error = zfsctl_snapshot_zpath(path, PATH_MAX, full_path);
	if (error)
		goto error;

	/*
	 * Attempt to mount the snapshot from user space.  Normally this
	 * would be done using the vfs_kern_mount() function, however that
	 * function is marked GPL-only and cannot be used.  On error we
	 * careful to log the real error to the console and return EISDIR
	 * to safely abort the automount.  This should be very rare.
	 */
	argv[2] = kmem_asprintf(SET_MOUNT_CMD, full_name, full_path);
	error = call_usermodehelper(argv[0], argv, envp, 1);
	strfree(argv[2]);
	if (error) {
		printk("ZFS: Unable to automount %s at %s: %d\n",
		    full_name, full_path, error);
		error = EISDIR;
		goto error;
	}

	mutex_enter(&zsb->z_ctldir_lock);

	/*
	 * Ensure a previous entry does not exist, if it does safely remove
	 * it any cancel the outstanding expiration.  This can occur when a
	 * snapshot is manually unmounted and then an automount is triggered.
	 */
	search.se_name = full_name;
	sep = avl_find(&zsb->z_ctldir_snaps, &search, NULL);
	if (sep) {
		avl_remove(&zsb->z_ctldir_snaps, sep);
		cancel_delayed_work_sync(&sep->se_work);
		zfsctl_sep_free(sep);
	}

	sep = zfsctl_sep_alloc();
	sep->se_name = full_name;
	sep->se_path = full_path;
	sep->se_inode = ip;
	avl_add(&zsb->z_ctldir_snaps, sep);

        spl_init_delayed_work(&sep->se_work, zfsctl_expire_snapshot, sep);
	schedule_delayed_work(&sep->se_work, zfs_expire_snapshot * HZ);

	mutex_exit(&zsb->z_ctldir_lock);
error:
	if (error) {
		kmem_free(full_name, MAXNAMELEN);
		kmem_free(full_path, PATH_MAX);
	}

	ZFS_EXIT(zsb);

	return (error);
}
static void usbhs0_hardware_exit(struct platform_device *pdev)
{
	struct usbhs_private *priv = usbhs_get_priv(pdev);

	cancel_delayed_work_sync(&priv->work);
}
static inline void
WaitForDelayedWork(CommOSWork *work)
{
   cancel_delayed_work_sync(work);
}
示例#23
0
static int compass_akm_set_mode(struct i2c_client *client, char mode)
{
	struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); 
	int result = 0;	

	switch(mode & 0x0f)
	{
		case AK8963_MODE_SNG_MEASURE:
		case AK8963_MODE_SELF_TEST: 	
		case AK8963_MODE_FUSE_ACCESS:			
			if(sensor->status_cur == SENSOR_OFF)
			{
				if(sensor->pdata->irq_enable)
				{
					//DBG("%s:enable irq=%d\n",__func__,client->irq);
					//enable_irq(client->irq);
				}	
				else
				{
					schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
				}
				
				sensor->status_cur = SENSOR_ON;
			}

			break;

		case AK8963_MODE_POWERDOWN: 	
			if(sensor->status_cur == SENSOR_ON)
			{
				if(sensor->pdata->irq_enable)
				{	
					//DBG("%s:disable irq=%d\n",__func__,client->irq);
					//disable_irq_nosync(client->irq);//disable irq
				}
				else
				cancel_delayed_work_sync(&sensor->delaywork);	

				sensor->status_cur = SENSOR_OFF;
			}
			break;

	}
	
	switch(mode & 0x0f)
	{
		case AK8963_MODE_SNG_MEASURE:		
			result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
			if(result)
			printk("%s:i2c error,mode=%d\n",__func__,mode);				
			break;
		case AK8963_MODE_SELF_TEST:			
			result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
			if(result)
			printk("%s:i2c error,mode=%d\n",__func__,mode);
			break;
		case AK8963_MODE_FUSE_ACCESS:
			result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
			if(result)
			printk("%s:i2c error,mode=%d\n",__func__,mode);
			break;
		case AK8963_MODE_POWERDOWN:
			/* Set powerdown mode */
			result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_MODE_POWERDOWN);
			if(result)
			printk("%s:i2c error,mode=%d\n",__func__,mode);
			udelay(100);
			break;
		default:
			printk("%s: Unknown mode(%d)", __func__, mode);
			result = -EINVAL;
			break;
	}
	DBG("%s:mode=0x%x\n",__func__,mode);
	return result;

}
示例#24
0
void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
{
	cancel_delayed_work_sync(&rt2x00dev->link.work);
}
示例#25
0
static int  mma8452_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct mma8452_data *mma8452;
	struct mma8452_platform_data *pdata = pdata = client->dev.platform_data;
	int err;
	char devid;

	mmaprintkf("%s enter\n",__FUNCTION__);

	mma8452 = kzalloc(sizeof(struct mma8452_data), GFP_KERNEL);
	if (!mma8452) {
		mmaprintk("[mma8452]:alloc data failed.\n");
		err = -ENOMEM;
		goto exit_alloc_data_failed;
	}
    
	INIT_WORK(&mma8452->work, mma8452_work_func);
	INIT_DELAYED_WORK(&mma8452->delaywork, mma8452_delaywork_func);

	memset(&(mma8452->sense_data), 0, sizeof(struct mma8452_axis) );
	mutex_init(&(mma8452->sense_data_mutex) );

	atomic_set(&(mma8452->data_ready), 0);
	init_waitqueue_head(&(mma8452->data_ready_wq) );

	mma8452->start_count = 0;
	mutex_init(&(mma8452->operation_mutex) );

	mma8452->status = MMA8452_CLOSE;

	mma8452->client = client;
	i2c_set_clientdata(client, mma8452);

	this_client = client;

	devid = mma8452_get_devid(this_client);
	if ((MMA8452_DEVID != devid) && (MMA8451_DEVID != devid)) {
		pr_info("mma8452: invalid devid\n");
		goto exit_invalid_devid;
	}

	err = mma8452_init_client(client);
	if (err < 0) {
		mmaprintk(KERN_ERR
		       "mma8452_probe: mma8452_init_client failed\n");
		goto exit_request_gpio_irq_failed;
	}

	mma8452->input_dev = input_allocate_device();
	if (!mma8452->input_dev) {
		err = -ENOMEM;
		mmaprintk(KERN_ERR
		       "mma8452_probe: Failed to allocate input device\n");
		goto exit_input_allocate_device_failed;
	}

	set_bit(EV_ABS, mma8452->input_dev->evbit);

	/* x-axis acceleration */
	input_set_abs_params(mma8452->input_dev, ABS_X, -2000, 2000, 0, 0); //2g full scale range
	/* y-axis acceleration */
	input_set_abs_params(mma8452->input_dev, ABS_Y, -2000, 2000, 0, 0); //2g full scale range
	/* z-axis acceleration */
	input_set_abs_params(mma8452->input_dev, ABS_Z, -2000, 2000, 0, 0); //2g full scale range

	// mma8452->input_dev->name = "compass";
	mma8452->input_dev->name = "gsensor";
	mma8452->input_dev->dev.parent = &client->dev;

	err = input_register_device(mma8452->input_dev);
	if (err < 0) {
		mmaprintk(KERN_ERR
		       "mma8452_probe: Unable to register input device: %s\n",
		       mma8452->input_dev->name);
		goto exit_input_register_device_failed;
	}

    mma8452_device.parent = &client->dev;
	err = misc_register(&mma8452_device);
	if (err < 0) {
		mmaprintk(KERN_ERR
		       "mma8452_probe: mmad_device register failed\n");
		goto exit_misc_device_register_mma8452_device_failed;
	}

	err = gsensor_sysfs_init();
	if (err < 0) {
		mmaprintk(KERN_ERR
            "mma8452_probe: gsensor sysfs init failed\n");
		goto exit_gsensor_sysfs_init_failed;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
    mma8452_early_suspend.suspend = mma8452_suspend;
    mma8452_early_suspend.resume = mma8452_resume;
    mma8452_early_suspend.level = 0x2;
    register_early_suspend(&mma8452_early_suspend);
#endif

	printk(KERN_INFO "mma8452 probe ok\n");
#if  0
//	mma8452_start_test(this_client);
	mma8452_start(client, MMA8452_RATE_12P5);
#endif
	return 0;

exit_gsensor_sysfs_init_failed:
    misc_deregister(&mma8452_device);
exit_misc_device_register_mma8452_device_failed:
    input_unregister_device(mma8452->input_dev);
exit_input_register_device_failed:
	input_free_device(mma8452->input_dev);
exit_input_allocate_device_failed:
	free_irq(client->irq, mma8452);
exit_request_gpio_irq_failed:
	cancel_delayed_work_sync(&mma8452->delaywork);
	cancel_work_sync(&mma8452->work);
exit_invalid_devid:
	kfree(mma8452);
exit_alloc_data_failed:
    ;
	mmaprintk("%s error %d\n", __FUNCTION__, err);
	return -1;
}
示例#26
0
void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
{
	cancel_delayed_work_sync(&rt2x00dev->link.watchdog_work);
}
示例#27
0
static int hvfb_probe(struct hv_device *hdev,
		      const struct hv_vmbus_device_id *dev_id)
{
	struct fb_info *info;
	struct hvfb_par *par;
	int ret;

	info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
	if (!info) {
		pr_err("No memory for framebuffer info\n");
		return -ENOMEM;
	}

	par = info->par;
	par->info = info;
	par->fb_ready = false;
	init_completion(&par->wait);
	INIT_DELAYED_WORK(&par->dwork, hvfb_update_work);

	/* Connect to VSP */
	hv_set_drvdata(hdev, info);
	ret = synthvid_connect_vsp(hdev);
	if (ret) {
		pr_err("Unable to connect to VSP\n");
		goto error1;
	}

	ret = hvfb_getmem(info);
	if (ret) {
		pr_err("No memory for framebuffer\n");
		goto error2;
	}

	hvfb_get_option(info);
	pr_info("Screen resolution: %dx%d, Color depth: %d\n",
		screen_width, screen_height, screen_depth);


	/* Set up fb_info */
	info->flags = FBINFO_DEFAULT;

	info->var.xres_virtual = info->var.xres = screen_width;
	info->var.yres_virtual = info->var.yres = screen_height;
	info->var.bits_per_pixel = screen_depth;

	if (info->var.bits_per_pixel == 16) {
		info->var.red = (struct fb_bitfield){11, 5, 0};
		info->var.green = (struct fb_bitfield){5, 6, 0};
		info->var.blue = (struct fb_bitfield){0, 5, 0};
		info->var.transp = (struct fb_bitfield){0, 0, 0};
	} else {
		info->var.red = (struct fb_bitfield){16, 8, 0};
		info->var.green = (struct fb_bitfield){8, 8, 0};
		info->var.blue = (struct fb_bitfield){0, 8, 0};
		info->var.transp = (struct fb_bitfield){24, 8, 0};
	}

	info->var.activate = FB_ACTIVATE_NOW;
	info->var.height = -1;
	info->var.width = -1;
	info->var.vmode = FB_VMODE_NONINTERLACED;

	strcpy(info->fix.id, KBUILD_MODNAME);
	info->fix.type = FB_TYPE_PACKED_PIXELS;
	info->fix.visual = FB_VISUAL_TRUECOLOR;
	info->fix.line_length = screen_width * screen_depth / 8;
	info->fix.accel = FB_ACCEL_NONE;

	info->fbops = &hvfb_ops;
	info->pseudo_palette = par->pseudo_palette;

	/* Send config to host */
	ret = synthvid_send_config(hdev);
	if (ret)
		goto error;

	ret = register_framebuffer(info);
	if (ret) {
		pr_err("Unable to register framebuffer\n");
		goto error;
	}

	par->fb_ready = true;

	par->synchronous_fb = false;
	par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
	atomic_notifier_chain_register(&panic_notifier_list,
				       &par->hvfb_panic_nb);

	return 0;

error:
	hvfb_putmem(info);
error2:
	vmbus_close(hdev->channel);
error1:
	cancel_delayed_work_sync(&par->dwork);
	hv_set_drvdata(hdev, NULL);
	framebuffer_release(info);
	return ret;
}


static int hvfb_remove(struct hv_device *hdev)
{
	struct fb_info *info = hv_get_drvdata(hdev);
	struct hvfb_par *par = info->par;

	atomic_notifier_chain_unregister(&panic_notifier_list,
					 &par->hvfb_panic_nb);

	par->update = false;
	par->fb_ready = false;

	unregister_framebuffer(info);
	cancel_delayed_work_sync(&par->dwork);

	vmbus_close(hdev->channel);
	hv_set_drvdata(hdev, NULL);

	hvfb_putmem(info);
	framebuffer_release(info);

	return 0;
}


static const struct pci_device_id pci_stub_id_table[] = {
	{
		.vendor      = PCI_VENDOR_ID_MICROSOFT,
		.device      = PCI_DEVICE_ID_HYPERV_VIDEO,
	},
	{ /* end of list */ }
};

static const struct hv_vmbus_device_id id_table[] = {
	/* Synthetic Video Device GUID */
	{HV_SYNTHVID_GUID},
	{}
};

MODULE_DEVICE_TABLE(pci, pci_stub_id_table);
MODULE_DEVICE_TABLE(vmbus, id_table);

static struct hv_driver hvfb_drv = {
	.name = KBUILD_MODNAME,
	.id_table = id_table,
	.probe = hvfb_probe,
	.remove = hvfb_remove,
};

static int hvfb_pci_stub_probe(struct pci_dev *pdev,
			       const struct pci_device_id *ent)
{
	return 0;
}

static void hvfb_pci_stub_remove(struct pci_dev *pdev)
{
}

static struct pci_driver hvfb_pci_stub_driver = {
	.name =		KBUILD_MODNAME,
	.id_table =	pci_stub_id_table,
	.probe =	hvfb_pci_stub_probe,
	.remove =	hvfb_pci_stub_remove,
};

static int __init hvfb_drv_init(void)
{
	int ret;

	ret = vmbus_driver_register(&hvfb_drv);
	if (ret != 0)
		return ret;

	ret = pci_register_driver(&hvfb_pci_stub_driver);
	if (ret != 0) {
		vmbus_driver_unregister(&hvfb_drv);
		return ret;
	}

	return 0;
}

static void __exit hvfb_drv_exit(void)
{
	pci_unregister_driver(&hvfb_pci_stub_driver);
	vmbus_driver_unregister(&hvfb_drv);
}

module_init(hvfb_drv_init);
module_exit(hvfb_drv_exit);

MODULE_LICENSE("GPL");
MODULE_VERSION(HV_DRV_VERSION);
MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver");
示例#28
0
static void vss_on_reset(void)
{
	if (cancel_delayed_work_sync(&vss_timeout_work))
		vss_respond_to_host(HV_E_FAIL);
	vss_transaction.state = HVUTIL_DEVICE_INIT;
}
示例#29
0
static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
{
	struct qedf_ioreq *orig_io_req;
	struct qedf_ioreq *srr_req;
	struct qedf_mp_req *mp_req;
	struct fc_frame_header *mp_fc_hdr, *fh;
	struct fc_frame *fp;
	void *resp_buf, *fc_payload;
	u32 resp_len;
	struct fc_lport *lport;
	struct qedf_ctx *qedf;
	int refcount;
	u8 opcode;

	srr_req = cb_arg->io_req;
	qedf = srr_req->fcport->qedf;
	lport = qedf->lport;

	orig_io_req = cb_arg->aborted_io_req;

	if (!orig_io_req)
		goto out_free;

	clear_bit(QEDF_CMD_SRR_SENT, &orig_io_req->flags);

	if (srr_req->event != QEDF_IOREQ_EV_ELS_TMO &&
	    srr_req->event != QEDF_IOREQ_EV_ELS_ERR_DETECT)
		cancel_delayed_work_sync(&orig_io_req->timeout_work);

	refcount = kref_read(&orig_io_req->refcount);
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Entered: orig_io=%p,"
		   " orig_io_xid=0x%x, rec_xid=0x%x, refcount=%d\n",
		   orig_io_req, orig_io_req->xid, srr_req->xid, refcount);

	/* If a SRR times out, simply free resources */
	if (srr_req->event == QEDF_IOREQ_EV_ELS_TMO)
		goto out_put;

	/* Normalize response data into struct fc_frame */
	mp_req = &(srr_req->mp_req);
	mp_fc_hdr = &(mp_req->resp_fc_hdr);
	resp_len = mp_req->resp_len;
	resp_buf = mp_req->resp_buf;

	fp = fc_frame_alloc(lport, resp_len);
	if (!fp) {
		QEDF_ERR(&(qedf->dbg_ctx),
		    "fc_frame_alloc failure.\n");
		goto out_put;
	}

	/* Copy frame header from firmware into fp */
	fh = (struct fc_frame_header *)fc_frame_header_get(fp);
	memcpy(fh, mp_fc_hdr, sizeof(struct fc_frame_header));

	/* Copy payload from firmware into fp */
	fc_payload = fc_frame_payload_get(fp, resp_len);
	memcpy(fc_payload, resp_buf, resp_len);

	opcode = fc_frame_payload_op(fp);
	switch (opcode) {
	case ELS_LS_ACC:
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
		    "SRR success.\n");
		break;
	case ELS_LS_RJT:
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_ELS,
		    "SRR rejected.\n");
		qedf_initiate_abts(orig_io_req, true);
		break;
	}

	fc_frame_free(fp);
out_put:
	/* Put reference for original command since SRR completed */
	kref_put(&orig_io_req->refcount, qedf_release_cmd);
out_free:
	kfree(cb_arg);
}
/* LGE_CHANGE_E : LCD ESD Protection*/ 
static int mipi_lg4573b_lcd_on(struct platform_device *pdev)
{
	struct msm_fb_data_type *mfd;
	struct mipi_panel_info *mipi;
	int result=0;
/* LGE_CHANGE_S : LCD ESD Protection 
 * 2012-01-30, [email protected]
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	bool int_en_wq_ret;
	if ( (!local_pdev_for_pwm) && (pdev) )
	{
		local_pdev_for_pwm = pdev;
	} 
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	mfd = platform_get_drvdata(pdev);
	mipi  = &mfd->panel_info.mipi;

	if (!mfd)
		return -ENODEV;
	if (mfd->key != MFD_KEY)
		return -EINVAL;

	printk( "mipi_lg4573b_lcd_on START\n");
	
#ifndef CONFIG_FB_MSM_MIPI_DSI_LG4573B_BOOT_LOGO
	if(!lglogo_firstboot)
#endif
	{	
	#if 1//LGE_CHANGE_S [changbum.lee] 20120128 
	//jangsu.lee
// LGE_S, [email protected], 12-11-28 without this U0 JB does not go 1.8mA
#if 1 //defined(CONFIG_MACH_MSM7X27A_U0)
	udelay(500);//mdelay(1);//1
	gpio_set_value(GPIO_U0_LCD_RESET, 1);	
	msleep(10);	//10	
#endif
// LGE_E, [email protected], 12-11-28 without this U0 JB does not go 1.8mA
    #endif//LGE_CHANGE_E [changbum.lee] 20120128 
/* LGE_CHANGE_S : LCD ESD Protection 
 * 2012-01-30, [email protected]
 * LCD ESD Protection
 */
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	/*If any work pending flush it & disable irq */	
	int_en_wq_ret = cancel_delayed_work_sync(&lcd_esd->esd_det_work);
	int_en_wq_ret = cancel_delayed_work_sync(&lcd_esd->esd_dsi_panel_on);
	int_en_wq_ret = flush_delayed_work_sync(&lcd_esd->esd_int_en_work);
	if( true == int_en_wq_ret)
	{
		printk("Pending INTR EN work Finished \n");
	}			
	if( 1 == atomic_read(&lcd_esd->esd_irq_state))
	{
		disable_irq(lcd_esd->esd_irq);
		printk("ESD irq Disabled \n");
		atomic_set(&lcd_esd->esd_irq_state,0);
	}
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	mipi_set_tx_power_mode(1);

	result=mipi_dsi_cmds_tx(&lg4573b_tx_buf, lg4573b_init_on_cmds,
			ARRAY_SIZE(lg4573b_init_on_cmds));

	mdelay(10);
	
	result=mipi_dsi_cmds_tx(&lg4573b_tx_buf, lg4573b_sleep_out_cmds,
			ARRAY_SIZE(lg4573b_sleep_out_cmds));

/*LGE_CHANGE_S, [email protected], 12-12-28, for V7 reduce the display time*/
#if !defined(CONFIG_MACH_MSM8X25_V7)
	/*[LGSI_SP4_BSP_BEGIN] [[email protected]]: Sometimes display is blank or distorted during bootlogo*/
	if(lglogo_firstboot){
		mdelay(120);
	}
	/*[LGSI_SP4_BSP_END] [[email protected]]*/
#endif
/*LGE_CHANGE_E, [email protected], 12-12-28, for V7 reduce the display time*/
	
	result=mipi_dsi_cmds_tx(&lg4573b_tx_buf, lg4573b_disp_on_cmds,
			ARRAY_SIZE(lg4573b_disp_on_cmds));

	mipi_set_tx_power_mode(0);
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
	is_esd_occured = false;
#endif
/* LGE_CHANGE_S : LCD ESD Protection 
 * 2012-01-30, [email protected]
 * LCD ESD Protection
 */	
#ifdef CONFIG_LGE_LCD_ESD_DETECTION
/*Make Panel power off state to ZERO. So that esd irq can be enabled in int wq handler*/
	if(1 == atomic_read(&lcd_esd->panel_poweroff))
	{
		atomic_set(&lcd_esd->panel_poweroff,0);
	}
	/*Schedule work after 1 sec to enable ESD interrupt*/
	schedule_delayed_work(&lcd_esd->esd_int_en_work,ESD_INT_EN_DELAY);
#endif
/* LGE_CHANGE_E : LCD ESD Protection*/ 

	printk( "mipi_lg4573b_lcd_on FINISH\n");
	}

	/*LGE_CHANGE_S, [email protected], 13-01-03, for V7 lcd backlight timing code*/
	#if defined(CONFIG_MACH_MSM8X25_V7)
	lcd_on_completed = 1;
	#endif
	/*LGE_CHANGE_E, [email protected], 13-01-03, for V7 lcd backlight timing code*/
	return 0;
}