121f9f90cSImre Vadász /*-
221f9f90cSImre Vadász * Copyright (c) 2008 Alexander Motin <mav@FreeBSD.org>
321f9f90cSImre Vadász * All rights reserved.
421f9f90cSImre Vadász *
521f9f90cSImre Vadász * Redistribution and use in source and binary forms, with or without
621f9f90cSImre Vadász * modification, are permitted provided that the following conditions
721f9f90cSImre Vadász * are met:
821f9f90cSImre Vadász * 1. Redistributions of source code must retain the above copyright
921f9f90cSImre Vadász * notice, this list of conditions and the following disclaimer.
1021f9f90cSImre Vadász * 2. Redistributions in binary form must reproduce the above copyright
1121f9f90cSImre Vadász * notice, this list of conditions and the following disclaimer in the
1221f9f90cSImre Vadász * documentation and/or other materials provided with the distribution.
1321f9f90cSImre Vadász *
1421f9f90cSImre Vadász * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1521f9f90cSImre Vadász * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1621f9f90cSImre Vadász * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1721f9f90cSImre Vadász * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1821f9f90cSImre Vadász * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1921f9f90cSImre Vadász * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2021f9f90cSImre Vadász * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2121f9f90cSImre Vadász * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2221f9f90cSImre Vadász * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2321f9f90cSImre Vadász * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2421f9f90cSImre Vadász */
2521f9f90cSImre Vadász
2621f9f90cSImre Vadász #include <sys/param.h>
2721f9f90cSImre Vadász #include <sys/systm.h>
2821f9f90cSImre Vadász #include <sys/bus.h>
2921f9f90cSImre Vadász #include <sys/kernel.h>
3021f9f90cSImre Vadász #include <sys/module.h>
3121f9f90cSImre Vadász #include <sys/resource.h>
3221f9f90cSImre Vadász #include <sys/rman.h>
3321f9f90cSImre Vadász #include <sys/taskqueue.h>
3421f9f90cSImre Vadász
3521f9f90cSImre Vadász #include "acpi.h"
3621f9f90cSImre Vadász #include "opt_acpi.h"
3721f9f90cSImre Vadász #include <dev/acpica/acpivar.h>
3821f9f90cSImre Vadász
3921f9f90cSImre Vadász #include <bus/pci/pcivar.h>
4021f9f90cSImre Vadász
4121f9f90cSImre Vadász #include <bus/mmc/bridge.h>
4221f9f90cSImre Vadász
434d3ae590SImre Vadász #include <dev/disk/sdhci/sdhci.h>
444d3ae590SImre Vadász
4521f9f90cSImre Vadász #include "mmcbr_if.h"
4621f9f90cSImre Vadász #include "sdhci_if.h"
4721f9f90cSImre Vadász
4821f9f90cSImre Vadász ACPI_MODULE_NAME("sdhci_acpi");
4921f9f90cSImre Vadász
5021f9f90cSImre Vadász struct sdhci_acpi_softc {
5121f9f90cSImre Vadász device_t dev; /* Controller device */
5221f9f90cSImre Vadász ACPI_HANDLE handle;
5321f9f90cSImre Vadász struct resource *irq_res; /* IRQ resource */
5421f9f90cSImre Vadász void *intrhand; /* Interrupt handle */
5521f9f90cSImre Vadász
5621f9f90cSImre Vadász struct sdhci_slot slot;
5721f9f90cSImre Vadász struct resource *mem_res; /* Memory resource */
5821f9f90cSImre Vadász };
5921f9f90cSImre Vadász
6021f9f90cSImre Vadász static uint8_t
sdhci_acpi_read_1(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off)6170a02aadSImre Vadász sdhci_acpi_read_1(device_t dev, struct sdhci_slot *slot __unused,
6270a02aadSImre Vadász bus_size_t off)
6321f9f90cSImre Vadász {
6421f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
6521f9f90cSImre Vadász
6621f9f90cSImre Vadász bus_barrier(sc->mem_res, 0, 0xFF,
6721f9f90cSImre Vadász BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
6821f9f90cSImre Vadász return bus_read_1(sc->mem_res, off);
6921f9f90cSImre Vadász }
7021f9f90cSImre Vadász
7121f9f90cSImre Vadász static void
sdhci_acpi_write_1(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off,uint8_t val)7270a02aadSImre Vadász sdhci_acpi_write_1(device_t dev, struct sdhci_slot *slot __unused,
7370a02aadSImre Vadász bus_size_t off, uint8_t val)
7421f9f90cSImre Vadász {
7521f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
7621f9f90cSImre Vadász
7721f9f90cSImre Vadász bus_barrier(sc->mem_res, 0, 0xFF,
7821f9f90cSImre Vadász BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
7921f9f90cSImre Vadász bus_write_1(sc->mem_res, off, val);
8021f9f90cSImre Vadász }
8121f9f90cSImre Vadász
8221f9f90cSImre Vadász static uint16_t
sdhci_acpi_read_2(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off)8370a02aadSImre Vadász sdhci_acpi_read_2(device_t dev, struct sdhci_slot *slot __unused,
8470a02aadSImre Vadász bus_size_t off)
8521f9f90cSImre Vadász {
8621f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
8721f9f90cSImre Vadász
8821f9f90cSImre Vadász bus_barrier(sc->mem_res, 0, 0xFF,
8921f9f90cSImre Vadász BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
9021f9f90cSImre Vadász return bus_read_2(sc->mem_res, off);
9121f9f90cSImre Vadász }
9221f9f90cSImre Vadász
9321f9f90cSImre Vadász static void
sdhci_acpi_write_2(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off,uint16_t val)9470a02aadSImre Vadász sdhci_acpi_write_2(device_t dev, struct sdhci_slot *slot __unused,
9570a02aadSImre Vadász bus_size_t off, uint16_t val)
9621f9f90cSImre Vadász {
9721f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
9821f9f90cSImre Vadász
9921f9f90cSImre Vadász bus_barrier(sc->mem_res, 0, 0xFF,
10021f9f90cSImre Vadász BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
10121f9f90cSImre Vadász bus_write_2(sc->mem_res, off, val);
10221f9f90cSImre Vadász }
10321f9f90cSImre Vadász
10421f9f90cSImre Vadász static uint32_t
sdhci_acpi_read_4(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off)10570a02aadSImre Vadász sdhci_acpi_read_4(device_t dev, struct sdhci_slot *slot __unused,
10670a02aadSImre Vadász bus_size_t off)
10721f9f90cSImre Vadász {
10821f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
10921f9f90cSImre Vadász
11021f9f90cSImre Vadász bus_barrier(sc->mem_res, 0, 0xFF,
11121f9f90cSImre Vadász BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
11221f9f90cSImre Vadász return bus_read_4(sc->mem_res, off);
11321f9f90cSImre Vadász }
11421f9f90cSImre Vadász
11521f9f90cSImre Vadász static void
sdhci_acpi_write_4(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off,uint32_t val)11670a02aadSImre Vadász sdhci_acpi_write_4(device_t dev, struct sdhci_slot *slot __unused,
11770a02aadSImre Vadász bus_size_t off, uint32_t val)
11821f9f90cSImre Vadász {
11921f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
12021f9f90cSImre Vadász
12121f9f90cSImre Vadász bus_barrier(sc->mem_res, 0, 0xFF,
12221f9f90cSImre Vadász BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
12321f9f90cSImre Vadász bus_write_4(sc->mem_res, off, val);
12421f9f90cSImre Vadász }
12521f9f90cSImre Vadász
12621f9f90cSImre Vadász static void
sdhci_acpi_read_multi_4(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off,uint32_t * data,bus_size_t count)12770a02aadSImre Vadász sdhci_acpi_read_multi_4(device_t dev, struct sdhci_slot *slot __unused,
12821f9f90cSImre Vadász bus_size_t off, uint32_t *data, bus_size_t count)
12921f9f90cSImre Vadász {
13021f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
13121f9f90cSImre Vadász
13221f9f90cSImre Vadász bus_read_multi_stream_4(sc->mem_res, off, data, count);
13321f9f90cSImre Vadász }
13421f9f90cSImre Vadász
13521f9f90cSImre Vadász static void
sdhci_acpi_write_multi_4(device_t dev,struct sdhci_slot * slot __unused,bus_size_t off,uint32_t * data,bus_size_t count)13670a02aadSImre Vadász sdhci_acpi_write_multi_4(device_t dev, struct sdhci_slot *slot __unused,
13721f9f90cSImre Vadász bus_size_t off, uint32_t *data, bus_size_t count)
13821f9f90cSImre Vadász {
13921f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
14021f9f90cSImre Vadász
14121f9f90cSImre Vadász bus_write_multi_stream_4(sc->mem_res, off, data, count);
14221f9f90cSImre Vadász }
14321f9f90cSImre Vadász
14421f9f90cSImre Vadász static void sdhci_acpi_intr(void *arg);
14521f9f90cSImre Vadász
1467ba10b88SImre Vadász #define INTEL_ATOM_QUIRKS_SDCARD \
1477ba10b88SImre Vadász SDHCI_QUIRK_WHITELIST_ADMA2 | SDHCI_QUIRK_WAIT_WHILE_BUSY
1487ba10b88SImre Vadász #define INTEL_ATOM_QUIRKS_EMMC \
1497ba10b88SImre Vadász INTEL_ATOM_QUIRKS_SDCARD | SDHCI_QUIRK_MMC_DDR52 | \
1507ba10b88SImre Vadász SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 | SDHCI_QUIRK_PRESET_VALUE_BROKEN
1517ba10b88SImre Vadász
15285ccd313SImre Vadász static struct {
15385ccd313SImre Vadász char *hid;
1547ba10b88SImre Vadász char *uid;
15585ccd313SImre Vadász u_int quirks;
15685ccd313SImre Vadász } sdhci_devices[] = {
1577ba10b88SImre Vadász /* The Intel Atom integrated controllers work fine with ADMA2. */
1587ba10b88SImre Vadász /* Bay Trail / Braswell */
1597ba10b88SImre Vadász {"80860F14", "1", INTEL_ATOM_QUIRKS_EMMC},
1607ba10b88SImre Vadász {"80860F14", "3", INTEL_ATOM_QUIRKS_SDCARD},
1617ba10b88SImre Vadász {"80860F16", NULL, INTEL_ATOM_QUIRKS_SDCARD},
1627ba10b88SImre Vadász /* Apollo Lake */
163ffb8e567SImre Vadász {"80865ACA", NULL,
164ffb8e567SImre Vadász SDHCI_QUIRK_BROKEN_DMA | /* APL18 erratum */
165ffb8e567SImre Vadász INTEL_ATOM_QUIRKS_SDCARD},
166ffb8e567SImre Vadász {"80865ACC", NULL,
167ffb8e567SImre Vadász SDHCI_QUIRK_BROKEN_DMA | /* APL18 erratum */
168ffb8e567SImre Vadász INTEL_ATOM_QUIRKS_EMMC},
16985ccd313SImre Vadász };
17085ccd313SImre Vadász
17185ccd313SImre Vadász static char *sdhci_ids[] = {
17285ccd313SImre Vadász "80860F14",
17385ccd313SImre Vadász "80860F16",
1747ba10b88SImre Vadász "80865ACA",
1757ba10b88SImre Vadász "80865ACC",
17685ccd313SImre Vadász NULL
17785ccd313SImre Vadász };
17885ccd313SImre Vadász
17921f9f90cSImre Vadász static int
sdhci_acpi_probe(device_t dev)18021f9f90cSImre Vadász sdhci_acpi_probe(device_t dev)
18121f9f90cSImre Vadász {
18285ccd313SImre Vadász if (acpi_disabled("sdhci"))
18385ccd313SImre Vadász return (ENXIO);
18421f9f90cSImre Vadász
18585ccd313SImre Vadász if (ACPI_ID_PROBE(device_get_parent(dev), dev, sdhci_ids) == NULL)
18621f9f90cSImre Vadász return (ENXIO);
18721f9f90cSImre Vadász
18821f9f90cSImre Vadász device_set_desc(dev, "SDHCI controller");
18921f9f90cSImre Vadász return (0);
19021f9f90cSImre Vadász }
19121f9f90cSImre Vadász
19221f9f90cSImre Vadász static int
sdhci_acpi_attach(device_t dev)19321f9f90cSImre Vadász sdhci_acpi_attach(device_t dev)
19421f9f90cSImre Vadász {
19521f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
19685ccd313SImre Vadász char *id;
19785ccd313SImre Vadász int err, i, rid, quirks;
19885ccd313SImre Vadász
19985ccd313SImre Vadász id = ACPI_ID_PROBE(device_get_parent(dev), dev, sdhci_ids);
20085ccd313SImre Vadász if (id == NULL)
20185ccd313SImre Vadász return (ENXIO);
20221f9f90cSImre Vadász
20321f9f90cSImre Vadász sc->dev = dev;
20421f9f90cSImre Vadász sc->handle = acpi_get_handle(dev);
20521f9f90cSImre Vadász
20685ccd313SImre Vadász quirks = 0;
20785ccd313SImre Vadász for (i = 0; i < NELEM(sdhci_devices); i++) {
2087ba10b88SImre Vadász if (strcmp(sdhci_devices[i].hid, id) == 0 &&
2097ba10b88SImre Vadász (sdhci_devices[i].uid == NULL ||
2107ba10b88SImre Vadász acpi_MatchUid(sc->handle, sdhci_devices[i].uid))) {
21185ccd313SImre Vadász quirks = sdhci_devices[i].quirks;
21285ccd313SImre Vadász break;
21385ccd313SImre Vadász }
21485ccd313SImre Vadász }
2157ba10b88SImre Vadász quirks &= ~sdhci_quirk_clear;
2167ba10b88SImre Vadász quirks |= sdhci_quirk_set;
21785ccd313SImre Vadász
21821f9f90cSImre Vadász /* Allocate IRQ. */
21921f9f90cSImre Vadász rid = 0;
22021f9f90cSImre Vadász sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
22121f9f90cSImre Vadász RF_SHAREABLE);
22221f9f90cSImre Vadász if (sc->irq_res == NULL) {
22321f9f90cSImre Vadász device_printf(dev, "Can't allocate IRQ\n");
22421f9f90cSImre Vadász err = ENOMEM;
22521f9f90cSImre Vadász goto error;
22621f9f90cSImre Vadász }
22721f9f90cSImre Vadász
22821f9f90cSImre Vadász /* Allocate memory. */
22921f9f90cSImre Vadász rid = 0;
23021f9f90cSImre Vadász sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
23121f9f90cSImre Vadász RF_ACTIVE);
23221f9f90cSImre Vadász if (sc->mem_res == NULL) {
23321f9f90cSImre Vadász device_printf(dev, "Can't allocate memory for slot %d\n", 0);
23421f9f90cSImre Vadász err = ENOMEM;
23521f9f90cSImre Vadász goto error;
23621f9f90cSImre Vadász }
23721f9f90cSImre Vadász
23821f9f90cSImre Vadász pci_set_powerstate(dev, PCI_POWERSTATE_D0);
23985ccd313SImre Vadász
24085ccd313SImre Vadász sc->slot.quirks = quirks;
24121f9f90cSImre Vadász if (sdhci_init_slot(dev, &sc->slot, 0) != 0) {
24221f9f90cSImre Vadász device_printf(dev, "sdhci initialization failed\n");
24321f9f90cSImre Vadász pci_set_powerstate(dev, PCI_POWERSTATE_D3);
24421f9f90cSImre Vadász err = ENXIO;
24521f9f90cSImre Vadász goto error;
24621f9f90cSImre Vadász }
24721f9f90cSImre Vadász
24821f9f90cSImre Vadász device_printf(dev, "%d slot(s) allocated\n", 1);
24921f9f90cSImre Vadász /* Activate the interrupt */
25021f9f90cSImre Vadász err = bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE,
25121f9f90cSImre Vadász sdhci_acpi_intr, sc, &sc->intrhand, NULL);
25221f9f90cSImre Vadász if (err)
25321f9f90cSImre Vadász device_printf(dev, "Can't setup IRQ\n");
25421f9f90cSImre Vadász
25521f9f90cSImre Vadász /* Process cards detection. */
25621f9f90cSImre Vadász sdhci_start_slot(&sc->slot);
25721f9f90cSImre Vadász
25821f9f90cSImre Vadász return (0);
25921f9f90cSImre Vadász
26021f9f90cSImre Vadász error:
26121f9f90cSImre Vadász if (sc->irq_res != NULL) {
26221f9f90cSImre Vadász bus_release_resource(dev, SYS_RES_IRQ,
26321f9f90cSImre Vadász rman_get_rid(sc->irq_res), sc->irq_res);
26421f9f90cSImre Vadász }
26521f9f90cSImre Vadász if (sc->mem_res != NULL) {
26621f9f90cSImre Vadász bus_release_resource(dev, SYS_RES_MEMORY,
26721f9f90cSImre Vadász rman_get_rid(sc->mem_res), sc->mem_res);
26821f9f90cSImre Vadász }
26921f9f90cSImre Vadász return (err);
27021f9f90cSImre Vadász }
27121f9f90cSImre Vadász
27221f9f90cSImre Vadász static int
sdhci_acpi_detach(device_t dev)27321f9f90cSImre Vadász sdhci_acpi_detach(device_t dev)
27421f9f90cSImre Vadász {
27521f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
27621f9f90cSImre Vadász
27721f9f90cSImre Vadász bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
27821f9f90cSImre Vadász bus_release_resource(dev, SYS_RES_IRQ,
27921f9f90cSImre Vadász rman_get_rid(sc->irq_res), sc->irq_res);
28021f9f90cSImre Vadász
28121f9f90cSImre Vadász sdhci_cleanup_slot(&sc->slot);
28221f9f90cSImre Vadász bus_release_resource(dev, SYS_RES_MEMORY,
28321f9f90cSImre Vadász rman_get_rid(sc->mem_res), sc->mem_res);
28421f9f90cSImre Vadász pci_set_powerstate(dev, PCI_POWERSTATE_D3);
28521f9f90cSImre Vadász return (0);
28621f9f90cSImre Vadász }
28721f9f90cSImre Vadász
28821f9f90cSImre Vadász static int
sdhci_acpi_suspend(device_t dev)28921f9f90cSImre Vadász sdhci_acpi_suspend(device_t dev)
29021f9f90cSImre Vadász {
29121f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
29221f9f90cSImre Vadász int err;
29321f9f90cSImre Vadász
29421f9f90cSImre Vadász err = bus_generic_suspend(dev);
29521f9f90cSImre Vadász if (err)
29621f9f90cSImre Vadász return (err);
29721f9f90cSImre Vadász sdhci_generic_suspend(&sc->slot);
29821f9f90cSImre Vadász return (0);
29921f9f90cSImre Vadász }
30021f9f90cSImre Vadász
30121f9f90cSImre Vadász static int
sdhci_acpi_resume(device_t dev)30221f9f90cSImre Vadász sdhci_acpi_resume(device_t dev)
30321f9f90cSImre Vadász {
30421f9f90cSImre Vadász struct sdhci_acpi_softc *sc = device_get_softc(dev);
30521f9f90cSImre Vadász
30621f9f90cSImre Vadász sdhci_generic_resume(&sc->slot);
30721f9f90cSImre Vadász return (bus_generic_resume(dev));
30821f9f90cSImre Vadász }
30921f9f90cSImre Vadász
31021f9f90cSImre Vadász static void
sdhci_acpi_intr(void * arg)31121f9f90cSImre Vadász sdhci_acpi_intr(void *arg)
31221f9f90cSImre Vadász {
31321f9f90cSImre Vadász struct sdhci_acpi_softc *sc = (struct sdhci_acpi_softc *)arg;
31421f9f90cSImre Vadász
31521f9f90cSImre Vadász sdhci_generic_intr(&sc->slot);
31621f9f90cSImre Vadász }
31721f9f90cSImre Vadász
31821f9f90cSImre Vadász static device_method_t sdhci_methods[] = {
31921f9f90cSImre Vadász /* device_if */
32021f9f90cSImre Vadász DEVMETHOD(device_probe, sdhci_acpi_probe),
32121f9f90cSImre Vadász DEVMETHOD(device_attach, sdhci_acpi_attach),
32221f9f90cSImre Vadász DEVMETHOD(device_detach, sdhci_acpi_detach),
32321f9f90cSImre Vadász DEVMETHOD(device_suspend, sdhci_acpi_suspend),
32421f9f90cSImre Vadász DEVMETHOD(device_resume, sdhci_acpi_resume),
32521f9f90cSImre Vadász
32621f9f90cSImre Vadász /* Bus interface */
32721f9f90cSImre Vadász DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar),
32821f9f90cSImre Vadász DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar),
32921f9f90cSImre Vadász
33021f9f90cSImre Vadász /* mmcbr_if */
33121f9f90cSImre Vadász DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios),
3327ba10b88SImre Vadász DEVMETHOD(mmcbr_switch_vccq, sdhci_generic_switch_vccq),
33321f9f90cSImre Vadász DEVMETHOD(mmcbr_request, sdhci_generic_request),
33421f9f90cSImre Vadász DEVMETHOD(mmcbr_get_ro, sdhci_generic_get_ro),
33521f9f90cSImre Vadász DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
33621f9f90cSImre Vadász DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
33721f9f90cSImre Vadász
3387ba10b88SImre Vadász /* SDHCI accessors */
33921f9f90cSImre Vadász DEVMETHOD(sdhci_read_1, sdhci_acpi_read_1),
34021f9f90cSImre Vadász DEVMETHOD(sdhci_read_2, sdhci_acpi_read_2),
34121f9f90cSImre Vadász DEVMETHOD(sdhci_read_4, sdhci_acpi_read_4),
34221f9f90cSImre Vadász DEVMETHOD(sdhci_read_multi_4, sdhci_acpi_read_multi_4),
34321f9f90cSImre Vadász DEVMETHOD(sdhci_write_1, sdhci_acpi_write_1),
34421f9f90cSImre Vadász DEVMETHOD(sdhci_write_2, sdhci_acpi_write_2),
34521f9f90cSImre Vadász DEVMETHOD(sdhci_write_4, sdhci_acpi_write_4),
34621f9f90cSImre Vadász DEVMETHOD(sdhci_write_multi_4, sdhci_acpi_write_multi_4),
3477ba10b88SImre Vadász DEVMETHOD(sdhci_set_uhs_timing, sdhci_generic_set_uhs_timing),
34821f9f90cSImre Vadász
34921f9f90cSImre Vadász DEVMETHOD_END
35021f9f90cSImre Vadász };
35121f9f90cSImre Vadász
35221f9f90cSImre Vadász static driver_t sdhci_acpi_driver = {
35321f9f90cSImre Vadász "sdhci_acpi",
35421f9f90cSImre Vadász sdhci_methods,
35521f9f90cSImre Vadász sizeof(struct sdhci_acpi_softc),
356*df21e16dSImre Vadász .gpri = KOBJ_GPRI_ACPI
35721f9f90cSImre Vadász };
35821f9f90cSImre Vadász static devclass_t sdhci_acpi_devclass;
35921f9f90cSImre Vadász
36021f9f90cSImre Vadász DRIVER_MODULE(sdhci_acpi, acpi, sdhci_acpi_driver, sdhci_acpi_devclass, NULL,
36121f9f90cSImre Vadász NULL);
36221f9f90cSImre Vadász MODULE_DEPEND(sdhci_acpi, sdhci, 1, 1, 1);
363