gpiolib: add hogs support for machine code
Board files constitute a significant part of the users of the legacy GPIO framework. In many cases they only export a line and set its desired value. We could use GPIO hogs for that like we do for DT and ACPI but there's no support for that in machine code. This patch proposes to extend the machine.h API with support for registering hog tables in board files. Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:

committed by
Linus Walleij

parent
192a35b134
commit
a411e81e61
@@ -71,6 +71,9 @@ static DEFINE_MUTEX(gpio_lookup_lock);
|
||||
static LIST_HEAD(gpio_lookup_list);
|
||||
LIST_HEAD(gpio_devices);
|
||||
|
||||
static DEFINE_MUTEX(gpio_machine_hogs_mutex);
|
||||
static LIST_HEAD(gpio_machine_hogs);
|
||||
|
||||
static void gpiochip_free_hogs(struct gpio_chip *chip);
|
||||
static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
|
||||
struct lock_class_key *lock_key,
|
||||
@@ -1171,6 +1174,41 @@ err_remove_device:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void gpiochip_machine_hog(struct gpio_chip *chip, struct gpiod_hog *hog)
|
||||
{
|
||||
struct gpio_desc *desc;
|
||||
int rv;
|
||||
|
||||
desc = gpiochip_get_desc(chip, hog->chip_hwnum);
|
||||
if (IS_ERR(desc)) {
|
||||
pr_err("%s: unable to get GPIO desc: %ld\n",
|
||||
__func__, PTR_ERR(desc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (desc->flags & FLAG_IS_HOGGED)
|
||||
return;
|
||||
|
||||
rv = gpiod_hog(desc, hog->line_name, hog->lflags, hog->dflags);
|
||||
if (rv)
|
||||
pr_err("%s: unable to hog GPIO line (%s:%u): %d\n",
|
||||
__func__, chip->label, hog->chip_hwnum, rv);
|
||||
}
|
||||
|
||||
static void machine_gpiochip_add(struct gpio_chip *chip)
|
||||
{
|
||||
struct gpiod_hog *hog;
|
||||
|
||||
mutex_lock(&gpio_machine_hogs_mutex);
|
||||
|
||||
list_for_each_entry(hog, &gpio_machine_hogs, list) {
|
||||
if (!strcmp(chip->label, hog->chip_label))
|
||||
gpiochip_machine_hog(chip, hog);
|
||||
}
|
||||
|
||||
mutex_unlock(&gpio_machine_hogs_mutex);
|
||||
}
|
||||
|
||||
static void gpiochip_setup_devs(void)
|
||||
{
|
||||
struct gpio_device *gdev;
|
||||
@@ -1326,6 +1364,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
|
||||
|
||||
acpi_gpiochip_add(chip);
|
||||
|
||||
machine_gpiochip_add(chip);
|
||||
|
||||
/*
|
||||
* By first adding the chardev, and then adding the device,
|
||||
* we get a device node entry in sysfs under
|
||||
@@ -3462,6 +3502,33 @@ 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 gpio_chip *chip;
|
||||
struct gpiod_hog *hog;
|
||||
|
||||
mutex_lock(&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.
|
||||
*/
|
||||
chip = find_chip_by_name(hog->chip_label);
|
||||
if (chip)
|
||||
gpiochip_machine_hog(chip, hog);
|
||||
}
|
||||
|
||||
mutex_unlock(&gpio_machine_hogs_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpiod_add_hogs);
|
||||
|
||||
static struct gpiod_lookup_table *gpiod_find_lookup_table(struct device *dev)
|
||||
{
|
||||
const char *dev_id = dev ? dev_name(dev) : NULL;
|
||||
|
Reference in New Issue
Block a user