The branch stable/13 has been updated by mw:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=693af80b74359d38417ae5da7a1f02c83ec8332a

commit 693af80b74359d38417ae5da7a1f02c83ec8332a
Author:     Bartlomiej Grzesik <b...@semihalf.com>
AuthorDate: 2021-07-15 12:29:15 +0000
Commit:     Marcin Wojtas <m...@freebsd.org>
CommitDate: 2022-03-29 22:24:27 +0000

    sdhci_xenon: split driver file into generic file and fdt parts
    
    This patch splits driver code into two seperate files sdhci_xenon.c
    and sdhci_xenon_fdt.c. This will allow future implementation of ACPI
    discovery of sdhci on Xenon chips.
    
    Reviewed by: mw
    Sponsored by: Semihalf
    Differential revision: https://reviews.freebsd.org/D31599
    
    (cherry picked from commit d78e464d23304084be17cb8db8981558f2829d6c)
---
 sys/conf/files.arm64            |   3 +-
 sys/dev/sdhci/sdhci_xenon.c     | 206 ++++++++++++----------------------------
 sys/dev/sdhci/sdhci_xenon.h     |  29 ++++++
 sys/dev/sdhci/sdhci_xenon_fdt.c | 173 +++++++++++++++++++++++++++++++++
 4 files changed, 264 insertions(+), 147 deletions(-)

diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index b694ed091d88..f1a2efe16448 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -263,7 +263,8 @@ dev/psci/smccc.c                            standard
 
 dev/safexcel/safexcel.c                                optional safexcel fdt
 
-dev/sdhci/sdhci_xenon.c                                optional sdhci_xenon 
sdhci fdt
+dev/sdhci/sdhci_xenon.c                                optional sdhci_xenon 
sdhci
+dev/sdhci/sdhci_xenon_fdt.c                    optional sdhci_xenon sdhci fdt
 
 dev/uart/uart_cpu_arm64.c                      optional uart
 dev/uart/uart_dev_mu.c                         optional uart uart_mu
diff --git a/sys/dev/sdhci/sdhci_xenon.c b/sys/dev/sdhci/sdhci_xenon.c
index d88514d8fd8f..6dc0974c4e4e 100644
--- a/sys/dev/sdhci/sdhci_xenon.c
+++ b/sys/dev/sdhci/sdhci_xenon.c
@@ -48,17 +48,12 @@ __FBSDID("$FreeBSD$");
 #include <machine/resource.h>
 
 #include <dev/extres/regulator/regulator.h>
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
 
 #include <dev/mmc/bridge.h>
-#include <dev/mmc/mmc_fdt_helpers.h>
 #include <dev/mmc/mmcbrvar.h>
 #include <dev/mmc/mmcreg.h>
 
 #include <dev/sdhci/sdhci.h>
-#include <dev/sdhci/sdhci_fdt_gpio.h>
 #include <dev/sdhci/sdhci_xenon.h>
 
 #include "mmcbr_if.h"
@@ -69,34 +64,6 @@ __FBSDID("$FreeBSD$");
 
 #define        MAX_SLOTS               6
 
-static struct ofw_compat_data compat_data[] = {
-       { "marvell,armada-3700-sdhci",  1 },
-#ifdef SOC_MARVELL_8K
-       { "marvell,armada-cp110-sdhci", 1 },
-       { "marvell,armada-ap806-sdhci", 1 },
-       { "marvell,armada-ap807-sdhci", 1 },
-#endif
-       { NULL, 0 }
-};
-
-struct sdhci_xenon_softc {
-       device_t        dev;            /* Controller device */
-       int             slot_id;        /* Controller ID */
-       phandle_t       node;           /* FDT node */
-       struct resource *irq_res;       /* IRQ resource */
-       void            *intrhand;      /* Interrupt handle */
-       struct sdhci_fdt_gpio *gpio;    /* GPIO pins for CD detection. */
-
-       struct sdhci_slot *slot;        /* SDHCI internal data */
-       struct resource *mem_res;       /* Memory resource */
-
-       uint8_t         znr;            /* PHY ZNR */
-       uint8_t         zpr;            /* PHY ZPR */
-       bool            slow_mode;      /* PHY slow mode */
-
-       struct mmc_helper       mmc_helper; /* MMC helper for parsing FDT */
-};
-
 static uint8_t
 sdhci_xenon_read_1(device_t dev, struct sdhci_slot *slot __unused,
     bus_size_t off)
