diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpiolib.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 623fcd9b547a..2ba6127c4fae 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -80,6 +80,33 @@ static inline struct gpio_chip *gpio_to_chip(unsigned gpio) | |||
80 | return gpio_desc[gpio].chip; | 80 | return gpio_desc[gpio].chip; |
81 | } | 81 | } |
82 | 82 | ||
83 | /* dynamic allocation of GPIOs, e.g. on a hotplugged device */ | ||
84 | static int gpiochip_find_base(int ngpio) | ||
85 | { | ||
86 | int i; | ||
87 | int spare = 0; | ||
88 | int base = -ENOSPC; | ||
89 | |||
90 | for (i = ARCH_NR_GPIOS - 1; i >= 0 ; i--) { | ||
91 | struct gpio_chip *chip = gpio_desc[i].chip; | ||
92 | |||
93 | if (!chip) { | ||
94 | spare++; | ||
95 | if (spare == ngpio) { | ||
96 | base = i; | ||
97 | break; | ||
98 | } | ||
99 | } else { | ||
100 | spare = 0; | ||
101 | i -= chip->ngpio - 1; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | if (gpio_is_valid(base)) | ||
106 | pr_debug("%s: found new base at %d\n", __func__, base); | ||
107 | return base; | ||
108 | } | ||
109 | |||
83 | /** | 110 | /** |
84 | * gpiochip_add() - register a gpio_chip | 111 | * gpiochip_add() - register a gpio_chip |
85 | * @chip: the chip to register, with chip->base initialized | 112 | * @chip: the chip to register, with chip->base initialized |
@@ -88,38 +115,49 @@ static inline struct gpio_chip *gpio_to_chip(unsigned gpio) | |||
88 | * Returns a negative errno if the chip can't be registered, such as | 115 | * Returns a negative errno if the chip can't be registered, such as |
89 | * because the chip->base is invalid or already associated with a | 116 | * because the chip->base is invalid or already associated with a |
90 | * different chip. Otherwise it returns zero as a success code. | 117 | * different chip. Otherwise it returns zero as a success code. |
118 | * | ||
119 | * If chip->base is negative, this requests dynamic assignment of | ||
120 | * a range of valid GPIOs. | ||
91 | */ | 121 | */ |
92 | int gpiochip_add(struct gpio_chip *chip) | 122 | int gpiochip_add(struct gpio_chip *chip) |
93 | { | 123 | { |
94 | unsigned long flags; | 124 | unsigned long flags; |
95 | int status = 0; | 125 | int status = 0; |
96 | unsigned id; | 126 | unsigned id; |
127 | int base = chip->base; | ||
97 | 128 | ||
98 | /* NOTE chip->base negative is reserved to mean a request for | 129 | if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio)) |
99 | * dynamic allocation. We don't currently support that. | 130 | && base >= 0) { |
100 | */ | ||
101 | |||
102 | if (chip->base < 0 || !gpio_is_valid(chip->base + chip->ngpio)) { | ||
103 | status = -EINVAL; | 131 | status = -EINVAL; |
104 | goto fail; | 132 | goto fail; |
105 | } | 133 | } |
106 | 134 | ||
107 | spin_lock_irqsave(&gpio_lock, flags); | 135 | spin_lock_irqsave(&gpio_lock, flags); |
108 | 136 | ||
137 | if (base < 0) { | ||
138 | base = gpiochip_find_base(chip->ngpio); | ||
139 | if (base < 0) { | ||
140 | status = base; | ||
141 | goto fail_unlock; | ||
142 | } | ||
143 | chip->base = base; | ||
144 | } | ||
145 | |||
109 | /* these GPIO numbers must not be managed by another gpio_chip */ | 146 | /* these GPIO numbers must not be managed by another gpio_chip */ |
110 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 147 | for (id = base; id < base + chip->ngpio; id++) { |
111 | if (gpio_desc[id].chip != NULL) { | 148 | if (gpio_desc[id].chip != NULL) { |
112 | status = -EBUSY; | 149 | status = -EBUSY; |
113 | break; | 150 | break; |
114 | } | 151 | } |
115 | } | 152 | } |
116 | if (status == 0) { | 153 | if (status == 0) { |
117 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 154 | for (id = base; id < base + chip->ngpio; id++) { |
118 | gpio_desc[id].chip = chip; | 155 | gpio_desc[id].chip = chip; |
119 | gpio_desc[id].flags = 0; | 156 | gpio_desc[id].flags = 0; |
120 | } | 157 | } |
121 | } | 158 | } |
122 | 159 | ||
160 | fail_unlock: | ||
123 | spin_unlock_irqrestore(&gpio_lock, flags); | 161 | spin_unlock_irqrestore(&gpio_lock, flags); |
124 | fail: | 162 | fail: |
125 | /* failures here can mean systems won't boot... */ | 163 | /* failures here can mean systems won't boot... */ |