static int __exit bcmpmu_otg_xceiv_remove(struct platform_device *pdev)
{
    struct bcmpmu_otg_xceiv_data *xceiv_data = platform_get_drvdata(pdev);

    xceiv_data->otg_xceiver.xceiver.state = OTG_STATE_UNDEFINED;
    device_remove_file(xceiv_data->dev, &dev_attr_wake);
    device_remove_file(xceiv_data->dev, &dev_attr_vbus);
    device_remove_file(xceiv_data->dev, &dev_attr_host);

    pm_runtime_disable(&pdev->dev);

    if (wake_lock_active(&xceiv_data->otg_xceiver.xceiver_wake_lock)) {
        wake_unlock(&xceiv_data->otg_xceiver.xceiver_wake_lock);
        wake_lock_destroy(&xceiv_data->otg_xceiver.xceiver_wake_lock);
    }
    bcmpmu_remove_notifier(BCMPMU_USB_EVENT_VBUS_VALID,
                           &xceiv_data->bcm_otg_vbus_validity_notifier);
    bcmpmu_remove_notifier(BCMPMU_USB_EVENT_SESSION_INVALID,
                           &xceiv_data->bcm_otg_vbus_validity_notifier);
    bcmpmu_remove_notifier(BCMPMU_USB_EVENT_ID_CHANGE,
                           &xceiv_data->bcm_otg_id_chg_notifier);
    bcmpmu_remove_notifier(BCMPMU_USB_EVENT_USB_DETECTION,
                           &xceiv_data->bcm_otg_chg_detection_notifier);

    destroy_workqueue(xceiv_data->bcm_otg_work_queue);
    bcmpmu_otg_free_regulator(xceiv_data);
    kfree(xceiv_data);
    bcm_hsotgctrl_phy_deinit();

    local_otg_xceiver = NULL;

    return 0;
}
static int bcmpmu_spa_pb_remove(struct platform_device *pdev)
{
	struct bcmpmu59xxx *bcmpmu = dev_get_drvdata(pdev->dev.parent);
	struct bcmpmu_spa_pb *bcmpmu_spa_pb = bcmpmu->spa_pb_info;

	bcmpmu->unregister_irq(bcmpmu, PMU_IRQ_MBTEMPLOW);
	bcmpmu->unregister_irq(bcmpmu, PMU_IRQ_MBTEMPHIGH);
	bcmpmu->unregister_irq(bcmpmu, PMU_IRQ_CHGERRDIS);
	bcmpmu->unregister_irq(bcmpmu, PMU_IRQ_MBOV);
	bcmpmu->unregister_irq(bcmpmu, PMU_IRQ_MBOV_DIS);
	bcmpmu->unregister_irq(bcmpmu, PMU_IRQ_EOC);

	bcmpmu_remove_notifier(PMU_ACCY_EVT_OUT_CHRGR_TYPE,
			&bcmpmu_spa_pb->nb_chgr_det);
	bcmpmu_remove_notifier(PMU_ACCY_EVT_OUT_USB_IN,
			&bcmpmu_spa_pb->nb_usbin);
	power_supply_unregister(&bcmpmu_spa_pb->chrgr);
	kfree(bcmpmu_spa_pb);

	return 0;
}
static int bcmpmu_spa_pb_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct bcmpmu_spa_pb *bcmpmu_spa_pb;
	struct bcmpmu59xxx *bcmpmu = dev_get_drvdata(pdev->dev.parent);
	struct bcmpmu59xxx_spa_pb_pdata *pdata;
	pdata = (struct  bcmpmu59xxx_spa_pb_pdata *)pdev->dev.platform_data;
	pr_pb(INIT, "%s\n", __func__);
	BUG_ON(!(bcmpmu->flags & BCMPMU_SPA_EN) || !pdata);
	bcmpmu_spa_pb = kzalloc(sizeof(struct bcmpmu_spa_pb), GFP_KERNEL);
	if (bcmpmu_spa_pb == NULL) {
		dev_err(&pdev->dev, "failed to alloc mem: %d\n", ret);
		return -ENOMEM;
	}
	bcmpmu_info = bcmpmu;
	bcmpmu_spa_pb->bcmpmu = bcmpmu;
	bcmpmu->spa_pb_info = (void *)bcmpmu_spa_pb;

	mutex_init(&bcmpmu_spa_pb->lock);

	INIT_DELAYED_WORK(&bcmpmu_spa_pb->spa_work, bcmpmu_spa_pb_work);

	bcmpmu_spa_pb->chrgr.properties = bcmpmu_spa_pb_chrgr_props;
	bcmpmu_spa_pb->chrgr.num_properties =
			ARRAY_SIZE(bcmpmu_spa_pb_chrgr_props);
	bcmpmu_spa_pb->chrgr.get_property = bcmpmu_spa_pb_chrgr_get_property;
	bcmpmu_spa_pb->chrgr.set_property = bcmpmu_spa_pb_chrgr_set_property;
	bcmpmu_spa_pb->chrgr.name = pdata->chrgr_name;

	ret = power_supply_register(&pdev->dev, &bcmpmu_spa_pb->chrgr);
	if (ret)
		goto cghr_err;

	bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBTEMPLOW,
		bcmpmu_spa_pb_isr, bcmpmu_spa_pb);
	bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBTEMPHIGH,
		bcmpmu_spa_pb_isr, bcmpmu_spa_pb);
	bcmpmu->register_irq(bcmpmu, PMU_IRQ_CHGERRDIS,
		bcmpmu_spa_pb_isr, bcmpmu_spa_pb);
	bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBOV,
		bcmpmu_spa_pb_isr, bcmpmu_spa_pb);
	bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBOV_DIS,
		bcmpmu_spa_pb_isr, bcmpmu_spa_pb);