@@ -182,16 +149,7 @@ sdhci_xenon_get_ro(device_t bus, device_t dev)
 {
        struct sdhci_xenon_softc *sc = device_get_softc(bus);
 
-       return (sdhci_generic_get_ro(bus, dev) ^
-           (sc->mmc_helper.props & MMC_PROP_WP_INVERTED));
-}
-
-static bool
-sdhci_xenon_get_card_present(device_t dev, struct sdhci_slot *slot)
-{
-       struct sdhci_xenon_softc *sc = device_get_softc(dev);
-
-       return (sdhci_fdt_gpio_get_present(sc->gpio));
+       return (sdhci_generic_get_ro(bus, dev) ^ sc->wp_inverted);
 }
 
 static void
@@ -387,19 +345,19 @@ sdhci_xenon_update_ios(device_t brdev, device_t reqdev)
                if (bootverbose)
                        device_printf(sc->dev, "Powering down sd/mmc\n");
 
-               if (sc->mmc_helper.vmmc_supply)
-                       regulator_disable(sc->mmc_helper.vmmc_supply);
-               if (sc->mmc_helper.vqmmc_supply)
-                       regulator_disable(sc->mmc_helper.vqmmc_supply);
+               if (sc->vmmc_supply)
+                       regulator_disable(sc->vmmc_supply);
+               if (sc->vqmmc_supply)
+                       regulator_disable(sc->vqmmc_supply);
                break;
        case power_up:
                if (bootverbose)
                        device_printf(sc->dev, "Powering up sd/mmc\n");
 
-               if (sc->mmc_helper.vmmc_supply)
-                       regulator_enable(sc->mmc_helper.vmmc_supply);
-               if (sc->mmc_helper.vqmmc_supply)
-                       regulator_enable(sc->mmc_helper.vqmmc_supply);
+               if (sc->vmmc_supply)
+                       regulator_enable(sc->vmmc_supply);
+               if (sc->vqmmc_supply)
+                       regulator_enable(sc->vqmmc_supply);
                break;
        };
 
@@ -432,8 +390,8 @@ sdhci_xenon_switch_vccq(device_t brdev, device_t reqdev)
 
        sc = device_get_softc(brdev);
 
-       if (sc->mmc_helper.vqmmc_supply == NULL)
-               return EOPNOTSUPP;
+       if (sc->vqmmc_supply == NULL && !sc->skip_regulators)
+               return (EOPNOTSUPP);
 
        err = 0;
 
@@ -445,15 +403,17 @@ sdhci_xenon_switch_vccq(device_t brdev, device_t reqdev)
                hostctrl2 &= ~SDHCI_CTRL2_S18_ENABLE;
                bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2);
 
