aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/tc6387xb.c
diff options
context:
space:
mode:
authorIan Molton <spyro@f2s.com>2008-07-15 10:12:52 -0400
committerSamuel Ortiz <sameo@openedhand.com>2008-08-10 14:09:55 -0400
commitcbdfb426392557d49b1a0e7cb59b16c20dc42955 (patch)
treec012fcaff3114613050536e421a353184dff14ef /drivers/mfd/tc6387xb.c
parent1f192015ca5b2f4d0a79c191f03f64e72fd8fc29 (diff)
mfd: driver for the TC6387XB TMIO controller.
This patch adds support for the TC6387XB. Unlike other TMIO devices this one has only one subdevice and no interrupt mux, however using the MFD framework allows it to share the TMIO MMC driver. Signed-off-by: Ian Molton <spyro@f2s.com> Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
Diffstat (limited to 'drivers/mfd/tc6387xb.c')
-rw-r--r--drivers/mfd/tc6387xb.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
new file mode 100644
index 000000000000..03718feda4d8
--- /dev/null
+++ b/drivers/mfd/tc6387xb.c
@@ -0,0 +1,172 @@
1/*
2 * Toshiba TC6387XB support
3 * Copyright (c) 2005 Ian Molton
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This file contains TC6387XB base support.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/err.h>
16#include <linux/mfd/core.h>
17#include <linux/mfd/tmio.h>
18#include <linux/mfd/tc6387xb.h>
19
20#ifdef CONFIG_PM
21static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
22{
23 struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
24
25 if (pdata && pdata->suspend)
26 pdata->suspend(dev);
27
28 return 0;
29}
30
31static int tc6387xb_resume(struct platform_device *dev)
32{
33 struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
34
35 if (pdata && pdata->resume)
36 pdata->resume(dev);
37
38 return 0;
39}
40#else
41#define tc6387xb_suspend NULL
42#define tc6387xb_resume NULL
43#endif
44
45/*--------------------------------------------------------------------------*/
46
47static int tc6387xb_mmc_enable(struct platform_device *mmc)
48{
49 struct platform_device *dev = to_platform_device(mmc->dev.parent);
50 struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
51
52 if (tc6387xb->enable_clk32k)
53 tc6387xb->enable_clk32k(dev);
54
55 return 0;
56}
57
58static int tc6387xb_mmc_disable(struct platform_device *mmc)
59{
60 struct platform_device *dev = to_platform_device(mmc->dev.parent);
61 struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
62
63 if (tc6387xb->disable_clk32k)
64 tc6387xb->disable_clk32k(dev);
65
66 return 0;
67}
68
69/*--------------------------------------------------------------------------*/
70
71static struct resource tc6387xb_mmc_resources[] = {
72 {
73 .start = 0x800,
74 .end = 0x9ff,
75 .flags = IORESOURCE_MEM,
76 },
77 {
78 .start = 0x200,
79 .end = 0x2ff,
80 .flags = IORESOURCE_MEM,
81 },
82 {
83 .start = 0,
84 .end = 0,
85 .flags = IORESOURCE_IRQ,
86 },
87};
88
89static struct mfd_cell tc6387xb_cells[] = {
90 {
91 .name = "tmio-mmc",
92 .enable = tc6387xb_mmc_enable,
93 .disable = tc6387xb_mmc_disable,
94 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
95 .resources = tc6387xb_mmc_resources,
96 },
97};
98
99static int tc6387xb_probe(struct platform_device *dev)
100{
101 struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
102 struct resource *iomem;
103 int irq, ret;
104
105 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
106 if (!iomem) {
107 ret = -EINVAL;
108 goto err_resource;
109 }
110
111 ret = platform_get_irq(dev, 0);
112 if (ret >= 0)
113 irq = ret;
114 else
115 goto err_resource;
116
117 if (data && data->enable)
118 data->enable(dev);
119
120 printk(KERN_INFO "Toshiba tc6387xb initialised\n");
121
122 ret = mfd_add_devices(dev, tc6387xb_cells,
123 ARRAY_SIZE(tc6387xb_cells), iomem, irq);
124
125 if (!ret)
126 return 0;
127
128err_resource:
129 return ret;
130}
131
132static int tc6387xb_remove(struct platform_device *dev)
133{
134 struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
135
136 if (data && data->disable)
137 data->disable(dev);
138
139 /* FIXME - free the resources! */
140
141 return 0;
142}
143
144
145static struct platform_driver tc6387xb_platform_driver = {
146 .driver = {
147 .name = "tc6387xb",
148 },
149 .probe = tc6387xb_probe,
150 .remove = tc6387xb_remove,
151 .suspend = tc6387xb_suspend,
152 .resume = tc6387xb_resume,
153};
154
155
156static int __init tc6387xb_init(void)
157{
158 return platform_driver_register(&tc6387xb_platform_driver);
159}
160
161static void __exit tc6387xb_exit(void)
162{
163 platform_driver_unregister(&tc6387xb_platform_driver);
164}
165
166module_init(tc6387xb_init);
167module_exit(tc6387xb_exit);
168
169MODULE_DESCRIPTION("Toshiba TC6387XB core driver");
170MODULE_LICENSE("GPL v2");
171MODULE_AUTHOR("Ian Molton");
172MODULE_ALIAS("platform:tc6387xb");