summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2017-03-01 20:22:25 +0000
committerian <ian@FreeBSD.org>2017-03-01 20:22:25 +0000
commit729b5d708ca03f0facd9c13337866fa1cb306ebe (patch)
treeca146ad2064af9b741545d2cfdcd58647186bb3e /sys/arm
parentb6db1fb93d0aefdf2d82e9b20ca36094d5a3cb32 (diff)
downloadFreeBSD-src-729b5d708ca03f0facd9c13337866fa1cb306ebe.zip
FreeBSD-src-729b5d708ca03f0facd9c13337866fa1cb306ebe.tar.gz
MFC r311734, r311735, r311951, r314071:
Add new helper routines for sdhci bridge drivers that use gpio pins for card presence and write protect switch detection. Use the new sdhci_fdt_gpio helper functions to add full support for FDT gpio pins for detecting card insert/remove and write protect for ti_sdhci. Include sys/systm.h for use of bootverbose. Revert to ti_sdhci driver's historic behavior: assume an sd card is writable if the fdt data doesn't provide a gpio pin for reading the write protect switch and also doesn't contain a "wp-disable" property.
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/ti/ti_sdhci.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/sys/arm/ti/ti_sdhci.c b/sys/arm/ti/ti_sdhci.c
index ed7f1e7..379edc7 100644
--- a/sys/arm/ti/ti_sdhci.c
+++ b/sys/arm/ti/ti_sdhci.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <dev/mmc/mmcbrvar.h>
#include <dev/sdhci/sdhci.h>
+#include <dev/sdhci/sdhci_fdt_gpio.h>
#include "sdhci_if.h"
#include <arm/ti/ti_cpuid.h>
@@ -61,7 +62,7 @@ __FBSDID("$FreeBSD$");
struct ti_sdhci_softc {
device_t dev;
- device_t gpio_dev;
+ struct sdhci_fdt_gpio * gpio;
struct resource * mem_res;
struct resource * irq_res;
void * intr_cookie;
@@ -75,6 +76,7 @@ struct ti_sdhci_softc {
uint32_t sdhci_clkdiv;
boolean_t disable_highspeed;
boolean_t force_card_present;
+ boolean_t disable_readonly;
};
/*
@@ -362,20 +364,27 @@ static int
ti_sdhci_get_ro(device_t brdev, device_t reqdev)
{
struct ti_sdhci_softc *sc = device_get_softc(brdev);
- unsigned int readonly = 0;
- /* If a gpio pin is configured, read it. */
- if (sc->gpio_dev != NULL) {
- GPIO_PIN_GET(sc->gpio_dev, sc->wp_gpio_pin, &readonly);
- }
+ if (sc->disable_readonly)
+ return (0);
- return (readonly);
+ return (sdhci_fdt_gpio_get_readonly(sc->gpio));
+}
+
+static bool
+ti_sdhci_get_card_present(device_t dev, struct sdhci_slot *slot)
+{
+ struct ti_sdhci_softc *sc = device_get_softc(dev);
+
+ return (sdhci_fdt_gpio_get_present(sc->gpio));
}
static int
ti_sdhci_detach(device_t dev)
{
+ /* sdhci_fdt_gpio_teardown(sc->gpio); */
+
return (EBUSY);
}
@@ -502,25 +511,6 @@ ti_sdhci_attach(device_t dev)
}
/*
- * See if we've got a GPIO-based write detect pin. This is not the
- * standard documented property for this, we added it in freebsd.
- */
- if ((OF_getencprop(node, "mmchs-wp-gpio-pin", &prop, sizeof(prop))) <= 0)
- sc->wp_gpio_pin = 0xffffffff;
- else
- sc->wp_gpio_pin = prop;
-
- if (sc->wp_gpio_pin != 0xffffffff) {
- sc->gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
- if (sc->gpio_dev == NULL)
- device_printf(dev, "Error: No GPIO device, "
- "Write Protect pin will not function\n");
- else
- GPIO_PIN_SETFLAGS(sc->gpio_dev, sc->wp_gpio_pin,
- GPIO_PIN_INPUT);
- }
-
- /*
* Set the offset from the device's memory start to the MMCHS registers.
* Also for OMAP4 disable high speed mode due to erratum ID i626.
*/
@@ -572,6 +562,21 @@ ti_sdhci_attach(device_t dev)
goto fail;
}
+ /*
+ * Set up handling of card-detect and write-protect gpio lines.
+ *
+ * If there is no write protect info in the fdt data, fall back to the
+ * historical practice of assuming that the card is writable. This
+ * works around bad fdt data from the upstream source. The alternative
+ * would be to trust the sdhci controller's PRESENT_STATE register WP
+ * bit, but it may say write protect is in effect when it's not if the
+ * pinmux setup doesn't route the WP signal into the sdchi block.
+ */
+ sc->gpio = sdhci_fdt_gpio_setup(sc->dev, &sc->slot);
+
+ if (!OF_hasprop(node, "wp-gpios") && !OF_hasprop(node, "wp-disable"))
+ sc->disable_readonly = true;
+
/* Initialise the MMCHS hardware. */
ti_sdhci_hw_init(dev);
@@ -706,6 +711,7 @@ static device_method_t ti_sdhci_methods[] = {
DEVMETHOD(sdhci_write_2, ti_sdhci_write_2),
DEVMETHOD(sdhci_write_4, ti_sdhci_write_4),
DEVMETHOD(sdhci_write_multi_4, ti_sdhci_write_multi_4),
+ DEVMETHOD(sdhci_get_card_present, ti_sdhci_get_card_present),
DEVMETHOD_END
};
OpenPOWER on IntegriCloud