diff options
author | Peter Robinson <pbrobinson@gmail.com> | 2013-09-04 02:43:18 +0100 |
---|---|---|
committer | Peter Robinson <pbrobinson@gmail.com> | 2013-09-04 02:43:18 +0100 |
commit | bad69a54fc999f7ed3871b472a31c1a760ed1e81 (patch) | |
tree | 16a0df217b495c859746080ca7f3cc4e1ff26366 /0002-omap_hsmmc-Add-reset-gpio.patch | |
parent | 7ad7e4c4014b96bb176b000b8be71063cf5fc60f (diff) | |
download | kernel-bad69a54fc999f7ed3871b472a31c1a760ed1e81.tar.gz kernel-bad69a54fc999f7ed3871b472a31c1a760ed1e81.tar.xz kernel-bad69a54fc999f7ed3871b472a31c1a760ed1e81.zip |
Add patch set to fix MMC on AM33xx, Add basic support for BeagleBone Black
Diffstat (limited to '0002-omap_hsmmc-Add-reset-gpio.patch')
-rw-r--r-- | 0002-omap_hsmmc-Add-reset-gpio.patch | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/0002-omap_hsmmc-Add-reset-gpio.patch b/0002-omap_hsmmc-Add-reset-gpio.patch new file mode 100644 index 000000000..ea686e78e --- /dev/null +++ b/0002-omap_hsmmc-Add-reset-gpio.patch @@ -0,0 +1,138 @@ +From 364d4535955f21a8ce13e969aedde946a2d566b8 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <panto@antoniou-consulting.com> +Date: Fri, 30 Nov 2012 12:18:16 +0200 +Subject: [PATCH 2/2] omap_hsmmc: Add reset gpio + +Add a gpio property for controlling reset of the mmc device. +eMMC on the beaglebone black requires it. + +Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com> +--- + drivers/mmc/host/omap_hsmmc.c | 40 +++++++++++++++++++++++++++++++++- + include/linux/platform_data/mmc-omap.h | 3 +++ + 2 files changed, 42 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c +index 8ab4a93..1fe7469 100644 +--- a/drivers/mmc/host/omap_hsmmc.c ++++ b/drivers/mmc/host/omap_hsmmc.c +@@ -40,6 +40,8 @@ + #include <linux/pinctrl/consumer.h> + #include <linux/pm_runtime.h> + #include <linux/platform_data/mmc-omap.h> ++#include <linux/pinctrl/consumer.h> ++#include <linux/err.h> + + /* OMAP HSMMC Host Controller Registers */ + #define OMAP_HSMMC_SYSSTATUS 0x0014 +@@ -396,6 +398,7 @@ static inline int omap_hsmmc_have_reg(void) + static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) + { + int ret; ++ unsigned long flags; + + if (gpio_is_valid(pdata->slots[0].switch_pin)) { + if (pdata->slots[0].cover) +@@ -425,6 +428,24 @@ static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata) + } else + pdata->slots[0].gpio_wp = -EINVAL; + ++ if (gpio_is_valid(pdata->slots[0].gpio_reset)) { ++ flags = pdata->slots[0].gpio_reset_active_low ? ++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; ++ ret = gpio_request_one(pdata->slots[0].gpio_reset, flags, ++ "mmc_reset"); ++ if (ret) ++ goto err_free_wp; ++ ++ /* hold reset */ ++ udelay(pdata->slots[0].gpio_reset_hold_us); ++ ++ gpio_set_value(pdata->slots[0].gpio_reset, ++ !pdata->slots[0].gpio_reset_active_low); ++ ++ } else ++ pdata->slots[0].gpio_reset = -EINVAL; ++ ++ + return 0; + + err_free_wp: +@@ -438,6 +459,8 @@ err_free_sp: + + static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata) + { ++ if (gpio_is_valid(pdata->slots[0].gpio_reset)) ++ gpio_free(pdata->slots[0].gpio_reset); + if (gpio_is_valid(pdata->slots[0].gpio_wp)) + gpio_free(pdata->slots[0].gpio_wp); + if (gpio_is_valid(pdata->slots[0].switch_pin)) +@@ -792,7 +815,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, + * ac, bc, adtc, bcr. Only commands ending an open ended transfer need + * a val of 0x3, rest 0x0. + */ +- if (cmd == host->mrq->stop) ++ if (host->mrq && cmd == host->mrq->stop) + cmdtype = 0x3; + + cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); +@@ -835,6 +858,8 @@ static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_req + int completed; + unsigned long flags; + ++ BUG_ON(mrq == NULL); ++ + spin_lock_irqsave(&host->irq_lock, flags); + + host->req_flags &= ~RQF_REQ_IN_PROGRESS; +@@ -1775,6 +1800,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) + struct device_node *np = dev->of_node; + u32 bus_width, max_freq; + int cd_gpio, wp_gpio; ++ enum of_gpio_flags reset_flags; + + cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); + wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); +@@ -1792,6 +1818,14 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) + pdata->nr_slots = 1; + pdata->slots[0].switch_pin = cd_gpio; + pdata->slots[0].gpio_wp = wp_gpio; ++ reset_flags = 0; ++ pdata->slots[0].gpio_reset = of_get_named_gpio_flags(np, ++ "reset-gpios", 0, &reset_flags); ++ pdata->slots[0].gpio_reset_active_low = ++ (reset_flags & OF_GPIO_ACTIVE_LOW) != 0; ++ pdata->slots[0].gpio_reset_hold_us = 100; /* default */ ++ of_property_read_u32(np, "reset-gpio-hold-us", ++ &pdata->slots[0].gpio_reset_hold_us); + + if (of_find_property(np, "ti,non-removable", NULL)) { + pdata->slots[0].nonremovable = true; +@@ -1858,6 +1892,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev) + return -ENXIO; + } + ++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); ++ if (IS_ERR(pinctrl)) ++ dev_warn(&pdev->dev, "unable to select pin group\n"); ++ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (res == NULL || irq < 0) +diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h +index 2bf1b30..d548994 100644 +--- a/include/linux/platform_data/mmc-omap.h ++++ b/include/linux/platform_data/mmc-omap.h +@@ -115,6 +115,9 @@ struct omap_mmc_platform_data { + + int switch_pin; /* gpio (card detect) */ + int gpio_wp; /* gpio (write protect) */ ++ int gpio_reset; /* gpio (reset) */ ++ int gpio_reset_active_low; /* 1 if reset is active low */ ++ u32 gpio_reset_hold_us; /* time to hold in us */ + + int (*set_bus_mode)(struct device *dev, int slot, int bus_mode); + int (*set_power)(struct device *dev, int slot, +-- +1.8.2.1 + |