svn commit: r362400 - in stable/12/sys: arm/allwinner conf dev/mmc dev/mmc/host

Emmanuel Vadot manu at FreeBSD.org
Fri Jun 19 18:05:16 UTC 2020


Author: manu
Date: Fri Jun 19 18:05:14 2020
New Revision: 362400
URL: https://svnweb.freebsd.org/changeset/base/362400

Log:
  MFC r359924-r359925, r359927, r359932, r359965
  
  r359924:
  Those functions are here to help fdt mmc controller drivers to parse
  the dts to find the supported speeds and the regulators.
  Not all DTS have every settings properly defined so host controller
  will still have to add some caps themselves.
  It also add a mmc_fdt_gpio_setup function which will read the cd-gpios
  property and register it as the CD pin.
  If the pin support interrupts one will be registered and the cd_helper
  function will be called.
  If the pin doesn't support interrupts the internal taskqueue will poll
  for change and call the same cd_helper function.
  mmc_fdt_gpio_setup will also parse the wp-gpio property and MMC drivers
  can know the write-protect pin value by calling the
  mmc_fdt_gpio_get_readonly function.
  
  Differential Revision:	https://reviews.freebsd.org/D23267
  
  r359925:
  arm: allwinner: aw_mmc: Use the mmc_fdt_helper
  
  The fdt properties are now parsed via the help of mmc_fdt_helper functions.
  This also adds card detection.
  Note that on some boards (like the Pine64) card detection is broken due to
  a missing resistor on the cd pin.
  
  Differential Revision:	https://reviews.freebsd.org/D23268
  
  r359927:
  arm: dwmmc: Use mmc_fdt_helpers
  
  Use the mmc_fdt_parse function instead of parsing everything in the
  driver.
  
  r359932:
  files: Add mmc_fdt_helpers for mmccam enabled config
  
  X-MFC-With:	r359924
  
  r359965:
  mmc_fdt_helpers: Do not schedule a card detection is there is no cd gpio
  
  If the fdt node doesn't have a cd-gpios properties or if the node is set
  as non-removable we do not init the card detection timeout task as it is
  useless so don't schedule it too.
  
  X-MFC-With:	r359924

Added:
  stable/12/sys/dev/mmc/mmc_fdt_helpers.c
     - copied, changed from r359925, head/sys/dev/mmc/mmc_fdt_helpers.c
  stable/12/sys/dev/mmc/mmc_fdt_helpers.h
     - copied unchanged from r359925, head/sys/dev/mmc/mmc_fdt_helpers.h
Modified:
  stable/12/sys/arm/allwinner/aw_mmc.c
  stable/12/sys/conf/files
  stable/12/sys/dev/mmc/host/dwmmc.c
  stable/12/sys/dev/mmc/host/dwmmc_altera.c
  stable/12/sys/dev/mmc/host/dwmmc_hisi.c
  stable/12/sys/dev/mmc/host/dwmmc_rockchip.c
  stable/12/sys/dev/mmc/host/dwmmc_samsung.c
  stable/12/sys/dev/mmc/host/dwmmc_var.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/arm/allwinner/aw_mmc.c
==============================================================================
--- stable/12/sys/arm/allwinner/aw_mmc.c	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/arm/allwinner/aw_mmc.c	Fri Jun 19 18:05:14 2020	(r362400)
@@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/resource.h>
 #include <sys/rman.h>
 #include <sys/sysctl.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
 
 #include <machine/bus.h>
 
@@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/mmc/bridge.h>
 #include <dev/mmc/mmcbrvar.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
 
 #include <arm/allwinner/aw_mmc.h>
 #include <dev/extres/clk/clk.h>
