gpiolib-acpi.c 13.7 KB
Newer Older
M
Mathias Nyman 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * ACPI helpers for GPIO API
 *
 * Copyright (C) 2012, Intel Corporation
 * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/errno.h>
14
#include <linux/gpio/consumer.h>
15
#include <linux/gpio/driver.h>
M
Mathias Nyman 已提交
16 17
#include <linux/export.h>
#include <linux/acpi.h>
18
#include <linux/interrupt.h>
19
#include <linux/mutex.h>
M
Mathias Nyman 已提交
20

21 22
#include "gpiolib.h"

23
struct acpi_gpio_event {
24
	struct list_head node;
25
	acpi_handle handle;
26 27 28 29
	unsigned int pin;
	unsigned int irq;
};

30 31 32 33 34
struct acpi_gpio_connection {
	struct list_head node;
	struct gpio_desc *desc;
};

35
struct acpi_gpio_chip {
36 37 38 39 40 41 42 43
	/*
	 * ACPICA requires that the first field of the context parameter
	 * passed to acpi_install_address_space_handler() is large enough
	 * to hold struct acpi_connection_info.
	 */
	struct acpi_connection_info conn_info;
	struct list_head conns;
	struct mutex conn_lock;
44
	struct gpio_chip *chip;
45
	struct list_head events;
46 47
};

M
Mathias Nyman 已提交
48 49 50 51 52 53 54 55 56
static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
{
	if (!gc->dev)
		return false;

	return ACPI_HANDLE(gc->dev) == data;
}

/**
57
 * acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API
M
Mathias Nyman 已提交
58 59 60
 * @path:	ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
 * @pin:	ACPI GPIO pin number (0-based, controller-relative)
 *
61 62
 * Returns GPIO descriptor to use with Linux generic GPIO API, or ERR_PTR
 * error value
M
Mathias Nyman 已提交
63 64
 */

65
static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
M
Mathias Nyman 已提交
66 67 68 69 70 71 72
{
	struct gpio_chip *chip;
	acpi_handle handle;
	acpi_status status;

	status = acpi_get_handle(NULL, path, &handle);
	if (ACPI_FAILURE(status))
73
		return ERR_PTR(-ENODEV);
M
Mathias Nyman 已提交
74 75 76

	chip = gpiochip_find(handle, acpi_gpiochip_find);
	if (!chip)
77
		return ERR_PTR(-ENODEV);
M
Mathias Nyman 已提交
78

79 80
	if (pin < 0 || pin > chip->ngpio)
		return ERR_PTR(-EINVAL);
M
Mathias Nyman 已提交
81

82
	return gpiochip_get_desc(chip, pin);
M
Mathias Nyman 已提交
83
}
84 85 86

static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
{
87
	struct acpi_gpio_event *event = data;
88

89
	acpi_evaluate_object(event->handle, NULL, NULL, NULL);
90 91 92 93

	return IRQ_HANDLED;
}

94 95
static irqreturn_t acpi_gpio_irq_handler_evt(int irq, void *data)
{
96
	struct acpi_gpio_event *event = data;
97

98
	acpi_execute_simple_method(event->handle, NULL, event->pin);
99 100 101 102

	return IRQ_HANDLED;
}

103
static void acpi_gpio_chip_dh(acpi_handle handle, void *data)
104 105 106 107
{
	/* The address of this function is used as a key. */
}

108 109
static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
						   void *context)
110
{
111
	struct acpi_gpio_chip *acpi_gpio = context;
112
	struct gpio_chip *chip = acpi_gpio->chip;
113
	struct acpi_resource_gpio *agpio;
114
	acpi_handle handle, evt_handle;
115 116 117 118 119
	struct acpi_gpio_event *event;
	irq_handler_t handler = NULL;
	struct gpio_desc *desc;
	unsigned long irqflags;
	int ret, pin, irq;
120

121 122 123 124 125 126
	if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
		return AE_OK;

	agpio = &ares->data.gpio;
	if (agpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_INT)
		return AE_OK;
127 128

	handle = ACPI_HANDLE(chip->dev);
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
	pin = agpio->pin_table[0];

	if (pin <= 255) {
		char ev_name[5];
		sprintf(ev_name, "_%c%02X",
			agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L',
			pin);
		if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle)))
			handler = acpi_gpio_irq_handler;
	}
	if (!handler) {
		if (ACPI_SUCCESS(acpi_get_handle(handle, "_EVT", &evt_handle)))
			handler = acpi_gpio_irq_handler_evt;
	}
	if (!handler)
		return AE_BAD_PARAMETER;
