aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/sa11xx_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/sa11xx_base.c')
-rw-r--r--drivers/pcmcia/sa11xx_base.c100
1 files changed, 64 insertions, 36 deletions
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index e15d59f2d8a9..fa28d8911b00 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -37,6 +37,7 @@
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <linux/io.h> 39#include <linux/io.h>
40#include <linux/slab.h>
40 41
41#include <mach/hardware.h> 42#include <mach/hardware.h>
42#include <asm/irq.h> 43#include <asm/irq.h>
@@ -171,12 +172,58 @@ static const char *skt_names[] = {
171#define SKT_DEV_INFO_SIZE(n) \ 172#define SKT_DEV_INFO_SIZE(n) \
172 (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) 173 (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
173 174
175int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
176{
177 skt->res_skt.start = _PCMCIA(skt->nr);
178 skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
179 skt->res_skt.name = skt_names[skt->nr];
180 skt->res_skt.flags = IORESOURCE_MEM;
181
182 skt->res_io.start = _PCMCIAIO(skt->nr);
183 skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
184 skt->res_io.name = "io";
185 skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
186
187 skt->res_mem.start = _PCMCIAMem(skt->nr);
188 skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
189 skt->res_mem.name = "memory";
190 skt->res_mem.flags = IORESOURCE_MEM;
191
192 skt->res_attr.start = _PCMCIAAttr(skt->nr);
193 skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
194 skt->res_attr.name = "attribute";
195 skt->res_attr.flags = IORESOURCE_MEM;
196
197 return soc_pcmcia_add_one(skt);
198}
199EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one);
200
201void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
202{
203 /*
204 * set default MECR calculation if the board specific
205 * code did not specify one...
206 */
207 if (!ops->get_timing)
208 ops->get_timing = sa1100_pcmcia_default_mecr_timing;
209
210 /* Provide our SA11x0 specific timing routines. */
211 ops->set_timing = sa1100_pcmcia_set_timing;
212 ops->show_timing = sa1100_pcmcia_show_timing;
213#ifdef CONFIG_CPU_FREQ
214 ops->frequency_change = sa1100_pcmcia_frequency_change;
215#endif
216}
217EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops);
218
174int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, 219int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
175 int first, int nr) 220 int first, int nr)
176{ 221{
177 struct skt_dev_info *sinfo; 222 struct skt_dev_info *sinfo;
178 struct soc_pcmcia_socket *skt; 223 struct soc_pcmcia_socket *skt;
179 int i; 224 int i, ret = 0;
225
226 sa11xx_drv_pcmcia_ops(ops);
180 227
181 sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); 228 sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
182 if (!sinfo) 229 if (!sinfo)
@@ -188,45 +235,26 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
188 for (i = 0; i < nr; i++) { 235 for (i = 0; i < nr; i++) {
189 skt = &sinfo->skt[i]; 236 skt = &sinfo->skt[i];
190 237
191 skt->nr = first + i; 238 skt->nr = first + i;
192 skt->irq = NO_IRQ; 239 skt->ops = ops;
193 240 skt->socket.owner = ops->owner;
194 skt->res_skt.start = _PCMCIA(skt->nr); 241 skt->socket.dev.parent = dev;
195 skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; 242 skt->socket.pci_irq = NO_IRQ;
196 skt->res_skt.name = skt_names[skt->nr];
197 skt->res_skt.flags = IORESOURCE_MEM;
198
199 skt->res_io.start = _PCMCIAIO(skt->nr);
200 skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
201 skt->res_io.name = "io";
202 skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
203 243
204 skt->res_mem.start = _PCMCIAMem(skt->nr); 244 ret = sa11xx_drv_pcmcia_add_one(skt);
205 skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; 245 if (ret)
206 skt->res_mem.name = "memory"; 246 break;
207 skt->res_mem.flags = IORESOURCE_MEM;
208
209 skt->res_attr.start = _PCMCIAAttr(skt->nr);
210 skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
211 skt->res_attr.name = "attribute";
212 skt->res_attr.flags = IORESOURCE_MEM;
213 } 247 }
214 248
215 /* 249 if (ret) {
216 * set default MECR calculation if the board specific 250 while (--i >= 0)
217 * code did not specify one... 251 soc_pcmcia_remove_one(&sinfo->skt[i]);
218 */ 252 kfree(sinfo);
219 if (!ops->get_timing) 253 } else {
220 ops->get_timing = sa1100_pcmcia_default_mecr_timing; 254 dev_set_drvdata(dev, sinfo);
221 255 }
222 /* Provide our SA11x0 specific timing routines. */
223 ops->set_timing = sa1100_pcmcia_set_timing;
224 ops->show_timing = sa1100_pcmcia_show_timing;
225#ifdef CONFIG_CPU_FREQ
226 ops->frequency_change = sa1100_pcmcia_frequency_change;
227#endif
228 256
229 return soc_common_drv_pcmcia_probe(dev, ops, sinfo); 257 return ret;
230} 258}
231EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe); 259EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
232 260