@@ -122,6 +125,7 @@ struct aw_mmc_softc {
 	int			aw_timeout;
 	struct callout		aw_timeoutc;
 	struct mmc_host		aw_host;
+	struct mmc_fdt_helper	mmc_helper;
 #ifdef MMCCAM
 	union ccb *		ccb;
 	struct cam_devq *	devq;
@@ -136,9 +140,8 @@ struct aw_mmc_softc {
 	uint32_t		aw_intr;
 	uint32_t		aw_intr_wait;
 	void *			aw_intrhand;
-	regulator_t		aw_reg_vmmc;
-	regulator_t		aw_reg_vqmmc;
 	unsigned int		aw_clock;
+	device_t		child;
 
 	/* Fields required for DMA access. */
 	bus_addr_t	  	aw_dma_desc_phys;
@@ -164,6 +167,7 @@ static int aw_mmc_reset(struct aw_mmc_softc *);
 static int aw_mmc_init(struct aw_mmc_softc *);
 static void aw_mmc_intr(void *);
 static int aw_mmc_update_clock(struct aw_mmc_softc *, uint32_t);
+static void aw_mmc_helper_cd_handler(device_t, bool);
 
 static void aw_mmc_print_error(uint32_t);
 static int aw_mmc_update_ios(device_t, device_t);
@@ -380,6 +384,40 @@ aw_mmc_cam_request(struct aw_mmc_softc *sc, union ccb 
 }
 #endif /* MMCCAM */
 
+static void
+aw_mmc_helper_cd_handler(device_t dev, bool present)
+{
+	struct aw_mmc_softc *sc;
+
+	sc = device_get_softc(dev);
+	AW_MMC_LOCK(sc);
+	if (present) {
+		if (sc->child == NULL) {
+			if (bootverbose)
+				device_printf(sc->aw_dev, "Card inserted\n");
+
+			sc->child = device_add_child(sc->aw_dev, "mmc", -1);
+			AW_MMC_UNLOCK(sc);
+			if (sc->child) {
+				device_set_ivars(sc->child, sc);
+				(void)device_probe_and_attach(sc->child);
+			}
+		} else
+			AW_MMC_UNLOCK(sc);
+	} else {
+		/* Card isn't present, detach if necessary */
+		if (sc->child != NULL) {
+			if (bootverbose)
+				device_printf(sc->aw_dev, "Card removed\n");
+
+			AW_MMC_UNLOCK(sc);
+			device_delete_child(sc->aw_dev, sc->child);
+			sc->child = NULL;
+		} else
+			AW_MMC_UNLOCK(sc);
+	}
+}
+
 static int
 aw_mmc_probe(device_t dev)
 {
@@ -397,15 +435,11 @@ aw_mmc_probe(device_t dev)
 static int
 aw_mmc_attach(device_t dev)
 {
-	device_t child;
 	struct aw_mmc_softc *sc;
 	struct sysctl_ctx_list *ctx;
 	struct sysctl_oid_list *tree;
-	uint32_t bus_width, max_freq;
-	phandle_t node;
 	int error;
 
-	node = ofw_bus_get_node(dev);
 	sc = device_get_softc(dev);
 	sc->aw_dev = dev;
 
@@ -419,7 +453,7 @@ aw_mmc_attach(device_t dev)
 		return (ENXIO);
 	}
 	if (bus_setup_intr(dev, sc->aw_res[AW_MMC_IRQRES],
-	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_mmc_intr, sc,
+	    INTR_TYPE_NET | INTR_MPSAFE, NULL, aw_mmc_intr, sc,
 	    &sc->aw_intrhand)) {
 		bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res);
 		device_printf(dev, "cannot setup interrupt handler\n");
@@ -483,47 +517,15 @@ aw_mmc_attach(device_t dev)
 		goto fail;
 	}
 
-	if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0)
-		bus_width = 4;
-
-	if (regulator_get_by_ofw_property(dev, 0, "vmmc-supply",
-	    &sc->aw_reg_vmmc) == 0) {
-		if (bootverbose)
-			device_printf(dev, "vmmc-supply regulator found\n");
-	}
-	if (regulator_get_by_ofw_property(dev, 0, "vqmmc-supply",
-	    &sc->aw_reg_vqmmc) == 0 && bootverbose) {
-		if (bootverbose)
-			device_printf(dev, "vqmmc-supply regulator found\n");
-	}
-
+	/* Set some defaults for freq and supported mode */
 	sc->aw_host.f_min = 400000;
-
-	if (OF_getencprop(node, "max-frequency", &max_freq,
-	    sizeof(uint32_t)) <= 0)
-		max_freq = 52000000;
-	sc->aw_host.f_max = max_freq;
-
+	sc->aw_host.f_max = 52000000;
 	sc->aw_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
-	sc->aw_host.caps = MMC_CAP_HSPEED | MMC_CAP_UHS_SDR12 |
-			   MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
-			   MMC_CAP_UHS_DDR50 | MMC_CAP_MMC_DDR52;
+	sc->aw_host.caps |= MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330;
+	mmc_fdt_parse(dev, 0, &sc->mmc_helper, &sc->aw_host);
+	mmc_fdt_gpio_setup(dev, 0, &sc->mmc_helper, aw_mmc_helper_cd_handler);
 
-	if (sc->aw_reg_vqmmc != NULL) {
-		if (regulator_check_voltage(sc->aw_reg_vqmmc, 1800000) == 0)
-			sc->aw_host.caps |= MMC_CAP_SIGNALING_180;
-		if (regulator_check_voltage(sc->aw_reg_vqmmc, 3300000) == 0)
-			sc->aw_host.caps |= MMC_CAP_SIGNALING_330;
-	} else
-		sc->aw_host.caps |= MMC_CAP_SIGNALING_330;
-
-	if (bus_width >= 4)
-		sc->aw_host.caps |= MMC_CAP_4_BIT_DATA;
-	if (bus_width >= 8)
-		sc->aw_host.caps |= MMC_CAP_8_BIT_DATA;
-
 #ifdef MMCCAM
-	child = NULL; /* Not used by MMCCAM, need to silence compiler warnings */
 	sc->ccb = NULL;
 	if ((sc->devq = cam_simq_alloc(1)) == NULL) {
 		goto fail;
@@ -550,18 +552,8 @@ aw_mmc_attach(device_t dev)
 	}
 
 	mtx_unlock(&sc->sim_mtx);
-#else /* !MMCCAM */
-	child = device_add_child(dev, "mmc", -1);
-	if (child == NULL) {
-		device_printf(dev, "attaching MMC bus failed!\n");
-		goto fail;
-	}
-	if (device_probe_and_attach(child) != 0) {
-		device_printf(dev, "attaching MMC child failed!\n");
-		device_delete_child(dev, child);
-		goto fail;
-	}
 #endif /* MMCCAM */
+
 	return (0);
 
 fail:
@@ -1314,7 +1306,7 @@ aw_mmc_switch_vccq(device_t bus, device_t child)
 
 	sc = device_get_softc(bus);
 
-	if (sc->aw_reg_vqmmc == NULL)
+	if (sc->mmc_helper.vqmmc_supply == NULL)
 		return EOPNOTSUPP;
 
 	switch (sc->aw_host.ios.vccq) {
@@ -1328,7 +1320,7 @@ aw_mmc_switch_vccq(device_t bus, device_t child)
 		return EINVAL;
 	}
 
-	err = regulator_set_voltage(sc->aw_reg_vqmmc, uvolt, uvolt);
+	err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply, uvolt, uvolt);
 	if (err != 0) {
 		device_printf(sc->aw_dev,
 		    "Cannot set vqmmc to %d<->%d\n",
@@ -1373,10 +1365,10 @@ aw_mmc_update_ios(device_t bus, device_t child)
 		if (bootverbose)
 			device_printf(sc->aw_dev, "Powering down sd/mmc\n");
 
-		if (sc->aw_reg_vmmc)
-			regulator_disable(sc->aw_reg_vmmc);
-		if (sc->aw_reg_vqmmc)
-			regulator_disable(sc->aw_reg_vqmmc);
+		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);
 
 		aw_mmc_reset(sc);
 		break;
@@ -1384,10 +1376,10 @@ aw_mmc_update_ios(device_t bus, device_t child)
 		if (bootverbose)
 			device_printf(sc->aw_dev, "Powering up sd/mmc\n");
 
-		if (sc->aw_reg_vmmc)
-			regulator_enable(sc->aw_reg_vmmc);
-		if (sc->aw_reg_vqmmc)
-			regulator_enable(sc->aw_reg_vqmmc);
+		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);
 		aw_mmc_init(sc);
 		break;
 	};