145

146 147 148 149 150
	desc = gpiochip_get_desc(chip, pin);
	if (IS_ERR(desc)) {
		dev_err(chip->dev, "Failed to get GPIO descriptor\n");
		return AE_ERROR;
	}
151

152 153 154 155 156
	ret = gpiochip_request_own_desc(desc, "ACPI:Event");
	if (ret) {
		dev_err(chip->dev, "Failed to request GPIO\n");
		return AE_ERROR;
	}
157

158
	gpiod_direction_input(desc);
159

160
	ret = gpio_lock_as_irq(chip, pin);
161 162 163 164
	if (ret) {
		dev_err(chip->dev, "Failed to lock GPIO as interrupt\n");
		goto fail_free_desc;
	}
165

166 167 168 169 170
	irq = gpiod_to_irq(desc);
	if (irq < 0) {
		dev_err(chip->dev, "Failed to translate GPIO to IRQ\n");
		goto fail_unlock_irq;
	}
171

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
	irqflags = IRQF_ONESHOT;
	if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
		if (agpio->polarity == ACPI_ACTIVE_HIGH)
			irqflags |= IRQF_TRIGGER_HIGH;
		else
			irqflags |= IRQF_TRIGGER_LOW;
	} else {
		switch (agpio->polarity) {
		case ACPI_ACTIVE_HIGH:
			irqflags |= IRQF_TRIGGER_RISING;
			break;
		case ACPI_ACTIVE_LOW:
			irqflags |= IRQF_TRIGGER_FALLING;
			break;
		default:
			irqflags |= IRQF_TRIGGER_RISING |
				    IRQF_TRIGGER_FALLING;
			break;
190
		}
191
	}
192

193 194 195
	event = kzalloc(sizeof(*event), GFP_KERNEL);
	if (!event)
		goto fail_unlock_irq;
196

197 198 199
	event->handle = evt_handle;
	event->irq = irq;
	event->pin = pin;
200

201 202 203 204 205 206
	ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
				   "ACPI:Event", event);
	if (ret) {
		dev_err(chip->dev, "Failed to setup interrupt handler for %d\n",
			event->irq);
		goto fail_free_event;
207
	}
208 209 210 211 212 213 214

	list_add_tail(&event->node, &acpi_gpio->events);
	return AE_OK;

fail_free_event:
	kfree(event);
fail_unlock_irq:
215
	gpio_unlock_as_irq(chip, pin);
216 217 218 219
fail_free_desc:
	gpiochip_free_own_desc(desc);

	return AE_ERROR;
220
}
221

222
/**
223
 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
224
 * @chip:      GPIO chip
225
 *
226 227 228 229 230 231
 * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
 * handled by ACPI event methods which need to be called from the GPIO
 * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
 * gpio pins have acpi event methods and assigns interrupt handlers that calls
 * the acpi event methods for those pins.
 */
232
void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
233
{
234 235 236 237 238 239
	struct acpi_gpio_chip *acpi_gpio;
	acpi_handle handle;
	acpi_status status;

	if (!chip->dev || !chip->to_irq)
		return;
240

241 242 243 244 245 246
	handle = ACPI_HANDLE(chip->dev);
	if (!handle)
		return;

	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
	if (ACPI_FAILURE(status))
247 248 249 250 251 252 253 254 255
		return;

	INIT_LIST_HEAD(&acpi_gpio->events);
	acpi_walk_resources(ACPI_HANDLE(chip->dev), "_AEI",
			    acpi_gpiochip_request_interrupt, acpi_gpio);
}

/**
 * acpi_gpiochip_free_interrupts() - Free GPIO ACPI event interrupts.
256
 * @chip:      GPIO chip
257
 *
258 259
 * Free interrupts associated with GPIO ACPI event method for the given
 * GPIO chip.
260
 */
261
void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
262
{
263
	struct acpi_gpio_chip *acpi_gpio;
264
	struct acpi_gpio_event *event, *ep;
265 266 267 268 269
	acpi_handle handle;
	acpi_status status;

	if (!chip->dev || !chip->to_irq)
		return;
270

271 272 273 274 275 276
	handle = ACPI_HANDLE(chip->dev);
	if (!handle)
		return;

	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
	if (ACPI_FAILURE(status))
277 278
		return;

279
	list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
280 281 282 283 284 285
		struct gpio_desc *desc;

		free_irq(event->irq, event);
		desc = gpiochip_get_desc(chip, event->pin);
		if (WARN_ON(IS_ERR(desc)))
			continue;
286
		gpio_unlock_as_irq(chip, event->pin);
287
		gpiochip_free_own_desc(desc);
288 289
		list_del(&event->node);
		kfree(event);
290 291 292
	}
}

