mirror of
https://github.com/joel16/android_kernel_sony_msm8994.git
synced 2024-12-13 15:27:12 +00:00
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: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.orh> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
This commit is contained in:
parent
372e722ea4
commit
6c0b4e6c85
@ -72,6 +72,8 @@ struct gpio_desc {
|
|||||||
};
|
};
|
||||||
static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
|
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);
|
static LIST_HEAD(gpio_chips);
|
||||||
|
|
||||||
#ifdef CONFIG_GPIO_SYSFS
|
#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)
|
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)
|
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;
|
unsigned gpio;
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio_lock, flags);
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
gpio = chip->base;
|
gpio = 0;
|
||||||
while (gpio_desc[gpio].chip == chip)
|
while (gpio < chip->ngpio)
|
||||||
gpio_desc[gpio++].chip = NULL;
|
chip->desc[gpio++].chip = NULL;
|
||||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
|
|
||||||
pr_debug("%s: chip %s status %d\n", __func__,
|
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);
|
status = gpiochip_add_to_list(chip);
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
for (id = base; id < base + chip->ngpio; id++) {
|
chip->desc = &gpio_desc[chip->base];
|
||||||
gpio_desc[id].chip = chip;
|
|
||||||
|
for (id = 0; id < chip->ngpio; id++) {
|
||||||
|
struct gpio_desc *desc = &chip->desc[id];
|
||||||
|
desc->chip = chip;
|
||||||
|
|
||||||
/* REVISIT: most hardware initializes GPIOs as
|
/* REVISIT: most hardware initializes GPIOs as
|
||||||
* inputs (often with pullups enabled) so power
|
* 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,
|
* and in case chip->get_direction is not set,
|
||||||
* we may expose the wrong direction in sysfs.
|
* we may expose the wrong direction in sysfs.
|
||||||
*/
|
*/
|
||||||
gpio_desc[id].flags = !chip->direction_input
|
desc->flags = !chip->direction_input
|
||||||
? (1 << FLAG_IS_OUT)
|
? (1 << FLAG_IS_OUT)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
@ -1249,15 +1254,15 @@ int gpiochip_remove(struct gpio_chip *chip)
|
|||||||
gpiochip_remove_pin_ranges(chip);
|
gpiochip_remove_pin_ranges(chip);
|
||||||
of_gpiochip_remove(chip);
|
of_gpiochip_remove(chip);
|
||||||
|
|
||||||
for (id = chip->base; id < chip->base + chip->ngpio; id++) {
|
for (id = 0; id < chip->ngpio; id++) {
|
||||||
if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
|
if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) {
|
||||||
status = -EBUSY;
|
status = -EBUSY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
for (id = chip->base; id < chip->base + chip->ngpio; id++)
|
for (id = 0; id < chip->ngpio; id++)
|
||||||
gpio_desc[id].chip = NULL;
|
chip->desc[id].chip = NULL;
|
||||||
|
|
||||||
list_del(&chip->list);
|
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)
|
const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
|
||||||
{
|
{
|
||||||
unsigned gpio = chip->base + offset;
|
struct gpio_desc *desc;
|
||||||
struct gpio_desc *desc = &gpio_desc[gpio];
|
|
||||||
|
|
||||||
if (!gpio_is_valid(gpio) || desc->chip != chip)
|
if (!GPIO_OFFSET_VALID(chip, offset))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
desc = &chip->desc[offset];
|
||||||
|
|
||||||
if (test_bit(FLAG_REQUESTED, &desc->flags) == 0)
|
if (test_bit(FLAG_REQUESTED, &desc->flags) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
@ -2025,7 +2032,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned gpio = chip->base;
|
unsigned gpio = chip->base;
|
||||||
struct gpio_desc *gdesc = &gpio_desc[gpio];
|
struct gpio_desc *gdesc = &chip->desc[0];
|
||||||
int is_out;
|
int is_out;
|
||||||
|
|
||||||
for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
|
for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
|
||||||
|
@ -47,6 +47,7 @@ struct gpio;
|
|||||||
struct seq_file;
|
struct seq_file;
|
||||||
struct module;
|
struct module;
|
||||||
struct device_node;
|
struct device_node;
|
||||||
|
struct gpio_desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct gpio_chip - abstract a GPIO controller
|
* struct gpio_chip - abstract a GPIO controller
|
||||||
@ -76,6 +77,7 @@ struct device_node;
|
|||||||
* negative during registration, requests dynamic ID allocation.
|
* negative during registration, requests dynamic ID allocation.
|
||||||
* @ngpio: the number of GPIOs handled by this controller; the last GPIO
|
* @ngpio: the number of GPIOs handled by this controller; the last GPIO
|
||||||
* handled is (base + ngpio - 1).
|
* handled is (base + ngpio - 1).
|
||||||
|
* @desc: array of ngpio descriptors. Private.
|
||||||
* @can_sleep: flag must be set iff get()/set() methods sleep, as they
|
* @can_sleep: flag must be set iff get()/set() methods sleep, as they
|
||||||
* must while accessing GPIO expander chips over I2C or SPI
|
* must while accessing GPIO expander chips over I2C or SPI
|
||||||
* @names: if set, must be an array of strings to use as alternative
|
* @names: if set, must be an array of strings to use as alternative
|
||||||
@ -126,6 +128,7 @@ struct gpio_chip {
|
|||||||
struct gpio_chip *chip);
|
struct gpio_chip *chip);
|
||||||
int base;
|
int base;
|
||||||
u16 ngpio;
|
u16 ngpio;
|
||||||
|
struct gpio_desc *desc;
|
||||||
const char *const *names;
|
const char *const *names;
|
||||||
unsigned can_sleep:1;
|
unsigned can_sleep:1;
|
||||||
unsigned exported:1;
|
unsigned exported:1;
|
||||||
|
Loading…
Reference in New Issue
Block a user