Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Jun 2020 21:44:49 +0000 (UTC)
From:      Emmanuel Vadot <manu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r362344 - in stable/12/sys: arm/amlogic/aml8726 arm64/conf conf dev/mmc/host mips/ingenic
Message-ID:  <202006182144.05ILinnB091978@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: manu
Date: Thu Jun 18 21:44:49 2020
New Revision: 362344
URL: https://svnweb.freebsd.org/changeset/base/362344

Log:
  MFC r349584, r349728, r349731, r350440, r350443, r351185, r353493, r353575, r355625, r355627, r355629, r356813
  
  r349584:
  Since r349571 we need all the accessor to be present for set or get
  otherwise we panic.
  dwmmc don't handle VCCQ (voltage for the IO line of the SD/eMMC) or
  TIMING.
  Add the needed accessor in the {read,write}_ivar functions.
  
  Reviewed by:	imp (previous version)
  
  r349728 by imp:
  Implement missing MMCBR ivars
  
  All MMCBR bridges have to implement all the MMCBR variables. This
  implements them for everybody that currently doesn't.
  
  A common routine for this should be written.
  
  r349731 by imp:
  Fix cut-and-pasto that slipped through my testing.
  
  r350440 by br:
  Add support for the SD/MMC controller found in Terasic DE10-Pro
  (an Intel Stratix 10 GX/SX FPGA Development Kit).
  
  Set the bus speed manually due to lack of clock management support.
  
  Sponsored by:	DARPA, AFRL
  
  r350443 by br:
  Fix MMCCAM kernel build.
  
  Sponsored by:	DARPA, AFRL
  
  r351185 by mmel:
  Enhance support of extres in dwmmc driver.
  Handle all clocks, regulators and resets defined by dwmmc bindings.
  
  r353493 by br:
  Fix the driver attachment in cases when the external resource devices
  (resets, regulators, clocks) are not available.
  
  Rely on a system initialization done by a bootloader in that cases.
  
  This fixes operation on Terasic DE10-Pro (an Intel Stratix 10
  development kit).
  
  Sponsored by:	DARPA, AFRL
  
  r353575 by br:
  Fix dwmmc(4) driver attachment when ext_resources are not present.
  
  Ignore only ENOENT (no DTS properties found) and ENODEV (driver not
  present) non-zero return values from ext_resources.
  
  Reviewed by:	manu
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D22043
  
  r355625:
  dwmmc: Add a detach method
  
  This method will disable the regulators, clocks and assert the reset of
  the module. It will also detach it's children (the mmc device) and release
  it's resources.
  While here enable the regulators on attach as we need them to power up
  the sdcard or emmc.
  
  r355627:
  dwmmc: Handle the card detect interrupt
  
  The driver used to always add the mmc device as it's child even
  it no card was detected. Add a function that will detect if the
  card is present or not and that will attach/detach the mmc device.
  The function is either call on attach (as we won't have the interrupt
  fired) or from two taskqueues. The first taskqueue will directly call
  the function when the sdcard was present and is now removed and the other
  one will delay a bit the attach when we didn't had a card and now have one.
  This is mostly based on comments from the sdhci driver where it describe
  a situation when the CD pin is detected before the others pins are connected.
  
  r355629:
  dwmmc: Use device_delete_children
  
  Instead of first detaching the children(s) and then delete them,
  use the device_delete_children function that does all of that.
  
  Suggested by:	ian
  
  r356813:
  dwmmc: Remove max_hz from the softc
  
  We never use it so directly set the value to the mmc host structure.

Modified:
  stable/12/sys/arm/amlogic/aml8726/aml8726_mmc.c
  stable/12/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
  stable/12/sys/arm64/conf/GENERIC
  stable/12/sys/conf/files.arm64
  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
  stable/12/sys/mips/ingenic/jz4780_mmc.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/arm/amlogic/aml8726/aml8726_mmc.c
