1*1fc1a228SAndrew Turner /*- 2*1fc1a228SAndrew Turner * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*1fc1a228SAndrew Turner * 4*1fc1a228SAndrew Turner * Copyright (c) 2020 Amazon.com, Inc. or its affiliates. 5*1fc1a228SAndrew Turner * All rights reserved. 6*1fc1a228SAndrew Turner * 7*1fc1a228SAndrew Turner * Redistribution and use in source and binary forms, with or without 8*1fc1a228SAndrew Turner * modification, are permitted provided that the following conditions 9*1fc1a228SAndrew Turner * are met: 10*1fc1a228SAndrew Turner * 1. Redistributions of source code must retain the above copyright 11*1fc1a228SAndrew Turner * notice, this list of conditions and the following disclaimer. 12*1fc1a228SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 13*1fc1a228SAndrew Turner * notice, this list of conditions and the following disclaimer in the 14*1fc1a228SAndrew Turner * documentation and/or other materials provided with the distribution. 15*1fc1a228SAndrew Turner * 16*1fc1a228SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*1fc1a228SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*1fc1a228SAndrew Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*1fc1a228SAndrew Turner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*1fc1a228SAndrew Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*1fc1a228SAndrew Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*1fc1a228SAndrew Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*1fc1a228SAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*1fc1a228SAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*1fc1a228SAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*1fc1a228SAndrew Turner * SUCH DAMAGE. 27*1fc1a228SAndrew Turner */ 28*1fc1a228SAndrew Turner 29*1fc1a228SAndrew Turner #include "opt_acpi.h" 30*1fc1a228SAndrew Turner 31*1fc1a228SAndrew Turner #include <sys/cdefs.h> 32*1fc1a228SAndrew Turner __FBSDID("$FreeBSD$"); 33*1fc1a228SAndrew Turner 34*1fc1a228SAndrew Turner #include <sys/param.h> 35*1fc1a228SAndrew Turner #include <sys/systm.h> 36*1fc1a228SAndrew Turner #include <sys/bus.h> 37*1fc1a228SAndrew Turner #include <sys/kernel.h> 38*1fc1a228SAndrew Turner #include <sys/module.h> 39*1fc1a228SAndrew Turner #include <sys/lock.h> 40*1fc1a228SAndrew Turner #include <sys/mutex.h> 41*1fc1a228SAndrew Turner 42*1fc1a228SAndrew Turner #include <machine/intr.h> 43*1fc1a228SAndrew Turner 44*1fc1a228SAndrew Turner #include <contrib/dev/acpica/include/acpi.h> 45*1fc1a228SAndrew Turner #include <contrib/dev/acpica/include/accommon.h> 46*1fc1a228SAndrew Turner 47*1fc1a228SAndrew Turner #include <dev/acpica/acpivar.h> 48*1fc1a228SAndrew Turner #include <dev/gpio/gpiobusvar.h> 49*1fc1a228SAndrew Turner 50*1fc1a228SAndrew Turner #include "pl061.h" 51*1fc1a228SAndrew Turner 52*1fc1a228SAndrew Turner static char *gpio_ids[] = { "ARMH0061", NULL }; 53*1fc1a228SAndrew Turner 54*1fc1a228SAndrew Turner static int 55*1fc1a228SAndrew Turner pl061_acpi_probe(device_t dev) 56*1fc1a228SAndrew Turner { 57*1fc1a228SAndrew Turner int rv; 58*1fc1a228SAndrew Turner 59*1fc1a228SAndrew Turner if (acpi_disabled("gpio")) 60*1fc1a228SAndrew Turner return (ENXIO); 61*1fc1a228SAndrew Turner 62*1fc1a228SAndrew Turner rv = ACPI_ID_PROBE(device_get_parent(dev), dev, gpio_ids, NULL); 63*1fc1a228SAndrew Turner 64*1fc1a228SAndrew Turner if (rv <= 0) 65*1fc1a228SAndrew Turner device_set_desc(dev, "Arm PL061 GPIO Controller"); 66*1fc1a228SAndrew Turner 67*1fc1a228SAndrew Turner return (rv); 68*1fc1a228SAndrew Turner } 69*1fc1a228SAndrew Turner 70*1fc1a228SAndrew Turner static int 71*1fc1a228SAndrew Turner pl061_acpi_attach(device_t dev) 72*1fc1a228SAndrew Turner { 73*1fc1a228SAndrew Turner int error; 74*1fc1a228SAndrew Turner 75*1fc1a228SAndrew Turner error = pl061_attach(dev); 76*1fc1a228SAndrew Turner if (error != 0) 77*1fc1a228SAndrew Turner return (error); 78*1fc1a228SAndrew Turner 79*1fc1a228SAndrew Turner if (!intr_pic_register(dev, ACPI_INTR_XREF)) { 80*1fc1a228SAndrew Turner device_printf(dev, "couldn't register PIC\n"); 81*1fc1a228SAndrew Turner pl061_detach(dev); 82*1fc1a228SAndrew Turner error = ENXIO; 83*1fc1a228SAndrew Turner } 84*1fc1a228SAndrew Turner 85*1fc1a228SAndrew Turner return (error); 86*1fc1a228SAndrew Turner } 87*1fc1a228SAndrew Turner 88*1fc1a228SAndrew Turner static device_method_t pl061_acpi_methods[] = { 89*1fc1a228SAndrew Turner /* Device interface */ 90*1fc1a228SAndrew Turner DEVMETHOD(device_probe, pl061_acpi_probe), 91*1fc1a228SAndrew Turner DEVMETHOD(device_attach, pl061_acpi_attach), 92*1fc1a228SAndrew Turner 93*1fc1a228SAndrew Turner DEVMETHOD_END 94*1fc1a228SAndrew Turner }; 95*1fc1a228SAndrew Turner 96*1fc1a228SAndrew Turner DEFINE_CLASS_1(pl061, pl061_acpi_driver, pl061_acpi_methods, 97*1fc1a228SAndrew Turner sizeof(struct pl061_softc), pl061_driver); 98*1fc1a228SAndrew Turner 99*1fc1a228SAndrew Turner static devclass_t pl061_devclass; 100*1fc1a228SAndrew Turner 101*1fc1a228SAndrew Turner DRIVER_MODULE(pl061, acpi, pl061_driver, pl061_devclass, NULL, NULL); 102*1fc1a228SAndrew Turner MODULE_DEPEND(pl061, acpi, 1, 1, 1); 103*1fc1a228SAndrew Turner MODULE_DEPEND(pl061, gpiobus, 1, 1, 1); 104