diff options
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/pxa2xx_base.c | 86 | ||||
-rw-r--r-- | drivers/pcmcia/sa11xx_base.c | 48 | ||||
-rw-r--r-- | drivers/pcmcia/soc_common.c | 54 | ||||
-rw-r--r-- | drivers/pcmcia/soc_common.h | 7 |
4 files changed, 140 insertions, 55 deletions
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 0227691860ae..16f84aab6ab3 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -38,6 +38,44 @@ | |||
38 | #include "soc_common.h" | 38 | #include "soc_common.h" |
39 | #include "pxa2xx_base.h" | 39 | #include "pxa2xx_base.h" |
40 | 40 | ||
41 | /* | ||
42 | * Personal Computer Memory Card International Association (PCMCIA) sockets | ||
43 | */ | ||
44 | |||
45 | #define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */ | ||
46 | #define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */ | ||
47 | #define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */ | ||
48 | #define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */ | ||
49 | #define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */ | ||
50 | |||
51 | #define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */ | ||
52 | #define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */ | ||
53 | #define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */ | ||
54 | #define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */ | ||
55 | |||
56 | #define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */ | ||
57 | #define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */ | ||
58 | #define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */ | ||
59 | #define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */ | ||
60 | |||
61 | #define _PCMCIA(Nb) /* PCMCIA [0..1] */ \ | ||
62 | (0x20000000 + (Nb) * PCMCIASp) | ||
63 | #define _PCMCIAIO(Nb) _PCMCIA(Nb) /* PCMCIA I/O [0..1] */ | ||
64 | #define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \ | ||
65 | (_PCMCIA(Nb) + 2 * PCMCIAPrtSp) | ||
66 | #define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \ | ||
67 | (_PCMCIA(Nb) + 3 * PCMCIAPrtSp) | ||
68 | |||
69 | #define _PCMCIA0 _PCMCIA(0) /* PCMCIA 0 */ | ||
70 | #define _PCMCIA0IO _PCMCIAIO(0) /* PCMCIA 0 I/O */ | ||
71 | #define _PCMCIA0Attr _PCMCIAAttr(0) /* PCMCIA 0 Attribute */ | ||
72 | #define _PCMCIA0Mem _PCMCIAMem(0) /* PCMCIA 0 Memory */ | ||
73 | |||
74 | #define _PCMCIA1 _PCMCIA(1) /* PCMCIA 1 */ | ||
75 | #define _PCMCIA1IO _PCMCIAIO(1) /* PCMCIA 1 I/O */ | ||
76 | #define _PCMCIA1Attr _PCMCIAAttr(1) /* PCMCIA 1 Attribute */ | ||
77 | #define _PCMCIA1Mem _PCMCIAMem(1) /* PCMCIA 1 Memory */ | ||
78 | |||
41 | 79 | ||
42 | #define MCXX_SETUP_MASK (0x7f) | 80 | #define MCXX_SETUP_MASK (0x7f) |
43 | #define MCXX_ASST_MASK (0x1f) | 81 | #define MCXX_ASST_MASK (0x1f) |
@@ -182,23 +220,67 @@ static void pxa2xx_configure_sockets(struct device *dev) | |||
182 | MECR &= ~MECR_NOS; | 220 | MECR &= ~MECR_NOS; |
183 | } | 221 | } |
184 | 222 | ||
223 | static const char *skt_names[] = { | ||
224 | "PCMCIA socket 0", | ||
225 | "PCMCIA socket 1", | ||
226 | }; | ||
227 | |||
228 | #define SKT_DEV_INFO_SIZE(n) \ | ||
229 | (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) | ||
230 | |||
185 | int __pxa2xx_drv_pcmcia_probe(struct device *dev) | 231 | int __pxa2xx_drv_pcmcia_probe(struct device *dev) |
186 | { | 232 | { |
187 | int ret; | 233 | int i, ret; |
188 | struct pcmcia_low_level *ops; | 234 | struct pcmcia_low_level *ops; |
235 | struct skt_dev_info *sinfo; | ||
236 | struct soc_pcmcia_socket *skt; | ||
189 | 237 | ||
190 | if (!dev || !dev->platform_data) | 238 | if (!dev || !dev->platform_data) |
191 | return -ENODEV; | 239 | return -ENODEV; |
192 | 240 | ||
193 | ops = (struct pcmcia_low_level *)dev->platform_data; | 241 | ops = (struct pcmcia_low_level *)dev->platform_data; |
194 | 242 | ||
243 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); | ||
244 | if (!sinfo) | ||
245 | return -ENOMEM; | ||
246 | |||
247 | sinfo->nskt = ops->nr; | ||
248 | |||
249 | /* Initialize processor specific parameters */ | ||
250 | for (i = 0; i < ops->nr; i++) { | ||
251 | skt = &sinfo->skt[i]; | ||
252 | |||
253 | skt->nr = i; | ||
254 | skt->irq = NO_IRQ; | ||
255 | |||
256 | skt->res_skt.start = _PCMCIA(skt->nr); | ||
257 | skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; | ||
258 | skt->res_skt.name = skt_names[skt->nr]; | ||
259 | skt->res_skt.flags = IORESOURCE_MEM; | ||
260 | |||
261 | skt->res_io.start = _PCMCIAIO(skt->nr); | ||
262 | skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1; | ||
263 | skt->res_io.name = "io"; | ||
264 | skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
265 | |||
266 | skt->res_mem.start = _PCMCIAMem(skt->nr); | ||
267 | skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; | ||
268 | skt->res_mem.name = "memory"; | ||
269 | skt->res_mem.flags = IORESOURCE_MEM; | ||
270 | |||
271 | skt->res_attr.start = _PCMCIAAttr(skt->nr); | ||
272 | skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1; | ||
273 | skt->res_attr.name = "attribute"; | ||
274 | skt->res_attr.flags = IORESOURCE_MEM; | ||
275 | } | ||
276 | |||
195 | /* Provide our PXA2xx specific timing routines. */ | 277 | /* Provide our PXA2xx specific timing routines. */ |
196 | ops->set_timing = pxa2xx_pcmcia_set_timing; | 278 | ops->set_timing = pxa2xx_pcmcia_set_timing; |
197 | #ifdef CONFIG_CPU_FREQ | 279 | #ifdef CONFIG_CPU_FREQ |
198 | ops->frequency_change = pxa2xx_pcmcia_frequency_change; | 280 | ops->frequency_change = pxa2xx_pcmcia_frequency_change; |
199 | #endif | 281 | #endif |
200 | 282 | ||
201 | ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr); | 283 | ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo); |
202 | 284 | ||
203 | if (!ret) | 285 | if (!ret) |
204 | pxa2xx_configure_sockets(dev); | 286 | pxa2xx_configure_sockets(dev); |
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 7cb1273202cc..810ac492a8c9 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c | |||
@@ -163,9 +163,55 @@ sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf) | |||
163 | return p - buf; | 163 | return p - buf; |
164 | } | 164 | } |
165 | 165 | ||
166 | static const char *skt_names[] = { | ||
167 | "PCMCIA socket 0", | ||
168 | "PCMCIA socket 1", | ||
169 | }; | ||
170 | |||
171 | #define SKT_DEV_INFO_SIZE(n) \ | ||
172 | (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) | ||
173 | |||
166 | int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, | 174 | int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, |
167 | int first, int nr) | 175 | int first, int nr) |
168 | { | 176 | { |
177 | struct skt_dev_info *sinfo; | ||
178 | struct soc_pcmcia_socket *skt; | ||
179 | int i; | ||
180 | |||
181 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); | ||
182 | if (!sinfo) | ||
183 | return -ENOMEM; | ||
184 | |||
185 | sinfo->nskt = nr; | ||
186 | |||
187 | /* Initiliaze processor specific parameters */ | ||
188 | for (i = 0; i < nr; i++) { | ||
189 | skt = &sinfo->skt[i]; | ||
190 | |||
191 | skt->nr = first + i; | ||
192 | skt->irq = NO_IRQ; | ||
193 | |||
194 | skt->res_skt.start = _PCMCIA(skt->nr); | ||
195 | skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; | ||
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 | |||
204 | skt->res_mem.start = _PCMCIAMem(skt->nr); | ||
205 | skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; | ||
206 | skt->res_mem.name = "memory"; | ||
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 | } | ||
214 | |||
169 | /* | 215 | /* |
170 | * set default MECR calculation if the board specific | 216 | * set default MECR calculation if the board specific |
171 | * code did not specify one... | 217 | * code did not specify one... |
@@ -180,7 +226,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
180 | ops->frequency_change = sa1100_pcmcia_frequency_change; | 226 | ops->frequency_change = sa1100_pcmcia_frequency_change; |
181 | #endif | 227 | #endif |
182 | 228 | ||
183 | return soc_common_drv_pcmcia_probe(dev, ops, first, nr); | 229 | return soc_common_drv_pcmcia_probe(dev, ops, sinfo); |
184 | } | 230 | } |
185 | EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe); | 231 | EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe); |
186 | 232 | ||
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index f49ac6666153..163cf98e2386 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c | |||
@@ -49,11 +49,6 @@ | |||
49 | 49 | ||
50 | #include "soc_common.h" | 50 | #include "soc_common.h" |
51 | 51 | ||
52 | /* FIXME: platform dependent resource declaration has to move out of this file */ | ||
53 | #ifdef CONFIG_ARCH_PXA | ||
54 | #include <mach/pxa-regs.h> | ||
55 | #endif | ||
56 | |||
57 | #ifdef CONFIG_PCMCIA_DEBUG | 52 | #ifdef CONFIG_PCMCIA_DEBUG |
58 | 53 | ||
59 | static int pc_debug; | 54 | static int pc_debug; |
@@ -581,19 +576,6 @@ EXPORT_SYMBOL(soc_pcmcia_enable_irqs); | |||
581 | LIST_HEAD(soc_pcmcia_sockets); | 576 | LIST_HEAD(soc_pcmcia_sockets); |
582 | static DEFINE_MUTEX(soc_pcmcia_sockets_lock); | 577 | static DEFINE_MUTEX(soc_pcmcia_sockets_lock); |
583 | 578 | ||
584 | static const char *skt_names[] = { | ||
585 | "PCMCIA socket 0", | ||
586 | "PCMCIA socket 1", | ||
587 | }; | ||
588 | |||
589 | struct skt_dev_info { | ||
590 | int nskt; | ||
591 | struct soc_pcmcia_socket skt[0]; | ||
592 | }; | ||
593 | |||
594 | #define SKT_DEV_INFO_SIZE(n) \ | ||
595 | (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) | ||
596 | |||
597 | #ifdef CONFIG_CPU_FREQ | 579 | #ifdef CONFIG_CPU_FREQ |
598 | static int | 580 | static int |
599 | soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data) | 581 | soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data) |
@@ -637,26 +619,18 @@ static int soc_pcmcia_cpufreq_register(void) { return 0; } | |||
637 | static void soc_pcmcia_cpufreq_unregister(void) {} | 619 | static void soc_pcmcia_cpufreq_unregister(void) {} |
638 | #endif | 620 | #endif |
639 | 621 | ||
640 | int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) | 622 | int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, |
623 | struct skt_dev_info *sinfo) | ||
641 | { | 624 | { |
642 | struct skt_dev_info *sinfo; | ||
643 | struct soc_pcmcia_socket *skt; | 625 | struct soc_pcmcia_socket *skt; |
644 | int ret, i; | 626 | int ret, i; |
645 | 627 | ||
646 | mutex_lock(&soc_pcmcia_sockets_lock); | 628 | mutex_lock(&soc_pcmcia_sockets_lock); |
647 | 629 | ||
648 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); | ||
649 | if (!sinfo) { | ||
650 | ret = -ENOMEM; | ||
651 | goto out; | ||
652 | } | ||
653 | |||
654 | sinfo->nskt = nr; | ||
655 | |||
656 | /* | 630 | /* |
657 | * Initialise the per-socket structure. | 631 | * Initialise the per-socket structure. |
658 | */ | 632 | */ |
659 | for (i = 0; i < nr; i++) { | 633 | for (i = 0; i < sinfo->nskt; i++) { |
660 | skt = &sinfo->skt[i]; | 634 | skt = &sinfo->skt[i]; |
661 | 635 | ||
662 | skt->socket.ops = &soc_common_pcmcia_operations; | 636 | skt->socket.ops = &soc_common_pcmcia_operations; |
@@ -668,43 +642,21 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops | |||
668 | skt->poll_timer.data = (unsigned long)skt; | 642 | skt->poll_timer.data = (unsigned long)skt; |
669 | skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD; | 643 | skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD; |
670 | 644 | ||
671 | skt->nr = first + i; | ||
672 | skt->irq = NO_IRQ; | ||
673 | skt->dev = dev; | 645 | skt->dev = dev; |
674 | skt->ops = ops; | 646 | skt->ops = ops; |
675 | 647 | ||
676 | skt->res_skt.start = _PCMCIA(skt->nr); | ||
677 | skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; | ||
678 | skt->res_skt.name = skt_names[skt->nr]; | ||
679 | skt->res_skt.flags = IORESOURCE_MEM; | ||
680 | |||
681 | ret = request_resource(&iomem_resource, &skt->res_skt); | 648 | ret = request_resource(&iomem_resource, &skt->res_skt); |
682 | if (ret) | 649 | if (ret) |
683 | goto out_err_1; | 650 | goto out_err_1; |
684 | 651 | ||
685 | skt->res_io.start = _PCMCIAIO(skt->nr); | ||
686 | skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1; | ||
687 | skt->res_io.name = "io"; | ||
688 | skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
689 | |||
690 | ret = request_resource(&skt->res_skt, &skt->res_io); | 652 | ret = request_resource(&skt->res_skt, &skt->res_io); |
691 | if (ret) | 653 | if (ret) |
692 | goto out_err_2; | 654 | goto out_err_2; |
693 | 655 | ||
694 | skt->res_mem.start = _PCMCIAMem(skt->nr); | ||
695 | skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; | ||
696 | skt->res_mem.name = "memory"; | ||
697 | skt->res_mem.flags = IORESOURCE_MEM; | ||
698 | |||
699 | ret = request_resource(&skt->res_skt, &skt->res_mem); | 656 | ret = request_resource(&skt->res_skt, &skt->res_mem); |
700 | if (ret) | 657 | if (ret) |
701 | goto out_err_3; | 658 | goto out_err_3; |
702 | 659 | ||
703 | skt->res_attr.start = _PCMCIAAttr(skt->nr); | ||
704 | skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1; | ||
705 | skt->res_attr.name = "attribute"; | ||
706 | skt->res_attr.flags = IORESOURCE_MEM; | ||
707 | |||
708 | ret = request_resource(&skt->res_skt, &skt->res_attr); | 660 | ret = request_resource(&skt->res_skt, &skt->res_attr); |
709 | if (ret) | 661 | if (ret) |
710 | goto out_err_4; | 662 | goto out_err_4; |
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 38c67375f363..290e143839ee 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h | |||
@@ -58,6 +58,11 @@ struct soc_pcmcia_socket { | |||
58 | struct list_head node; | 58 | struct list_head node; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct skt_dev_info { | ||
62 | int nskt; | ||
63 | struct soc_pcmcia_socket skt[0]; | ||
64 | }; | ||
65 | |||
61 | struct pcmcia_state { | 66 | struct pcmcia_state { |
62 | unsigned detect: 1, | 67 | unsigned detect: 1, |
63 | ready: 1, | 68 | ready: 1, |
@@ -132,7 +137,7 @@ extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_ | |||
132 | 137 | ||
133 | extern struct list_head soc_pcmcia_sockets; | 138 | extern struct list_head soc_pcmcia_sockets; |
134 | 139 | ||
135 | extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr); | 140 | extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo); |
136 | extern int soc_common_drv_pcmcia_remove(struct device *dev); | 141 | extern int soc_common_drv_pcmcia_remove(struct device *dev); |
137 | 142 | ||
138 | 143 | ||