@@ -1463,8 +1455,11 @@ aw_mmc_update_ios(device_t bus, device_t child)
 static int
 aw_mmc_get_ro(device_t bus, device_t child)
 {
+	struct aw_mmc_softc *sc;
 
-	return (0);
+	sc = device_get_softc(bus);
+
+	return (mmc_fdt_gpio_get_readonly(&sc->mmc_helper));
 }
 
 static int

Modified: stable/12/sys/conf/files
==============================================================================
--- stable/12/sys/conf/files	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/conf/files	Fri Jun 19 18:05:14 2020	(r362400)
@@ -2473,6 +2473,7 @@ dev/mmc/mmc.c			optional mmc !mmccam
 dev/mmc/mmcbr_if.m		standard
 dev/mmc/mmcbus_if.m		standard
 dev/mmc/mmcsd.c			optional mmcsd !mmccam
+dev/mmc/mmc_fdt_helpers.c	optional mmc fdt | mmccam fdt
 dev/mmcnull/mmcnull.c		optional mmcnull
 dev/mn/if_mn.c			optional mn pci
 dev/mpr/mpr.c			optional mpr

Modified: stable/12/sys/dev/mmc/host/dwmmc.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc.c	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/dev/mmc/host/dwmmc.c	Fri Jun 19 18:05:14 2020	(r362400)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/mmc/bridge.h>
 #include <dev/mmc/mmcbrvar.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
 
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
@@ -446,7 +447,6 @@ dwmmc_card_task(void *arg, int pending __unused)
 			}
 		} else
 			DWMMC_UNLOCK(sc);
