static int __init exynos5_manta_battery_late_init(void) { int ret; struct usb_phy *usb_xceiv; ret = power_supply_register(NULL, &manta_battery_psy); if (ret) pr_err("%s: failed to register power_supply\n", __func__); ret = request_threaded_irq(gpio_to_irq(GPIO_OTG_VBUS_SENSE), NULL, ta_int_intr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "usb_vbus", NULL); if (ret) { pr_err("%s: usb_vbus irq register failed, ret=%d\n", __func__, ret); } else { ret = enable_irq_wake(gpio_to_irq(GPIO_OTG_VBUS_SENSE)); if (ret) pr_warn("%s: failed to enable irq_wake for usb_vbus\n", __func__); } ret = request_threaded_irq(gpio_to_irq(GPIO_VBUS_POGO_5V), NULL, ta_int_intr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "pogo_vbus", NULL); if (ret) { pr_err("%s: pogo_vbus irq register failed, ret=%d\n", __func__, ret); } else { ret = enable_irq_wake(gpio_to_irq(GPIO_VBUS_POGO_5V)); if (ret) pr_warn("%s: failed to enable irq_wake for pogo_vbus\n", __func__); } ret = register_pm_notifier(&exynos5_manta_battery_pm_notifier_block); if (ret) pr_warn("%s: failed to register PM notifier; ret=%d\n", __func__, ret); usb_xceiv = usb_get_transceiver(); if (!usb_xceiv) { pr_err("%s: No USB transceiver found\n", __func__); } else { ret = usb_register_notifier(usb_xceiv, &manta_bat_usb_nb); if (ret) { pr_err("%s: usb_register_notifier on transceiver %s failed\n", __func__, dev_name(usb_xceiv->dev)); } } /* get initial charger status */ change_charger_status(false, false); return 0; }
static int __init otg_wakelock_init(void) { int ret; otgwl_xceiv = usb_get_transceiver(); if (!otgwl_xceiv) { pr_err("%s: No USB transceiver found\n", __func__); return -ENODEV; } snprintf(vbus_lock.name, sizeof(vbus_lock.name), "vbus-%s", dev_name(otgwl_xceiv->dev)); wake_lock_init(&vbus_lock.wakelock, WAKE_LOCK_SUSPEND, vbus_lock.name); otgwl_nb.notifier_call = otgwl_otg_notifications; ret = usb_register_notifier(otgwl_xceiv, &otgwl_nb); if (ret) { pr_err("%s: usb_register_notifier on transceiver %s" " failed\n", __func__, dev_name(otgwl_xceiv->dev)); otgwl_xceiv = NULL; wake_lock_destroy(&vbus_lock.wakelock); return ret; } otgwl_handle_event(otgwl_xceiv->last_event); return ret; }
static int __init tsunagi_power_init(void) { pr_info("%s\n", __func__); platform_driver_register(&tsunagi_power_driver); #ifdef CONFIG_USB_ANDROID usb_register_notifier(&usb_status_notifier); #endif return 0; }
static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; musb->xceiv = usb_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work); status = pm_runtime_get_sync(dev); if (status < 0) { dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); goto err1; } l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { l &= ~ULPI_12PIN; l |= UTMI_8BIT; } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); musb->nb.notifier_call = musb_otg_notifications; status = usb_register_notifier(musb->xceiv, &musb->nb); if (status) dev_dbg(musb->controller, "notification register failed\n"); setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); pm_runtime_put_noidle(musb->controller); return 0; err1: return status; }
static int __init htc_battery_init(void) { // this used to be WAKE_LOCK_SUSPEND, but make it an idle lock in order to // prevent msm_sleep() try to collapse arm11 (using idle_sleep mode) several // times a second which sooner or later get's the device to freeze when usb // is connected wake_lock_init(&vbus_wake_lock, WAKE_LOCK_IDLE, "vbus_present"); usb_register_notifier(&usb_status_notifier); g_vbus_notifier_work_queue = create_workqueue("vbus-notifier"); if (g_vbus_notifier_work_queue == NULL) { printk("%s error: vbus notifier workqueue creation failed\n",__func__); } platform_driver_register(&htc_battery_driver); BATT("HTC Battery Driver initialized\n"); return 0; }
static int sec_otg_init(struct dwc3_msm *dwcm, struct usb_phy *phy) { int ret = 0; pr_info("%s: register notifier\n", __func__); sec_noti.nb.notifier_call = sec_otg_notifications; sec_noti.dwcm = dwcm; #ifdef CONFIG_CHARGER_BQ24260 usb_vbus_msm_init(dwcm, phy); #endif #if 0 ret = usb_register_notifier(phy, &sec_noti.nb); if (ret) { pr_err("%s: usb_register_notifier failed\n", __func__); return ret; } #endif return ret; }
static int ux500_musb_init(struct musb *musb) { int status; musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { pr_err("HS USB OTG: no transceiver configured\n"); return -EPROBE_DEFER; } musb->nb.notifier_call = musb_otg_notifications; status = usb_register_notifier(musb->xceiv, &musb->nb); if (status < 0) { dev_dbg(musb->controller, "notification register failed\n"); return status; } musb->isr = ux500_musb_interrupt; return 0; }
static int pda_power_probe(struct platform_device *pdev) { int ret = 0; dev = &pdev->dev; if (pdev->id != -1) { dev_err(dev, "it's meaningless to register several " "pda_powers; use id = -1\n"); ret = -EINVAL; goto wrongid; } pdata = pdev->dev.platform_data; if (pdata->init) { ret = pdata->init(dev); if (ret < 0) goto init_failed; } update_status(); update_charger(); if (!pdata->wait_for_status) pdata->wait_for_status = 500; if (!pdata->wait_for_charger) pdata->wait_for_charger = 500; if (!pdata->polling_interval) pdata->polling_interval = 2000; if (!pdata->ac_max_uA) pdata->ac_max_uA = 500000; setup_timer(&charger_timer, charger_timer_func, 0); setup_timer(&supply_timer, supply_timer_func, 0); ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); if (pdata->supplied_to) { pda_psy_ac.supplied_to = pdata->supplied_to; pda_psy_ac.num_supplicants = pdata->num_supplicants; pda_psy_usb.supplied_to = pdata->supplied_to; pda_psy_usb.num_supplicants = pdata->num_supplicants; } ac_draw = regulator_get(dev, "ac_draw"); if (IS_ERR(ac_draw)) { dev_dbg(dev, "couldn't get ac_draw regulator\n"); ac_draw = NULL; ret = PTR_ERR(ac_draw); } #ifdef CONFIG_USB_OTG_UTILS transceiver = usb_get_transceiver(); if (transceiver && !pdata->is_usb_online) { pdata->is_usb_online = otg_is_usb_online; } if (transceiver && !pdata->is_ac_online) { pdata->is_ac_online = otg_is_ac_online; } #endif if (pdata->is_ac_online) { ret = power_supply_register(&pdev->dev, &pda_psy_ac); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_psy_ac.name); goto ac_supply_failed; } if (ac_irq) { ret = request_irq(ac_irq->start, power_changed_isr, get_irq_flags(ac_irq), ac_irq->name, &pda_psy_ac); if (ret) { dev_err(dev, "request ac irq failed\n"); goto ac_irq_failed; } } else { polling = 1; } } if (pdata->is_usb_online) { ret = power_supply_register(&pdev->dev, &pda_psy_usb); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_psy_usb.name); goto usb_supply_failed; } if (usb_irq) { ret = request_irq(usb_irq->start, power_changed_isr, get_irq_flags(usb_irq), usb_irq->name, &pda_psy_usb); if (ret) { dev_err(dev, "request usb irq failed\n"); goto usb_irq_failed; } } else { polling = 1; } } #ifdef CONFIG_USB_OTG_UTILS if (transceiver && pdata->use_otg_notifier) { otg_nb.notifier_call = otg_handle_notification; ret = usb_register_notifier(transceiver, &otg_nb); if (ret) { dev_err(dev, "failure to register otg notifier\n"); goto otg_reg_notifier_failed; } polling = 0; } #endif if (polling) { dev_dbg(dev, "will poll for status\n"); setup_timer(&polling_timer, polling_timer_func, 0); mod_timer(&polling_timer, jiffies + msecs_to_jiffies(pdata->polling_interval)); } if (ac_irq || usb_irq) device_init_wakeup(&pdev->dev, 1); return 0; #ifdef CONFIG_USB_OTG_UTILS otg_reg_notifier_failed: if (pdata->is_usb_online && usb_irq) free_irq(usb_irq->start, &pda_psy_usb); #endif usb_irq_failed: if (pdata->is_usb_online) power_supply_unregister(&pda_psy_usb); usb_supply_failed: if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_psy_ac); #ifdef CONFIG_USB_OTG_UTILS if (transceiver) usb_put_transceiver(transceiver); #endif ac_irq_failed: if (pdata->is_ac_online) power_supply_unregister(&pda_psy_ac); ac_supply_failed: if (ac_draw) { regulator_put(ac_draw); ac_draw = NULL; } if (pdata->exit) pdata->exit(dev); init_failed: wrongid: return ret; }
static int isp1704_charger_probe(struct platform_device *pdev) { struct isp1704_charger *isp; int ret = -ENODEV; struct power_supply_config psy_cfg = {}; struct isp1704_charger_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *np = pdev->dev.of_node; if (np) { int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0); if (gpio < 0) { dev_err(&pdev->dev, "missing DT GPIO nxp,enable-gpio\n"); return gpio; } pdata = devm_kzalloc(&pdev->dev, sizeof(struct isp1704_charger_data), GFP_KERNEL); if (!pdata) { ret = -ENOMEM; goto fail0; } pdata->enable_gpio = gpio; dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio); ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio, GPIOF_OUT_INIT_HIGH, "isp1704_reset"); if (ret) { dev_err(&pdev->dev, "gpio request failed\n"); goto fail0; } } if (!pdata) { dev_err(&pdev->dev, "missing platform data!\n"); return -ENODEV; } isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); if (!isp) return -ENOMEM; if (np) isp->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); else isp->phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(isp->phy)) { ret = PTR_ERR(isp->phy); dev_err(&pdev->dev, "usb_get_phy failed\n"); goto fail0; } isp->dev = &pdev->dev; platform_set_drvdata(pdev, isp); isp1704_charger_set_power(isp, 1); ret = isp1704_test_ulpi(isp); if (ret < 0) { dev_err(&pdev->dev, "isp1704_test_ulpi failed\n"); goto fail1; } isp->psy_desc.name = "isp1704"; isp->psy_desc.type = POWER_SUPPLY_TYPE_USB; isp->psy_desc.properties = power_props; isp->psy_desc.num_properties = ARRAY_SIZE(power_props); isp->psy_desc.get_property = isp1704_charger_get_property; psy_cfg.drv_data = isp; isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg); if (IS_ERR(isp->psy)) { ret = PTR_ERR(isp->psy); dev_err(&pdev->dev, "power_supply_register failed\n"); goto fail1; } /* * REVISIT: using work in order to allow the usb notifications to be * made atomically in the future. */ INIT_WORK(&isp->work, isp1704_charger_work); isp->nb.notifier_call = isp1704_notifier_call; ret = usb_register_notifier(isp->phy, &isp->nb); if (ret) { dev_err(&pdev->dev, "usb_register_notifier failed\n"); goto fail2; } dev_info(isp->dev, "registered with product id %s\n", isp->model); /* * Taking over the D+ pullup. * * FIXME: The device will be disconnected if it was already * enumerated. The charger driver should be always loaded before any * gadget is loaded. */ if (isp->phy->otg->gadget) usb_gadget_disconnect(isp->phy->otg->gadget); if (isp->phy->last_event == USB_EVENT_NONE) isp1704_charger_set_power(isp, 0); /* Detect charger if VBUS is valid (the cable was already plugged). */ if (isp->phy->last_event == USB_EVENT_VBUS && !isp->phy->otg->default_a) schedule_work(&isp->work); return 0; fail2: power_supply_unregister(isp->psy); fail1: isp1704_charger_set_power(isp, 0); fail0: dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); return ret; }
static struct dwc_otg2 *dwc3_otg_alloc(struct device *dev) { struct dwc_otg2 *otg = NULL; struct usb_phy *usb_phy; int retval; otg = kzalloc(sizeof(*otg), GFP_KERNEL); if (!otg) { dev_err(dev, "Alloc otg failed\n"); return NULL; } the_transceiver = otg; otg->otg_data = dev->platform_data; usb_phy = &otg->usb2_phy; otg->otg.phy = usb_phy; otg->usb2_phy.otg = &otg->otg; otg->dev = dev; otg->usb3_phy.dev = otg->dev; otg->usb3_phy.label = "dwc-usb3-phy"; otg->usb3_phy.state = OTG_STATE_UNDEFINED; otg->usb3_phy.otg = &otg->otg; otg->usb2_phy.dev = otg->dev; otg->usb2_phy.label = "dwc-usb2-phy"; otg->usb2_phy.state = OTG_STATE_UNDEFINED; otg->usb2_phy.set_power = dwc3_otg_pdata->set_power; otg->usb2_phy.get_chrg_status = dwc_otg_get_chrg_status; otg->usb2_phy.io_ops = &dwc_otg_io_ops; otg->usb2_phy.otg = &otg->otg; otg->otg.set_host = dwc_otg2_set_host; otg->otg.set_peripheral = dwc_otg2_set_peripheral; ATOMIC_INIT_NOTIFIER_HEAD(&otg->usb2_phy.notifier); ATOMIC_INIT_NOTIFIER_HEAD(&otg->usb3_phy.notifier); otg->state = DWC_STATE_B_IDLE; spin_lock_init(&otg->lock); init_waitqueue_head(&otg->main_wq); /* Register otg notifier to monitor ID and VBus change events */ otg->nb.notifier_call = dwc_otg_handle_notification; usb_register_notifier(&otg->usb2_phy, &otg->nb); otg_dbg(otg, "Version: %s\n", VERSION); retval = usb_add_phy(&otg->usb2_phy, USB_PHY_TYPE_USB2); if (retval) { otg_err(otg, "can't register transceiver, err: %d\n", retval); goto err1; } retval = usb_add_phy(&otg->usb3_phy, USB_PHY_TYPE_USB3); if (retval) { otg_err(otg, "can't register transceiver, err: %d\n", retval); goto err2; } return otg; err2: usb_remove_phy(&otg->usb2_phy); err1: kfree(otg); otg = NULL; return otg; }
static int __init twl4030_bci_probe(struct platform_device *pdev) { struct twl4030_bci *bci; int ret; u32 reg; bci = kzalloc(sizeof(*bci), GFP_KERNEL); if (bci == NULL) return -ENOMEM; bci->dev = &pdev->dev; bci->irq_chg = platform_get_irq(pdev, 0); bci->irq_bci = platform_get_irq(pdev, 1); platform_set_drvdata(pdev, bci); bci->ac.name = "twl4030_ac"; bci->ac.type = POWER_SUPPLY_TYPE_MAINS; bci->ac.properties = twl4030_charger_props; bci->ac.num_properties = ARRAY_SIZE(twl4030_charger_props); bci->ac.get_property = twl4030_bci_get_property; ret = power_supply_register(&pdev->dev, &bci->ac); if (ret) { dev_err(&pdev->dev, "failed to register ac: %d\n", ret); goto fail_register_ac; } bci->usb.name = "twl4030_usb"; bci->usb.type = POWER_SUPPLY_TYPE_USB; bci->usb.properties = twl4030_charger_props; bci->usb.num_properties = ARRAY_SIZE(twl4030_charger_props); bci->usb.get_property = twl4030_bci_get_property; ret = power_supply_register(&pdev->dev, &bci->usb); if (ret) { dev_err(&pdev->dev, "failed to register usb: %d\n", ret); goto fail_register_usb; } ret = request_threaded_irq(bci->irq_chg, NULL, twl4030_charger_interrupt, 0, pdev->name, bci); if (ret < 0) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", bci->irq_chg, ret); goto fail_chg_irq; } ret = request_threaded_irq(bci->irq_bci, NULL, twl4030_bci_interrupt, 0, pdev->name, bci); if (ret < 0) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", bci->irq_bci, ret); goto fail_bci_irq; } INIT_WORK(&bci->work, twl4030_bci_usb_work); bci->transceiver = usb_get_transceiver(); if (bci->transceiver != NULL) { bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; usb_register_notifier(bci->transceiver, &bci->usb_nb); } /* Enable interrupts now. */ reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 | TWL4030_TBATOR1 | TWL4030_BATSTS); ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, TWL4030_INTERRUPTS_BCIIMR1A); if (ret < 0) { dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret); goto fail_unmask_interrupts; } reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV); ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, TWL4030_INTERRUPTS_BCIIMR2A); if (ret < 0) dev_warn(&pdev->dev, "failed to unmask interrupts: %d\n", ret); twl4030_charger_enable_ac(true); twl4030_charger_enable_usb(bci, true); return 0; fail_unmask_interrupts: if (bci->transceiver != NULL) { usb_unregister_notifier(bci->transceiver, &bci->usb_nb); usb_put_transceiver(bci->transceiver); } free_irq(bci->irq_bci, bci); fail_bci_irq: free_irq(bci->irq_chg, bci); fail_chg_irq: power_supply_unregister(&bci->usb); fail_register_usb: power_supply_unregister(&bci->ac); fail_register_ac: platform_set_drvdata(pdev, NULL); kfree(bci); return ret; }
static int __init twl4030_bci_probe(struct platform_device *pdev) { struct twl4030_bci *bci; const struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; int ret; u32 reg; bci = kzalloc(sizeof(*bci), GFP_KERNEL); if (bci == NULL) return -ENOMEM; if (!pdata) pdata = twl4030_bci_parse_dt(&pdev->dev); bci->dev = &pdev->dev; bci->irq_chg = platform_get_irq(pdev, 0); bci->irq_bci = platform_get_irq(pdev, 1); /* Only proceed further *IF* battery is physically present */ ret = twl4030_is_battery_present(bci); if (ret) { dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret); goto fail_no_battery; } platform_set_drvdata(pdev, bci); bci->ac = power_supply_register(&pdev->dev, &twl4030_bci_ac_desc, NULL); if (IS_ERR(bci->ac)) { ret = PTR_ERR(bci->ac); dev_err(&pdev->dev, "failed to register ac: %d\n", ret); goto fail_register_ac; } bci->usb_reg = regulator_get(bci->dev, "bci3v1"); bci->usb = power_supply_register(&pdev->dev, &twl4030_bci_usb_desc, NULL); if (IS_ERR(bci->usb)) { ret = PTR_ERR(bci->usb); dev_err(&pdev->dev, "failed to register usb: %d\n", ret); goto fail_register_usb; } ret = request_threaded_irq(bci->irq_chg, NULL, twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name, bci); if (ret < 0) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", bci->irq_chg, ret); goto fail_chg_irq; } ret = request_threaded_irq(bci->irq_bci, NULL, twl4030_bci_interrupt, IRQF_ONESHOT, pdev->name, bci); if (ret < 0) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", bci->irq_bci, ret); goto fail_bci_irq; } INIT_WORK(&bci->work, twl4030_bci_usb_work); bci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(bci->transceiver)) { bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; usb_register_notifier(bci->transceiver, &bci->usb_nb); } /* Enable interrupts now. */ reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 | TWL4030_TBATOR1 | TWL4030_BATSTS); ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, TWL4030_INTERRUPTS_BCIIMR1A); if (ret < 0) { dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret); goto fail_unmask_interrupts; } reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV); ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, TWL4030_INTERRUPTS_BCIIMR2A); if (ret < 0) dev_warn(&pdev->dev, "failed to unmask interrupts: %d\n", ret); twl4030_charger_enable_ac(true); twl4030_charger_enable_usb(bci, true); if (pdata) twl4030_charger_enable_backup(pdata->bb_uvolt, pdata->bb_uamp); else twl4030_charger_enable_backup(0, 0); return 0; fail_unmask_interrupts: if (!IS_ERR_OR_NULL(bci->transceiver)) { usb_unregister_notifier(bci->transceiver, &bci->usb_nb); usb_put_phy(bci->transceiver); } free_irq(bci->irq_bci, bci); fail_bci_irq: free_irq(bci->irq_chg, bci); fail_chg_irq: power_supply_unregister(bci->usb); fail_register_usb: power_supply_unregister(bci->ac); fail_register_ac: fail_no_battery: kfree(bci); return ret; }
static int __devinit isp1704_charger_probe(struct platform_device *pdev) { struct isp1704_charger *isp; int ret = -ENODEV; isp = kzalloc(sizeof *isp, GFP_KERNEL); if (!isp) return -ENOMEM; isp->phy = usb_get_phy(); if (!isp->phy) goto fail0; isp->dev = &pdev->dev; platform_set_drvdata(pdev, isp); isp1704_charger_set_power(isp, 1); ret = isp1704_test_ulpi(isp); if (ret < 0) goto fail1; isp->psy.name = "isp1704"; isp->psy.type = POWER_SUPPLY_TYPE_USB; isp->psy.properties = power_props; isp->psy.num_properties = ARRAY_SIZE(power_props); isp->psy.get_property = isp1704_charger_get_property; ret = power_supply_register(isp->dev, &isp->psy); if (ret) goto fail1; /* * REVISIT: using work in order to allow the usb notifications to be * made atomically in the future. */ INIT_WORK(&isp->work, isp1704_charger_work); isp->nb.notifier_call = isp1704_notifier_call; ret = usb_register_notifier(isp->phy, &isp->nb); if (ret) goto fail2; dev_info(isp->dev, "registered with product id %s\n", isp->model); /* * Taking over the D+ pullup. * * FIXME: The device will be disconnected if it was already * enumerated. The charger driver should be always loaded before any * gadget is loaded. */ if (isp->phy->otg->gadget) usb_gadget_disconnect(isp->phy->otg->gadget); /* Detect charger if VBUS is valid (the cable was already plugged). */ ret = isp1704_read(isp, ULPI_USB_INT_STS); isp1704_charger_set_power(isp, 0); if ((ret & ULPI_INT_VBUS_VALID) && !isp->phy->otg->default_a) { isp->event = USB_EVENT_VBUS; schedule_work(&isp->work); } return 0; fail2: power_supply_unregister(&isp->psy); fail1: usb_put_phy(isp->phy); fail0: kfree(isp); dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); isp1704_charger_set_power(isp, 0); return ret; }
static int smsc375x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct smsc375x_chip *chip; int ret = 0, id_val = -1; chip = kzalloc(sizeof(struct smsc375x_chip), GFP_KERNEL); if (!chip) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } chip->client = client; #ifdef CONFIG_ACPI chip->pdata = smsc375x_platform_data(); #else chip->pdata = dev->platform_data; #endif i2c_set_clientdata(client, chip); wake_lock_init(&chip->wakelock, WAKE_LOCK_SUSPEND, "smsc375x_wakelock"); /* register with extcon */ chip->edev = kzalloc(sizeof(struct extcon_dev), GFP_KERNEL); if (!chip->edev) { dev_err(&client->dev, "mem alloc failed\n"); ret = -ENOMEM; goto extcon_mem_failed; } chip->edev->name = "smsc375x"; chip->edev->supported_cable = smsc375x_extcon_cable; ret = extcon_dev_register(chip->edev, &client->dev); if (ret) { dev_err(&client->dev, "extcon registration failed!!\n"); goto extcon_reg_failed; } /* register for EXTCON USB notification */ INIT_WORK(&chip->vbus_work, smsc375x_pwrsrc_event_worker); chip->vbus_nb.notifier_call = smsc375x_handle_pwrsrc_notification; ret = extcon_register_interest(&chip->cable_obj, NULL, SMSC375X_EXTCON_USB, &chip->vbus_nb); /* OTG notification */ chip->otg = usb_get_phy(USB_PHY_TYPE_USB2); if (!chip->otg) { dev_warn(&client->dev, "Failed to get otg transceiver!!\n"); goto otg_reg_failed; } INIT_WORK(&chip->otg_work, smsc375x_otg_event_worker); chip->id_nb.notifier_call = smsc375x_handle_otg_notification; ret = usb_register_notifier(chip->otg, &chip->id_nb); if (ret) { dev_err(&chip->client->dev, "failed to register otg notifier\n"); goto id_reg_failed; } ret = smsc375x_irq_init(chip); if (ret) goto intr_reg_failed; chip_ptr = chip; if (chip->otg->get_id_status) { ret = chip->otg->get_id_status(chip->otg, &id_val); if (ret < 0) { dev_warn(&client->dev, "otg get ID status failed:%d\n", ret); ret = 0; } } if (!id_val && !chip->id_short) atomic_notifier_call_chain(&chip->otg->notifier, USB_EVENT_ID, &id_val); else smsc375x_detect_dev(chip); /* Init Runtime PM State */ pm_runtime_put_noidle(&chip->client->dev); pm_schedule_suspend(&chip->client->dev, MSEC_PER_SEC); return 0; intr_reg_failed: usb_unregister_notifier(chip->otg, &chip->id_nb); id_reg_failed: usb_put_phy(chip->otg); otg_reg_failed: extcon_dev_unregister(chip->edev); extcon_reg_failed: kfree(chip->edev); extcon_mem_failed: kfree(chip); return ret; }
static int crystalcove_chgr_probe(struct platform_device *pdev) { struct chgr_info *info; int ret; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) { dev_err(&pdev->dev, "mem alloc failed\n"); return -ENOMEM; } dev_info(&pdev->dev, "crystalcove charger probe begin\n"); info->pdev = pdev; #ifdef CONFIG_ACPI info->pdata = crystalcove_chgr_pdata(NULL); #else info->pdata = pdev->dev.platform_data; #endif platform_set_drvdata(pdev, info); mutex_init(&info->lock); INIT_WORK(&info->otg_work, crystalcove_otg_event_worker); info->irq = platform_get_irq(pdev, 0); ret = request_threaded_irq(info->irq, NULL, crystalcove_chgr_isr, IRQF_TRIGGER_RISING | IRQF_ONESHOT, CHGR_DRV_NAME, info); if (ret) { dev_err(&pdev->dev, "unable to register irq %d\n", info->irq); goto psy_reg_failed; } info->otg = usb_get_phy(USB_PHY_TYPE_USB2); if (!info->otg) { dev_warn(&pdev->dev, "Failed to get otg transceiver!!\n"); } else { info->id_nb.notifier_call = crystalcove_handle_otg_event; ret = usb_register_notifier(info->otg, &info->id_nb); if (ret) dev_err(&pdev->dev, "failed to register otg notifier\n"); } info->max_cc = info->pdata->max_cc; info->max_cv = info->pdata->max_cv; info->psy_usb.name = CHGR_DRV_NAME; info->psy_usb.type = POWER_SUPPLY_TYPE_USB; info->psy_usb.properties = crystalcove_chrg_usb_props; info->psy_usb.num_properties = ARRAY_SIZE(crystalcove_chrg_usb_props); info->psy_usb.get_property = crystalcove_chgr_usb_get_property; info->psy_usb.set_property = crystalcove_chgr_usb_set_property; info->psy_usb.supplied_to = info->pdata->supplied_to; info->psy_usb.num_supplicants = info->pdata->num_supplicants; info->psy_usb.throttle_states = info->pdata->throttle_states; info->psy_usb.num_throttle_states = info->pdata->num_throttle_states; info->psy_usb.supported_cables = info->pdata->supported_cables; ret = power_supply_register(&pdev->dev, &info->psy_usb); if (ret) { dev_err(&pdev->dev, "Failed: power supply register (%d)\n", ret); goto psy_reg_failed; } /* unmask the CHGR interrupts */ intel_mid_pmic_writeb(CRYSTALCOVE_MCHGRIRQS0_REG, 0x00); intel_mid_pmic_writeb(CRYSTALCOVE_MCHGRIRQSX_REG, 0x00); return 0; psy_reg_failed: return ret; }