aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:03:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:03:16 -0500
commit3a43aaa31790c36b69ebf8a6396f37fade86b531 (patch)
tree7c7f8da6219d546f2b44534cb7be1fb5591d6ac4 /drivers/mfd
parentaed886ce777590eac87f7ce2897d9f8357754331 (diff)
parent6a5a0b9139b19dd1a107870269a35bc9cf18d2dc (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (137 commits) sh: include empty zero page in romImage sh: Make associative cache writes fatal on all SH-4A parts. sh: Drop associative writes for SH-4 cache flushes. sh: Partial revert of copy/clear_user_highpage() optimizations. sh: Add default uImage rule for se7724, ap325rxa, and migor. sh: allow runtime pm without suspend/resume callbacks sh: mach-ecovec24: Remove un-defined settings for VPU sh: mach-ecovec24: LCDC drive ability become high sh: fix sh7724 VEU3F resource size serial: sh-sci: Fix too early port disabling. sh: pfc: pr_info() -> pr_debug() cleanups. sh: pfc: Convert from ctrl_xxx() to __raw_xxx() I/O routines. sh: Improve kfr2r09 serial port setup code sh: Break out SuperH PFC code sh: Move KEYSC header file sh: convert /proc/cpu/aligmnent, /proc/cpu/kernel_alignment to seq_file sh: Add CPG save/restore code for sh7724 R-standby sh: Add SDHI power control support to Ecovec mfd: Add power control platform data to SDHI driver sh: mach-ecovec24: modify address map ...
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig8
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/sh_mobile_sdhi.c156
3 files changed, 165 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 08f2d07bf56a..a296e717e86e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -35,6 +35,14 @@ config MFD_ASIC3
35 This driver supports the ASIC3 multifunction chip found on many 35 This driver supports the ASIC3 multifunction chip found on many
36 PDAs (mainly iPAQ and HTC based ones) 36 PDAs (mainly iPAQ and HTC based ones)
37 37
38config MFD_SH_MOBILE_SDHI
39 bool "Support for SuperH Mobile SDHI"
40 depends on SUPERH
41 select MFD_CORE
42 ---help---
43 This driver supports the SDHI hardware block found in many
44 SuperH Mobile SoCs.
45
38config MFD_DM355EVM_MSP 46config MFD_DM355EVM_MSP
39 bool "DaVinci DM355 EVM microcontroller" 47 bool "DaVinci DM355 EVM microcontroller"
40 depends on I2C && MACH_DAVINCI_DM355_EVM 48 depends on I2C && MACH_DAVINCI_DM355_EVM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index af0fc903cec8..11350c1d9301 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_MFD_SM501) += sm501.o 5obj-$(CONFIG_MFD_SM501) += sm501.o
6obj-$(CONFIG_MFD_ASIC3) += asic3.o 6obj-$(CONFIG_MFD_ASIC3) += asic3.o
7obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
7 8
8obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 9obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
9obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 10obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
new file mode 100644
index 000000000000..03efae8041ab
--- /dev/null
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -0,0 +1,156 @@
1/*
2 * SuperH Mobile SDHI
3 *
4 * Copyright (C) 2009 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Based on "Compaq ASIC3 support":
11 *
12 * Copyright 2001 Compaq Computer Corporation.
13 * Copyright 2004-2005 Phil Blundell
14 * Copyright 2007-2008 OpenedHand Ltd.
15 *
16 * Authors: Phil Blundell <pb@handhelds.org>,
17 * Samuel Ortiz <sameo@openedhand.com>
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24
25#include <linux/mfd/core.h>
26#include <linux/mfd/tmio.h>
27#include <linux/mfd/sh_mobile_sdhi.h>
28
29struct sh_mobile_sdhi {
30 struct clk *clk;
31 struct tmio_mmc_data mmc_data;
32 struct mfd_cell cell_mmc;
33};
34
35static struct resource sh_mobile_sdhi_resources[] = {
36 {
37 .start = 0x000,
38 .end = 0x1ff,
39 .flags = IORESOURCE_MEM,
40 },
41 {
42 .start = 0,
43 .end = 0,
44 .flags = IORESOURCE_IRQ,
45 },
46};
47
48static struct mfd_cell sh_mobile_sdhi_cell = {
49 .name = "tmio-mmc",
50 .num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
51 .resources = sh_mobile_sdhi_resources,
52};
53
54static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state)
55{
56 struct platform_device *pdev = to_platform_device(tmio->dev.parent);
57 struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
58
59 if (p && p->set_pwr)
60 p->set_pwr(pdev, state);
61}
62
63static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
64{
65 struct sh_mobile_sdhi *priv;
66 struct resource *mem;
67 char clk_name[8];
68 int ret, irq;
69
70 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
71 if (!mem)
72 dev_err(&pdev->dev, "missing MEM resource\n");
73
74 irq = platform_get_irq(pdev, 0);
75 if (irq < 0)
76 dev_err(&pdev->dev, "missing IRQ resource\n");
77
78 if (!mem || (irq < 0))
79 return -EINVAL;
80
81 priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
82 if (priv == NULL) {
83 dev_err(&pdev->dev, "kzalloc failed\n");
84 return -ENOMEM;
85 }
86
87 snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
88 priv->clk = clk_get(&pdev->dev, clk_name);
89 if (IS_ERR(priv->clk)) {
90 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
91 ret = PTR_ERR(priv->clk);
92 kfree(priv);
93 return ret;
94 }
95
96 clk_enable(priv->clk);
97
98 /* FIXME: silly const unsigned int hclk */
99 *(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
100 priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr;
101
102 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
103 priv->cell_mmc.driver_data = &priv->mmc_data;
104 priv->cell_mmc.platform_data = &priv->cell_mmc;
105 priv->cell_mmc.data_size = sizeof(priv->cell_mmc);
106
107 platform_set_drvdata(pdev, priv);
108
109 ret = mfd_add_devices(&pdev->dev, pdev->id,
110 &priv->cell_mmc, 1, mem, irq);
111 if (ret) {
112 clk_disable(priv->clk);
113 clk_put(priv->clk);
114 kfree(priv);
115 }
116
117 return ret;
118}
119
120static int sh_mobile_sdhi_remove(struct platform_device *pdev)
121{
122 struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);
123
124 mfd_remove_devices(&pdev->dev);
125 clk_disable(priv->clk);
126 clk_put(priv->clk);
127 kfree(priv);
128
129 return 0;
130}
131
132static struct platform_driver sh_mobile_sdhi_driver = {
133 .driver = {
134 .name = "sh_mobile_sdhi",
135 .owner = THIS_MODULE,
136 },
137 .probe = sh_mobile_sdhi_probe,
138 .remove = __devexit_p(sh_mobile_sdhi_remove),
139};
140
141static int __init sh_mobile_sdhi_init(void)
142{
143 return platform_driver_register(&sh_mobile_sdhi_driver);
144}
145
146static void __exit sh_mobile_sdhi_exit(void)
147{
148 platform_driver_unregister(&sh_mobile_sdhi_driver);
149}
150
151module_init(sh_mobile_sdhi_init);
152module_exit(sh_mobile_sdhi_exit);
153
154MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
155MODULE_AUTHOR("Magnus Damm");
156MODULE_LICENSE("GPL v2");