static int collie_bat_probe()

in supply/collie_battery.c [315:439]


static int collie_bat_probe(struct ucb1x00_dev *dev)
{
	int ret;
	struct power_supply_config psy_main_cfg = {}, psy_bu_cfg = {};
	struct gpio_chip *gc = &dev->ucb->gpio;

	if (!machine_is_collie())
		return -ENODEV;

	ucb = dev->ucb;

	/* Obtain all the main battery GPIOs */
	collie_bat_main.gpio_full = gpiod_get(&dev->ucb->dev,
					      "main battery full",
					      GPIOD_IN);
	if (IS_ERR(collie_bat_main.gpio_full))
		return PTR_ERR(collie_bat_main.gpio_full);

	collie_mbat_low = gpiod_get(&dev->ucb->dev,
				    "main battery low",
				    GPIOD_IN);
	if (IS_ERR(collie_mbat_low)) {
		ret = PTR_ERR(collie_mbat_low);
		goto err_put_gpio_full;
	}

	collie_bat_main.gpio_charge_on = gpiod_get(&dev->ucb->dev,
						   "main charge on",
						   GPIOD_OUT_LOW);
	if (IS_ERR(collie_bat_main.gpio_charge_on)) {
		ret = PTR_ERR(collie_bat_main.gpio_charge_on);
		goto err_put_mbat_low;
	}

	/* COLLIE_GPIO_MBAT_ON = GPIO 7 on the UCB (TC35143) */
	collie_bat_main.gpio_bat = gpiochip_request_own_desc(gc,
						7,
						"main battery",
						GPIO_ACTIVE_HIGH,
						GPIOD_OUT_LOW);
	if (IS_ERR(collie_bat_main.gpio_bat)) {
		ret = PTR_ERR(collie_bat_main.gpio_bat);
		goto err_put_gpio_charge_on;
	}

	/* COLLIE_GPIO_TMP_ON = GPIO 9 on the UCB (TC35143) */
	collie_bat_main.gpio_temp = gpiochip_request_own_desc(gc,
						9,
						"main battery temp",
						GPIO_ACTIVE_HIGH,
						GPIOD_OUT_LOW);
	if (IS_ERR(collie_bat_main.gpio_temp)) {
		ret = PTR_ERR(collie_bat_main.gpio_temp);
		goto err_free_gpio_bat;
	}

	/*
	 * Obtain the backup battery COLLIE_GPIO_BBAT_ON which is
	 * GPIO 8 on the UCB (TC35143)
	 */
	collie_bat_bu.gpio_bat = gpiochip_request_own_desc(gc,
						8,
						"backup battery",
						GPIO_ACTIVE_HIGH,
						GPIOD_OUT_LOW);
	if (IS_ERR(collie_bat_bu.gpio_bat)) {
		ret = PTR_ERR(collie_bat_bu.gpio_bat);
		goto err_free_gpio_temp;
	}

	mutex_init(&collie_bat_main.work_lock);

	INIT_WORK(&bat_work, collie_bat_work);

	psy_main_cfg.drv_data = &collie_bat_main;
	collie_bat_main.psy = power_supply_register(&dev->ucb->dev,
						    &collie_bat_main_desc,
						    &psy_main_cfg);
	if (IS_ERR(collie_bat_main.psy)) {
		ret = PTR_ERR(collie_bat_main.psy);
		goto err_psy_reg_main;
	}

	psy_bu_cfg.drv_data = &collie_bat_bu;
	collie_bat_bu.psy = power_supply_register(&dev->ucb->dev,
						  &collie_bat_bu_desc,
						  &psy_bu_cfg);
	if (IS_ERR(collie_bat_bu.psy)) {
		ret = PTR_ERR(collie_bat_bu.psy);
		goto err_psy_reg_bu;
	}

	ret = request_irq(gpio_to_irq(COLLIE_GPIO_CO),
				collie_bat_gpio_isr,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"main full", &collie_bat_main);
	if (ret)
		goto err_irq;

	device_init_wakeup(&ucb->dev, 1);
	schedule_work(&bat_work);

	return 0;

err_irq:
	power_supply_unregister(collie_bat_bu.psy);
err_psy_reg_bu:
	power_supply_unregister(collie_bat_main.psy);
err_psy_reg_main:
	/* see comment in collie_bat_remove */
	cancel_work_sync(&bat_work);
	gpiochip_free_own_desc(collie_bat_bu.gpio_bat);
err_free_gpio_temp:
	gpiochip_free_own_desc(collie_bat_main.gpio_temp);
err_free_gpio_bat:
	gpiochip_free_own_desc(collie_bat_main.gpio_bat);
err_put_gpio_charge_on:
	gpiod_put(collie_bat_main.gpio_charge_on);
err_put_mbat_low:
	gpiod_put(collie_mbat_low);
err_put_gpio_full:
	gpiod_put(collie_bat_main.gpio_full);

	return ret;
}