Commit dea046e7 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

gpio: remove machine hogs

parent e627fc9f
Loading
Loading
Loading
Loading
+0 −16
Original line number Diff line number Diff line
@@ -239,22 +239,6 @@ mapping and is thus transparent to GPIO consumers.
A set of functions such as gpiod_set_value() is available to work with
the new descriptor-oriented interface.

Boards using platform data can also hog GPIO lines by defining GPIO hog tables.

.. code-block:: c

        struct gpiod_hog gpio_hog_table[] = {
                GPIO_HOG("gpio.0", 10, "foo", GPIO_ACTIVE_LOW, GPIOD_OUT_HIGH),
                { }
        };

And the table can be added to the board code as follows::

        gpiod_add_hogs(gpio_hog_table);

The line will be hogged as soon as the gpiochip is created or - in case the
chip was created earlier - when the hog table is registered.

Arrays of pins
--------------
In addition to requesting pins belonging to a function one by one, a device may
+0 −71
Original line number Diff line number Diff line
@@ -103,9 +103,6 @@ static DEFINE_MUTEX(gpio_devices_lock);
/* Ensures coherence during read-only accesses to the list of GPIO devices. */
DEFINE_STATIC_SRCU(gpio_devices_srcu);

static DEFINE_MUTEX(gpio_machine_hogs_mutex);
static LIST_HEAD(gpio_machine_hogs);

const char *const gpio_suffixes[] = { "gpios", "gpio", NULL };

static void gpiochip_free_hogs(struct gpio_chip *gc);
@@ -930,36 +927,6 @@ static int gpiochip_setup_dev(struct gpio_chip *gc)
	return ret;
}

static void gpiochip_machine_hog(struct gpio_chip *gc, struct gpiod_hog *hog)
{
	struct gpio_desc *desc;
	int rv;

	desc = gpiochip_get_desc(gc, hog->chip_hwnum);
	if (IS_ERR(desc)) {
		gpiochip_err(gc, "%s: unable to get GPIO desc: %ld\n",
			     __func__, PTR_ERR(desc));
		return;
	}

	rv = gpiod_hog(desc, hog->line_name, hog->lflags, hog->dflags);
	if (rv)
		gpiod_err(desc, "%s: unable to hog GPIO line (%s:%u): %d\n",
			  __func__, gc->label, hog->chip_hwnum, rv);
}

static void gpiochip_machine_hog_lines(struct gpio_chip *gc)
{
	struct gpiod_hog *hog;

	guard(mutex)(&gpio_machine_hogs_mutex);

	list_for_each_entry(hog, &gpio_machine_hogs, list) {
		if (!strcmp(gc->label, hog->chip_label))
			gpiochip_machine_hog(gc, hog);
	}
}

int gpiochip_add_hog(struct gpio_chip *gc, struct fwnode_handle *fwnode)
{
	struct fwnode_handle *gc_node = dev_fwnode(&gc->gpiodev->dev);
@@ -1047,8 +1014,6 @@ static int gpiochip_hog_lines(struct gpio_chip *gc)
			return ret;
	}

	gpiochip_machine_hog_lines(gc);

	return 0;
}

@@ -4578,42 +4543,6 @@ void gpiod_remove_lookup_table(struct gpiod_lookup_table *table)
}
EXPORT_SYMBOL_GPL(gpiod_remove_lookup_table);

/**
 * gpiod_add_hogs() - register a set of GPIO hogs from machine code
 * @hogs: table of gpio hog entries with a zeroed sentinel at the end
 */
void gpiod_add_hogs(struct gpiod_hog *hogs)
{
	struct gpiod_hog *hog;

	guard(mutex)(&gpio_machine_hogs_mutex);

	for (hog = &hogs[0]; hog->chip_label; hog++) {
		list_add_tail(&hog->list, &gpio_machine_hogs);

		/*
		 * The chip may have been registered earlier, so check if it
		 * exists and, if so, try to hog the line now.
		 */
		struct gpio_device *gdev __free(gpio_device_put) =
				gpio_device_find_by_label(hog->chip_label);
		if (gdev)
			gpiochip_machine_hog(gpio_device_get_chip(gdev), hog);
	}
}
EXPORT_SYMBOL_GPL(gpiod_add_hogs);

void gpiod_remove_hogs(struct gpiod_hog *hogs)
{
	struct gpiod_hog *hog;

	guard(mutex)(&gpio_machine_hogs_mutex);

	for (hog = &hogs[0]; hog->chip_label; hog++)
		list_del(&hog->list);
}
EXPORT_SYMBOL_GPL(gpiod_remove_hogs);

static bool gpiod_match_lookup_table(struct device *dev,
				     const struct gpiod_lookup_table *table)
{
+0 −33
Original line number Diff line number Diff line
@@ -46,23 +46,6 @@ struct gpiod_lookup_table {
	struct gpiod_lookup table[];
};

/**
 * struct gpiod_hog - GPIO line hog table
 * @chip_label: name of the chip the GPIO belongs to
 * @chip_hwnum: hardware number (i.e. relative to the chip) of the GPIO
 * @line_name: consumer name for the hogged line
 * @lflags: bitmask of gpio_lookup_flags GPIO_* values
 * @dflags: GPIO flags used to specify the direction and value
 */
struct gpiod_hog {
	struct list_head list;
	const char *chip_label;
	u16 chip_hwnum;
	const char *line_name;
	unsigned long lflags;
	int dflags;
};

/*
 * Helper for lookup tables with just one single lookup for a device.
 */
@@ -95,24 +78,10 @@ static struct gpiod_lookup_table _name = { \
	.flags = _flags,                                                  \
}

/*
 * Simple definition of a single GPIO hog in an array.
 */
#define GPIO_HOG(_chip_label, _chip_hwnum, _line_name, _lflags, _dflags)  \
(struct gpiod_hog) {                                                      \
	.chip_label = _chip_label,                                        \
	.chip_hwnum = _chip_hwnum,                                        \
	.line_name = _line_name,                                          \
	.lflags = _lflags,                                                \
	.dflags = _dflags,                                                \
}

#ifdef CONFIG_GPIOLIB
void gpiod_add_lookup_table(struct gpiod_lookup_table *table);
void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n);
void gpiod_remove_lookup_table(struct gpiod_lookup_table *table);
void gpiod_add_hogs(struct gpiod_hog *hogs);
void gpiod_remove_hogs(struct gpiod_hog *hogs);
#else /* ! CONFIG_GPIOLIB */
static inline
void gpiod_add_lookup_table(struct gpiod_lookup_table *table) {}
@@ -120,8 +89,6 @@ static inline
void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n) {}
static inline
void gpiod_remove_lookup_table(struct gpiod_lookup_table *table) {}
static inline void gpiod_add_hogs(struct gpiod_hog *hogs) {}
static inline void gpiod_remove_hogs(struct gpiod_hog *hogs) {}
#endif /* CONFIG_GPIOLIB */

#endif /* __LINUX_GPIO_MACHINE_H */