293 294 295
struct acpi_gpio_lookup {
	struct acpi_gpio_info info;
	int index;
296
	struct gpio_desc *desc;
297 298 299 300 301 302 303 304 305 306
	int n;
};

static int acpi_find_gpio(struct acpi_resource *ares, void *data)
{
	struct acpi_gpio_lookup *lookup = data;

	if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
		return 1;

307
	if (lookup->n++ == lookup->index && !lookup->desc) {
308 309
		const struct acpi_resource_gpio *agpio = &ares->data.gpio;

310 311
		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
					      agpio->pin_table[0]);
312 313
		lookup->info.gpioint =
			agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
314 315
		lookup->info.active_low =
			agpio->polarity == ACPI_ACTIVE_LOW;
316 317 318 319 320 321
	}

	return 1;
}

/**
322
 * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
323 324 325 326 327
 * @dev: pointer to a device to get GPIO from
 * @index: index of GpioIo/GpioInt resource (starting from %0)
 * @info: info pointer to fill in (optional)
 *
 * Function goes through ACPI resources for @dev and based on @index looks
328
 * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor,
329 330 331
 * and returns it. @index matches GpioIo/GpioInt resources only so if there
 * are total %3 GPIO resources, the index goes from %0 to %2.
 *
332
 * If the GPIO cannot be translated or there is an error an ERR_PTR is
333 334 335 336 337
 * returned.
 *
 * Note: if the GPIO resource has multiple entries in the pin list, this
 * function only returns the first.
 */
338 339
struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
					  struct acpi_gpio_info *info)
340 341 342 343 344 345 346 347
{
	struct acpi_gpio_lookup lookup;
	struct list_head resource_list;
	struct acpi_device *adev;
	acpi_handle handle;
	int ret;

	if (!dev)
348
		return ERR_PTR(-EINVAL);
349 350 351

	handle = ACPI_HANDLE(dev);
	if (!handle || acpi_bus_get_device(handle, &adev))
352
		return ERR_PTR(-ENODEV);
353 354 355 356 357 358 359 360

	memset(&lookup, 0, sizeof(lookup));
	lookup.index = index;

	INIT_LIST_HEAD(&resource_list);
	ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
				     &lookup);
	if (ret < 0)
361
		return ERR_PTR(ret);
362 363 364

	acpi_dev_free_resource_list(&resource_list);

365
	if (lookup.desc && info)
366 367
		*info = lookup.info;

368
	return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
369
}
370

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
static acpi_status
acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
			    u32 bits, u64 *value, void *handler_context,
			    void *region_context)
{
	struct acpi_gpio_chip *achip = region_context;
	struct gpio_chip *chip = achip->chip;
	struct acpi_resource_gpio *agpio;
	struct acpi_resource *ares;
	acpi_status status;
	bool pull_up;
	int i;

	status = acpi_buffer_to_resource(achip->conn_info.connection,
					 achip->conn_info.length, &ares);
	if (ACPI_FAILURE(status))
		return status;

	if (WARN_ON(ares->type != ACPI_RESOURCE_TYPE_GPIO)) {
		ACPI_FREE(ares);
		return AE_BAD_PARAMETER;
	}

	agpio = &ares->data.gpio;
	pull_up = agpio->pin_config == ACPI_PIN_CONFIG_PULLUP;

	if (WARN_ON(agpio->io_restriction == ACPI_IO_RESTRICT_INPUT &&
	    function == ACPI_WRITE)) {
		ACPI_FREE(ares);
		return AE_BAD_PARAMETER;
	}

	for (i = 0; i < agpio->pin_table_length; i++) {
		unsigned pin = agpio->pin_table[i];
		struct acpi_gpio_connection *conn;
		struct gpio_desc *desc;
		bool found;

		desc = gpiochip_get_desc(chip, pin);
		if (IS_ERR(desc)) {
			status = AE_ERROR;
			goto out;
		}

		mutex_lock(&achip->conn_lock);

		found = false;
		list_for_each_entry(conn, &achip->conns, node) {
			if (conn->desc == desc) {
				found = true;
				break;
			}
		}
		if (!found) {
			int ret;

			ret = gpiochip_request_own_desc(desc, "ACPI:OpRegion");
			if (ret) {
				status = AE_ERROR;
				mutex_unlock(&achip->conn_lock);
				goto out;
			}

			switch (agpio->io_restriction) {
			case ACPI_IO_RESTRICT_INPUT:
				gpiod_direction_input(desc);
				break;
			case ACPI_IO_RESTRICT_OUTPUT:
				/*
				 * ACPI GPIO resources don't contain an
				 * initial value for the GPIO. Therefore we
				 * deduce that value from the pull field
				 * instead. If the pin is pulled up we
				 * assume default to be high, otherwise
				 * low.
				 */
				gpiod_direction_output(desc, pull_up);
				break;
			default:
				/*
				 * Assume that the BIOS has configured the
				 * direction and pull accordingly.
				 */
				break;
			}

			conn = kzalloc(sizeof(*conn), GFP_KERNEL);
			if (!conn) {
				status = AE_NO_MEMORY;
				gpiochip_free_own_desc(desc);
				mutex_unlock(&achip->conn_lock);
				goto out;
			}

			conn->desc = desc;
			list_add_tail(&conn->node, &achip->conns);
		}

		mutex_unlock(&achip->conn_lock);

		if (function == ACPI_WRITE)
472 473
			gpiod_set_raw_value_cansleep(desc,
						     !!((1 << i) & *value));
474
		else
475
			*value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
	}

out:
	ACPI_FREE(ares);
	return status;
}

