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 <i...@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 _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"