xref: /freebsd/sys/dev/gpio/pl061_acpi.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
11fc1a228SAndrew Turner /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31fc1a228SAndrew Turner  *
41fc1a228SAndrew Turner  * Copyright (c) 2020 Amazon.com, Inc. or its affiliates.
51fc1a228SAndrew Turner  * All rights reserved.
61fc1a228SAndrew Turner  *
71fc1a228SAndrew Turner  * Redistribution and use in source and binary forms, with or without
81fc1a228SAndrew Turner  * modification, are permitted provided that the following conditions
91fc1a228SAndrew Turner  * are met:
101fc1a228SAndrew Turner  * 1. Redistributions of source code must retain the above copyright
111fc1a228SAndrew Turner  *    notice, this list of conditions and the following disclaimer.
121fc1a228SAndrew Turner  * 2. Redistributions in binary form must reproduce the above copyright
131fc1a228SAndrew Turner  *    notice, this list of conditions and the following disclaimer in the
141fc1a228SAndrew Turner  *    documentation and/or other materials provided with the distribution.
151fc1a228SAndrew Turner  *
161fc1a228SAndrew Turner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
171fc1a228SAndrew Turner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
181fc1a228SAndrew Turner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
191fc1a228SAndrew Turner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
201fc1a228SAndrew Turner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
211fc1a228SAndrew Turner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
221fc1a228SAndrew Turner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
231fc1a228SAndrew Turner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
241fc1a228SAndrew Turner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
251fc1a228SAndrew Turner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261fc1a228SAndrew Turner  * SUCH DAMAGE.
271fc1a228SAndrew Turner  */
281fc1a228SAndrew Turner 
291fc1a228SAndrew Turner #include "opt_acpi.h"
301fc1a228SAndrew Turner 
311fc1a228SAndrew Turner #include <sys/param.h>
321fc1a228SAndrew Turner #include <sys/systm.h>
331fc1a228SAndrew Turner #include <sys/bus.h>
341fc1a228SAndrew Turner #include <sys/kernel.h>
351fc1a228SAndrew Turner #include <sys/module.h>
361fc1a228SAndrew Turner #include <sys/lock.h>
371fc1a228SAndrew Turner #include <sys/mutex.h>
381fc1a228SAndrew Turner 
391fc1a228SAndrew Turner #include <machine/intr.h>
401fc1a228SAndrew Turner 
411fc1a228SAndrew Turner #include <contrib/dev/acpica/include/acpi.h>
421fc1a228SAndrew Turner #include <contrib/dev/acpica/include/accommon.h>
431fc1a228SAndrew Turner 
441fc1a228SAndrew Turner #include <dev/acpica/acpivar.h>
451fc1a228SAndrew Turner #include <dev/gpio/gpiobusvar.h>
461fc1a228SAndrew Turner 
471fc1a228SAndrew Turner #include "pl061.h"
481fc1a228SAndrew Turner 
491fc1a228SAndrew Turner static char *gpio_ids[] = { "ARMH0061", NULL };
501fc1a228SAndrew Turner 
511fc1a228SAndrew Turner static int
pl061_acpi_probe(device_t dev)521fc1a228SAndrew Turner pl061_acpi_probe(device_t dev)
531fc1a228SAndrew Turner {
541fc1a228SAndrew Turner 	int rv;
551fc1a228SAndrew Turner 
561fc1a228SAndrew Turner 	if (acpi_disabled("gpio"))
571fc1a228SAndrew Turner 		return (ENXIO);
581fc1a228SAndrew Turner 
591fc1a228SAndrew Turner 	rv = ACPI_ID_PROBE(device_get_parent(dev), dev, gpio_ids, NULL);
601fc1a228SAndrew Turner 
611fc1a228SAndrew Turner 	if (rv <= 0)
621fc1a228SAndrew Turner 		device_set_desc(dev, "Arm PL061 GPIO Controller");
631fc1a228SAndrew Turner 
641fc1a228SAndrew Turner 	return (rv);
651fc1a228SAndrew Turner }
661fc1a228SAndrew Turner 
671fc1a228SAndrew Turner static int
pl061_acpi_attach(device_t dev)681fc1a228SAndrew Turner pl061_acpi_attach(device_t dev)
691fc1a228SAndrew Turner {
701fc1a228SAndrew Turner 	int error;
711fc1a228SAndrew Turner 
721fc1a228SAndrew Turner 	error = pl061_attach(dev);
731fc1a228SAndrew Turner 	if (error != 0)
741fc1a228SAndrew Turner 		return (error);
751fc1a228SAndrew Turner 
7615fe2adaSAndrew Turner 	if (!intr_pic_register(dev, ACPI_GPIO_XREF)) {
771fc1a228SAndrew Turner 		device_printf(dev, "couldn't register PIC\n");
781fc1a228SAndrew Turner 		pl061_detach(dev);
791fc1a228SAndrew Turner 		error = ENXIO;
801fc1a228SAndrew Turner 	}
811fc1a228SAndrew Turner 
821fc1a228SAndrew Turner 	return (error);
831fc1a228SAndrew Turner }
841fc1a228SAndrew Turner 
851fc1a228SAndrew Turner static device_method_t pl061_acpi_methods[] = {
861fc1a228SAndrew Turner 	/* Device interface */
871fc1a228SAndrew Turner 	DEVMETHOD(device_probe,		pl061_acpi_probe),
881fc1a228SAndrew Turner 	DEVMETHOD(device_attach,	pl061_acpi_attach),
891fc1a228SAndrew Turner 
901fc1a228SAndrew Turner 	DEVMETHOD_END
911fc1a228SAndrew Turner };
921fc1a228SAndrew Turner 
93128e746cSAndrew Turner DEFINE_CLASS_1(gpio, pl061_acpi_driver, pl061_acpi_methods,
941fc1a228SAndrew Turner     sizeof(struct pl061_softc), pl061_driver);
951fc1a228SAndrew Turner 
9684c5f982SJohn Baldwin EARLY_DRIVER_MODULE(pl061, acpi, pl061_acpi_driver, NULL, NULL,
9715fe2adaSAndrew Turner     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
981fc1a228SAndrew Turner MODULE_DEPEND(pl061, acpi, 1, 1, 1);
991fc1a228SAndrew Turner MODULE_DEPEND(pl061, gpiobus, 1, 1, 1);
100