-               uvolt = 3300000;
-               err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply,
-                   uvolt, uvolt);
-               if (err != 0) {
-                       device_printf(sc->dev,
-                           "Cannot set vqmmc to %d<->%d\n",
-                           uvolt,
-                           uvolt);
-                       return (err);
+               if (!sc->skip_regulators) {
+                       uvolt = 3300000;
+                       err = regulator_set_voltage(sc->vqmmc_supply,
+                           uvolt, uvolt);
+                       if (err != 0) {
+                               device_printf(sc->dev,
+                                   "Cannot set vqmmc to %d<->%d\n",
+                                   uvolt,
+                                   uvolt);
+                               return (err);
+                       }
                }
 
                /*
@@ -466,25 +426,27 @@ sdhci_xenon_switch_vccq(device_t brdev, device_t reqdev)
                hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2);
                if (!(hostctrl2 & SDHCI_CTRL2_S18_ENABLE))
                        return (0);
-               return EAGAIN;
+               return (EAGAIN);
        case vccq_180:
                if (!(slot->host.caps & MMC_CAP_SIGNALING_180)) {
-                       return EINVAL;
+                       return (EINVAL);
                }
                if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE)
                        return (0);
                hostctrl2 |= SDHCI_CTRL2_S18_ENABLE;
                bus_write_2(sc->mem_res, SDHCI_HOST_CONTROL2, hostctrl2);
 
-               uvolt = 1800000;
-               err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply,
-                   uvolt, uvolt);
-               if (err != 0) {
-                       device_printf(sc->dev,
-                           "Cannot set vqmmc to %d<->%d\n",
-                           uvolt,
-                           uvolt);
-                       return (err);
+               if (!sc->skip_regulators) {
+                       uvolt = 1800000;
+                       err = regulator_set_voltage(sc->vqmmc_supply,
+                               uvolt, uvolt);
+                       if (err != 0) {
+                               device_printf(sc->dev,
+                                       "Cannot set vqmmc to %d<->%d\n",
+                                       uvolt,
+                                       uvolt);
+                               return (err);
+                       }
                }
 
                /*
@@ -497,62 +459,46 @@ sdhci_xenon_switch_vccq(device_t brdev, device_t reqdev)
                hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2);
                if (hostctrl2 & SDHCI_CTRL2_S18_ENABLE)
                        return (0);
-               return EAGAIN;
+               return (EAGAIN);
        default:
                device_printf(brdev,
                    "Attempt to set unsupported signaling voltage\n");
-               return EINVAL;
+               return (EINVAL);
        }
 }
 
 static void
-sdhci_xenon_fdt_parse(device_t dev, struct sdhci_slot *slot)
+sdhci_xenon_parse_prop(device_t dev)
 {
-       struct sdhci_xenon_softc *sc = device_get_softc(dev);
-       pcell_t cid;
+       struct sdhci_xenon_softc *sc;
+       uint64_t val;
 
-       mmc_fdt_parse(dev, 0, &sc->mmc_helper, &slot->host);
+       sc = device_get_softc(dev);
+       val = 0;
 
-       /* Allow dts to patch quirks, slots, and max-frequency. */
-       if ((OF_getencprop(sc->node, "quirks", &cid, sizeof(cid))) > 0)
-               slot->quirks = cid;
-       if (OF_hasprop(sc->node, "marvell,xenon-phy-slow-mode"))
-               sc->slow_mode = true;
+       if (device_get_property(dev, "quirks", &val, sizeof(val)) > 0)
+               sc->slot->quirks = val;
        sc->znr = XENON_ZNR_DEF_VALUE;
-       if ((OF_getencprop(sc->node, "marvell,xenon-phy-znr", &cid,
-           sizeof(cid))) > 0)
-               sc->znr = cid & XENON_ZNR_MASK;
+       if (device_get_property(dev, "marvell,xenon-phy-znr",
+           &val, sizeof(val)) > 0)
+               sc->znr = val & XENON_ZNR_MASK;
        sc->zpr = XENON_ZPR_DEF_VALUE;
-       if ((OF_getencprop(sc->node, "marvell,xenon-phy-zpr", &cid,
-           sizeof(cid))) > 0)
-               sc->zpr = cid & XENON_ZPR_MASK;
-}
-
-static int
-sdhci_xenon_probe(device_t dev)
-{
-       if (!ofw_bus_status_okay(dev))
-               return (ENXIO);
-
-       if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
-               return (ENXIO);
-
-       device_set_desc(dev, "Armada Xenon SDHCI controller");
-
-       return (0);
+       if (device_get_property(dev, "marvell,xenon-phy-zpr",
+           &val, sizeof(val)) > 0)
+               sc->zpr = val & XENON_ZPR_MASK;
+       if (device_has_property(dev, "marvell,xenon-phy-slow-mode"))
+               sc->slow_mode = true;
 }
 
-static int
+int
 sdhci_xenon_attach(device_t dev)
 {
        struct sdhci_xenon_softc *sc = device_get_softc(dev);
-       struct sdhci_slot *slot;
        int err, rid;
        uint32_t reg;
 
        sc->dev = dev;
        sc->slot_id = 0;
-       sc->node = ofw_bus_get_node(dev);
 
        /* Allocate IRQ. */
        rid = 0;
@@ -574,27 +520,11 @@ sdhci_xenon_attach(device_t dev)
                return (ENOMEM);
        }
 
-       slot = malloc(sizeof(*slot), M_DEVBUF, M_ZERO | M_WAITOK);
-
-       /*
-        * Set up any gpio pin handling described in the FDT data. This cannot
-        * fail; see comments in sdhci_fdt_gpio.h for details.
-        */
-       sc->gpio = sdhci_fdt_gpio_setup(dev, slot);
+       sdhci_xenon_parse_prop(dev);
 
-       sdhci_xenon_fdt_parse(dev, slot);
-
-       slot->max_clk = XENON_MMC_MAX_CLK;
-       if (slot->host.f_max > 0)
-               slot->max_clk = slot->host.f_max;
-       /* Check if the device is flagged as non-removable. */
-       if (sc->mmc_helper.props & MMC_PROP_NON_REMOVABLE) {
-               slot->opt |= SDHCI_NON_REMOVABLE;
-               if (bootverbose)
-                       device_printf(dev, "Non-removable media\n");
-       }
-
-       sc->slot = slot;
+       sc->slot->max_clk = XENON_MMC_MAX_CLK;
+       if (sc->slot->host.f_max > 0)
+               sc->slot->max_clk = sc->slot->host.f_max;
 
        if (sdhci_init_slot(dev, sc->slot, 0))
                goto fail;
