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;
}
示例#2
0
文件: pda_power.c 项目: 274914765/C
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;

    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;
    }

    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;
        }
    }

    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;

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);
ac_irq_failed:
    if (pdata->is_ac_online)
        power_supply_unregister(&pda_psy_ac);
ac_supply_failed:
    if (pdata->exit)
        pdata->exit(dev);
init_failed:
wrongid:
    return ret;
}