==============================================================================
--- stable/12/sys/arm/amlogic/aml8726/aml8726_mmc.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/arm/amlogic/aml8726/aml8726_mmc.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -965,15 +965,26 @@ aml8726_mmc_read_ivar(device_t bus, device_t child,
 	case MMCBR_IVAR_POWER_MODE:
 		*(int *)result = sc->host.ios.power_mode;
 		break;
+	case MMCBR_IVAR_RETUNE_REQ:
+		*(int *)result = return_req_none;
 	case MMCBR_IVAR_VDD:
 		*(int *)result = sc->host.ios.vdd;
 		break;
+	case MMCBR_IVAR_VCCQ:
+		*result = sc->sc_host.ios.vccq;
+		break;
 	case MMCBR_IVAR_CAPS:
 		*(int *)result = sc->host.caps;
 		break;
+	case MMCBR_IVAR_TIMING:
+		*(int *)result = sc->sc_host.ios.timing;
+		break;
 	case MMCBR_IVAR_MAX_DATA:
 		*(int *)result = AML_MMC_MAX_DMA / MMC_SECTOR_SIZE;
 		break;
+	case MMCBR_IVAR_MAX_BUSY_TIMEOUT:
+		*(int *)result = 1000000;	/* 1s max */
+		break;
 	default:
 		return (EINVAL);
 	}