-		
 	} else {
 		/* Card isn't present, detach if necessary */
 		if (sc->child != NULL) {
@@ -466,7 +466,7 @@ parse_fdt(struct dwmmc_softc *sc)
 {
 	pcell_t dts_value[3];
 	phandle_t node;
-	uint32_t bus_hz = 0, bus_width;
+	uint32_t bus_hz = 0;
 	int len;
 #ifdef EXT_RESOURCES
 	int error;
@@ -475,18 +475,13 @@ parse_fdt(struct dwmmc_softc *sc)
 	if ((node = ofw_bus_get_node(sc->dev)) == -1)
 		return (ENXIO);
 
-	/* bus-width */
-	if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0)
-		bus_width = 4;
-	if (bus_width >= 4)
-		sc->host.caps |= MMC_CAP_4_BIT_DATA;
-	if (bus_width >= 8)
-		sc->host.caps |= MMC_CAP_8_BIT_DATA;
+	/* Set some defaults for freq and supported mode */
+	sc->host.f_min = 400000;
+	sc->host.f_max = 200000000;
+	sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
+	sc->host.caps = MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330;
+	mmc_fdt_parse(sc->dev, node, &sc->mmc_helper, &sc->host);
 
-	/* max-frequency */
-	if (OF_getencprop(node, "max-frequency", &sc->host.f_max, sizeof(uint32_t)) <= 0)
-		sc->host.f_max = 200000000;
-
 	/* fifo-depth */
 	if ((len = OF_getproplen(node, "fifo-depth")) > 0) {
 		OF_getencprop(node, "fifo-depth", dts_value, len);
@@ -721,11 +716,6 @@ dwmmc_attach(device_t dev)
 				   DWMMC_ERR_FLAGS |
 				   SDMMC_INTMASK_CD));
 	WRITE4(sc, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE);
-
-	sc->host.f_min = 400000;
-	sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
-	sc->host.caps |= MMC_CAP_HSPEED;
-	sc->host.caps |= MMC_CAP_SIGNALING_330;
 
 	TASK_INIT(&sc->card_task, 0, dwmmc_card_task, sc);
 	TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->card_delayed_task, 0,

Modified: stable/12/sys/dev/mmc/host/dwmmc_altera.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_altera.c	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/dev/mmc/host/dwmmc_altera.c	Fri Jun 19 18:05:14 2020	(r362400)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 
 #include <dev/mmc/bridge.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
 
 #include <dev/ofw/ofw_bus_subr.h>
 

Modified: stable/12/sys/dev/mmc/host/dwmmc_hisi.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_hisi.c	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/dev/mmc/host/dwmmc_hisi.c	Fri Jun 19 18:05:14 2020	(r362400)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 
 #include <dev/mmc/bridge.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
 
 #include <dev/ofw/ofw_bus_subr.h>
 

Modified: stable/12/sys/dev/mmc/host/dwmmc_rockchip.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_rockchip.c	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/dev/mmc/host/dwmmc_rockchip.c	Fri Jun 19 18:05:14 2020	(r362400)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 
 #include <dev/mmc/bridge.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
 
 #include <dev/ofw/ofw_bus_subr.h>
 

Modified: stable/12/sys/dev/mmc/host/dwmmc_samsung.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_samsung.c	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/dev/mmc/host/dwmmc_samsung.c	Fri Jun 19 18:05:14 2020	(r362400)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 
 #include <dev/mmc/bridge.h>
+#include <dev/mmc/mmc_fdt_helpers.h>
 
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>

Modified: stable/12/sys/dev/mmc/host/dwmmc_var.h
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_var.h	Fri Jun 19 18:04:41 2020	(r362399)
+++ stable/12/sys/dev/mmc/host/dwmmc_var.h	Fri Jun 19 18:05:14 2020	(r362400)
@@ -52,6 +52,7 @@ struct dwmmc_softc {
 	device_t		dev;
 	void			*intr_cookie;
 	struct mmc_host		host;
+	struct mmc_fdt_helper	mmc_helper;
 	struct mtx		sc_mtx;
 	struct mmc_request	*req;
 	struct mmc_command	*curcmd;

Copied and modified: stable/12/sys/dev/mmc/mmc_fdt_helpers.c (from r359925, head/sys/dev/mmc/mmc_fdt_helpers.c)
==============================================================================
--- head/sys/dev/mmc/mmc_fdt_helpers.c	Tue Apr 14 16:34:13 2020	(r359925, copy source)
+++ stable/12/sys/dev/mmc/mmc_fdt_helpers.c	Fri Jun 19 18:05:14 2020	(r362400)
@@ -217,7 +217,7 @@ cd_card_task(void *arg, int pending __unused)
 /*
  * Card detect setup.
  */
-static void
+static bool
 cd_setup(struct mmc_fdt_helper *helper, phandle_t node)
 {
 	int pincaps;
@@ -233,7 +233,7 @@ cd_setup(struct mmc_fdt_helper *helper, phandle_t node
 		helper->cd_disabled = true;
 		if (bootverbose)
 			device_printf(dev, "Non-removable media\n");
-		return;
+		return (false);
 	}
 
 	/*
@@ -246,14 +246,14 @@ cd_setup(struct mmc_fdt_helper *helper, phandle_t node
 	 */
 	if (gpio_pin_get_by_ofw_property(dev, node, "cd-gpios",
 	    &helper->cd_pin))
-		return;
+		return (false);
 
 	if (gpio_pin_getcaps(helper->cd_pin, &pincaps) != 0 ||
 	    !(pincaps & GPIO_PIN_INPUT)) {
 		device_printf(dev, "Cannot read card-detect gpio pin; "
 		    "setting card-always-present flag.\n");
 		helper->cd_disabled = true;
-		return;
+		return (false);
 	}
 
 	/*
@@ -313,6 +313,8 @@ without_interrupts:
 		    device_get_nameunit(helper->cd_pin->dev), helper->cd_pin->pin,
 		    cd_mode_str);
 	}
+
+	return (true);
 }
 
 /*
@@ -354,14 +356,16 @@ mmc_fdt_gpio_setup(device_t dev, phandle_t node, struc
 
 	helper->dev = dev;
 	helper->cd_handler = handler;
-	cd_setup(helper, node);
 	wp_setup(helper, node);
 
-	/* 
-	 * Schedule a card detection
-	 */
-	taskqueue_enqueue_timeout_sbt(taskqueue_swi_giant,
-	    &helper->cd_delayed_task, mstosbt(500), 0, C_PREL(2));
+	if (cd_setup(helper, node)) {
+		/* 
+		 * Schedule a card detection
+		 */
+		taskqueue_enqueue_timeout_sbt(taskqueue_swi_giant,
+		    &helper->cd_delayed_task, mstosbt(500), 0, C_PREL(2));
+	}
+
 	return (0);
 }
 

Copied: stable/12/sys/dev/mmc/mmc_fdt_helpers.h (from r359925, head/sys/dev/mmc/mmc_fdt_helpers.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/sys/dev/mmc/mmc_fdt_helpers.h	Fri Jun 19 18:05:14 2020	(r362400, copy of r359925, head/sys/dev/mmc/mmc_fdt_helpers.h)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2019 Emmanuel Vadot <manu at freebsd.org>
+ * Copyright (c) 2017 Ian Lepore <ian at 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$
+ */
+
+#ifndef _MMC_FDT_HELPERS_H_
+#define	_MMC_FDT_HELPERS_H_
+
+#include <dev/gpio/gpiobusvar.h>
+#include <dev/ofw/ofw_bus.h>
+
+#ifdef EXT_RESOURCES
+#include <dev/extres/regulator/regulator.h>
+#endif
+
+struct mmc_fdt_helper {
+	device_t		dev;
+	gpio_pin_t		wp_pin;
+	gpio_pin_t		cd_pin;
+	void *			cd_ihandler;
+	struct resource *	cd_ires;
+	int			cd_irid;
+	void			(*cd_handler)(device_t, bool);
+	struct timeout_task	cd_delayed_task;
+	bool			cd_disabled;
+	bool			wp_disabled;
+	bool			cd_present;
+	uint32_t		props;
+#define	MMC_PROP_BROKEN_CD	(1 << 0)
+#define	MMC_PROP_NON_REMOVABLE	(1 << 1)
+#define	MMC_PROP_WP_INVERTED	(1 << 2)
+#define	MMC_PROP_CD_INVERTED	(1 << 3)
+#define	MMC_PROP_DISABLE_WP	(1 << 4)
+#define	MMC_PROP_NO_SDIO	(1 << 5)
+#define	MMC_PROP_NO_SD		(1 << 6)
+#define	MMC_PROP_NO_MMC		(1 << 7)
+
+#ifdef EXT_RESOURCES
+	regulator_t	vmmc_supply;
+	regulator_t	vqmmc_supply;
+#endif
+};
+
+typedef void (*mmc_fdt_cd_handler)(device_t dev, bool present);
+
+int mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, struct mmc_host *host);
+int mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, mmc_fdt_cd_handler handler);
+void mmc_fdt_gpio_teardown(struct mmc_fdt_helper *helper);
+bool mmc_fdt_gpio_get_present(struct mmc_fdt_helper *helper);
+bool mmc_fdt_gpio_get_readonly(struct mmc_fdt_helper *helper);
+
+#endif


More information about the svn-src-all mailing list