static int __exit twl4030_bci_remove(struct platform_device *pdev)
{
	struct twl4030_bci *bci = platform_get_drvdata(pdev);

	twl4030_charger_enable_ac(false);
	twl4030_charger_enable_usb(bci, false);

	/* mask interrupts */
	twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
			 TWL4030_INTERRUPTS_BCIIMR1A);
	twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
			 TWL4030_INTERRUPTS_BCIIMR2A);

	if (bci->transceiver != NULL) {
		usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
		usb_put_transceiver(bci->transceiver);
	}
	free_irq(bci->irq_bci, bci);
	free_irq(bci->irq_chg, bci);
	power_supply_unregister(&bci->usb);
	power_supply_unregister(&bci->ac);
	platform_set_drvdata(pdev, NULL);
	kfree(bci);

	return 0;
}
Beispiel #2
0
static int ux500_musb_exit(struct musb *musb)
{
	usb_unregister_notifier(musb->xceiv, &musb->nb);

	usb_put_phy(musb->xceiv);

	return 0;
}
Beispiel #3
0
static int isp1704_charger_remove(struct platform_device *pdev)
{
	struct isp1704_charger *isp = platform_get_drvdata(pdev);

	usb_unregister_notifier(isp->phy, &isp->nb);
	power_supply_unregister(isp->psy);
	isp1704_charger_set_power(isp, 0);

	return 0;
}
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;
}
Beispiel #5
0
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 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;
}