@@ -1011,6 +1022,12 @@ aml8726_mmc_write_ivar(device_t bus, device_t child,
 		break;
 	case MMCBR_IVAR_VDD:
 		sc->host.ios.vdd = value;
+		break;
+	case MMCBR_IVAR_VCCQ:
+		sc->sc_host.ios.vccq = value;
+		break;
+	case MMCBR_IVAR_TIMING:
+		sc->sc_host.ios.timing = value;
 		break;
 	/* These are read-only */
 	case MMCBR_IVAR_CAPS:

Modified: stable/12/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
==============================================================================
--- stable/12/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -1245,15 +1245,27 @@ aml8726_sdxc_read_ivar(device_t bus, device_t child,
 	case MMCBR_IVAR_POWER_MODE:
 		*(int *)result = sc->host.ios.power_mode;
 		break;
+	case MMCBR_IVAR_RETUNE_REQ:
+		*(int *)result = return_req_none;
+		break;
 	case MMCBR_IVAR_VDD:
 		*(int *)result = sc->host.ios.vdd;
 		break;
+	case MMCBR_IVAR_VCCQ:
+		*result = sc->host.ios.vccq;
+		break;
 	case MMCBR_IVAR_CAPS:
 		*(int *)result = sc->host.caps;
 		break;
+	case MMCBR_IVAR_TIMING:
+		*(int *)result = sc->host.ios.timing;
+		break;
 	case MMCBR_IVAR_MAX_DATA:
 		*(int *)result = AML_SDXC_MAX_DMA / MMC_SECTOR_SIZE;
 		break;
+	case MMCBR_IVAR_MAX_BUSY_TIMEOUT:
+		*(int *)result = 1000000;	/* 1s max */
+		break;
 	default:
 		return (EINVAL);
 	}
@@ -1291,6 +1303,12 @@ aml8726_sdxc_write_ivar(device_t bus, device_t child,
 		break;
 	case MMCBR_IVAR_VDD:
 		sc->host.ios.vdd = value;
+		break;
+	case MMCBR_IVAR_VCCQ:
+		sc->host.ios.vccq = value;
+		break;
+	case MMCBR_IVAR_TIMING:
+		sc->host.ios.timing = value;
 		break;
 	/* These are read-only */
 	case MMCBR_IVAR_CAPS:

Modified: stable/12/sys/arm64/conf/GENERIC
==============================================================================
--- stable/12/sys/arm64/conf/GENERIC	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/arm64/conf/GENERIC	Thu Jun 18 21:44:49 2020	(r362344)
@@ -166,6 +166,7 @@ device		aw_mmc			# Allwinner SD/MMC controller
 device		mmc			# mmc/sd bus
 device		mmcsd			# mmc/sd flash cards
 device		dwmmc
+device		dwmmc_altera
 device		rk_emmcphy
 
 # Serial (COM) ports

Modified: stable/12/sys/conf/files.arm64
==============================================================================
--- stable/12/sys/conf/files.arm64	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/conf/files.arm64	Thu Jun 18 21:44:49 2020	(r362344)
@@ -223,6 +223,7 @@ dev/hwpmc/hwpmc_arm64.c		optional	hwpmc
 dev/hwpmc/hwpmc_arm64_md.c	optional	hwpmc
 dev/mbox/mbox_if.m		optional	soc_brcm_bcm2837
 dev/mmc/host/dwmmc.c		optional	dwmmc fdt
+dev/mmc/host/dwmmc_altera.c	optional	dwmmc fdt dwmmc_altera
 dev/mmc/host/dwmmc_hisi.c	optional	dwmmc fdt soc_hisi_hi6220
 dev/mmc/host/dwmmc_rockchip.c	optional	dwmmc fdt soc_rockchip_rk3328
 dev/neta/if_mvneta_fdt.c	optional	neta fdt

Modified: stable/12/sys/dev/mmc/host/dwmmc.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/dev/mmc/host/dwmmc.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2014-2019 Ruslan Bukin <br@bsdpad.com>
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/malloc.h>
 #include <sys/rman.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
 
 #include <dev/mmc/bridge.h>
 #include <dev/mmc/mmcbrvar.h>
@@ -125,6 +127,7 @@ static int dma_done(struct dwmmc_softc *, struct mmc_c
 static int dma_stop(struct dwmmc_softc *);
 static void pio_read(struct dwmmc_softc *, struct mmc_command *);
 static void pio_write(struct dwmmc_softc *, struct mmc_command *);
+static void dwmmc_handle_card_present(struct dwmmc_softc *sc, bool is_present);
 
 static struct resource_spec dwmmc_spec[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
@@ -372,7 +375,8 @@ dwmmc_intr(void *arg)
 			sc->dto_rcvd = 1;
 
 		if (reg & SDMMC_INTMASK_CD) {
-			/* XXX: Handle card detect */
+			dwmmc_handle_card_present(sc,
+			    READ4(sc, SDMMC_CDETECT) == 0 ? true : false);
 		}
 	}
 
@@ -405,6 +409,56 @@ dwmmc_intr(void *arg)
 	DWMMC_UNLOCK(sc);
 }
 
+static void
+dwmmc_handle_card_present(struct dwmmc_softc *sc, bool is_present)
+{
+	bool was_present;
+
+	was_present = sc->child != NULL;
+
+	if (!was_present && is_present) {
+		taskqueue_enqueue_timeout(taskqueue_swi_giant,
+		  &sc->card_delayed_task, -(hz / 2));
+	} else if (was_present && !is_present) {
+		taskqueue_enqueue(taskqueue_swi_giant, &sc->card_task);
+	}
+}
+
+static void
+dwmmc_card_task(void *arg, int pending __unused)
+{
+	struct dwmmc_softc *sc = arg;
+
+	DWMMC_LOCK(sc);
+
+	if (READ4(sc, SDMMC_CDETECT) == 0) {
+		if (sc->child == NULL) {
+			if (bootverbose)
+				device_printf(sc->dev, "Card inserted\n");
+
+			sc->child = device_add_child(sc->dev, "mmc", -1);
+			DWMMC_UNLOCK(sc);
+			if (sc->child) {
+				device_set_ivars(sc->child, sc);
+				(void)device_probe_and_attach(sc->child);
+			}
+		} else
+			DWMMC_UNLOCK(sc);
+		
+	} else {
+		/* Card isn't present, detach if necessary */
+		if (sc->child != NULL) {
+			if (bootverbose)
+				device_printf(sc->dev, "Card removed\n");
+
+			DWMMC_UNLOCK(sc);
+			device_delete_child(sc->dev, sc->child);
+			sc->child = NULL;
+		} else
+			DWMMC_UNLOCK(sc);
+	}
+}
+
 static int
 parse_fdt(struct dwmmc_softc *sc)
 {
@@ -428,8 +482,8 @@ parse_fdt(struct dwmmc_softc *sc)
 		sc->host.caps |= MMC_CAP_8_BIT_DATA;
 
 	/* max-frequency */
-	if (OF_getencprop(node, "max-frequency", &sc->max_hz, sizeof(uint32_t)) <= 0)
-		sc->max_hz = 200000000;
+	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) {
@@ -452,8 +506,54 @@ parse_fdt(struct dwmmc_softc *sc)
 	}
 
 #ifdef EXT_RESOURCES
+
+	/* IP block reset is optional */
+	error = hwreset_get_by_ofw_name(sc->dev, 0, "reset", &sc->hwreset);
+	if (error != 0 &&
+	    error != ENOENT &&
+	    error != ENODEV) {
+		device_printf(sc->dev, "Cannot get reset\n");
+		goto fail;
+	}
+
+	/* vmmc regulator is optional */
+	error = regulator_get_by_ofw_property(sc->dev, 0, "vmmc-supply",
+	     &sc->vmmc);
+	if (error != 0 &&
+	    error != ENOENT &&
+	    error != ENODEV) {
+		device_printf(sc->dev, "Cannot get regulator 'vmmc-supply'\n");
+		goto fail;
+	}
+
+	/* vqmmc regulator is optional */
+	error = regulator_get_by_ofw_property(sc->dev, 0, "vqmmc-supply",
+	     &sc->vqmmc);
+	if (error != 0 &&
+	    error != ENOENT &&
+	    error != ENODEV) {
+		device_printf(sc->dev, "Cannot get regulator 'vqmmc-supply'\n");
+		goto fail;
+	}
+
+	/* Assert reset first */
+	if (sc->hwreset != NULL) {
+		error = hwreset_assert(sc->hwreset);
+		if (error != 0) {
+			device_printf(sc->dev, "Cannot assert reset\n");
+			goto fail;
+		}
+	}
+
 	/* BIU (Bus Interface Unit clock) is optional */
 	error = clk_get_by_ofw_name(sc->dev, 0, "biu", &sc->biu);
+	if (error != 0 &&
+	    error != ENOENT &&
+	    error != ENODEV) {
+		device_printf(sc->dev, "Cannot get 'biu' clock\n");
+		goto fail;
+	}
+
 	if (sc->biu) {
 		error = clk_enable(sc->biu);
 		if (error != 0) {
@@ -467,20 +567,52 @@ parse_fdt(struct dwmmc_softc *sc)
 	 * if no clock-frequency property is given
 	 */
 	error = clk_get_by_ofw_name(sc->dev, 0, "ciu", &sc->ciu);
+	if (error != 0 &&
+	    error != ENOENT &&
+	    error != ENODEV) {
+		device_printf(sc->dev, "Cannot get 'ciu' clock\n");
+		goto fail;
+	}
+
 	if (sc->ciu) {
-		error = clk_enable(sc->ciu);
-		if (error != 0) {
-			device_printf(sc->dev, "cannot enable ciu clock\n");
-			goto fail;
-		}
 		if (bus_hz != 0) {
 			error = clk_set_freq(sc->ciu, bus_hz, 0);
 			if (error != 0)
 				device_printf(sc->dev,
 				    "cannot set ciu clock to %u\n", bus_hz);
 		}
+		error = clk_enable(sc->ciu);
+		if (error != 0) {
+			device_printf(sc->dev, "cannot enable ciu clock\n");
+			goto fail;
+		}
 		clk_get_freq(sc->ciu, &sc->bus_hz);
 	}
+
+	/* Enable regulators */
+	if (sc->vmmc != NULL) {
+		error = regulator_enable(sc->vmmc);
+		if (error != 0) {
+			device_printf(sc->dev, "Cannot enable vmmc regulator\n");
+			goto fail;
+		}
+	}
+	if (sc->vqmmc != NULL) {
+		error = regulator_enable(sc->vqmmc);
+		if (error != 0) {
+			device_printf(sc->dev, "Cannot enable vqmmc regulator\n");
+			goto fail;
+		}
+	}
+
+	/* Take dwmmc out of reset */
+	if (sc->hwreset != NULL) {
+		error = hwreset_deassert(sc->hwreset);
+		if (error != 0) {
+			device_printf(sc->dev, "Cannot deassert reset\n");
+			goto fail;
+		}
+	}
 #endif /* EXT_RESOURCES */
 
 	if (sc->bus_hz == 0) {
@@ -592,15 +724,64 @@ dwmmc_attach(device_t dev)
 	WRITE4(sc, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE);
 
 	sc->host.f_min = 400000;
-	sc->host.f_max = sc->max_hz;
 	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;
 
-	device_add_child(dev, "mmc", -1);
-	return (bus_generic_attach(dev));
+	TASK_INIT(&sc->card_task, 0, dwmmc_card_task, sc);
+	TIMEOUT_TASK_INIT(taskqueue_swi_giant, &sc->card_delayed_task, 0,
+		dwmmc_card_task, sc);
+
+	/* 
+	 * Schedule a card detection as we won't get an interrupt
+	 * if the card is inserted when we attach
+	 */
+	dwmmc_card_task(sc, 0);
+
+	return (0);
 }
 
+int
+dwmmc_detach(device_t dev)
+{
+	struct dwmmc_softc *sc;
+	int ret;
+
+	sc = device_get_softc(dev);
+
+	ret = device_delete_children(dev);
+	if (ret != 0)
+		return (ret);
+
+	taskqueue_drain(taskqueue_swi_giant, &sc->card_task);
+	taskqueue_drain_timeout(taskqueue_swi_giant, &sc->card_delayed_task);
+
+	if (sc->intr_cookie != NULL) {
+		ret = bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
+		if (ret != 0)
+			return (ret);
+	}
+	bus_release_resources(dev, dwmmc_spec, sc->res);
+
+	DWMMC_LOCK_DESTROY(sc);
+
+#ifdef EXT_RESOURCES
+	if (sc->hwreset != NULL && hwreset_deassert(sc->hwreset) != 0)
+		device_printf(sc->dev, "cannot deassert reset\n");
+	if (sc->biu != NULL && clk_disable(sc->biu) != 0)
+		device_printf(sc->dev, "cannot disable biu clock\n");
+	if (sc->ciu != NULL && clk_disable(sc->ciu) != 0)
+			device_printf(sc->dev, "cannot disable ciu clock\n");
+
+	if (sc->vmmc && regulator_disable(sc->vmmc) != 0)
+		device_printf(sc->dev, "Cannot disable vmmc regulator\n");
+	if (sc->vqmmc && regulator_disable(sc->vqmmc) != 0)
+		device_printf(sc->dev, "Cannot disable vqmmc regulator\n");
+#endif
+
+	return (0);
+}
+
 static int
 dwmmc_setup_bus(struct dwmmc_softc *sc, int freq)
 {
@@ -1090,11 +1271,18 @@ dwmmc_read_ivar(device_t bus, device_t child, int whic
 	case MMCBR_IVAR_VDD:
 		*(int *)result = sc->host.ios.vdd;
 		break;
+	case MMCBR_IVAR_VCCQ:
+		*(int *)result = sc->host.ios.vccq;
+		break;
 	case MMCBR_IVAR_CAPS:
 		*(int *)result = sc->host.caps;
 		break;
 	case MMCBR_IVAR_MAX_DATA:
 		*(int *)result = sc->desc_count;
+		break;
+	case MMCBR_IVAR_TIMING:
+		*(int *)result = sc->host.ios.timing;
+		break;
 	}
 	return (0);
 }
@@ -1132,6 +1320,12 @@ dwmmc_write_ivar(device_t bus, device_t child, int whi
 		break;
 	case MMCBR_IVAR_VDD:
 		sc->host.ios.vdd = value;
+		break;
+	case MMCBR_IVAR_TIMING:
+		sc->host.ios.timing = value;
+		break;
+	case MMCBR_IVAR_VCCQ:
+		sc->host.ios.vccq = value;
 		break;
 	/* These are read-only */
 	case MMCBR_IVAR_CAPS:

Modified: stable/12/sys/dev/mmc/host/dwmmc_altera.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_altera.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/dev/mmc/host/dwmmc_altera.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/bus.h>
 #include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
 
 #include <machine/bus.h>
 
@@ -41,6 +43,8 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/mmc/host/dwmmc_var.h>
 
+#include "opt_mmccam.h"
+
 static struct ofw_compat_data compat_data[] = {
 	{"altr,socfpga-dw-mshc",	1},
 	{NULL,				0},
@@ -66,9 +70,17 @@ static int
 altera_dwmmc_attach(device_t dev)
 {
 	struct dwmmc_softc *sc;
+	phandle_t root;
 
 	sc = device_get_softc(dev);
 	sc->hwtype = HWTYPE_ALTERA;
+
+	root = OF_finddevice("/");
+
+	if (ofw_bus_node_is_compatible(root, "altr,socfpga-stratix10")) {
+		sc->bus_hz = 24000000;
+		sc->use_pio = 1;
+	}
 
 	return (dwmmc_attach(dev));
 }

Modified: stable/12/sys/dev/mmc/host/dwmmc_hisi.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_hisi.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/dev/mmc/host/dwmmc_hisi.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/bus.h>
 #include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
 
 #include <machine/bus.h>
 

Modified: stable/12/sys/dev/mmc/host/dwmmc_rockchip.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_rockchip.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/dev/mmc/host/dwmmc_rockchip.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/bus.h>
 #include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
 
 #include <machine/bus.h>
 
@@ -134,6 +136,7 @@ static device_method_t rockchip_dwmmc_methods[] = {
 	/* bus interface */
 	DEVMETHOD(device_probe, rockchip_dwmmc_probe),
 	DEVMETHOD(device_attach, rockchip_dwmmc_attach),
+	DEVMETHOD(device_detach, dwmmc_detach),
 
 	DEVMETHOD_END
 };

Modified: stable/12/sys/dev/mmc/host/dwmmc_samsung.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_samsung.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/dev/mmc/host/dwmmc_samsung.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/bus.h>
 #include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
 
 #include <machine/bus.h>
 

Modified: stable/12/sys/dev/mmc/host/dwmmc_var.h
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_var.h	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/dev/mmc/host/dwmmc_var.h	Thu Jun 18 21:44:49 2020	(r362344)
@@ -35,6 +35,8 @@
 
 #ifdef EXT_RESOURCES
 #include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+#include <dev/extres/regulator/regulator.h>
 #endif
 
 enum {
@@ -59,6 +61,9 @@ struct dwmmc_softc {
 	uint32_t		use_pio;
 	uint32_t		pwren_inverted;
 	u_int			desc_count;
+	device_t		child;
+	struct task		card_task;	/* Card presence check task */
+	struct timeout_task	card_delayed_task;/* Card insert delayed task */
 
 	int			(*update_ios)(struct dwmmc_softc *sc, struct mmc_ios *ios);
 
@@ -74,7 +79,6 @@ struct dwmmc_softc {
 	uint32_t		acd_rcvd;
 	uint32_t		cmd_done;
 	uint64_t		bus_hz;
-	uint32_t		max_hz;
 	uint32_t		fifo_depth;
 	uint32_t		num_slots;
 	uint32_t		sdr_timing;
@@ -83,11 +87,15 @@ struct dwmmc_softc {
 #ifdef EXT_RESOURCES
 	clk_t			biu;
 	clk_t			ciu;
+	hwreset_t		hwreset;
+	regulator_t		vmmc;
+	regulator_t		vqmmc;
 #endif
 };
 
 DECLARE_CLASS(dwmmc_driver);
 
 int dwmmc_attach(device_t);
+int dwmmc_detach(device_t);
 
 #endif

Modified: stable/12/sys/mips/ingenic/jz4780_mmc.c
==============================================================================
--- stable/12/sys/mips/ingenic/jz4780_mmc.c	Thu Jun 18 21:42:54 2020	(r362343)
+++ stable/12/sys/mips/ingenic/jz4780_mmc.c	Thu Jun 18 21:44:49 2020	(r362344)
@@ -774,17 +774,26 @@ jz4780_mmc_read_ivar(device_t bus, device_t child, int
 	case MMCBR_IVAR_POWER_MODE:
 		*(int *)result = sc->sc_host.ios.power_mode;
 		break;
+	case MMCBR_IVAR_RETUNE_REQ:
+		*(int *)result = return_req_none;
+		break;
 	case MMCBR_IVAR_VDD:
 		*(int *)result = sc->sc_host.ios.vdd;
 		break;
+	case MMCBR_IVAR_VCCQ:
+		*result = sc->sc_host.ios.vccq;
+		break;
 	case MMCBR_IVAR_CAPS:
 		*(int *)result = sc->sc_host.caps;
 		break;
+	case MMCBR_IVAR_TIMING:
+		*(int *)result = sc->sc_host.ios.timing;
+		break;
 	case MMCBR_IVAR_MAX_DATA:
 		*(int *)result = 65535;
 		break;
-	case MMCBR_IVAR_TIMING:
-		*(int *)result = sc->sc_host.ios.timing;
+	case MMCBR_IVAR_MAX_BUSY_TIMEOUT:
+		*(int *)result = 1000000;	/* 1s max */
 		break;
 	}
 
@@ -824,6 +833,9 @@ jz4780_mmc_write_ivar(device_t bus, device_t child, in
 		break;
 	case MMCBR_IVAR_VDD:
 		sc->sc_host.ios.vdd = value;
+		break;
+	case MMCBR_IVAR_VCCQ:
+		sc->sc_host.ios.vccq = value;
 		break;
 	case MMCBR_IVAR_TIMING:
 		sc->sc_host.ios.timing = value;



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