Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143301617
D31599.id93871.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D31599.id93871.diff
View Options
Index: sys/conf/files.arm64
===================================================================
--- sys/conf/files.arm64
+++ sys/conf/files.arm64
@@ -276,7 +276,8 @@
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
Index: sys/dev/sdhci/sdhci_xenon.h
===================================================================
--- sys/dev/sdhci/sdhci_xenon.h
+++ sys/dev/sdhci/sdhci_xenon.h
@@ -101,4 +101,31 @@
#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 *irq_cookie; /* 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 */
+
+#ifdef EXT_RESOURCES
+ regulator_t vmmc_supply;
+ regulator_t vqmmc_supply;
+#endif
+};
+
+device_attach_t sdhci_xenon_attach;
+device_detach_t sdhci_xenon_detach;
+
#endif /* _SDHCI_XENON_H_ */
Index: sys/dev/sdhci/sdhci_xenon.c
===================================================================
--- sys/dev/sdhci/sdhci_xenon.c
+++ sys/dev/sdhci/sdhci_xenon.c
@@ -48,17 +48,12 @@
#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 @@
#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 @@
{
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 @@
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;
};
@@ -420,22 +378,19 @@
static int
sdhci_xenon_switch_vccq(device_t brdev, device_t reqdev)
{
- struct sdhci_xenon_softc *sc;
+ struct sdhci_xenon_softc *sc = device_get_softc(brdev);
struct sdhci_slot *slot;
uint16_t hostctrl2;
int uvolt, err;
+ err = 0;
slot = device_get_ivars(reqdev);
if (slot->version < SDHCI_SPEC_300)
return (0);
- sc = device_get_softc(brdev);
-
- if (sc->mmc_helper.vqmmc_supply == NULL)
- return EOPNOTSUPP;
-
- err = 0;
+ if (sc->vqmmc_supply == NULL && !sc->skip_regulators)
+ return (EOPNOTSUPP);
hostctrl2 = bus_read_2(sc->mem_res, SDHCI_HOST_CONTROL2);
switch (slot->host.ios.vccq) {
@@ -445,15 +400,17 @@
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 +423,27 @@
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 +456,46 @@
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;
-
- mmc_fdt_parse(dev, 0, &sc->mmc_helper, &slot->host);
+ uint64_t val;
- /* 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;
+ val = 0;
+ if (device_get_property(dev, "quirks", &val, sizeof(val)) > 0)
+ sc->slot->quirks = val;
+ val = 0;
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)))
+ sc->znr = val & XENON_ZNR_MASK;
+ val = 0;
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)))
+ 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);
+ sc->dev = dev;
+
+ sdhci_xenon_parse_prop(dev);
/* Allocate IRQ. */
rid = 0;
@@ -574,28 +517,6 @@
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_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;
-
if (sdhci_init_slot(dev, sc->slot, 0))
goto fail;
@@ -608,7 +529,7 @@
/* Activate the interrupt */
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
- NULL, sdhci_xenon_intr, sc, &sc->intrhand);
+ NULL, sdhci_xenon_intr, sc, &sc->irq_cookie);
if (err) {
device_printf(dev, "Cannot setup IRQ\n");
goto fail;
@@ -658,16 +579,13 @@
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_teardown_intr(dev, sc->irq_res, sc->irq_cookie);
bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq_res),
sc->irq_res);
sdhci_cleanup_slot(sc->slot);
@@ -680,11 +598,6 @@
}
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),
@@ -695,9 +608,9 @@
DEVMETHOD(mmcbr_get_ro, sdhci_xenon_get_ro),
DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
- DEVMETHOD(mmcbr_switch_vccq, sdhci_xenon_switch_vccq),
DEVMETHOD(mmcbr_tune, sdhci_generic_tune),
DEVMETHOD(mmcbr_retune, sdhci_generic_retune),
+ DEVMETHOD(mmcbr_switch_vccq, sdhci_xenon_switch_vccq),
/* SDHCI registers accessors */
DEVMETHOD(sdhci_read_1, sdhci_xenon_read_1),
@@ -708,21 +621,13 @@
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
Index: sys/dev/sdhci/sdhci_xenon_fdt.c
===================================================================
--- /dev/null
+++ sys/dev/sdhci/sdhci_xenon_fdt.c
@@ -0,0 +1,181 @@
+/*-
+ * 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 }
+};
+
+struct sdhci_xenon_fdt_softc {
+ struct sdhci_xenon_softc generic; /* Generic softc */
+
+ struct sdhci_fdt_gpio *gpio; /* GPIO pins for CD detection. */
+};
+
+
+static bool
+sdhci_xenon_fdt_get_card_present(device_t dev, struct sdhci_slot *slot)
+{
+ struct sdhci_xenon_fdt_softc *fdt_sc = device_get_softc(dev);
+
+ return (sdhci_fdt_gpio_get_present(fdt_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_fdt_softc *fdt_sc = device_get_softc(dev);
+ struct sdhci_xenon_softc *sc = &fdt_sc->generic;
+ struct mmc_helper mmc_helper;
+
+ 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_fdt_softc *fdt_sc = device_get_softc(dev);
+ struct sdhci_xenon_softc *sc = &fdt_sc->generic;
+ struct sdhci_slot *slot;
+
+ 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.
+ */
+ fdt_sc->gpio = sdhci_fdt_gpio_setup(dev, slot);
+
+ slot->max_clk = XENON_MMC_MAX_CLK;
+ if (slot->host.f_max > 0)
+ slot->max_clk = slot->host.f_max;
+ sc->slot = slot;
+
+ return (sdhci_xenon_attach(dev));
+}
+
+static int
+sdhci_xenon_fdt_detach(device_t dev)
+{
+ struct sdhci_xenon_fdt_softc *fdt_sc = device_get_softc(dev);
+
+ if (fdt_sc->gpio != NULL)
+ sdhci_fdt_gpio_teardown(fdt_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_fdt_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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 29, 3:31 PM (9 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28085826
Default Alt Text
D31599.id93871.diff (17 KB)
Attached To
Mode
D31599: sdhci_xenon: split driver file into generic file and fdt parts
Attached
Detach File
Event Timeline
Log In to Comment