#if 0
    /* Don't use PMU_IRQ_USBOV/PMU_IRQ_USBOV_DIS interrupt
	   bacause PMU's USBOV threshold(6.6V/8V) can't meet SS spec(6.8V).
	   So, SS use MUIC USBOV function(6.8V) instead of PMU USBOV*/
	bcmpmu->register_irq(bcmpmu, PMU_IRQ_USBOV,
	bcmpmu_spa_pb_isr, bcmpmu_spa_pb);
	bcmpmu->register_irq(bcmpmu, PMU_IRQ_USBOV_DIS,
	bcmpmu_spa_pb_isr, bcmpmu_spa_pb);
#endif

	bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBTEMPLOW);
	bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBTEMPHIGH);
	bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_CHGERRDIS);
	bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBOV);
	bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBOV_DIS);
#if 0
	bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_USBOV);
	bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_USBOV_DIS);
#endif

	bcmpmu_spa_pb->nb_chgr_det.notifier_call = bcmpmu_spa_pb_event_hndlr;
	ret = bcmpmu_add_notifier(PMU_ACCY_EVT_OUT_CHRGR_TYPE,
		&bcmpmu_spa_pb->nb_chgr_det);
	if (ret) {
		pr_pb(ERROR, "%s, failed to register chrgr det notifier\n",
			__func__);
		goto err;
	}
	bcmpmu_spa_pb->nb_usbin.notifier_call = bcmpmu_spa_pb_event_hndlr;
	ret = bcmpmu_add_notifier(PMU_ACCY_EVT_OUT_USB_IN,
		&bcmpmu_spa_pb->nb_usbin);
	if (ret) {
		pr_pb(ERROR, "%s, failed to register chrgr det notifier\n",
			__func__);
		goto err;
	}

#ifdef CONFIG_DEBUG_FS
	bcmpmu_spa_pb_dbg_init(bcmpmu_spa_pb);
#endif

	return 0;

err:
	bcmpmu_remove_notifier(PMU_ACCY_EVT_OUT_CHRGR_TYPE,
			&bcmpmu_spa_pb->nb_chgr_det);
	bcmpmu_remove_notifier(PMU_ACCY_EVT_OUT_USB_IN,
			&bcmpmu_spa_pb->nb_usbin);
	power_supply_unregister(&bcmpmu_spa_pb->chrgr);
cghr_err:
	kfree(bcmpmu_spa_pb);
	return ret;
}