Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F103194586
D23268.id67012.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D23268.id67012.diff
View Options
Index: sys/arm/allwinner/aw_mmc.c
===================================================================
--- sys/arm/allwinner/aw_mmc.c
+++ sys/arm/allwinner/aw_mmc.c
@@ -41,6 +41,8 @@
#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 @@
#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 @@
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 @@
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_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);
@@ -382,6 +386,40 @@
}
#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)
{
@@ -399,15 +437,11 @@
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;
@@ -421,7 +455,7 @@
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");
@@ -485,47 +519,16 @@
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;
-
- 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;
+ sc->aw_host.caps |= MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330;
+ sc->mmc_helper.cd_handler = &aw_mmc_helper_cd_handler;
+ mmc_fdt_parse(dev, 0, &sc->mmc_helper, &sc->aw_host);
+ mmc_fdt_gpio_setup(dev, 0, &sc->mmc_helper);
#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;
@@ -552,18 +555,8 @@
}
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:
@@ -1323,7 +1316,7 @@
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) {
@@ -1337,7 +1330,7 @@
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",
@@ -1382,10 +1375,10 @@
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;
@@ -1393,10 +1386,10 @@
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;
};
@@ -1472,8 +1465,11 @@
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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 23, 3:03 AM (1 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14788415
Default Alt Text
D23268.id67012.diff (6 KB)
Attached To
Mode
D23268: aw_mmc: Add support to card detection
Attached
Detach File
Event Timeline
Log In to Comment