static int omap_otg_remove(struct platform_device *pdev) { struct otg_device *otg_dev = platform_get_drvdata(pdev); struct extcon_dev *edev = otg_dev->extcon; extcon_unregister_notifier(edev, EXTCON_USB_HOST,&otg_dev->id_nb); extcon_unregister_notifier(edev, EXTCON_USB, &otg_dev->vbus_nb); return 0; }
static int dwc3_omap_remove(struct platform_device *pdev) { struct dwc3_omap *omap = platform_get_drvdata(pdev); extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); dwc3_omap_disable_irqs(omap); of_platform_depopulate(omap->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; }
static int axp288_charger_remove(struct platform_device *pdev) { struct axp288_chrg_info *info = dev_get_drvdata(&pdev->dev); if (info->otg.cable) extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST, &info->otg.id_nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, &info->cable.nb); power_supply_unregister(info->psy_usb); return 0; }
static int omap_otg_probe(struct platform_device *pdev) { const struct omap_usb_config *config = pdev->dev.platform_data; struct otg_device *otg_dev; struct extcon_dev *extcon; int ret; u32 rev; if (!config || !config->extcon) return -ENODEV; extcon = extcon_get_extcon_dev(config->extcon); if (!extcon) return -EPROBE_DEFER; otg_dev = devm_kzalloc(&pdev->dev, sizeof(*otg_dev), GFP_KERNEL); if (!otg_dev) return -ENOMEM; otg_dev->base = devm_ioremap_resource(&pdev->dev, &pdev->resource[0]); if (IS_ERR(otg_dev->base)) return PTR_ERR(otg_dev->base); otg_dev->extcon = extcon; otg_dev->id_nb.notifier_call = omap_otg_id_notifier; otg_dev->vbus_nb.notifier_call = omap_otg_vbus_notifier; ret = extcon_register_notifier(extcon, EXTCON_USB_HOST, &otg_dev->id_nb); if (ret) return ret; ret = extcon_register_notifier(extcon, EXTCON_USB, &otg_dev->vbus_nb); if (ret) { extcon_unregister_notifier(extcon, EXTCON_USB_HOST, &otg_dev->id_nb); return ret; } otg_dev->id = extcon_get_cable_state_(extcon, EXTCON_USB_HOST); otg_dev->vbus = extcon_get_cable_state_(extcon, EXTCON_USB); omap_otg_set_mode(otg_dev); rev = readl(otg_dev->base); dev_info(&pdev->dev, "OMAP USB OTG controller rev %d.%d (%s, id=%d, vbus=%d)\n", (rev >> 4) & 0xf, rev & 0xf, config->extcon, otg_dev->id, otg_dev->vbus); return 0; }
static int ulpmc_battery_remove(struct i2c_client *client) { struct ulpmc_chip_info *chip = i2c_get_clientdata(client); cancel_delayed_work_sync(&chip->work); if (chip->edev) extcon_unregister_notifier(chip->edev, &chip->nb); power_supply_unregister(&chip->chrg); power_supply_unregister(&chip->bat); mutex_destroy(&chip->lock); kfree(chip); return 0; }
static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) { struct msm_otg_platform_data *pdata; struct extcon_dev *ext_id, *ext_vbus; struct device_node *node = pdev->dev.of_node; struct property *prop; int len, ret, words; u32 val, tmp[3]; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; motg->pdata = pdata; pdata->phy_type = (enum msm_usb_phy_type)of_device_get_match_data(&pdev->dev); if (!pdata->phy_type) return 1; motg->link_rst = devm_reset_control_get(&pdev->dev, "link"); if (IS_ERR(motg->link_rst)) return PTR_ERR(motg->link_rst); motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); if (IS_ERR(motg->phy_rst)) motg->phy_rst = NULL; pdata->mode = usb_get_dr_mode(&pdev->dev); if (pdata->mode == USB_DR_MODE_UNKNOWN) pdata->mode = USB_DR_MODE_OTG; pdata->otg_control = OTG_PHY_CONTROL; if (!of_property_read_u32(node, "qcom,otg-control", &val)) if (val == OTG_PMIC_CONTROL) pdata->otg_control = val; if (!of_property_read_u32(node, "qcom,phy-num", &val) && val < 2) motg->phy_number = val; motg->vdd_levels[VDD_LEVEL_NONE] = USB_PHY_SUSP_DIG_VOL; motg->vdd_levels[VDD_LEVEL_MIN] = USB_PHY_VDD_DIG_VOL_MIN; motg->vdd_levels[VDD_LEVEL_MAX] = USB_PHY_VDD_DIG_VOL_MAX; if (of_get_property(node, "qcom,vdd-levels", &len) && len == sizeof(tmp)) { of_property_read_u32_array(node, "qcom,vdd-levels", tmp, len / sizeof(*tmp)); motg->vdd_levels[VDD_LEVEL_NONE] = tmp[VDD_LEVEL_NONE]; motg->vdd_levels[VDD_LEVEL_MIN] = tmp[VDD_LEVEL_MIN]; motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; } motg->manual_pullup = of_property_read_bool(node, "qcom,manual-pullup"); motg->switch_gpio = devm_gpiod_get_optional(&pdev->dev, "switch", GPIOD_OUT_LOW); if (IS_ERR(motg->switch_gpio)) return PTR_ERR(motg->switch_gpio); ext_id = ERR_PTR(-ENODEV); ext_vbus = ERR_PTR(-ENODEV); if (of_property_read_bool(node, "extcon")) { /* Each one of them is not mandatory */ ext_vbus = extcon_get_edev_by_phandle(&pdev->dev, 0); if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV) return PTR_ERR(ext_vbus); ext_id = extcon_get_edev_by_phandle(&pdev->dev, 1); if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV) return PTR_ERR(ext_id); } if (!IS_ERR(ext_vbus)) { motg->vbus.extcon = ext_vbus; motg->vbus.nb.notifier_call = msm_otg_vbus_notifier; ret = extcon_register_notifier(ext_vbus, EXTCON_USB, &motg->vbus.nb); if (ret < 0) { dev_err(&pdev->dev, "register VBUS notifier failed\n"); return ret; } ret = extcon_get_cable_state_(ext_vbus, EXTCON_USB); if (ret) set_bit(B_SESS_VLD, &motg->inputs); else clear_bit(B_SESS_VLD, &motg->inputs); } if (!IS_ERR(ext_id)) { motg->id.extcon = ext_id; motg->id.nb.notifier_call = msm_otg_id_notifier; ret = extcon_register_notifier(ext_id, EXTCON_USB_HOST, &motg->id.nb); if (ret < 0) { dev_err(&pdev->dev, "register ID notifier failed\n"); extcon_unregister_notifier(motg->vbus.extcon, EXTCON_USB, &motg->vbus.nb); return ret; } ret = extcon_get_cable_state_(ext_id, EXTCON_USB_HOST); if (ret) clear_bit(ID, &motg->inputs); else set_bit(ID, &motg->inputs); } prop = of_find_property(node, "qcom,phy-init-sequence", &len); if (!prop || !len) return 0; words = len / sizeof(u32); if (words >= ULPI_EXT_VENDOR_SPECIFIC) { dev_warn(&pdev->dev, "Too big PHY init sequence %d\n", words); return 0; } pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); if (!pdata->phy_init_seq) return 0; ret = of_property_read_u32_array(node, "qcom,phy-init-sequence", pdata->phy_init_seq, words); if (!ret) pdata->phy_init_sz = words; return 0; }
static int dwc3_omap_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct dwc3_omap *omap; struct resource *res; struct device *dev = &pdev->dev; struct regulator *vbus_reg = NULL; int ret; int irq; u32 reg; void __iomem *base; if (!node) { dev_err(dev, "device node not found\n"); return -EINVAL; } omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL); if (!omap) return -ENOMEM; platform_set_drvdata(pdev, omap); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "missing IRQ resource\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); if (of_property_read_bool(node, "vbus-supply")) { vbus_reg = devm_regulator_get(dev, "vbus"); if (IS_ERR(vbus_reg)) { dev_err(dev, "vbus init failed\n"); return PTR_ERR(vbus_reg); } } omap->dev = dev; omap->irq = irq; omap->base = base; omap->vbus_reg = vbus_reg; pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "get_sync failed with err %d\n", ret); goto err1; } dwc3_omap_map_offset(omap); dwc3_omap_set_utmi_mode(omap); /* check the DMA Status */ reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0, "dwc3-omap", omap); if (ret) { dev_err(dev, "failed to request IRQ #%d --> %d\n", omap->irq, ret); goto err1; } ret = dwc3_omap_extcon_register(omap); if (ret < 0) goto err1; ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { dev_err(&pdev->dev, "failed to create dwc3 core\n"); goto err2; } dwc3_omap_enable_irqs(omap); return 0; err2: extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); err1: pm_runtime_put_sync(dev); pm_runtime_disable(dev); return ret; }
static int axp288_charger_probe(struct platform_device *pdev) { int ret, i, pirq; struct axp288_chrg_info *info; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct power_supply_config charger_cfg = {}; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; info->pdev = pdev; info->regmap = axp20x->regmap; info->regmap_irqc = axp20x->regmap_irqc; info->pdata = pdev->dev.platform_data; if (!info->pdata) { /* Try ACPI provided pdata via device properties */ if (!device_property_present(&pdev->dev, "axp288_charger_data\n")) dev_err(&pdev->dev, "failed to get platform data\n"); return -ENODEV; } info->cable.edev = extcon_get_extcon_dev(AXP288_EXTCON_DEV_NAME); if (info->cable.edev == NULL) { dev_dbg(&pdev->dev, "%s is not ready, probe deferred\n", AXP288_EXTCON_DEV_NAME); return -EPROBE_DEFER; } /* Register for extcon notification */ INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker); info->cable.nb.notifier_call = axp288_charger_handle_cable_evt; ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); if (ret) { dev_err(&info->pdev->dev, "failed to register extcon notifier for SDP %d\n", ret); return ret; } ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, &info->cable.nb); if (ret) { dev_err(&info->pdev->dev, "failed to register extcon notifier for CDP %d\n", ret); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); return ret; } ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, &info->cable.nb); if (ret) { dev_err(&info->pdev->dev, "failed to register extcon notifier for DCP %d\n", ret); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, &info->cable.nb); return ret; } platform_set_drvdata(pdev, info); mutex_init(&info->lock); /* Register with power supply class */ charger_cfg.drv_data = info; info->psy_usb = power_supply_register(&pdev->dev, &axp288_charger_desc, &charger_cfg); if (IS_ERR(info->psy_usb)) { dev_err(&pdev->dev, "failed to register power supply charger\n"); ret = PTR_ERR(info->psy_usb); goto psy_reg_failed; } /* Register for OTG notification */ INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker); info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt; ret = extcon_register_notifier(info->otg.cable, EXTCON_USB_HOST, &info->otg.id_nb); if (ret) dev_warn(&pdev->dev, "failed to register otg notifier\n"); if (info->otg.cable) info->otg.id_short = extcon_get_cable_state_( info->otg.cable, EXTCON_USB_HOST); /* Register charger interrupts */ for (i = 0; i < CHRG_INTR_END; i++) { pirq = platform_get_irq(info->pdev, i); info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); if (info->irq[i] < 0) { dev_warn(&info->pdev->dev, "failed to get virtual interrupt=%d\n", pirq); ret = info->irq[i]; goto intr_reg_failed; } ret = devm_request_threaded_irq(&info->pdev->dev, info->irq[i], NULL, axp288_charger_irq_thread_handler, IRQF_ONESHOT, info->pdev->name, info); if (ret) { dev_err(&pdev->dev, "failed to request interrupt=%d\n", info->irq[i]); goto intr_reg_failed; } } charger_init_hw_regs(info); return 0; intr_reg_failed: if (info->otg.cable) extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST, &info->otg.id_nb); power_supply_unregister(info->psy_usb); psy_reg_failed: extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, &info->cable.nb); return ret; }