aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/devres.c32
-rw-r--r--drivers/gpio/gpio-sch.c293
-rw-r--r--drivers/gpio/gpiolib-acpi.c117
-rw-r--r--drivers/gpio/gpiolib.c85
-rw-r--r--drivers/gpio/gpiolib.h7
5 files changed, 332 insertions, 202 deletions
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
index 954b9f6b0ef8..13dbd3dfc33a 100644
--- a/drivers/gpio/devres.c
+++ b/drivers/gpio/devres.c
@@ -109,6 +109,38 @@ struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
109EXPORT_SYMBOL(__devm_gpiod_get_index); 109EXPORT_SYMBOL(__devm_gpiod_get_index);
110 110
111/** 111/**
112 * devm_get_gpiod_from_child - get a GPIO descriptor from a device's child node
113 * @dev: GPIO consumer
114 * @child: firmware node (child of @dev)
115 *
116 * GPIO descriptors returned from this function are automatically disposed on
117 * driver detach.
118 */
119struct gpio_desc *devm_get_gpiod_from_child(struct device *dev,
120 struct fwnode_handle *child)
121{
122 struct gpio_desc **dr;
123 struct gpio_desc *desc;
124
125 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
126 GFP_KERNEL);
127 if (!dr)
128 return ERR_PTR(-ENOMEM);
129
130 desc = fwnode_get_named_gpiod(child, "gpios");
131 if (IS_ERR(desc)) {
132 devres_free(dr);
133 return desc;
134 }
135
136 *dr = desc;
137 devres_add(dev, dr);
138
139 return desc;
140}
141EXPORT_SYMBOL(devm_get_gpiod_from_child);
142
143/**
112 * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() 144 * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
113 * @dev: GPIO consumer 145 * @dev: GPIO consumer
114 * @con_id: function within the GPIO consumer 146 * @con_id: function within the GPIO consumer
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index 41e91d70301e..99720c8bc8ed 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -29,290 +29,221 @@
29 29
30#include <linux/gpio.h> 30#include <linux/gpio.h>
31 31
32static DEFINE_SPINLOCK(gpio_lock); 32#define GEN 0x00
33 33#define GIO 0x04
34#define CGEN (0x00) 34#define GLV 0x08
35#define CGIO (0x04) 35
36#define CGLV (0x08) 36struct sch_gpio {
37 37 struct gpio_chip chip;
38#define RGEN (0x20) 38 spinlock_t lock;
39#define RGIO (0x24) 39 unsigned short iobase;
40#define RGLV (0x28) 40 unsigned short core_base;
41 41 unsigned short resume_base;
42static unsigned short gpio_ba; 42};
43
44static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned gpio_num)
45{
46 u8 curr_dirs;
47 unsigned short offset, bit;
48
49 spin_lock(&gpio_lock);
50
51 offset = CGIO + gpio_num / 8;
52 bit = gpio_num % 8;
53
54 curr_dirs = inb(gpio_ba + offset);
55
56 if (!(curr_dirs & (1 << bit)))
57 outb(curr_dirs | (1 << bit), gpio_ba + offset);
58 43
59 spin_unlock(&gpio_lock); 44#define to_sch_gpio(c) container_of(c, struct sch_gpio, chip)
60 return 0;
61}
62 45
63static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num) 46static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
47 unsigned reg)
64{ 48{
65 int res; 49 unsigned base = 0;
66 unsigned short offset, bit;
67 50
68 offset = CGLV + gpio_num / 8; 51 if (gpio >= sch->resume_base) {
69 bit = gpio_num % 8; 52 gpio -= sch->resume_base;
53 base += 0x20;
54 }
70 55
71 res = !!(inb(gpio_ba + offset) & (1 << bit)); 56 return base + reg + gpio / 8;
72 return res;
73} 57}
74 58
75static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val) 59static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
76{ 60{
77 u8 curr_vals; 61 if (gpio >= sch->resume_base)
78 unsigned short offset, bit; 62 gpio -= sch->resume_base;
79 63 return gpio % 8;
80 spin_lock(&gpio_lock);
81
82 offset = CGLV + gpio_num / 8;
83 bit = gpio_num % 8;
84
85 curr_vals = inb(gpio_ba + offset);
86
87 if (val)
88 outb(curr_vals | (1 << bit), gpio_ba + offset);
89 else
90 outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
91 spin_unlock(&gpio_lock);
92} 64}
93 65
94static int sch_gpio_core_direction_out(struct gpio_chip *gc, 66static void sch_gpio_enable(struct sch_gpio *sch, unsigned gpio)
95 unsigned gpio_num, int val)
96{ 67{
97 u8 curr_dirs;
98 unsigned short offset, bit; 68 unsigned short offset, bit;
69 u8 enable;
99 70
100 spin_lock(&gpio_lock); 71 spin_lock(&sch->lock);
101 72
102 offset = CGIO + gpio_num / 8; 73 offset = sch_gpio_offset(sch, gpio, GEN);
103 bit = gpio_num % 8; 74 bit = sch_gpio_bit(sch, gpio);
104
105 curr_dirs = inb(gpio_ba + offset);
106 if (curr_dirs & (1 << bit))
107 outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
108 75
109 spin_unlock(&gpio_lock); 76 enable = inb(sch->iobase + offset);
77 if (!(enable & (1 << bit)))
78 outb(enable | (1 << bit), sch->iobase + offset);
110 79
111 /* 80 spin_unlock(&sch->lock);
112 * according to the datasheet, writing to the level register has no
113 * effect when GPIO is programmed as input.
114 * Actually the the level register is read-only when configured as input.
115 * Thus presetting the output level before switching to output is _NOT_ possible.
116 * Hence we set the level after configuring the GPIO as output.
117 * But we cannot prevent a short low pulse if direction is set to high
118 * and an external pull-up is connected.
119 */
120 sch_gpio_core_set(gc, gpio_num, val);
121 return 0;
122} 81}
123 82
124static struct gpio_chip sch_gpio_core = { 83static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
125 .label = "sch_gpio_core",
126 .owner = THIS_MODULE,
127 .direction_input = sch_gpio_core_direction_in,
128 .get = sch_gpio_core_get,
129 .direction_output = sch_gpio_core_direction_out,
130 .set = sch_gpio_core_set,
131};
132
133static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
134 unsigned gpio_num)
135{ 84{
85 struct sch_gpio *sch = to_sch_gpio(gc);
136 u8 curr_dirs; 86 u8 curr_dirs;
137 unsigned short offset, bit; 87 unsigned short offset, bit;
138 88
139 spin_lock(&gpio_lock); 89 spin_lock(&sch->lock);
140 90
141 offset = RGIO + gpio_num / 8; 91 offset = sch_gpio_offset(sch, gpio_num, GIO);
142 bit = gpio_num % 8; 92 bit = sch_gpio_bit(sch, gpio_num);
143 93
144 curr_dirs = inb(gpio_ba + offset); 94 curr_dirs = inb(sch->iobase + offset);
145 95
146 if (!(curr_dirs & (1 << bit))) 96 if (!(curr_dirs & (1 << bit)))
147 outb(curr_dirs | (1 << bit), gpio_ba + offset); 97 outb(curr_dirs | (1 << bit), sch->iobase + offset);
148 98
149 spin_unlock(&gpio_lock); 99 spin_unlock(&sch->lock);
150 return 0; 100 return 0;
151} 101}
152 102
153static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num) 103static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
154{ 104{
105 struct sch_gpio *sch = to_sch_gpio(gc);
106 int res;
155 unsigned short offset, bit; 107 unsigned short offset, bit;
156 108
157 offset = RGLV + gpio_num / 8; 109 offset = sch_gpio_offset(sch, gpio_num, GLV);
158 bit = gpio_num % 8; 110 bit = sch_gpio_bit(sch, gpio_num);
111
112 res = !!(inb(sch->iobase + offset) & (1 << bit));
159 113
160 return !!(inb(gpio_ba + offset) & (1 << bit)); 114 return res;
161} 115}
162 116
163static void sch_gpio_resume_set(struct gpio_chip *gc, 117static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
164 unsigned gpio_num, int val)
165{ 118{
119 struct sch_gpio *sch = to_sch_gpio(gc);
166 u8 curr_vals; 120 u8 curr_vals;
167 unsigned short offset, bit; 121 unsigned short offset, bit;
168 122
169 spin_lock(&gpio_lock); 123 spin_lock(&sch->lock);
170 124
171 offset = RGLV + gpio_num / 8; 125 offset = sch_gpio_offset(sch, gpio_num, GLV);
172 bit = gpio_num % 8; 126 bit = sch_gpio_bit(sch, gpio_num);
173 127
174 curr_vals = inb(gpio_ba + offset); 128 curr_vals = inb(sch->iobase + offset);
175 129
176 if (val) 130 if (val)
177 outb(curr_vals | (1 << bit), gpio_ba + offset); 131 outb(curr_vals | (1 << bit), sch->iobase + offset);
178 else 132 else
179 outb((curr_vals & ~(1 << bit)), gpio_ba + offset); 133 outb((curr_vals & ~(1 << bit)), sch->iobase + offset);
180 134
181 spin_unlock(&gpio_lock); 135 spin_unlock(&sch->lock);
182} 136}
183 137
184static int sch_gpio_resume_direction_out(struct gpio_chip *gc, 138static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
185 unsigned gpio_num, int val) 139 int val)
186{ 140{
141 struct sch_gpio *sch = to_sch_gpio(gc);
187 u8 curr_dirs; 142 u8 curr_dirs;
188 unsigned short offset, bit; 143 unsigned short offset, bit;
189 144
190 offset = RGIO + gpio_num / 8; 145 spin_lock(&sch->lock);
191 bit = gpio_num % 8;
192 146
193 spin_lock(&gpio_lock); 147 offset = sch_gpio_offset(sch, gpio_num, GIO);
148 bit = sch_gpio_bit(sch, gpio_num);
194 149
195 curr_dirs = inb(gpio_ba + offset); 150 curr_dirs = inb(sch->iobase + offset);
196 if (curr_dirs & (1 << bit)) 151 if (curr_dirs & (1 << bit))
197 outb(curr_dirs & ~(1 << bit), gpio_ba + offset); 152 outb(curr_dirs & ~(1 << bit), sch->iobase + offset);
198 153
199 spin_unlock(&gpio_lock); 154 spin_unlock(&sch->lock);
200 155
201 /* 156 /*
202 * according to the datasheet, writing to the level register has no 157 * according to the datasheet, writing to the level register has no
203 * effect when GPIO is programmed as input. 158 * effect when GPIO is programmed as input.
204 * Actually the the level register is read-only when configured as input. 159 * Actually the the level register is read-only when configured as input.
205 * Thus presetting the output level before switching to output is _NOT_ possible. 160 * Thus presetting the output level before switching to output is _NOT_ possible.
206 * Hence we set the level after configuring the GPIO as output. 161 * Hence we set the level after configuring the GPIO as output.
207 * But we cannot prevent a short low pulse if direction is set to high 162 * But we cannot prevent a short low pulse if direction is set to high
208 * and an external pull-up is connected. 163 * and an external pull-up is connected.
209 */ 164 */
210 sch_gpio_resume_set(gc, gpio_num, val); 165 sch_gpio_set(gc, gpio_num, val);
211 return 0; 166 return 0;
212} 167}
213 168
214static struct gpio_chip sch_gpio_resume = { 169static struct gpio_chip sch_gpio_chip = {
215 .label = "sch_gpio_resume", 170 .label = "sch_gpio",
216 .owner = THIS_MODULE, 171 .owner = THIS_MODULE,
217 .direction_input = sch_gpio_resume_direction_in, 172 .direction_input = sch_gpio_direction_in,
218 .get = sch_gpio_resume_get, 173 .get = sch_gpio_get,
219 .direction_output = sch_gpio_resume_direction_out, 174 .direction_output = sch_gpio_direction_out,
220 .set = sch_gpio_resume_set, 175 .set = sch_gpio_set,
221}; 176};
222 177
223static int sch_gpio_probe(struct platform_device *pdev) 178static int sch_gpio_probe(struct platform_device *pdev)
224{ 179{
180 struct sch_gpio *sch;
225 struct resource *res; 181 struct resource *res;
226 int err, id;
227 182
228 id = pdev->id; 183 sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
229 if (!id) 184 if (!sch)
230 return -ENODEV; 185 return -ENOMEM;
231 186
232 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 187 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
233 if (!res) 188 if (!res)
234 return -EBUSY; 189 return -EBUSY;
235 190
236 if (!request_region(res->start, resource_size(res), pdev->name)) 191 if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
192 pdev->name))
237 return -EBUSY; 193 return -EBUSY;
238 194
239 gpio_ba = res->start; 195 spin_lock_init(&sch->lock);
196 sch->iobase = res->start;
197 sch->chip = sch_gpio_chip;
198 sch->chip.label = dev_name(&pdev->dev);
199 sch->chip.dev = &pdev->dev;
240 200
241 switch (id) { 201 switch (pdev->id) {
242 case PCI_DEVICE_ID_INTEL_SCH_LPC: 202 case PCI_DEVICE_ID_INTEL_SCH_LPC:
243 sch_gpio_core.base = 0; 203 sch->core_base = 0;
244 sch_gpio_core.ngpio = 10; 204 sch->resume_base = 10;
245 sch_gpio_resume.base = 10; 205 sch->chip.ngpio = 14;
246 sch_gpio_resume.ngpio = 4; 206
247 /* 207 /*
248 * GPIO[6:0] enabled by default 208 * GPIO[6:0] enabled by default
249 * GPIO7 is configured by the CMC as SLPIOVR 209 * GPIO7 is configured by the CMC as SLPIOVR
250 * Enable GPIO[9:8] core powered gpios explicitly 210 * Enable GPIO[9:8] core powered gpios explicitly
251 */ 211 */
252 outb(0x3, gpio_ba + CGEN + 1); 212 sch_gpio_enable(sch, 8);
213 sch_gpio_enable(sch, 9);
253 /* 214 /*
254 * SUS_GPIO[2:0] enabled by default 215 * SUS_GPIO[2:0] enabled by default
255 * Enable SUS_GPIO3 resume powered gpio explicitly 216 * Enable SUS_GPIO3 resume powered gpio explicitly
256 */ 217 */
257 outb(0x8, gpio_ba + RGEN); 218 sch_gpio_enable(sch, 13);
258 break; 219 break;
259 220
260 case PCI_DEVICE_ID_INTEL_ITC_LPC: 221 case PCI_DEVICE_ID_INTEL_ITC_LPC:
261 sch_gpio_core.base = 0; 222 sch->core_base = 0;
262 sch_gpio_core.ngpio = 5; 223 sch->resume_base = 5;
263 sch_gpio_resume.base = 5; 224 sch->chip.ngpio = 14;
264 sch_gpio_resume.ngpio = 9;
265 break; 225 break;
266 226
267 case PCI_DEVICE_ID_INTEL_CENTERTON_ILB: 227 case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
268 sch_gpio_core.base = 0; 228 sch->core_base = 0;
269 sch_gpio_core.ngpio = 21; 229 sch->resume_base = 21;
270 sch_gpio_resume.base = 21; 230 sch->chip.ngpio = 30;
271 sch_gpio_resume.ngpio = 9;
272 break; 231 break;
273 232
274 default: 233 default:
275 err = -ENODEV; 234 return -ENODEV;
276 goto err_sch_gpio_core;
277 } 235 }
278 236
279 sch_gpio_core.dev = &pdev->dev; 237 platform_set_drvdata(pdev, sch);
280 sch_gpio_resume.dev = &pdev->dev;
281
282 err = gpiochip_add(&sch_gpio_core);
283 if (err < 0)
284 goto err_sch_gpio_core;
285 238
286 err = gpiochip_add(&sch_gpio_resume); 239 return gpiochip_add(&sch->chip);
287 if (err < 0)
288 goto err_sch_gpio_resume;
289
290 return 0;
291
292err_sch_gpio_resume:
293 gpiochip_remove(&sch_gpio_core);
294
295err_sch_gpio_core:
296 release_region(res->start, resource_size(res));
297 gpio_ba = 0;
298
299 return err;
300} 240}
301 241
302static int sch_gpio_remove(struct platform_device *pdev) 242static int sch_gpio_remove(struct platform_device *pdev)
303{ 243{
304 struct resource *res; 244 struct sch_gpio *sch = platform_get_drvdata(pdev);
305 if (gpio_ba) {
306
307 gpiochip_remove(&sch_gpio_core);
308 gpiochip_remove(&sch_gpio_resume);
309
310 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
311
312 release_region(res->start, resource_size(res));
313 gpio_ba = 0;
314 }
315 245
246 gpiochip_remove(&sch->chip);
316 return 0; 247 return 0;
317} 248}
318 249
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 05c6275da224..ba98bb59a58f 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -287,9 +287,45 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
287 } 287 }
288} 288}
289 289
290int acpi_dev_add_driver_gpios(struct acpi_device *adev,
291 const struct acpi_gpio_mapping *gpios)
292{
293 if (adev && gpios) {
294 adev->driver_gpios = gpios;
295 return 0;
296 }
297 return -EINVAL;
298}
299EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
300
301static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
302 const char *name, int index,
303 struct acpi_reference_args *args)
304{
305 const struct acpi_gpio_mapping *gm;
306
307 if (!adev->driver_gpios)
308 return false;
309
310 for (gm = adev->driver_gpios; gm->name; gm++)
311 if (!strcmp(name, gm->name) && gm->data && index < gm->size) {
312 const struct acpi_gpio_params *par = gm->data + index;
313
314 args->adev = adev;
315 args->args[0] = par->crs_entry_index;
316 args->args[1] = par->line_index;
317 args->args[2] = par->active_low;
318 args->nargs = 3;
319 return true;
320 }
321
322 return false;
323}
324
290struct acpi_gpio_lookup { 325struct acpi_gpio_lookup {
291 struct acpi_gpio_info info; 326 struct acpi_gpio_info info;
292 int index; 327 int index;
328 int pin_index;
293 struct gpio_desc *desc; 329 struct gpio_desc *desc;
294 int n; 330 int n;
295}; 331};
@@ -303,13 +339,24 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
303 339
304 if (lookup->n++ == lookup->index && !lookup->desc) { 340 if (lookup->n++ == lookup->index && !lookup->desc) {
305 const struct acpi_resource_gpio *agpio = &ares->data.gpio; 341 const struct acpi_resource_gpio *agpio = &ares->data.gpio;
342 int pin_index = lookup->pin_index;
343
344 if (pin_index >= agpio->pin_table_length)
345 return 1;
306 346
307 lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr, 347 lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
308 agpio->pin_table[0]); 348 agpio->pin_table[pin_index]);
309 lookup->info.gpioint = 349 lookup->info.gpioint =
310 agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT; 350 agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
311 lookup->info.active_low = 351
312 agpio->polarity == ACPI_ACTIVE_LOW; 352 /*
353 * ActiveLow is only specified for GpioInt resource. If
354 * GpioIo is used then the only way to set the flag is
355 * to use _DSD "gpios" property.
356 */
357 if (lookup->info.gpioint)
358 lookup->info.active_low =
359 agpio->polarity == ACPI_ACTIVE_LOW;
313 } 360 }
314 361
315 return 1; 362 return 1;
@@ -317,40 +364,79 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
317 364
318/** 365/**
319 * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources 366 * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
320 * @dev: pointer to a device to get GPIO from 367 * @adev: pointer to a ACPI device to get GPIO from
368 * @propname: Property name of the GPIO (optional)
321 * @index: index of GpioIo/GpioInt resource (starting from %0) 369 * @index: index of GpioIo/GpioInt resource (starting from %0)
322 * @info: info pointer to fill in (optional) 370 * @info: info pointer to fill in (optional)
323 * 371 *
324 * Function goes through ACPI resources for @dev and based on @index looks 372 * Function goes through ACPI resources for @adev and based on @index looks
325 * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor, 373 * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor,
326 * and returns it. @index matches GpioIo/GpioInt resources only so if there 374 * and returns it. @index matches GpioIo/GpioInt resources only so if there
327 * are total %3 GPIO resources, the index goes from %0 to %2. 375 * are total %3 GPIO resources, the index goes from %0 to %2.
328 * 376 *
377 * If @propname is specified the GPIO is looked using device property. In
378 * that case @index is used to select the GPIO entry in the property value
379 * (in case of multiple).
380 *
329 * If the GPIO cannot be translated or there is an error an ERR_PTR is 381 * If the GPIO cannot be translated or there is an error an ERR_PTR is
330 * returned. 382 * returned.
331 * 383 *
332 * Note: if the GPIO resource has multiple entries in the pin list, this 384 * Note: if the GPIO resource has multiple entries in the pin list, this
333 * function only returns the first. 385 * function only returns the first.
334 */ 386 */
335struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index, 387struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
388 const char *propname, int index,
336 struct acpi_gpio_info *info) 389 struct acpi_gpio_info *info)
337{ 390{
338 struct acpi_gpio_lookup lookup; 391 struct acpi_gpio_lookup lookup;
339 struct list_head resource_list; 392 struct list_head resource_list;
340 struct acpi_device *adev; 393 bool active_low = false;
341 acpi_handle handle;
342 int ret; 394 int ret;
343 395
344 if (!dev) 396 if (!adev)
345 return ERR_PTR(-EINVAL);
346
347 handle = ACPI_HANDLE(dev);
348 if (!handle || acpi_bus_get_device(handle, &adev))
349 return ERR_PTR(-ENODEV); 397 return ERR_PTR(-ENODEV);
350 398
351 memset(&lookup, 0, sizeof(lookup)); 399 memset(&lookup, 0, sizeof(lookup));
352 lookup.index = index; 400 lookup.index = index;
353 401
402 if (propname) {
403 struct acpi_reference_args args;
404
405 dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
406
407 memset(&args, 0, sizeof(args));
408 ret = acpi_dev_get_property_reference(adev, propname,
409 index, &args);
410 if (ret) {
411 bool found = acpi_get_driver_gpio_data(adev, propname,
412 index, &args);
413 if (!found)
414 return ERR_PTR(ret);
415 }
416
417 /*
418 * The property was found and resolved so need to
419 * lookup the GPIO based on returned args instead.
420 */
421 adev = args.adev;
422 if (args.nargs >= 2) {
423 lookup.index = args.args[0];
424 lookup.pin_index = args.args[1];
425 /*
426 * 3rd argument, if present is used to
427 * specify active_low.
428 */
429 if (args.nargs >= 3)
430 active_low = !!args.args[2];
431 }
432
433 dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
434 dev_name(&adev->dev), args.nargs,
435 args.args[0], args.args[1], args.args[2]);
436 } else {
437 dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
438 }
439
354 INIT_LIST_HEAD(&resource_list); 440 INIT_LIST_HEAD(&resource_list);
355 ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio, 441 ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
356 &lookup); 442 &lookup);
@@ -359,8 +445,11 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
359 445
360 acpi_dev_free_resource_list(&resource_list); 446 acpi_dev_free_resource_list(&resource_list);
361 447
362 if (lookup.desc && info) 448 if (lookup.desc && info) {
363 *info = lookup.info; 449 *info = lookup.info;
450 if (active_low)
451 info->active_low = active_low;
452 }
364 453
365 return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT); 454 return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
366} 455}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e8e98ca25ec7..58659dbe702a 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1505,14 +1505,36 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
1505 unsigned int idx, 1505 unsigned int idx,
1506 enum gpio_lookup_flags *flags) 1506 enum gpio_lookup_flags *flags)
1507{ 1507{
1508 static const char * const suffixes[] = { "gpios", "gpio" };
1509 struct acpi_device *adev = ACPI_COMPANION(dev);
1508 struct acpi_gpio_info info; 1510 struct acpi_gpio_info info;
1509 struct gpio_desc *desc; 1511 struct gpio_desc *desc;
1512 char propname[32];
1513 int i;
1510 1514
1511 desc = acpi_get_gpiod_by_index(dev, idx, &info); 1515 /* Try first from _DSD */
1512 if (IS_ERR(desc)) 1516 for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
1513 return desc; 1517 if (con_id && strcmp(con_id, "gpios")) {
1518 snprintf(propname, sizeof(propname), "%s-%s",
1519 con_id, suffixes[i]);
1520 } else {
1521 snprintf(propname, sizeof(propname), "%s",
1522 suffixes[i]);
1523 }
1524
1525 desc = acpi_get_gpiod_by_index(adev, propname, idx, &info);
1526 if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
1527 break;
1528 }
1514 1529
1515 if (info.gpioint && info.active_low) 1530 /* Then from plain _CRS GPIOs */
1531 if (IS_ERR(desc)) {
1532 desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
1533 if (IS_ERR(desc))
1534 return desc;
1535 }
1536
1537 if (info.active_low)
1516 *flags |= GPIO_ACTIVE_LOW; 1538 *flags |= GPIO_ACTIVE_LOW;
1517 1539
1518 return desc; 1540 return desc;
@@ -1713,6 +1735,61 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
1713EXPORT_SYMBOL_GPL(__gpiod_get_index); 1735EXPORT_SYMBOL_GPL(__gpiod_get_index);
1714 1736
1715/** 1737/**
1738 * fwnode_get_named_gpiod - obtain a GPIO from firmware node
1739 * @fwnode: handle of the firmware node
1740 * @propname: name of the firmware property representing the GPIO
1741 *
1742 * This function can be used for drivers that get their configuration
1743 * from firmware.
1744 *
1745 * Function properly finds the corresponding GPIO using whatever is the
1746 * underlying firmware interface and then makes sure that the GPIO
1747 * descriptor is requested before it is returned to the caller.
1748 *
1749 * In case of error an ERR_PTR() is returned.
1750 */
1751struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
1752 const char *propname)
1753{
1754 struct gpio_desc *desc = ERR_PTR(-ENODEV);
1755 bool active_low = false;
1756 int ret;
1757
1758 if (!fwnode)
1759 return ERR_PTR(-EINVAL);
1760
1761 if (is_of_node(fwnode)) {
1762 enum of_gpio_flags flags;
1763
1764 desc = of_get_named_gpiod_flags(of_node(fwnode), propname, 0,
1765 &flags);
1766 if (!IS_ERR(desc))
1767 active_low = flags & OF_GPIO_ACTIVE_LOW;
1768 } else if (is_acpi_node(fwnode)) {
1769 struct acpi_gpio_info info;
1770
1771 desc = acpi_get_gpiod_by_index(acpi_node(fwnode), propname, 0,
1772 &info);
1773 if (!IS_ERR(desc))
1774 active_low = info.active_low;
1775 }
1776
1777 if (IS_ERR(desc))
1778 return desc;
1779
1780 ret = gpiod_request(desc, NULL);
1781 if (ret)
1782 return ERR_PTR(ret);
1783
1784 /* Only value flag can be set from both DT and ACPI is active_low */
1785 if (active_low)
1786 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
1787
1788 return desc;
1789}
1790EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
1791
1792/**
1716 * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO 1793 * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
1717 * function 1794 * function
1718 * @dev: GPIO consumer, can be NULL for system-global GPIOs 1795 * @dev: GPIO consumer, can be NULL for system-global GPIOs
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 9db2b6a71c5d..e3a52113a541 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -34,7 +34,8 @@ void acpi_gpiochip_remove(struct gpio_chip *chip);
34void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); 34void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
35void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); 35void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
36 36
37struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index, 37struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
38 const char *propname, int index,
38 struct acpi_gpio_info *info); 39 struct acpi_gpio_info *info);
39#else 40#else
40static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } 41static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
@@ -47,8 +48,8 @@ static inline void
47acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } 48acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
48 49
49static inline struct gpio_desc * 50static inline struct gpio_desc *
50acpi_get_gpiod_by_index(struct device *dev, int index, 51acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
51 struct acpi_gpio_info *info) 52 int index, struct acpi_gpio_info *info)
52{ 53{
53 return ERR_PTR(-ENOSYS); 54 return ERR_PTR(-ENOSYS);
54} 55}