Beispiel #1
0
static int exynos_usbswitch_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct exynos_usb_switch *usb_switch = platform_get_drvdata(pdev);

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

	return 0;
}
Beispiel #2
0
static int __devinit exynos_usbswitch_probe(struct platform_device *pdev)
{
	struct s5p_usbswitch_platdata *pdata = dev_get_platdata(&pdev->dev);
	struct device *dev = &pdev->dev;
	struct exynos_usb_switch *usb_switch;
	int irq;
	int ret = 0;

	usb_switch = kzalloc(sizeof(struct exynos_usb_switch), GFP_KERNEL);
	if (!usb_switch) {
		ret = -ENOMEM;
		return ret;
	}

	our_switch = usb_switch;
	mutex_init(&usb_switch->mutex);
	usb_switch->workqueue = create_singlethread_workqueue("usb_switch");
	INIT_WORK(&usb_switch->switch_work, exnos_usb_switch_worker);
	INIT_WORK(&usb_switch->switch_drd_work, exnos_usb_drd_switch_worker);

	usb_switch->gpio_host_detect = pdata->gpio_host_detect;
	usb_switch->gpio_device_detect = pdata->gpio_device_detect;
	usb_switch->gpio_host_vbus = pdata->gpio_host_vbus;
	usb_switch->gpio_drd_host_detect = pdata->gpio_drd_host_detect;
	usb_switch->gpio_drd_device_detect = pdata->gpio_drd_device_detect;

	usb_switch->ehci_dev = pdata->ehci_dev;
	usb_switch->ohci_dev = pdata->ohci_dev;
	usb_switch->xhci_dev = pdata->xhci_dev;
	usb_switch->s3c_udc_dev = pdata->s3c_udc_dev;
	usb_switch->exynos_udc_dev = pdata->exynos_udc_dev;

	/* USB Device detect IRQ */
	irq = platform_get_irq(pdev, 1);
	if (irq > 0 && usb_switch->s3c_udc_dev) {
		ret = request_threaded_irq(irq, NULL,
				exynos_device_detect_thread,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"DEVICE_DETECT", usb_switch);
		if (ret) {
			dev_err(dev, "Failed to request device irq %d\n", irq);
			goto fail;
		}
		usb_switch->device_detect_irq = irq;
	} else if (usb_switch->s3c_udc_dev)
		exynos_change_usb_mode(usb_switch, USB_DEVICE_ATTACHED);
	else
		dev_info(dev, "Disable device detect IRQ\n");

	/* USB Host detect IRQ */
	irq = platform_get_irq(pdev, 0);
	if (irq > 0 && (usb_switch->ehci_dev || usb_switch->ohci_dev)) {
		ret = request_threaded_irq(irq, NULL,
				exynos_host_detect_thread,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"HOST_DETECT", usb_switch);
		if (ret) {
			dev_err(dev, "Failed to request host irq %d\n", irq);
			goto fail_gpio_device_detect;
		}
		usb_switch->host_detect_irq = irq;
	} else if (usb_switch->ehci_dev || usb_switch->ohci_dev)
		exynos_change_usb_mode(usb_switch, USB_HOST_ATTACHED);
	else
		dev_info(dev, "Disable host detect IRQ\n");


	/* USB DRD Device detect IRQ */
	irq = platform_get_irq(pdev, 3);
	if (irq > 0 && usb_switch->exynos_udc_dev) {
		ret = request_threaded_irq(irq, NULL,
				exynos_drd_device_detect_thread,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"DRD_DEVICE_DETECT", usb_switch);
		if (ret) {
			dev_err(dev, "Failed to request drd device irq %d\n",
				irq);
			goto fail_gpio_host_detect;
		}
		usb_switch->device_drd_detect_irq = irq;
	} else if (usb_switch->exynos_udc_dev)
		exynos_change_usb_mode(usb_switch, USB_DRD_DEVICE_ATTACHED);
	else
		dev_info(dev, "Disable drd device detect IRQ\n");

	/* USB DRD Host detect IRQ */
	irq = platform_get_irq(pdev, 2);
	if (irq > 0 && usb_switch->xhci_dev) {
		ret = request_threaded_irq(irq, NULL,
				exynos_drd_host_detect_thread,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"DRD_HOST_DETECT", usb_switch);
		if (ret) {
			dev_err(dev, "Failed to request drd host irq %d\n",
				irq);
			goto fail_gpio_drd_device_detect;
		}
		usb_switch->host_drd_detect_irq = irq;
	} else if (usb_switch->xhci_dev)
		exynos_change_usb_mode(usb_switch, USB_DRD_HOST_ATTACHED);
	else
		dev_info(dev, "Disable drd host detect IRQ\n");

	exynos_usb_status_init(usb_switch);

	platform_set_drvdata(pdev, usb_switch);

	return ret;
fail_gpio_drd_device_detect:
	free_irq(usb_switch->device_drd_detect_irq, usb_switch);
fail_gpio_host_detect:
	free_irq(usb_switch->host_detect_irq, usb_switch);
fail_gpio_device_detect:
	free_irq(usb_switch->device_detect_irq, usb_switch);
fail:
	cancel_work_sync(&usb_switch->switch_work);
	destroy_workqueue(usb_switch->workqueue);
	mutex_destroy(&usb_switch->mutex);
	kfree(usb_switch);
	return ret;
}
static int exynos_usbswitch_probe(struct platform_device *pdev)
{
	struct s5p_usbswitch_platdata *pdata = dev_get_platdata(&pdev->dev);
	struct device *dev = &pdev->dev;
	struct exynos_usb_switch *usb_switch;
	int ret = 0;

	usb_switch = devm_kzalloc(dev, sizeof(struct exynos_usb_switch),
					GFP_KERNEL);
	if (!usb_switch)
		return -ENOMEM;

	our_switch = usb_switch;
	mutex_init(&usb_switch->mutex);
	wake_lock_init(&usb_switch->wake_lock, WAKE_LOCK_SUSPEND,
			"usb_switch_present");
	usb_switch->workqueue = create_singlethread_workqueue("usb_switch");
	INIT_WORK(&usb_switch->switch_work, exynos_usb_switch_worker);

	if (dev->of_node) {
		ret = exynos_usbswitch_parse_dt(usb_switch, dev);
		if (ret < 0) {
			dev_err(dev, "Failed to parse dt\n");
			goto fail;
		}
	} else if (pdata) {
		usb_switch->gpio_host_detect = pdata->gpio_host_detect;
		usb_switch->gpio_device_detect = pdata->gpio_device_detect;
		usb_switch->gpio_host_vbus = pdata->gpio_host_vbus;

		usb_switch->ehci_dev = pdata->ehci_dev;
		usb_switch->ohci_dev = pdata->ohci_dev;
		usb_switch->s3c_udc_dev = pdata->s3c_udc_dev;

		usb_switch->host_detect_irq = platform_get_irq(pdev, 0);
		usb_switch->device_detect_irq = platform_get_irq(pdev, 1);
	} else {
		dev_err(dev, "Platform data is not available\n");
		ret = -ENODEV;
		goto fail;
	}

	/* USB Device detect IRQ */
	if (usb_switch->device_detect_irq > 0 && usb_switch->s3c_udc_dev) {
		ret = devm_request_threaded_irq(dev,
				usb_switch->device_detect_irq,
				NULL, exynos_device_detect_thread,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				IRQF_ONESHOT, "DEVICE_DETECT", usb_switch);
		if (ret) {
			dev_err(dev, "Failed to request device irq %d\n",
					usb_switch->device_detect_irq);
			goto fail;
		}
	} else if (usb_switch->s3c_udc_dev) {
		exynos_change_usb_mode(usb_switch, USB_DEVICE_ATTACHED);
	} else {
		dev_info(dev, "Disable device detect IRQ\n");
	}

	/* USB Host detect IRQ */
	if (usb_switch->host_detect_irq > 0 && (usb_switch->ehci_dev ||
						usb_switch->ohci_dev)) {
		ret = devm_request_threaded_irq(dev,
				usb_switch->host_detect_irq,
				NULL, exynos_host_detect_thread,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				IRQF_ONESHOT, "HOST_DETECT", usb_switch);
		if (ret) {
			dev_err(dev, "Failed to request host irq %d\n",
					usb_switch->host_detect_irq);
			goto fail;
		}
	} else if (usb_switch->ehci_dev || usb_switch->ohci_dev) {
		exynos_change_usb_mode(usb_switch, USB_HOST_ATTACHED);
	} else {
		dev_info(dev, "Disable host detect IRQ\n");
	}

	exynos_usb_status_init(usb_switch);

	ret = sysfs_create_group(&dev->kobj, &exynos_usbswitch_attr_group);
	if (ret)
		dev_warn(dev, "failed to create dwc3 otg attributes\n");

	platform_set_drvdata(pdev, usb_switch);

	return 0;

fail:
	wake_unlock(&usb_switch->wake_lock);
	cancel_work_sync(&usb_switch->switch_work);
	destroy_workqueue(usb_switch->workqueue);
	mutex_destroy(&usb_switch->mutex);
	return ret;
}