Skip to content

Commit 77c2d79

Browse files
westeriLinus Walleij
authored andcommitted
gpiolib: Allow GPIO chips to request their own GPIOs
Sometimes it is useful to allow GPIO chips themselves to request GPIOs they own through gpiolib API. One use case is ACPI ASL code that should be able to toggle GPIOs through GPIO operation regions. We can't use gpio_request() because it will pin the module to the kernel forever (it calls try_module_get()). To solve this we move module refcount manipulation to gpiod_request() and let __gpiod_request() handle the actual request. This changes the sequence a bit as now try_module_get() is called outside of gpio_lock (I think this is safe, try_module_get() handles serialization it needs already). Then we provide gpiolib internal functions gpiochip_request/free_own_desc() that do the same as gpio_request() but don't manipulate module refrence count. This allows the GPIO chip driver to request and free descriptors it owns without being pinned to the kernel forever. Signed-off-by: Mika Westerberg <[email protected]> Reviewed-by: Alexandre Courbot <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 7b7f588 commit 77c2d79

File tree

2 files changed

+76
-27
lines changed

2 files changed

+76
-27
lines changed

drivers/gpio/gpiolib.c

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,26 +1458,14 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
14581458
* on each other, and help provide better diagnostics in debugfs.
14591459
* They're called even less than the "set direction" calls.
14601460
*/
1461-
static int gpiod_request(struct gpio_desc *desc, const char *label)
1461+
static int __gpiod_request(struct gpio_desc *desc, const char *label)
14621462
{
1463-
struct gpio_chip *chip;
1464-
int status = -EPROBE_DEFER;
1463+
struct gpio_chip *chip = desc->chip;
1464+
int status;
14651465
unsigned long flags;
14661466

1467-
if (!desc) {
1468-
pr_warn("%s: invalid GPIO\n", __func__);
1469-
return -EINVAL;
1470-
}
1471-
14721467
spin_lock_irqsave(&gpio_lock, flags);
14731468

1474-
chip = desc->chip;
1475-
if (chip == NULL)
1476-
goto done;
1477-
1478-
if (!try_module_get(chip->owner))
1479-
goto done;
1480-
14811469
/* NOTE: gpio_request() can be called in early boot,
14821470
* before IRQs are enabled, for non-sleeping (SOC) GPIOs.
14831471
*/
@@ -1487,7 +1475,6 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
14871475
status = 0;
14881476
} else {
14891477
status = -EBUSY;
1490-
module_put(chip->owner);
14911478
goto done;
14921479
}
14931480

@@ -1499,7 +1486,6 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
14991486

15001487
if (status < 0) {
15011488
desc_set_label(desc, NULL);
1502-
module_put(chip->owner);
15031489
clear_bit(FLAG_REQUESTED, &desc->flags);
15041490
goto done;
15051491
}
@@ -1510,10 +1496,35 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
15101496
gpiod_get_direction(desc);
15111497
spin_lock_irqsave(&gpio_lock, flags);
15121498
}
1499+
done:
1500+
spin_unlock_irqrestore(&gpio_lock, flags);
1501+
return status;
1502+
}
1503+
1504+
static int gpiod_request(struct gpio_desc *desc, const char *label)
1505+
{
1506+
int status = -EPROBE_DEFER;
1507+
struct gpio_chip *chip;
1508+
1509+
if (!desc) {
1510+
pr_warn("%s: invalid GPIO\n", __func__);
1511+
return -EINVAL;
1512+
}
1513+
1514+
chip = desc->chip;
1515+
if (!chip)
1516+
goto done;
1517+
1518+
if (try_module_get(chip->owner)) {
1519+
status = __gpiod_request(desc, label);
1520+
if (status < 0)
1521+
module_put(chip->owner);
1522+
}
1523+
15131524
done:
15141525
if (status)
15151526
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
1516-
spin_unlock_irqrestore(&gpio_lock, flags);
1527+
15171528
return status;
15181529
}
15191530

@@ -1523,18 +1534,14 @@ int gpio_request(unsigned gpio, const char *label)
15231534
}
15241535
EXPORT_SYMBOL_GPL(gpio_request);
15251536

1526-
static void gpiod_free(struct gpio_desc *desc)
1537+
static bool __gpiod_free(struct gpio_desc *desc)
15271538
{
1539+
bool ret = false;
15281540
unsigned long flags;
15291541
struct gpio_chip *chip;
15301542

15311543
might_sleep();
15321544

1533-
if (!desc) {
1534-
WARN_ON(extra_checks);
1535-
return;
1536-
}
1537-
15381545
gpiod_unexport(desc);
15391546

15401547
spin_lock_irqsave(&gpio_lock, flags);
@@ -1548,15 +1555,23 @@ static void gpiod_free(struct gpio_desc *desc)
15481555
spin_lock_irqsave(&gpio_lock, flags);
15491556
}
15501557
desc_set_label(desc, NULL);
1551-
module_put(desc->chip->owner);
15521558
clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
15531559
clear_bit(FLAG_REQUESTED, &desc->flags);
15541560
clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
15551561
clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
1556-
} else
1557-
WARN_ON(extra_checks);
1562+
ret = true;
1563+
}
15581564

15591565
spin_unlock_irqrestore(&gpio_lock, flags);
1566+
return ret;
1567+
}
1568+
1569+
static void gpiod_free(struct gpio_desc *desc)
1570+
{
1571+
if (desc && __gpiod_free(desc))
1572+
module_put(desc->chip->owner);
1573+
else
1574+
WARN_ON(extra_checks);
15601575
}
15611576

15621577
void gpio_free(unsigned gpio)
@@ -1678,6 +1693,37 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
16781693
}
16791694
EXPORT_SYMBOL_GPL(gpiochip_is_requested);
16801695

1696+
/**
1697+
* gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor
1698+
* @desc: GPIO descriptor to request
1699+
* @label: label for the GPIO
1700+
*
1701+
* Function allows GPIO chip drivers to request and use their own GPIO
1702+
* descriptors via gpiolib API. Difference to gpiod_request() is that this
1703+
* function will not increase reference count of the GPIO chip module. This
1704+
* allows the GPIO chip module to be unloaded as needed (we assume that the
1705+
* GPIO chip driver handles freeing the GPIOs it has requested).
1706+
*/
1707+
int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label)
1708+
{
1709+
if (!desc || !desc->chip)
1710+
return -EINVAL;
1711+
1712+
return __gpiod_request(desc, label);
1713+
}
1714+
1715+
/**
1716+
* gpiochip_free_own_desc - Free GPIO requested by the chip driver
1717+
* @desc: GPIO descriptor to free
1718+
*
1719+
* Function frees the given GPIO requested previously with
1720+
* gpiochip_request_own_desc().
1721+
*/
1722+
void gpiochip_free_own_desc(struct gpio_desc *desc)
1723+
{
1724+
if (desc)
1725+
__gpiod_free(desc);
1726+
}
16811727

16821728
/* Drivers MUST set GPIO direction before making get/set calls. In
16831729
* some cases this is done in early boot, before IRQs are enabled.

drivers/gpio/gpiolib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,7 @@ acpi_get_gpiod_by_index(struct device *dev, int index,
4343
}
4444
#endif
4545

46+
int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label);
47+
void gpiochip_free_own_desc(struct gpio_desc *desc);
48+
4649
#endif /* GPIOLIB_H */

0 commit comments

Comments
 (0)