@@ -20,6 +20,7 @@
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/suspend.h>
+#include <linux/of.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
@@ -436,3 +437,95 @@ void mmc_free_host(struct mmc_host *host)
}
EXPORT_SYMBOL(mmc_free_host);
+
+/**
+ * mmc_of_populate_caps - support all MMC capabilities from Device Tree
+ * @np: MMC OF device node
+ * @caps: Host capabilities - as per linux/mmc/host.h
+ * @caps2: More host cabibilies - as per linux/mmc/host.h
+ *
+ * Read capability string from the device node provided and populate
+ * the capability container accordingly.
+ */
+void mmc_of_populate_caps(struct device_node *np,
+ unsigned long *caps,
+ unsigned int *caps2)
+{
+ if(of_property_read_bool(np, "mmc-cap-4-bit-data"))
+ *caps |= MMC_CAP_4_BIT_DATA;
+ if(of_property_read_bool(np, "mmc-cap-mmc-highspeed"))
+ *caps |= MMC_CAP_MMC_HIGHSPEED;
+ if(of_property_read_bool(np, "mmc-cap-sd-highspeed"))
+ *caps |= MMC_CAP_SD_HIGHSPEED;
+ if(of_property_read_bool(np, "mmc-cap-sdio-irq"))
+ *caps |= MMC_CAP_SDIO_IRQ;
+ if(of_property_read_bool(np, "mmc-cap-spi"))
+ *caps |= MMC_CAP_SPI;
+ if(of_property_read_bool(np, "mmc-cap-needs-poll"))
+ *caps |= MMC_CAP_NEEDS_POLL;
+ if(of_property_read_bool(np, "mmc-cap-8-bit-data"))
+ *caps |= MMC_CAP_8_BIT_DATA;
+ if(of_property_read_bool(np, "mmc-cap-nonremovable"))
+ *caps |= MMC_CAP_NONREMOVABLE;
+ if(of_property_read_bool(np, "mmc-cap-wait-while-busy"))
+ *caps |= MMC_CAP_WAIT_WHILE_BUSY;
+ if(of_property_read_bool(np, "mmc-cap-erase"))
+ *caps |= MMC_CAP_ERASE;
+ if(of_property_read_bool(np, "mmc-cap-1-8v-ddr"))
+ *caps |= MMC_CAP_1_8V_DDR;
+ if(of_property_read_bool(np, "mmc-cap-1-2v-ddr"))
+ *caps |= MMC_CAP_1_2V_DDR;
+ if(of_property_read_bool(np, "mmc-cap-power-off-card"))
+ *caps |= MMC_CAP_POWER_OFF_CARD;
+ if(of_property_read_bool(np, "mmc-cap-bus-width-test"))
+ *caps |= MMC_CAP_BUS_WIDTH_TEST;
+ if(of_property_read_bool(np, "mmc-cap-uhs-sdr12"))
+ *caps |= MMC_CAP_UHS_SDR12;
+ if(of_property_read_bool(np, "mmc-cap-uhs-sdr25"))
+ *caps |= MMC_CAP_UHS_SDR25;
+ if(of_property_read_bool(np, "mmc-cap-uhs-sdr50"))
+ *caps |= MMC_CAP_UHS_SDR50;
+ if(of_property_read_bool(np, "mmc-cap-uhs-sdr104"))
+ *caps |= MMC_CAP_UHS_SDR104;
+ if(of_property_read_bool(np, "mmc-cap-uhs-ddr50"))
+ *caps |= MMC_CAP_UHS_DDR50;
+ if(of_property_read_bool(np, "mmc-cap-driver-type-a"))
+ *caps |= MMC_CAP_DRIVER_TYPE_A;
+ if(of_property_read_bool(np, "mmc-cap-driver-type-c"))
+ *caps |= MMC_CAP_DRIVER_TYPE_C;
+ if(of_property_read_bool(np, "mmc-cap-driver-type-d"))
+ *caps |= MMC_CAP_DRIVER_TYPE_D;
+ if(of_property_read_bool(np, "mmc-cap-cmd23"))
+ *caps |= MMC_CAP_CMD23;
+ if(of_property_read_bool(np, "mmc-cap-hw-reset"))
+ *caps |= MMC_CAP_HW_RESET;
+
+ if(of_property_read_bool(np, "mmc-cap2-bootpart-noacc"))
+ *caps2 |= MMC_CAP2_BOOTPART_NOACC;
+ if(of_property_read_bool(np, "mmc-cap2-cache-ctrl"))
+ *caps2 |= MMC_CAP2_CACHE_CTRL;
+ if(of_property_read_bool(np, "mmc-cap2-poweroff-notify"))
+ *caps2 |= MMC_CAP2_POWEROFF_NOTIFY;
+ if(of_property_read_bool(np, "mmc-cap2-no-multi-read"))
+ *caps2 |= MMC_CAP2_NO_MULTI_READ;
+ if(of_property_read_bool(np, "mmc-cap2-no-sleep-cmd"))
+ *caps2 |= MMC_CAP2_NO_SLEEP_CMD;
+ if(of_property_read_bool(np, "mmc-cap2-hs200-1-8v-sdr"))
+ *caps2 |= MMC_CAP2_HS200_1_8V_SDR;
+ if(of_property_read_bool(np, "mmc-cap2-hs200-1-2v-sdr"))
+ *caps2 |= MMC_CAP2_HS200_1_2V_SDR;
+ if(of_property_read_bool(np, "mmc-cap2-hs200"))
+ *caps2 |= MMC_CAP2_HS200;
+ if(of_property_read_bool(np, "mmc-cap2-broken-voltage"))
+ *caps2 |= MMC_CAP2_BROKEN_VOLTAGE;
+ if(of_property_read_bool(np, "mmc-cap2-detect-on-err"))
+ *caps2 |= MMC_CAP2_DETECT_ON_ERR;
+ if(of_property_read_bool(np, "mmc-cap2-hc-erase-sz"))
+ *caps2 |= MMC_CAP2_HC_ERASE_SZ;
+ if(of_property_read_bool(np, "mmc-cap2-cd-active-high"))
+ *caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+ if(of_property_read_bool(np, "mmc-cap2-ro-active-high"))
+ *caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+}
+
+EXPORT_SYMBOL(mmc_of_populate_caps);
@@ -344,7 +344,8 @@ extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
extern int mmc_add_host(struct mmc_host *);
extern void mmc_remove_host(struct mmc_host *);
extern void mmc_free_host(struct mmc_host *);
-
+extern void mmc_of_populate_caps(struct device_node *,
+ unsigned long *, unsigned int *);
static inline void *mmc_priv(struct mmc_host *host)
{
return (void *)host->private;