static void acpi_gpiochip_request_regions(struct acpi_gpio_chip *achip)
{
	struct gpio_chip *chip = achip->chip;
	acpi_handle handle = ACPI_HANDLE(chip->dev);
	acpi_status status;

	INIT_LIST_HEAD(&achip->conns);
	mutex_init(&achip->conn_lock);
	status = acpi_install_address_space_handler(handle, ACPI_ADR_SPACE_GPIO,
						    acpi_gpio_adr_space_handler,
						    NULL, achip);
	if (ACPI_FAILURE(status))
		dev_err(chip->dev, "Failed to install GPIO OpRegion handler\n");
}

static void acpi_gpiochip_free_regions(struct acpi_gpio_chip *achip)
{
	struct gpio_chip *chip = achip->chip;
	acpi_handle handle = ACPI_HANDLE(chip->dev);
	struct acpi_gpio_connection *conn, *tmp;
	acpi_status status;

	status = acpi_remove_address_space_handler(handle, ACPI_ADR_SPACE_GPIO,
						   acpi_gpio_adr_space_handler);
	if (ACPI_FAILURE(status)) {
		dev_err(chip->dev, "Failed to remove GPIO OpRegion handler\n");
		return;
	}

	list_for_each_entry_safe_reverse(conn, tmp, &achip->conns, node) {
		gpiochip_free_own_desc(conn->desc);
		list_del(&conn->node);
		kfree(conn);
	}
}

519 520
void acpi_gpiochip_add(struct gpio_chip *chip)
{
521 522 523 524
	struct acpi_gpio_chip *acpi_gpio;
	acpi_handle handle;
	acpi_status status;

525 526 527
	if (!chip || !chip->dev)
		return;

528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
	handle = ACPI_HANDLE(chip->dev);
	if (!handle)
		return;

	acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
	if (!acpi_gpio) {
		dev_err(chip->dev,
			"Failed to allocate memory for ACPI GPIO chip\n");
		return;
	}

	acpi_gpio->chip = chip;

	status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
	if (ACPI_FAILURE(status)) {
		dev_err(chip->dev, "Failed to attach ACPI GPIO chip\n");
		kfree(acpi_gpio);
		return;
	}

548
	acpi_gpiochip_request_regions(acpi_gpio);
549 550 551 552
}

void acpi_gpiochip_remove(struct gpio_chip *chip)
{
553 554 555 556
	struct acpi_gpio_chip *acpi_gpio;
	acpi_handle handle;
	acpi_status status;

557 558 559
	if (!chip || !chip->dev)
		return;

560 561 562 563 564 565 566 567 568 569
	handle = ACPI_HANDLE(chip->dev);
	if (!handle)
		return;

	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
	if (ACPI_FAILURE(status)) {
		dev_warn(chip->dev, "Failed to retrieve ACPI GPIO chip\n");
		return;
	}

570
	acpi_gpiochip_free_regions(acpi_gpio);
571 572 573

	acpi_detach_data(handle, acpi_gpio_chip_dh);
	kfree(acpi_gpio);
574
}