Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Mar 2017 20:22:25 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r314508 - in stable/11/sys: arm/ti conf dev/sdhci
Message-ID:  <201703012022.v21KMPJv098266@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Wed Mar  1 20:22:25 2017
New Revision: 314508
URL: https://svnweb.freebsd.org/changeset/base/314508

Log:
  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.

Added:
  stable/11/sys/dev/sdhci/sdhci_fdt_gpio.c
     - copied, changed from r311734, head/sys/dev/sdhci/sdhci_fdt_gpio.c
  stable/11/sys/dev/sdhci/sdhci_fdt_gpio.h
     - copied unchanged from r311734, head/sys/dev/sdhci/sdhci_fdt_gpio.h
Modified:
  stable/11/sys/arm/ti/ti_sdhci.c
  stable/11/sys/conf/files
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/ti/ti_sdhci.c
==============================================================================
--- stable/11/sys/arm/ti/ti_sdhci.c	Wed Mar  1 20:00:19 2017	(r314507)
+++ stable/11/sys/arm/ti/ti_sdhci.c	Wed Mar  1 20:22:25 2017	(r314508)
@@ -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
 };

Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files	Wed Mar  1 20:00:19 2017	(r314507)
+++ stable/11/sys/conf/files	Wed Mar  1 20:22:25 2017	(r314508)
@@ -2556,6 +2556,7 @@ dev/scc/scc_dev_z8530.c		optional scc
 dev/scd/scd.c			optional scd isa
 dev/scd/scd_isa.c		optional scd isa
 dev/sdhci/sdhci.c		optional sdhci
+dev/sdhci/sdhci_fdt_gpio.c	optional sdhci fdt gpio
 dev/sdhci/sdhci_if.m		optional sdhci
 dev/sdhci/sdhci_acpi.c		optional sdhci acpi
 dev/sdhci/sdhci_pci.c		optional sdhci pci

Copied and modified: stable/11/sys/dev/sdhci/sdhci_fdt_gpio.c (from r311734, head/sys/dev/sdhci/sdhci_fdt_gpio.c)
==============================================================================
--- head/sys/dev/sdhci/sdhci_fdt_gpio.c	Mon Jan  9 01:54:36 2017	(r311734, copy source)
+++ stable/11/sys/dev/sdhci/sdhci_fdt_gpio.c	Wed Mar  1 20:22:25 2017	(r314508)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/bus.h>
 #include <sys/gpio.h>
 #include <sys/sysctl.h>
+#include <sys/systm.h>
 #include <sys/taskqueue.h>
 
 #include <dev/gpio/gpiobusvar.h>

Copied: stable/11/sys/dev/sdhci/sdhci_fdt_gpio.h (from r311734, head/sys/dev/sdhci/sdhci_fdt_gpio.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/sys/dev/sdhci/sdhci_fdt_gpio.h	Wed Mar  1 20:22:25 2017	(r314508, copy of r311734, head/sys/dev/sdhci/sdhci_fdt_gpio.h)
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2017 Ian Lepore <ian@freebsd.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Support routines usable by any SoC sdhci bridge driver that uses gpio pins
+ * for card detect and/or write protect, and uses FDT data to describe those
+ * pins.  A bridge driver need only supply a couple 2-line forwarding functions
+ * to connect the get_present and get_readonly accessors to the corresponding
+ * driver interface functions, and add setup/teardown calls to its attach and
+ * detach functions.
+ */
+
+#ifndef	_SDHCI_FDT_GPIO_H_
+#define	_SDHCI_FDT_GPIO_H_
+
+struct sdhci_slot;
+struct sdhci_fdt_gpio;
+
+/*
+ * sdhci_fdt_gpio_setup()
+ * sdhci_fdt_gpio_teardown()
+ *
+ * Process FDT properties that use gpio pins and set up interrupt handling (if
+ * supported by hardware) and accessor functions to read the pins.
+ *
+ * Setup cannot fail.  If the properties are not present, the accessors will
+ * return the values from standard sdhci registers.  If the gpio controller
+ * can't trigger interrupts on both edges, it configures the slot to use polling
+ * for card presence detection.  If it can't access the gpio pin at all it sets
+ * up the get_present() accessor to always return true.  Likewise the
+ * get_readonly() accessor always returns false if its pin can't be accessed.
+ */
+struct sdhci_fdt_gpio *sdhci_fdt_gpio_setup(device_t dev, struct sdhci_slot *slot);
+void sdhci_fdt_gpio_teardown(struct sdhci_fdt_gpio *gpio);
+
+/*
+ * sdhci_fdt_gpio_get_present()
+ * sdhci_fdt_gpio_get_readonly()
+ *
+ * Gpio pin state accessor functions.
+ */
+bool sdhci_fdt_gpio_get_present(struct sdhci_fdt_gpio *gpio);
+int  sdhci_fdt_gpio_get_readonly(struct sdhci_fdt_gpio *gpio);
+
+#endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703012022.v21KMPJv098266>