@@ -658,14 +588,11 @@ fail:
        return (ENXIO);
 }
 
-static int
+int
 sdhci_xenon_detach(device_t dev)
 {
        struct sdhci_xenon_softc *sc = device_get_softc(dev);
 
-       if (sc->gpio != NULL)
-               sdhci_fdt_gpio_teardown(sc->gpio);
-
        bus_generic_detach(dev);
        bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
        bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq_res),
@@ -680,11 +607,6 @@ sdhci_xenon_detach(device_t dev)
 }
 
 static device_method_t sdhci_xenon_methods[] = {
-       /* device_if */
-       DEVMETHOD(device_probe,         sdhci_xenon_probe),
-       DEVMETHOD(device_attach,        sdhci_xenon_attach),
-       DEVMETHOD(device_detach,        sdhci_xenon_detach),
-
        /* Bus interface */
        DEVMETHOD(bus_read_ivar,        sdhci_generic_read_ivar),
        DEVMETHOD(bus_write_ivar,       sdhci_generic_write_ivar),
@@ -708,21 +630,13 @@ static device_method_t sdhci_xenon_methods[] = {
        DEVMETHOD(sdhci_write_2,        sdhci_xenon_write_2),
        DEVMETHOD(sdhci_write_4,        sdhci_xenon_write_4),
        DEVMETHOD(sdhci_write_multi_4,  sdhci_xenon_write_multi_4),
-       DEVMETHOD(sdhci_get_card_present,       sdhci_xenon_get_card_present),
        DEVMETHOD(sdhci_set_uhs_timing, sdhci_xenon_set_uhs_timing),
 
        DEVMETHOD_END
 };
 
-static driver_t sdhci_xenon_driver = {
-       "sdhci_xenon",
-       sdhci_xenon_methods,
-       sizeof(struct sdhci_xenon_softc),
-};
-static devclass_t sdhci_xenon_devclass;
-
-DRIVER_MODULE(sdhci_xenon, simplebus, sdhci_xenon_driver, sdhci_xenon_devclass,
-    NULL, NULL);
+DEFINE_CLASS_0(sdhci_xenon, sdhci_xenon_driver, sdhci_xenon_methods,
+    sizeof(struct sdhci_xenon_softc));
 
 SDHCI_DEPEND(sdhci_xenon);
 #ifndef MMCCAM
diff --git a/sys/dev/sdhci/sdhci_xenon.h b/sys/dev/sdhci/sdhci_xenon.h
index 07ed99339b8d..9d8449b90c82 100644
--- a/sys/dev/sdhci/sdhci_xenon.h
+++ b/sys/dev/sdhci/sdhci_xenon.h
@@ -101,4 +101,33 @@
 #define        XENON_EMMC_PHY_LOGIC_TIMING_ADJUST      
(XENON_EMMC_PHY_REG_BASE + 0x18)
 #define         XENON_LOGIC_TIMING_VALUE               0x00AA8977
 
+DECLARE_CLASS(sdhci_xenon_driver);
+
+struct sdhci_xenon_softc {
+       device_t        dev;            /* Controller device */
+       int             slot_id;        /* Controller ID */
+
+       struct resource *mem_res;       /* Memory resource */
+       struct resource *irq_res;       /* IRQ resource */
+       void            *intrhand;      /* Interrupt handle */
+
+       struct sdhci_slot *slot;        /* SDHCI internal data */
+
+       uint8_t         znr;            /* PHY ZNR */
+       uint8_t         zpr;            /* PHY ZPR */
+       bool            slow_mode;      /* PHY slow mode */
+       bool            wp_inverted;
+       bool            skip_regulators; /* Don't switch regulators */
+
+       regulator_t     vmmc_supply;
+       regulator_t     vqmmc_supply;
+
+#ifdef FDT
+       struct sdhci_fdt_gpio *gpio;    /* GPIO pins for CD detection. */
+#endif
+};
+
+device_attach_t sdhci_xenon_attach;
+device_detach_t sdhci_xenon_detach;
+
 #endif /* _SDHCI_XENON_H_ */
diff --git a/sys/dev/sdhci/sdhci_xenon_fdt.c b/sys/dev/sdhci/sdhci_xenon_fdt.c
new file mode 100644
index 000000000000..2d96105bd7e9
--- /dev/null
+++ b/sys/dev/sdhci/sdhci_xenon_fdt.c
@@ -0,0 +1,173 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Semihalf
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+#include <sys/taskqueue.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcbrvar.h>
+#include <dev/mmc/mmcreg.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
+
+#include <dev/sdhci/sdhci.h>
+#include <dev/sdhci/sdhci_fdt_gpio.h>
+#include <dev/sdhci/sdhci_xenon.h>
+
+#include "mmcbr_if.h"
+#include "sdhci_if.h"
+
+#include "opt_mmccam.h"
+#include "opt_soc.h"
+
+static struct ofw_compat_data compat_data[] = {
+       { "marvell,armada-3700-sdhci",  1 },
+#ifdef SOC_MARVELL_8K
+       { "marvell,armada-cp110-sdhci", 1 },
+       { "marvell,armada-ap806-sdhci", 1 },
+       { "marvell,armada-ap807-sdhci", 1 },
+#endif
+       { NULL, 0 }
+};
+
+static bool
+sdhci_xenon_fdt_get_card_present(device_t dev, struct sdhci_slot *slot)
+{
+       struct sdhci_xenon_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sdhci_fdt_gpio_get_present(sc->gpio));
+}
+
+static int
+sdhci_xenon_fdt_probe(device_t dev)
+{
+       if (!ofw_bus_status_okay(dev))
+               return (ENXIO);
+
+       if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+               return (ENXIO);
+
+       device_set_desc(dev, "Armada Xenon SDHCI controller");
+
+       return (BUS_PROBE_SPECIFIC);
+}
+
+static void
+sdhci_xenon_fdt_parse(device_t dev, struct sdhci_slot *slot)
+{
+       struct sdhci_xenon_softc *sc;
+       struct mmc_helper mmc_helper;
+
+       sc = device_get_softc(dev);
+       memset(&mmc_helper, 0, sizeof(mmc_helper));
+
+       /* MMC helper for parsing FDT */
+       mmc_fdt_parse(dev, 0, &mmc_helper, &slot->host);
+
+       sc->skip_regulators = false;
+       sc->vmmc_supply = mmc_helper.vmmc_supply;
+       sc->vqmmc_supply = mmc_helper.vqmmc_supply;
+       sc->wp_inverted = mmc_helper.props & MMC_PROP_WP_INVERTED;
+
+       /* Check if the device is flagged as non-removable. */
+       if (mmc_helper.props & MMC_PROP_NON_REMOVABLE) {
+               slot->opt |= SDHCI_NON_REMOVABLE;
+               if (bootverbose)
+                       device_printf(dev, "Non-removable media\n");
+       }
+}
+
+static int
+sdhci_xenon_fdt_attach(device_t dev)
+{
+       struct sdhci_xenon_softc *sc;
+       struct sdhci_slot *slot;
+
+       sc = device_get_softc(dev);
+       slot = malloc(sizeof(*slot), M_DEVBUF, M_ZERO | M_WAITOK);
+
+       sdhci_xenon_fdt_parse(dev, slot);
+
+       /*
+        * Set up any gpio pin handling described in the FDT data. This cannot
+        * fail; see comments in sdhci_fdt_gpio.h for details.
+        */
+       sc->gpio = sdhci_fdt_gpio_setup(dev, slot);
+       sc->slot = slot;
+
+       return (sdhci_xenon_attach(dev));
+}
+
+static int
+sdhci_xenon_fdt_detach(device_t dev)
+{
+       struct sdhci_xenon_softc *sc;
+
+       sc = device_get_softc(dev);
+       if (sc->gpio != NULL)
+               sdhci_fdt_gpio_teardown(sc->gpio);
+
+       return (sdhci_xenon_detach(dev));
+}
+
+static device_method_t sdhci_xenon_fdt_methods[] = {
+       /* device_if */
+       DEVMETHOD(device_probe,         sdhci_xenon_fdt_probe),
+       DEVMETHOD(device_attach,        sdhci_xenon_fdt_attach),
+       DEVMETHOD(device_detach,        sdhci_xenon_fdt_detach),
+
+       DEVMETHOD(sdhci_get_card_present, sdhci_xenon_fdt_get_card_present),
+
+       DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(sdhci_xenon, sdhci_xenon_fdt_driver, sdhci_xenon_fdt_methods,
+    sizeof(struct sdhci_xenon_softc), sdhci_xenon_driver);
+
+static devclass_t sdhci_xenon_fdt_devclass;
+
+DRIVER_MODULE(sdhci_xenon, simplebus, sdhci_xenon_fdt_driver,
+    sdhci_xenon_fdt_devclass, NULL, NULL);
+
+#ifndef MMCCAM
+MMC_DECLARE_BRIDGE(sdhci_xenon_fdt);
+#endif

Reply via email to