diff --git a/patch.sh b/patch.sh index a351b426..e2549d51 100755 --- a/patch.sh +++ b/patch.sh @@ -144,3 +144,11 @@ if [ -e ${DIR}/kernel/am335x-pm-firmware.bin ] ; then cp ${DIR}/kernel/am335x-pm-firmware.bin ${EXPORTPATH}-oe/recipes-kernel/linux/${RECIPEDIR}/ fi +#Added to support in applying the bbb_wl18xx patch files +cd $DIR +echo "Applying patch configs/beaglebone for WL18xx on BBB" +git apply patches/bbb_wl18xx/0001-beaglebone-defconfig-changes-to-support-wl18xx-on-bbb.patch +echo "Applying kernel patches for WL18xx on BBB" +cd ${DIR}/kernel +git apply ${DIR}/patches/bbb_wl18xx/0002.mmc-dts-changes-to-support-wl18xx-on-bbb.patch +echo "Done applying WL18xx patches" diff --git a/patches/bbb_wl18xx/0001-beaglebone-defconfig-changes-to-support-wl18xx-on-bbb.patch b/patches/bbb_wl18xx/0001-beaglebone-defconfig-changes-to-support-wl18xx-on-bbb.patch new file mode 100644 index 00000000..9ea5c755 --- /dev/null +++ b/patches/bbb_wl18xx/0001-beaglebone-defconfig-changes-to-support-wl18xx-on-bbb.patch @@ -0,0 +1,130 @@ +From d0edc04e0d4961c4c628f56b9e2674cd4fa2fe39 Mon Sep 17 00:00:00 2001 +From: soma +Date: Fri, 13 Dec 2013 15:50:00 +0530 +Subject: [PATCH] Supported wl18xx on beaglebone black platform + +--- + configs/beaglebone | 34 ++++++++++++++++++++-------------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +diff --git a/configs/beaglebone b/configs/beaglebone +index 343f298..b9bcf72 100644 +--- a/configs/beaglebone ++++ b/configs/beaglebone +@@ -703,9 +703,10 @@ CONFIG_BRIDGE_NETFILTER=y + # CONFIG_NETFILTER_NETLINK_ACCT is not set + # CONFIG_NETFILTER_NETLINK_QUEUE is not set + # CONFIG_NETFILTER_NETLINK_LOG is not set +-# CONFIG_NF_CONNTRACK is not set ++CONFIG_NF_CONNTRACK=y ++CONFIG_NF_CONNTRACK_PROC_COMPAT=y + # CONFIG_NETFILTER_TPROXY is not set +-CONFIG_NETFILTER_XTABLES=m ++CONFIG_NETFILTER_XTABLES=y + + # + # Xtables combined modules +@@ -807,15 +808,20 @@ CONFIG_IP_VS_SH_TAB_BITS=8 + # + # IP: Netfilter Configuration + # +-# CONFIG_NF_DEFRAG_IPV4 is not set ++CONFIG_NF_NAT=y ++CONFIG_NF_NAT_NEEDED=y ++CONFIG_IP_NF_TARGET_MASQUERADE=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_NF_DEFRAG_IPV4=y + CONFIG_IP_NF_QUEUE=m +-CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_IPTABLES=y + CONFIG_IP_NF_MATCH_AH=m + CONFIG_IP_NF_MATCH_ECN=m + CONFIG_IP_NF_MATCH_RPFILTER=m + CONFIG_IP_NF_MATCH_TTL=m +-CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_FILTER=y + CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_TARGET_LOG=y + CONFIG_IP_NF_TARGET_ULOG=m + CONFIG_IP_NF_MANGLE=m + CONFIG_IP_NF_TARGET_ECN=m +@@ -855,15 +861,15 @@ CONFIG_IP6_NF_SECURITY=m + CONFIG_L2TP=m + CONFIG_L2TP_DEBUGFS=m + # CONFIG_L2TP_V3 is not set +-CONFIG_STP=m ++CONFIG_STP=y + CONFIG_GARP=m +-CONFIG_BRIDGE=m ++CONFIG_BRIDGE=y + CONFIG_BRIDGE_IGMP_SNOOPING=y + CONFIG_HAVE_NET_DSA=y + CONFIG_VLAN_8021Q=m + CONFIG_VLAN_8021Q_GVRP=y + # CONFIG_DECNET is not set +-CONFIG_LLC=m ++CONFIG_LLC=y + # CONFIG_LLC2 is not set + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +@@ -1079,7 +1085,7 @@ CONFIG_MAC80211_DEBUGFS=y + # CONFIG_MAC80211_DEBUG_MENU is not set + CONFIG_WIMAX=m + CONFIG_WIMAX_DEBUG_LEVEL=8 +-CONFIG_RFKILL=m ++CONFIG_RFKILL=y + CONFIG_RFKILL_LEDS=y + CONFIG_RFKILL_INPUT=y + CONFIG_RFKILL_REGULATOR=m +@@ -1324,7 +1330,7 @@ CONFIG_EEPROM_93CX6=y + # + # Texas Instruments shared transport line discipline + # +-CONFIG_TI_ST=m ++CONFIG_TI_ST=y + # CONFIG_SENSORS_LIS3_SPI is not set + # CONFIG_SENSORS_LIS3_I2C is not set + +@@ -1767,7 +1773,7 @@ CONFIG_INPUT_MISC=y + # CONFIG_INPUT_CM109 is not set + CONFIG_INPUT_TWL4030_PWRBUTTON=y + # CONFIG_INPUT_TWL4030_VIBRA is not set +-CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_UINPUT=y + # CONFIG_INPUT_PCF8574 is not set + # CONFIG_INPUT_PWM_BEEPER is not set + CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +@@ -2612,7 +2618,6 @@ CONFIG_VIDEO_MT9V011=m + # CONFIG_SOC_CAMERA_IMX074 is not set + CONFIG_SOC_CAMERA_MT9M001=y + CONFIG_SOC_CAMERA_MT9M111=y +-CONFIG_SOC_CAMERA_MT9M114=y + CONFIG_SOC_CAMERA_MT9T031=y + CONFIG_SOC_CAMERA_MT9T112=y + CONFIG_SOC_CAMERA_MT9V022=y +@@ -4188,7 +4193,7 @@ CONFIG_CRYPTO_AUTHENC=m + CONFIG_CRYPTO_CBC=m + # CONFIG_CRYPTO_CTR is not set + # CONFIG_CRYPTO_CTS is not set +-CONFIG_CRYPTO_ECB=m ++CONFIG_CRYPTO_ECB=y + # CONFIG_CRYPTO_LRW is not set + # CONFIG_CRYPTO_PCBC is not set + # CONFIG_CRYPTO_XTS is not set +@@ -4225,7 +4230,7 @@ CONFIG_CRYPTO_SHA256=m + CONFIG_CRYPTO_AES=y + CONFIG_CRYPTO_AES_ARM=y + # CONFIG_CRYPTO_ANUBIS is not set +-CONFIG_CRYPTO_ARC4=m ++CONFIG_CRYPTO_ARC4=y + # CONFIG_CRYPTO_BLOWFISH is not set + # CONFIG_CRYPTO_CAMELLIA is not set + # CONFIG_CRYPTO_CAST5 is not set +@@ -4304,3 +4309,4 @@ CONFIG_CLZ_TAB=y + # CONFIG_DDR is not set + CONFIG_MPILIB=m + CONFIG_OID_REGISTRY=m ++CONTIG_TI_ST=y +-- +1.7.10.4 + diff --git a/patches/bbb_wl18xx/0002.mmc-dts-changes-to-support-wl18xx-on-bbb.patch b/patches/bbb_wl18xx/0002.mmc-dts-changes-to-support-wl18xx-on-bbb.patch new file mode 100644 index 00000000..0ff472c8 --- /dev/null +++ b/patches/bbb_wl18xx/0002.mmc-dts-changes-to-support-wl18xx-on-bbb.patch @@ -0,0 +1,502 @@ +commit a09ee0f0596016f9e464b0d8f4f3aafe8938d3ec +Author: soma +Date: Fri Dec 13 15:36:27 2013 +0530 + + Supporting wl18xx support on beaglebone black platform + +diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt +index a591c67..18778ab 100644 +--- a/Documentation/devicetree/bindings/mmc/mmc.txt ++++ b/Documentation/devicetree/bindings/mmc/mmc.txt +@@ -23,6 +23,10 @@ Optional properties: + - max-frequency: maximum operating clock frequency + - no-1-8-v: when present, denotes that 1.8v card voltage is not supported on + this system, even if the controller claims it is. ++- cap-sd-highspeed: SD high-speed timing is supported ++- cap-mmc-highspeed: MMC high-speed timing is supported ++- cap-power-off-card: powering off the card is safe ++- cap-sdio-irq: enable SDIO IRQ signalling on this interface + + Optional SDIO properties: + - keep-power-in-suspend: Preserves card power during a suspend/resume cycle +diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi +index 89240d0..ac8ccfe 100644 +--- a/arch/arm/boot/dts/am335x-bone-common.dtsi ++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi +@@ -22,10 +22,10 @@ + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; +- ++/*using mmc2pins for enabling wi-Link8 cape on beagle bone black.*/ + am33xx_pinmux: pinmux@44e10800 { + pinctrl-names = "default"; +- pinctrl-0 = <&userled_pins>; ++ pinctrl-0 = <&userled_pins &mmc2_pins>; + + userled_pins: pinmux_userled_pins { + pinctrl-single,pins = < +@@ -35,6 +35,7 @@ + 0x60 0x17 /* gpmc_a8.gpio1_24, OUTPUT_PULLUP | MODE7 */ + >; + }; ++ + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + 0x188 0x70 /* i2c0_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE0 */ +@@ -43,15 +44,58 @@ + }; + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < +- 0x178 0x73 /* uart1_ctsn.i2c2_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */ +- 0x17c 0x73 /* uart1_rtsn.i2c2_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */ ++ 0x17c 0x73 /* uart1_ctsn.i2c2_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */ ++ 0x178 0x73 /* uart1_rtsn.i2c2_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */ + >; + }; ++ ++ + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < +- 0x160 0x2f /* GPIO0_6 (PIN_INPUT | MUX_MODE7) */ ++ 0x160 0x2f //GPIO0_6 (PIN_INPUT | MUX_MODE7) + >; + }; ++ ++/*describe about pin mux configuration for wi-Link8 cape.*/ ++ /* wl12xx/wl18xx card on mmc2 */ ++ mmc2_pins: pinmux_mmc1_pins { ++ pinctrl-single,pins = < ++ 0x7c 0x00 /* BUFFER_EN - P8_26 OUT PUT | MODE0 */ ++ 0x00 0x31 /* dat0 - gpmc_ad0.mmc1_ dat0, INPUT_PULLUP | MODE1 */ ++ 0x04 0x31 /* dat1 - gpmc_ad1.mmc1_ dat1, INPUT_PULLUP | MODE1 */ ++ 0x08 0x31 /* dat2 - gpmc_ad2.mmc1_ dat2, INPUT_PULLUP | MODE1 */ ++ 0x0c 0x31 /* dat3 - gpmc_ad3.mmc1_ dat3, INPUT_PULLUP | MODE1 */ ++ 0x84 0x32 /* CMD - gpmc_csn2.mmc1_ cmd, INPUT_PULLUP | MODE2 */ ++ 0x80 0x32 /* CLK - gpmc_csn1.mmc1_ clk, INPUT_PULLUP | MODE2 */ ++ >; ++ }; ++ }; ++/*power control mechanism is used for turning the WLAN sub system on/off based on system commands*/ ++ wlan_en_reg: fixedregulator@2 { ++ compatible = "regulator-fixed"; ++ regulator-name = "wlan-en-regulator"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ /* WLAN_EN GPIO for this board - Bank3, pin16 */ ++ gpio = <&gpio1 26 0>; ++ ++ /* WLAN card specific delay */ ++ startup-delay-us = <70000>; ++ enable-active-high; ++ }; ++ ++/* setting wlan_irq pin */ ++ wlcore { ++ compatible = "wlcore"; ++ gpio = <27>; /* Bank0, pin27 */ ++ ++ /* use edge irqs for suspend/resume */ ++ platform-quirks = <1>; ++ ++ /* if a 12xx card is there, configure the clock to ++ WL12XX_REFCLOCK_38_XTAL */ ++ board-ref-clock = <4>; + }; + + ocp: ocp { +@@ -118,9 +162,11 @@ + }; + + slots { ++ + slot@0 { + eeprom = <&cape_eeprom0>; + }; ++ + + slot@1 { + eeprom = <&cape_eeprom1>; +@@ -210,8 +256,9 @@ + manufacturer = "Adafruit"; + part-number = "BB-BONE-GPS-01"; + }; +- ++ /*emmc is using mmc2 controller,for wi-link8 we are using mmc2 controller,to avoid*/ + /* Beaglebone black has it soldered on */ ++ /* + slot@100 { + ti,cape-override; + priority = <1>; +@@ -221,8 +268,10 @@ + manufacturer = "Texas Instruments"; + part-number = "BB-BONE-EMMC-2G"; + }; +- ++ */ ++ /*disabling hdmi to avoid hdmi pin-conflict*/ + /* Beaglebone black has it soldered on */ ++ /* + slot@101 { + ti,cape-override; + priority = <1>; +@@ -232,8 +281,10 @@ + manufacturer = "Texas Instruments"; + part-number = "BB-BONELT-HDMI"; + }; ++ */ + + /* Beaglebone black has it soldered on (but no audio) */ ++ /* + slot@102 { + ti,cape-override; + priority = <2>; +@@ -243,7 +294,17 @@ + manufacturer = "Texas Instruments"; + part-number = "BB-BONELT-HDMIN"; + }; +- ++ */ ++ /*Adding wi-link8 cape details*/ ++ /* WiLink8 cape version A0 without an EEPROM */ ++ slot@103 { ++ ti,cape-override; ++ compatible = "kernel-command-line", "runtime"; ++ board-name = "WILINK8"; ++ version = "00A0"; ++ manufacturer = "Texas Instruments"; ++ part-number = "XWL1835MODGA"; ++ }; + }; + + /* mapping between board names and dtb objects */ +@@ -269,16 +330,17 @@ + dtbo = "cape-bone-dvi-00A2.dtbo"; + }; + }; +- ++ /*for wi-link8 mmc2 controller is used,to avoid emmc conflict disabling emmc*/ + /* beaglebone black emmc on board */ +- cape@1 { ++ /* cape@1 { */ + /* board-name = "BeagleBone 2G eMMC1 CAPE"; */ +- part-number = "BB-BONE-EMMC-2G"; ++ /* part-number = "BB-BONE-EMMC-2G"; + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-2g-emmc1.dtbo"; + }; +- }; ++ */ ++ /* }; */ + + /* geiger cape */ + cape@2 { +@@ -312,6 +374,7 @@ + }; + + /* beaglebone black hdmi on board */ ++ /* + cape@5 { + part-number = "BB-BONELT-HDMI"; + version@00A0 { +@@ -319,6 +382,7 @@ + dtbo = "cape-boneblack-hdmi-00A0.dtbo"; + }; + }; ++ */ + + /* nixie cape */ + cape@6 { +@@ -385,6 +449,7 @@ + + + /* beaglebone black hdmi on board (No audio) */ ++ /* + cape@14 { + part-number = "BB-BONELT-HDMIN"; + version@00A0 { +@@ -392,6 +457,8 @@ + dtbo = "cape-boneblack-hdmin-00A0.dtbo"; + }; + }; ++ */ ++ + + /* remain backwards compatible with old EEPROM */ + cape@15 { +@@ -401,6 +468,15 @@ + dtbo = "cape-bebopr-R2.dtbo"; + }; + }; ++ /* To support for Wi-Link8 cape*/ ++ /* WILINK8 cape dtbo file */ ++ cape@16 { ++ part-number = "XWL1835MODGA"; ++ version@00A0 { ++ version = "00A0"; ++ dtbo = "XWL1835MODGA.dtbo"; ++ }; ++ }; + + }; + }; +@@ -518,17 +594,40 @@ + phy_id = <&davinci_mdio>, <1>; + }; + ++ + &mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + bus-width = <0x4>; +- cd-gpios = <&gpio1 6 0>; /* gpio1 is misnamed, 0 == GPIO_ACTIVE_HIGH */ ++ cd-gpios = <&gpio1 6 0>; // gpio1 is misnamed, 0 == GPIO_ACTIVE_HIGH + cd-inverted; + status = "okay"; + vmmc-supply = <&ldo3_reg>; + ti,vcc-aux-disable-is-sleep; + }; + ++/* using mmc2 pins for wi-link8 board*/ ++ ++&mmc2 { ++ /*pinctrl-names = "default"; ++ pinctrl-0 = <&mmc1_pins>;*/ ++ ++ /* these are on the crossbar and are outlined in the ++ xbar-event-map element */ ++/* dmas = <&edma 12 ++ &edma 13>; ++ dma-names = "tx", "rx"; ++*/ ++ status = "okay"; ++ vmmc-supply = <&wlan_en_reg>; ++ bus-width = <4>; ++ ti,non-removable; ++ ti,needs-special-hs-handling; ++ cap-power-off-card; ++ keep-power-in-suspend; ++}; ++ ++ + &edma { + ti,edma-xbar-event-map = <32 12>, /* gpevt2 -> 12 */ + <30 20>; /* xdma_event_intr2 -> 20 */ +diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts +index a7eb55b..288e72d 100644 +--- a/arch/arm/boot/dts/am335x-boneblack.dts ++++ b/arch/arm/boot/dts/am335x-boneblack.dts +@@ -42,16 +42,19 @@ + vmmc-supply = <&vmmcsd_fixed>; + }; + ++/* disabling mmc2 information,though mmc2 is already enabled in the am335x-bone-common.dtsi*/ ++/* + &mmc2 { + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <8>; + ti,non-removable; +- status = "disabled"; +- ++ status = "okay"; ++ pinctrl-names = "default" ++ pinctrl-o = <&mmc2_pins>; + reset = <&rstctl 0 0>; + reset-names = "eMMC_RSTn-CONSUMER"; + }; +- ++*/ + + &cpu { + /* +diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c +index ee2e16b..821cd82 100644 +--- a/drivers/mmc/core/host.c ++++ b/drivers/mmc/core/host.c +@@ -15,6 +15,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -23,6 +25,7 @@ + + #include + #include ++#include + + #include "core.h" + #include "host.h" +@@ -295,6 +298,126 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) + #endif + + /** ++ * mmc_of_parse() - parse host's device-tree node ++ * @host: host whose node should be parsed. ++ * ++ * To keep the rest of the MMC subsystem unaware of whether DT has been ++ * used to to instantiate and configure this host instance or not, we ++ * parse the properties and set respective generic mmc-host flags and ++ * parameters. ++ */ ++void mmc_of_parse(struct mmc_host *host) ++{ ++ struct device_node *np; ++ u32 bus_width; ++ bool explicit_inv_wp, gpio_inv_wp = false; ++ enum of_gpio_flags flags; ++ int len, ret, gpio; ++ ++ if (!host->parent || !host->parent->of_node) ++ return; ++ ++ np = host->parent->of_node; ++ ++ /* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */ ++ if (of_property_read_u32(np, "bus-width", &bus_width) < 0) { ++ dev_dbg(host->parent, ++ "\"bus-width\" property is missing, assuming 1 bit.\n"); ++ bus_width = 1; ++ } ++ ++ switch (bus_width) { ++ case 8: ++ host->caps |= MMC_CAP_8_BIT_DATA; ++ /* Hosts capable of 8-bit transfers can also do 4 bits */ ++ case 4: ++ host->caps |= MMC_CAP_4_BIT_DATA; ++ break; ++ case 1: ++ break; ++ default: ++ dev_err(host->parent, ++ "Invalid \"bus-width\" value %ud!\n", bus_width); ++ } ++ ++ /* f_max is obtained from the optional "max-frequency" property */ ++ of_property_read_u32(np, "max-frequency", &host->f_max); ++ ++ /* ++ * Configure CD and WP pins. They are both by default active low to ++ * match the SDHCI spec. If GPIOs are provided for CD and / or WP, the ++ * mmc-gpio helpers are used to attach, configure and use them. If ++ * polarity inversion is specified in DT, one of MMC_CAP2_CD_ACTIVE_HIGH ++ * and MMC_CAP2_RO_ACTIVE_HIGH capability-2 flags is set. If the ++ * "broken-cd" property is provided, the MMC_CAP_NEEDS_POLL capability ++ * is set. If the "non-removable" property is found, the ++ * MMC_CAP_NONREMOVABLE capability is set and no card-detection ++ * configuration is performed. ++ */ ++ ++ /* Parse Card Detection */ ++ if (of_find_property(np, "non-removable", &len)) { ++ host->caps |= MMC_CAP_NONREMOVABLE; ++ } else { ++ bool explicit_inv_cd, gpio_inv_cd = false; ++ ++ explicit_inv_cd = of_property_read_bool(np, "cd-inverted"); ++ ++ if (of_find_property(np, "broken-cd", &len)) ++ host->caps |= MMC_CAP_NEEDS_POLL; ++ ++ gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags); ++ if (gpio_is_valid(gpio)) { ++ if (!(flags & OF_GPIO_ACTIVE_LOW)) ++ gpio_inv_cd = true; ++ ++ ret = mmc_gpio_request_cd(host, gpio); ++ if (ret < 0) ++ dev_err(host->parent, ++ "Failed to request CD GPIO #%d: %d!\n", ++ gpio, ret); ++ else ++ dev_info(host->parent, "Got CD GPIO #%d.\n", ++ gpio); ++ } ++ ++ if (explicit_inv_cd ^ gpio_inv_cd) ++ host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; ++ } ++ ++ /* Parse Write Protection */ ++ explicit_inv_wp = of_property_read_bool(np, "wp-inverted"); ++ ++ gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags); ++ if (gpio_is_valid(gpio)) { ++ if (!(flags & OF_GPIO_ACTIVE_LOW)) ++ gpio_inv_wp = true; ++ ++ ret = mmc_gpio_request_ro(host, gpio); ++ if (ret < 0) ++ dev_err(host->parent, ++ "Failed to request WP GPIO: %d!\n", ret); ++ } ++ if (explicit_inv_wp ^ gpio_inv_wp) ++ host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; ++ ++ if (of_find_property(np, "cap-sd-highspeed", &len)) ++ host->caps |= MMC_CAP_SD_HIGHSPEED; ++ if (of_find_property(np, "cap-mmc-highspeed", &len)) ++ host->caps |= MMC_CAP_MMC_HIGHSPEED; ++ if (of_find_property(np, "cap-power-off-card", &len)) ++ host->caps |= MMC_CAP_POWER_OFF_CARD; ++ if (of_find_property(np, "cap-sdio-irq", &len)) ++ host->caps |= MMC_CAP_SDIO_IRQ; ++ if (of_find_property(np, "keep-power-in-suspend", &len)) ++ host->pm_caps |= MMC_PM_KEEP_POWER; ++ if (of_find_property(np, "enable-sdio-wakeup", &len)) ++ host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; ++} ++ ++EXPORT_SYMBOL(mmc_of_parse); ++ ++/** + * mmc_alloc_host - initialise the per-host structure. + * @extra: sizeof private data structure + * @dev: pointer to host device model structure +diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c +index 04daf72..9019fef 100644 +--- a/drivers/mmc/host/omap_hsmmc.c ++++ b/drivers/mmc/host/omap_hsmmc.c +@@ -265,8 +265,10 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, + * With DT, never turn OFF the regulator. This is because + * the pbias cell programming support is still missing when + * booting with Device tree ++ * To support slots which are not affected by the above missing ++ * functionally, power down if MMC_CAP_POWER_OFF_CARD is set. + */ +- if (dev->of_node && !vdd) ++ if (dev->of_node && !vdd && !(host->mmc->caps & MMC_CAP_POWER_OFF_CARD)) + return 0; + + if (mmc_slot(host).before_set_reg) +@@ -1779,6 +1781,12 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) + else if (bus_width == 8) + pdata->slots[0].caps |= MMC_CAP_8_BIT_DATA; + ++ if (of_find_property(np, "cap-power-off-card", NULL)) ++ pdata->slots[0].caps |= MMC_CAP_POWER_OFF_CARD; ++ ++ if (of_find_property(np, "keep-power-in-suspend", NULL)) ++ pdata->slots[0].pm_caps |= MMC_PM_KEEP_POWER; ++ + if (of_find_property(np, "ti,needs-special-reset", NULL)) + pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET; + +diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h +index 61a10c1..13c0c8d 100644 +--- a/include/linux/mmc/host.h ++++ b/include/linux/mmc/host.h +@@ -345,6 +345,7 @@ 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 *); ++void mmc_of_parse(struct mmc_host *host); + + static inline void *mmc_priv(struct mmc_host *host) + {