in extcon-qcom-spmi-misc.c [87:164]
static int qcom_usb_extcon_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct qcom_usb_extcon_info *info;
int ret;
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->edev = devm_extcon_dev_allocate(dev, qcom_usb_extcon_cable);
if (IS_ERR(info->edev)) {
dev_err(dev, "failed to allocate extcon device\n");
return -ENOMEM;
}
ret = devm_extcon_dev_register(dev, info->edev);
if (ret < 0) {
dev_err(dev, "failed to register extcon device\n");
return ret;
}
ret = extcon_set_property_capability(info->edev,
EXTCON_USB, EXTCON_PROP_USB_SS);
ret |= extcon_set_property_capability(info->edev,
EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
if (ret) {
dev_err(dev, "failed to register extcon props rc=%d\n",
ret);
return ret;
}
info->debounce_jiffies = msecs_to_jiffies(USB_ID_DEBOUNCE_MS);
ret = devm_delayed_work_autocancel(dev, &info->wq_detcable,
qcom_usb_extcon_detect_cable);
if (ret)
return ret;
info->id_irq = platform_get_irq_byname(pdev, "usb_id");
if (info->id_irq > 0) {
ret = devm_request_threaded_irq(dev, info->id_irq, NULL,
qcom_usb_irq_handler,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
pdev->name, info);
if (ret < 0) {
dev_err(dev, "failed to request handler for ID IRQ\n");
return ret;
}
}
info->vbus_irq = platform_get_irq_byname(pdev, "usb_vbus");
if (info->vbus_irq > 0) {
ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL,
qcom_usb_irq_handler,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
pdev->name, info);
if (ret < 0) {
dev_err(dev, "failed to request handler for VBUS IRQ\n");
return ret;
}
}
if (info->id_irq < 0 && info->vbus_irq < 0) {
dev_err(dev, "ID and VBUS IRQ not found\n");
return -EINVAL;
}
platform_set_drvdata(pdev, info);
device_init_wakeup(dev, 1);
/* Perform initial detection */
qcom_usb_extcon_detect_cable(&info->wq_detcable.work);
return 0;
}