diff options
author | Rajendra Nayak <rnayak@ti.com> | 2012-03-12 11:02:37 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-03-27 12:20:09 -0400 |
commit | 46856a68dcb5f67c779d211fd6bcb5d7a2a7f19b (patch) | |
tree | 9c89099550263e3b4d7178d3869f6fcdb0d0ab5b | |
parent | f3c55a7b5d7f2d40c805a62174bb733b55875523 (diff) |
mmc: omap_hsmmc: Convert hsmmc driver to use device tree
Define dt bindings for the ti-omap-hsmmc, and adapt the driver to extract
data (which was earlier passed as platform_data) from device tree.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | 33 | ||||
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 73 |
2 files changed, 106 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt new file mode 100644 index 000000000000..dbd4368ab8cc --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | |||
@@ -0,0 +1,33 @@ | |||
1 | * TI Highspeed MMC host controller for OMAP | ||
2 | |||
3 | The Highspeed MMC Host Controller on TI OMAP family | ||
4 | provides an interface for MMC, SD, and SDIO types of memory cards. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: | ||
8 | Should be "ti,omap2-hsmmc", for OMAP2 controllers | ||
9 | Should be "ti,omap3-hsmmc", for OMAP3 controllers | ||
10 | Should be "ti,omap4-hsmmc", for OMAP4 controllers | ||
11 | - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1 | ||
12 | - reg : should contain hsmmc registers location and length | ||
13 | |||
14 | Optional properties: | ||
15 | ti,dual-volt: boolean, supports dual voltage cards | ||
16 | <supply-name>-supply: phandle to the regulator device tree node | ||
17 | "supply-name" examples are "vmmc", "vmmc_aux" etc | ||
18 | ti,bus-width: Number of data lines, default assumed is 1 if the property is missing. | ||
19 | cd-gpios: GPIOs for card detection | ||
20 | wp-gpios: GPIOs for write protection | ||
21 | ti,non-removable: non-removable slot (like eMMC) | ||
22 | ti,needs-special-reset: Requires a special softreset sequence | ||
23 | |||
24 | Example: | ||
25 | mmc1: mmc@0x4809c000 { | ||
26 | compatible = "ti,omap4-hsmmc"; | ||
27 | reg = <0x4809c000 0x400>; | ||
28 | ti,hwmods = "mmc1"; | ||
29 | ti,dual-volt; | ||
30 | ti,bus-width = <4>; | ||
31 | vmmc-supply = <&vmmc>; /* phandle to regulator node */ | ||
32 | ti,non-removable; | ||
33 | }; | ||
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 0306aea329d4..e0808d4a7681 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -26,6 +26,9 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/of.h> | ||
30 | #include <linux/of_gpio.h> | ||
31 | #include <linux/of_device.h> | ||
29 | #include <linux/mmc/host.h> | 32 | #include <linux/mmc/host.h> |
30 | #include <linux/mmc/core.h> | 33 | #include <linux/mmc/core.h> |
31 | #include <linux/mmc/mmc.h> | 34 | #include <linux/mmc/mmc.h> |
@@ -1710,6 +1713,65 @@ static void omap_hsmmc_debugfs(struct mmc_host *mmc) | |||
1710 | 1713 | ||
1711 | #endif | 1714 | #endif |
1712 | 1715 | ||
1716 | #ifdef CONFIG_OF | ||
1717 | static u16 omap4_reg_offset = 0x100; | ||
1718 | |||
1719 | static const struct of_device_id omap_mmc_of_match[] = { | ||
1720 | { | ||
1721 | .compatible = "ti,omap2-hsmmc", | ||
1722 | }, | ||
1723 | { | ||
1724 | .compatible = "ti,omap3-hsmmc", | ||
1725 | }, | ||
1726 | { | ||
1727 | .compatible = "ti,omap4-hsmmc", | ||
1728 | .data = &omap4_reg_offset, | ||
1729 | }, | ||
1730 | {}, | ||
1731 | } | ||
1732 | MODULE_DEVICE_TABLE(of, omap_mmc_of_match); | ||
1733 | |||
1734 | static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | ||
1735 | { | ||
1736 | struct omap_mmc_platform_data *pdata; | ||
1737 | struct device_node *np = dev->of_node; | ||
1738 | u32 bus_width; | ||
1739 | |||
1740 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
1741 | if (!pdata) | ||
1742 | return NULL; /* out of memory */ | ||
1743 | |||
1744 | if (of_find_property(np, "ti,dual-volt", NULL)) | ||
1745 | pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; | ||
1746 | |||
1747 | /* This driver only supports 1 slot */ | ||
1748 | pdata->nr_slots = 1; | ||
1749 | pdata->slots[0].switch_pin = of_get_named_gpio(np, "cd-gpios", 0); | ||
1750 | pdata->slots[0].gpio_wp = of_get_named_gpio(np, "wp-gpios", 0); | ||
1751 | |||
1752 | if (of_find_property(np, "ti,non-removable", NULL)) { | ||
1753 | pdata->slots[0].nonremovable = true; | ||
1754 | pdata->slots[0].no_regulator_off_init = true; | ||
1755 | } | ||
1756 | of_property_read_u32(np, "ti,bus-width", &bus_width); | ||
1757 | if (bus_width == 4) | ||
1758 | pdata->slots[0].caps |= MMC_CAP_4_BIT_DATA; | ||
1759 | else if (bus_width == 8) | ||
1760 | pdata->slots[0].caps |= MMC_CAP_8_BIT_DATA; | ||
1761 | |||
1762 | if (of_find_property(np, "ti,needs-special-reset", NULL)) | ||
1763 | pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET; | ||
1764 | |||
1765 | return pdata; | ||
1766 | } | ||
1767 | #else | ||
1768 | static inline struct omap_mmc_platform_data | ||
1769 | *of_get_hsmmc_pdata(struct device *dev) | ||
1770 | { | ||
1771 | return NULL; | ||
1772 | } | ||
1773 | #endif | ||
1774 | |||
1713 | static int __init omap_hsmmc_probe(struct platform_device *pdev) | 1775 | static int __init omap_hsmmc_probe(struct platform_device *pdev) |
1714 | { | 1776 | { |
1715 | struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; | 1777 | struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; |
@@ -1717,6 +1779,16 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1717 | struct omap_hsmmc_host *host = NULL; | 1779 | struct omap_hsmmc_host *host = NULL; |
1718 | struct resource *res; | 1780 | struct resource *res; |
1719 | int ret, irq; | 1781 | int ret, irq; |
1782 | const struct of_device_id *match; | ||
1783 | |||
1784 | match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); | ||
1785 | if (match) { | ||
1786 | pdata = of_get_hsmmc_pdata(&pdev->dev); | ||
1787 | if (match->data) { | ||
1788 | u16 *offsetp = match->data; | ||
1789 | pdata->reg_offset = *offsetp; | ||
1790 | } | ||
1791 | } | ||
1720 | 1792 | ||
1721 | if (pdata == NULL) { | 1793 | if (pdata == NULL) { |
1722 | dev_err(&pdev->dev, "Platform Data is missing\n"); | 1794 | dev_err(&pdev->dev, "Platform Data is missing\n"); |
@@ -2122,6 +2194,7 @@ static struct platform_driver omap_hsmmc_driver = { | |||
2122 | .name = DRIVER_NAME, | 2194 | .name = DRIVER_NAME, |
2123 | .owner = THIS_MODULE, | 2195 | .owner = THIS_MODULE, |
2124 | .pm = &omap_hsmmc_dev_pm_ops, | 2196 | .pm = &omap_hsmmc_dev_pm_ops, |
2197 | .of_match_table = of_match_ptr(omap_mmc_of_match), | ||
2125 | }, | 2198 | }, |
2126 | }; | 2199 | }; |
2127 | 2200 | ||