Commit 6c0b4e6c authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Grant Likely
Browse files

gpiolib: let gpio_chip reference its descriptors



Add a pointer to the gpio_chip structure that references the array of
GPIO descriptors belonging to the chip, and update gpiolib code to use
this pointer instead of the global gpio_desc[] array. This is another
step towards the removal of the gpio_desc[] global array.

Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.orh>
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 372e722e
Loading
Loading
Loading
Loading
+23 −16
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@ struct gpio_desc {
};
static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];

#define GPIO_OFFSET_VALID(chip, offset) (offset >= 0 && offset < chip->ngpio)

static LIST_HEAD(gpio_chips);

#ifdef CONFIG_GPIO_SYSFS
@@ -112,7 +114,7 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
 */
static int gpio_chip_hwgpio(const struct gpio_desc *desc)
{
	return (desc - &gpio_desc[0]) - desc->chip->base;
	return desc - &desc->chip->desc[0];
}

/**
@@ -133,7 +135,7 @@ static struct gpio_desc *gpio_to_desc(unsigned gpio)
 */
static int desc_to_gpio(const struct gpio_desc *desc)
{
	return desc - &gpio_desc[0];
	return desc->chip->base + gpio_chip_hwgpio(desc);
}


@@ -1007,9 +1009,9 @@ static int gpiochip_export(struct gpio_chip *chip)
		unsigned	gpio;

		spin_lock_irqsave(&gpio_lock, flags);
		gpio = chip->base;
		while (gpio_desc[gpio].chip == chip)
			gpio_desc[gpio++].chip = NULL;
		gpio = 0;
		while (gpio < chip->ngpio)
			chip->desc[gpio++].chip = NULL;
		spin_unlock_irqrestore(&gpio_lock, flags);

		pr_debug("%s: chip %s status %d\n", __func__,
@@ -1186,8 +1188,11 @@ int gpiochip_add(struct gpio_chip *chip)
	status = gpiochip_add_to_list(chip);

	if (status == 0) {
		for (id = base; id < base + chip->ngpio; id++) {
			gpio_desc[id].chip = chip;
		chip->desc = &gpio_desc[chip->base];

		for (id = 0; id < chip->ngpio; id++) {
			struct gpio_desc *desc = &chip->desc[id];
			desc->chip = chip;

			/* REVISIT:  most hardware initializes GPIOs as
			 * inputs (often with pullups enabled) so power
@@ -1196,7 +1201,7 @@ int gpiochip_add(struct gpio_chip *chip)
			 * and in case chip->get_direction is not set,
			 * we may expose the wrong direction in sysfs.
			 */
			gpio_desc[id].flags = !chip->direction_input
			desc->flags = !chip->direction_input
				? (1 << FLAG_IS_OUT)
				: 0;
		}
@@ -1249,15 +1254,15 @@ int gpiochip_remove(struct gpio_chip *chip)
	gpiochip_remove_pin_ranges(chip);
	of_gpiochip_remove(chip);

	for (id = chip->base; id < chip->base + chip->ngpio; id++) {
		if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
	for (id = 0; id < chip->ngpio; id++) {
		if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) {
			status = -EBUSY;
			break;
		}
	}
	if (status == 0) {
		for (id = chip->base; id < chip->base + chip->ngpio; id++)
			gpio_desc[id].chip = NULL;
		for (id = 0; id < chip->ngpio; id++)
			chip->desc[id].chip = NULL;

		list_del(&chip->list);
	}
@@ -1582,11 +1587,13 @@ EXPORT_SYMBOL_GPL(gpio_free_array);
 */
const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
{
	unsigned gpio = chip->base + offset;
	struct gpio_desc *desc = &gpio_desc[gpio];
	struct gpio_desc *desc;

	if (!gpio_is_valid(gpio) || desc->chip != chip)
	if (!GPIO_OFFSET_VALID(chip, offset))
		return NULL;

	desc = &chip->desc[offset];

	if (test_bit(FLAG_REQUESTED, &desc->flags) == 0)
		return NULL;
#ifdef CONFIG_DEBUG_FS
@@ -2025,7 +2032,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
	unsigned		i;
	unsigned		gpio = chip->base;
	struct gpio_desc	*gdesc = &gpio_desc[gpio];
	struct gpio_desc	*gdesc = &chip->desc[0];
	int			is_out;

	for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
+3 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ struct gpio;
struct seq_file;
struct module;
struct device_node;
struct gpio_desc;

/**
 * struct gpio_chip - abstract a GPIO controller
@@ -76,6 +77,7 @@ struct device_node;
 *	negative during registration, requests dynamic ID allocation.
 * @ngpio: the number of GPIOs handled by this controller; the last GPIO
 *	handled is (base + ngpio - 1).
 * @desc: array of ngpio descriptors. Private.
 * @can_sleep: flag must be set iff get()/set() methods sleep, as they
 *	must while accessing GPIO expander chips over I2C or SPI
 * @names: if set, must be an array of strings to use as alternative
@@ -126,6 +128,7 @@ struct gpio_chip {
						struct gpio_chip *chip);
	int			base;
	u16			ngpio;
	struct gpio_desc	*desc;
	const char		*const *names;
	unsigned		can_sleep:1;
	unsigned		exported:1;