diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/pcmcia | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/pcmcia')
54 files changed, 1104 insertions, 607 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index c80a7a6e7698..6e318ce41136 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -69,7 +69,7 @@ comment "PC-card bridges" | |||
69 | config YENTA | 69 | config YENTA |
70 | tristate "CardBus yenta-compatible bridge support" | 70 | tristate "CardBus yenta-compatible bridge support" |
71 | depends on PCI | 71 | depends on PCI |
72 | select CARDBUS if !EMBEDDED | 72 | select CARDBUS if !EXPERT |
73 | select PCCARD_NONSTATIC if PCMCIA != n | 73 | select PCCARD_NONSTATIC if PCMCIA != n |
74 | ---help--- | 74 | ---help--- |
75 | This option enables support for CardBus host bridges. Virtually | 75 | This option enables support for CardBus host bridges. Virtually |
@@ -84,27 +84,27 @@ config YENTA | |||
84 | 84 | ||
85 | config YENTA_O2 | 85 | config YENTA_O2 |
86 | default y | 86 | default y |
87 | bool "Special initialization for O2Micro bridges" if EMBEDDED | 87 | bool "Special initialization for O2Micro bridges" if EXPERT |
88 | depends on YENTA | 88 | depends on YENTA |
89 | 89 | ||
90 | config YENTA_RICOH | 90 | config YENTA_RICOH |
91 | default y | 91 | default y |
92 | bool "Special initialization for Ricoh bridges" if EMBEDDED | 92 | bool "Special initialization for Ricoh bridges" if EXPERT |
93 | depends on YENTA | 93 | depends on YENTA |
94 | 94 | ||
95 | config YENTA_TI | 95 | config YENTA_TI |
96 | default y | 96 | default y |
97 | bool "Special initialization for TI and EnE bridges" if EMBEDDED | 97 | bool "Special initialization for TI and EnE bridges" if EXPERT |
98 | depends on YENTA | 98 | depends on YENTA |
99 | 99 | ||
100 | config YENTA_ENE_TUNE | 100 | config YENTA_ENE_TUNE |
101 | default y | 101 | default y |
102 | bool "Auto-tune EnE bridges for CB cards" if EMBEDDED | 102 | bool "Auto-tune EnE bridges for CB cards" if EXPERT |
103 | depends on YENTA_TI && CARDBUS | 103 | depends on YENTA_TI && CARDBUS |
104 | 104 | ||
105 | config YENTA_TOSHIBA | 105 | config YENTA_TOSHIBA |
106 | default y | 106 | default y |
107 | bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED | 107 | bool "Special initialization for Toshiba ToPIC bridges" if EXPERT |
108 | depends on YENTA | 108 | depends on YENTA |
109 | 109 | ||
110 | config PD6729 | 110 | config PD6729 |
@@ -215,7 +215,8 @@ config PCMCIA_PXA2XX | |||
215 | depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ | 215 | depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ |
216 | || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ | 216 | || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ |
217 | || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ | 217 | || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ |
218 | || MACH_VPAC270 || MACH_BALLOON3) | 218 | || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ |
219 | || MACH_COLIBRI320) | ||
219 | select PCMCIA_SOC_COMMON | 220 | select PCMCIA_SOC_COMMON |
220 | help | 221 | help |
221 | Say Y here to include support for the PXA2xx PCMCIA controller | 222 | Say Y here to include support for the PXA2xx PCMCIA controller |
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 8d9386a22eb3..29935ea921df 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -50,8 +50,9 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o | |||
50 | sa1100_cs-y += sa1100_generic.o | 50 | sa1100_cs-y += sa1100_generic.o |
51 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o | 51 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o |
52 | sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o | 52 | sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o |
53 | sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o | 53 | sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o |
54 | sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o | 54 | sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o |
55 | sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o | ||
55 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o | 56 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o |
56 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o | 57 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o |
57 | 58 | ||
@@ -70,6 +71,8 @@ pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o | |||
70 | pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o | 71 | pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o |
71 | pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o | 72 | pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o |
72 | pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o | 73 | pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o |
74 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o | ||
75 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI320) += pxa2xx_colibri.o | ||
73 | 76 | ||
74 | obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) | 77 | obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) |
75 | 78 | ||
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 88c4c4098789..95dd7c62741f 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c | |||
@@ -441,14 +441,12 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
441 | 441 | ||
442 | 442 | ||
443 | out_err: | 443 | out_err: |
444 | flush_scheduled_work(); | ||
445 | ops->hw_shutdown(skt); | 444 | ops->hw_shutdown(skt); |
446 | while (i-- > 0) { | 445 | while (i-- > 0) { |
447 | skt = PCMCIA_SOCKET(i); | 446 | skt = PCMCIA_SOCKET(i); |
448 | 447 | ||
449 | del_timer_sync(&skt->poll_timer); | 448 | del_timer_sync(&skt->poll_timer); |
450 | pcmcia_unregister_socket(&skt->socket); | 449 | pcmcia_unregister_socket(&skt->socket); |
451 | flush_scheduled_work(); | ||
452 | if (i == 0) { | 450 | if (i == 0) { |
453 | iounmap(skt->virt_io + (u32)mips_io_port_base); | 451 | iounmap(skt->virt_io + (u32)mips_io_port_base); |
454 | skt->virt_io = NULL; | 452 | skt->virt_io = NULL; |
@@ -480,7 +478,6 @@ int au1x00_drv_pcmcia_remove(struct platform_device *dev) | |||
480 | 478 | ||
481 | del_timer_sync(&skt->poll_timer); | 479 | del_timer_sync(&skt->poll_timer); |
482 | pcmcia_unregister_socket(&skt->socket); | 480 | pcmcia_unregister_socket(&skt->socket); |
483 | flush_scheduled_work(); | ||
484 | skt->ops->hw_shutdown(skt); | 481 | skt->ops->hw_shutdown(skt); |
485 | au1x00_pcmcia_config_skt(skt, &dead_socket); | 482 | au1x00_pcmcia_config_skt(skt, &dead_socket); |
486 | iounmap(skt->virt_io + (u32)mips_io_port_base); | 483 | iounmap(skt->virt_io + (u32)mips_io_port_base); |
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h index 67530cefcf3c..5c36bda2963b 100644 --- a/drivers/pcmcia/au1000_generic.h +++ b/drivers/pcmcia/au1000_generic.h | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | /* include the world */ | 24 | /* include the world */ |
25 | 25 | ||
26 | #include <pcmcia/cs.h> | ||
27 | #include <pcmcia/ss.h> | 26 | #include <pcmcia/ss.h> |
28 | #include <pcmcia/cistpl.h> | 27 | #include <pcmcia/cistpl.h> |
29 | #include "cs_internal.h" | 28 | #include "cs_internal.h" |
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c index 807f2d75dad3..b2396647a165 100644 --- a/drivers/pcmcia/au1000_pb1x00.c +++ b/drivers/pcmcia/au1000_pb1x00.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/proc_fs.h> | 31 | #include <linux/proc_fs.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | 33 | ||
34 | #include <pcmcia/cs.h> | ||
35 | #include <pcmcia/ss.h> | 34 | #include <pcmcia/ss.h> |
36 | #include <pcmcia/cistpl.h> | 35 | #include <pcmcia/cistpl.h> |
37 | 36 | ||
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index eae9cbe37a3e..49221395101e 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c | |||
@@ -235,7 +235,7 @@ static int __devinit bfin_cf_probe(struct platform_device *pdev) | |||
235 | cf->irq = irq; | 235 | cf->irq = irq; |
236 | cf->socket.pci_irq = irq; | 236 | cf->socket.pci_irq = irq; |
237 | 237 | ||
238 | set_irq_type(irq, IRQF_TRIGGER_LOW); | 238 | irq_set_irq_type(irq, IRQF_TRIGGER_LOW); |
239 | 239 | ||
240 | io_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 240 | io_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
241 | attr_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 241 | attr_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 91414a0ddc44..884a984216fe 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
29 | 29 | ||
30 | #include <pcmcia/ss.h> | 30 | #include <pcmcia/ss.h> |
31 | #include <pcmcia/cs.h> | ||
32 | #include <pcmcia/cisreg.h> | 31 | #include <pcmcia/cisreg.h> |
33 | #include <pcmcia/cistpl.h> | 32 | #include <pcmcia/cistpl.h> |
34 | #include "cs_internal.h" | 33 | #include "cs_internal.h" |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 2ec8ac97445c..d9ea192c4001 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
34 | 34 | ||
35 | #include <pcmcia/ss.h> | 35 | #include <pcmcia/ss.h> |
36 | #include <pcmcia/cs.h> | ||
37 | #include <pcmcia/cistpl.h> | 36 | #include <pcmcia/cistpl.h> |
38 | #include <pcmcia/cisreg.h> | 37 | #include <pcmcia/cisreg.h> |
39 | #include <pcmcia/ds.h> | 38 | #include <pcmcia/ds.h> |
@@ -845,7 +844,7 @@ static int pcmcia_socket_dev_resume_noirq(struct device *dev) | |||
845 | return __pcmcia_pm_op(dev, socket_early_resume); | 844 | return __pcmcia_pm_op(dev, socket_early_resume); |
846 | } | 845 | } |
847 | 846 | ||
848 | static int pcmcia_socket_dev_resume(struct device *dev) | 847 | static int __used pcmcia_socket_dev_resume(struct device *dev) |
849 | { | 848 | { |
850 | return __pcmcia_pm_op(dev, socket_late_resume); | 849 | return __pcmcia_pm_op(dev, socket_late_resume); |
851 | } | 850 | } |
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index da055dc14d98..7f1953f78b12 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
@@ -33,18 +33,9 @@ | |||
33 | typedef struct config_t { | 33 | typedef struct config_t { |
34 | struct kref ref; | 34 | struct kref ref; |
35 | unsigned int state; | 35 | unsigned int state; |
36 | unsigned int Attributes; | ||
37 | unsigned int IntType; | ||
38 | unsigned int ConfigBase; | ||
39 | unsigned char Status, Pin, Copy, Option, ExtStatus; | ||
40 | unsigned int CardValues; | ||
41 | 36 | ||
42 | struct resource io[MAX_IO_WIN]; /* io ports */ | 37 | struct resource io[MAX_IO_WIN]; /* io ports */ |
43 | struct resource mem[MAX_WIN]; /* mem areas */ | 38 | struct resource mem[MAX_WIN]; /* mem areas */ |
44 | |||
45 | struct { | ||
46 | u_int Attributes; | ||
47 | } irq; | ||
48 | } config_t; | 39 | } config_t; |
49 | 40 | ||
50 | 41 | ||
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 27575e6378a1..01757f18a208 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c | |||
@@ -181,7 +181,7 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) | |||
181 | /* all other (older) Db1x00 boards use a GPIO to show | 181 | /* all other (older) Db1x00 boards use a GPIO to show |
182 | * card detection status: use both-edge triggers. | 182 | * card detection status: use both-edge triggers. |
183 | */ | 183 | */ |
184 | set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH); | 184 | irq_set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH); |
185 | ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq, | 185 | ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq, |
186 | 0, "pcmcia_carddetect", sock); | 186 | 0, "pcmcia_carddetect", sock); |
187 | 187 | ||
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 55570d9e1e4c..749c2a16012c 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/dma-mapping.h> | 26 | #include <linux/dma-mapping.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #include <pcmcia/cs.h> | ||
30 | #include <pcmcia/cistpl.h> | 29 | #include <pcmcia/cistpl.h> |
31 | #include <pcmcia/ds.h> | 30 | #include <pcmcia/ds.h> |
32 | #include <pcmcia/ss.h> | 31 | #include <pcmcia/ss.h> |
@@ -46,13 +45,13 @@ MODULE_LICENSE("GPL"); | |||
46 | 45 | ||
47 | static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | 46 | static void pcmcia_check_driver(struct pcmcia_driver *p_drv) |
48 | { | 47 | { |
49 | struct pcmcia_device_id *did = p_drv->id_table; | 48 | const struct pcmcia_device_id *did = p_drv->id_table; |
50 | unsigned int i; | 49 | unsigned int i; |
51 | u32 hash; | 50 | u32 hash; |
52 | 51 | ||
53 | if (!p_drv->probe || !p_drv->remove) | 52 | if (!p_drv->probe || !p_drv->remove) |
54 | printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " | 53 | printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " |
55 | "function\n", p_drv->drv.name); | 54 | "function\n", p_drv->name); |
56 | 55 | ||
57 | while (did && did->match_flags) { | 56 | while (did && did->match_flags) { |
58 | for (i = 0; i < 4; i++) { | 57 | for (i = 0; i < 4; i++) { |
@@ -65,7 +64,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | |||
65 | 64 | ||
66 | printk(KERN_DEBUG "pcmcia: %s: invalid hash for " | 65 | printk(KERN_DEBUG "pcmcia: %s: invalid hash for " |
67 | "product string \"%s\": is 0x%x, should " | 66 | "product string \"%s\": is 0x%x, should " |
68 | "be 0x%x\n", p_drv->drv.name, did->prod_id[i], | 67 | "be 0x%x\n", p_drv->name, did->prod_id[i], |
69 | did->prod_id_hash[i], hash); | 68 | did->prod_id_hash[i], hash); |
70 | printk(KERN_DEBUG "pcmcia: see " | 69 | printk(KERN_DEBUG "pcmcia: see " |
71 | "Documentation/pcmcia/devicetable.txt for " | 70 | "Documentation/pcmcia/devicetable.txt for " |
@@ -180,10 +179,11 @@ int pcmcia_register_driver(struct pcmcia_driver *driver) | |||
180 | /* initialize common fields */ | 179 | /* initialize common fields */ |
181 | driver->drv.bus = &pcmcia_bus_type; | 180 | driver->drv.bus = &pcmcia_bus_type; |
182 | driver->drv.owner = driver->owner; | 181 | driver->drv.owner = driver->owner; |
182 | driver->drv.name = driver->name; | ||
183 | mutex_init(&driver->dynids.lock); | 183 | mutex_init(&driver->dynids.lock); |
184 | INIT_LIST_HEAD(&driver->dynids.list); | 184 | INIT_LIST_HEAD(&driver->dynids.list); |
185 | 185 | ||
186 | pr_debug("registering driver %s\n", driver->drv.name); | 186 | pr_debug("registering driver %s\n", driver->name); |
187 | 187 | ||
188 | error = driver_register(&driver->drv); | 188 | error = driver_register(&driver->drv); |
189 | if (error < 0) | 189 | if (error < 0) |
@@ -203,7 +203,7 @@ EXPORT_SYMBOL(pcmcia_register_driver); | |||
203 | */ | 203 | */ |
204 | void pcmcia_unregister_driver(struct pcmcia_driver *driver) | 204 | void pcmcia_unregister_driver(struct pcmcia_driver *driver) |
205 | { | 205 | { |
206 | pr_debug("unregistering driver %s\n", driver->drv.name); | 206 | pr_debug("unregistering driver %s\n", driver->name); |
207 | driver_unregister(&driver->drv); | 207 | driver_unregister(&driver->drv); |
208 | pcmcia_free_dynids(driver); | 208 | pcmcia_free_dynids(driver); |
209 | } | 209 | } |
@@ -264,7 +264,7 @@ static int pcmcia_device_probe(struct device *dev) | |||
264 | p_drv = to_pcmcia_drv(dev->driver); | 264 | p_drv = to_pcmcia_drv(dev->driver); |
265 | s = p_dev->socket; | 265 | s = p_dev->socket; |
266 | 266 | ||
267 | dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name); | 267 | dev_dbg(dev, "trying to bind to %s\n", p_drv->name); |
268 | 268 | ||
269 | if ((!p_drv->probe) || (!p_dev->function_config) || | 269 | if ((!p_drv->probe) || (!p_dev->function_config) || |
270 | (!try_module_get(p_drv->owner))) { | 270 | (!try_module_get(p_drv->owner))) { |
@@ -276,21 +276,28 @@ static int pcmcia_device_probe(struct device *dev) | |||
276 | ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG, | 276 | ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG, |
277 | &cis_config); | 277 | &cis_config); |
278 | if (!ret) { | 278 | if (!ret) { |
279 | p_dev->conf.ConfigBase = cis_config.base; | 279 | p_dev->config_base = cis_config.base; |
280 | p_dev->conf.Present = cis_config.rmask[0]; | 280 | p_dev->config_regs = cis_config.rmask[0]; |
281 | dev_dbg(dev, "base %x, regs %x", p_dev->config_base, | ||
282 | p_dev->config_regs); | ||
281 | } else { | 283 | } else { |
282 | dev_printk(KERN_INFO, dev, | 284 | dev_printk(KERN_INFO, dev, |
283 | "pcmcia: could not parse base and rmask0 of CIS\n"); | 285 | "pcmcia: could not parse base and rmask0 of CIS\n"); |
284 | p_dev->conf.ConfigBase = 0; | 286 | p_dev->config_base = 0; |
285 | p_dev->conf.Present = 0; | 287 | p_dev->config_regs = 0; |
286 | } | 288 | } |
287 | 289 | ||
288 | ret = p_drv->probe(p_dev); | 290 | ret = p_drv->probe(p_dev); |
289 | if (ret) { | 291 | if (ret) { |
290 | dev_dbg(dev, "binding to %s failed with %d\n", | 292 | dev_dbg(dev, "binding to %s failed with %d\n", |
291 | p_drv->drv.name, ret); | 293 | p_drv->name, ret); |
292 | goto put_module; | 294 | goto put_module; |
293 | } | 295 | } |
296 | dev_dbg(dev, "%s bound: Vpp %d.%d, idx %x, IRQ %d", p_drv->name, | ||
297 | p_dev->vpp/10, p_dev->vpp%10, p_dev->config_index, p_dev->irq); | ||
298 | dev_dbg(dev, "resources: ioport %pR %pR iomem %pR %pR %pR", | ||
299 | p_dev->resource[0], p_dev->resource[1], p_dev->resource[2], | ||
300 | p_dev->resource[3], p_dev->resource[4]); | ||
294 | 301 | ||
295 | mutex_lock(&s->ops_mutex); | 302 | mutex_lock(&s->ops_mutex); |
296 | if ((s->pcmcia_pfc) && | 303 | if ((s->pcmcia_pfc) && |
@@ -374,13 +381,13 @@ static int pcmcia_device_remove(struct device *dev) | |||
374 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) | 381 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) |
375 | dev_printk(KERN_INFO, dev, | 382 | dev_printk(KERN_INFO, dev, |
376 | "pcmcia: driver %s did not release config properly\n", | 383 | "pcmcia: driver %s did not release config properly\n", |
377 | p_drv->drv.name); | 384 | p_drv->name); |
378 | 385 | ||
379 | for (i = 0; i < MAX_WIN; i++) | 386 | for (i = 0; i < MAX_WIN; i++) |
380 | if (p_dev->_win & CLIENT_WIN_REQ(i)) | 387 | if (p_dev->_win & CLIENT_WIN_REQ(i)) |
381 | dev_printk(KERN_INFO, dev, | 388 | dev_printk(KERN_INFO, dev, |
382 | "pcmcia: driver %s did not release window properly\n", | 389 | "pcmcia: driver %s did not release window properly\n", |
383 | p_drv->drv.name); | 390 | p_drv->name); |
384 | 391 | ||
385 | /* references from pcmcia_probe_device */ | 392 | /* references from pcmcia_probe_device */ |
386 | pcmcia_put_dev(p_dev); | 393 | pcmcia_put_dev(p_dev); |
@@ -777,7 +784,7 @@ static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filenam | |||
777 | 784 | ||
778 | 785 | ||
779 | static inline int pcmcia_devmatch(struct pcmcia_device *dev, | 786 | static inline int pcmcia_devmatch(struct pcmcia_device *dev, |
780 | struct pcmcia_device_id *did) | 787 | const struct pcmcia_device_id *did) |
781 | { | 788 | { |
782 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) { | 789 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) { |
783 | if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id)) | 790 | if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id)) |
@@ -883,7 +890,7 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) | |||
883 | { | 890 | { |
884 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 891 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
885 | struct pcmcia_driver *p_drv = to_pcmcia_drv(drv); | 892 | struct pcmcia_driver *p_drv = to_pcmcia_drv(drv); |
886 | struct pcmcia_device_id *did = p_drv->id_table; | 893 | const struct pcmcia_device_id *did = p_drv->id_table; |
887 | struct pcmcia_dynid *dynid; | 894 | struct pcmcia_dynid *dynid; |
888 | 895 | ||
889 | /* match dynamic devices first */ | 896 | /* match dynamic devices first */ |
@@ -1136,7 +1143,7 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state) | |||
1136 | dev_printk(KERN_ERR, dev, | 1143 | dev_printk(KERN_ERR, dev, |
1137 | "pcmcia: device %s (driver %s) did " | 1144 | "pcmcia: device %s (driver %s) did " |
1138 | "not want to go to sleep (%d)\n", | 1145 | "not want to go to sleep (%d)\n", |
1139 | p_dev->devname, p_drv->drv.name, ret); | 1146 | p_dev->devname, p_drv->name, ret); |
1140 | mutex_lock(&p_dev->socket->ops_mutex); | 1147 | mutex_lock(&p_dev->socket->ops_mutex); |
1141 | p_dev->suspended = 0; | 1148 | p_dev->suspended = 0; |
1142 | mutex_unlock(&p_dev->socket->ops_mutex); | 1149 | mutex_unlock(&p_dev->socket->ops_mutex); |
@@ -1178,7 +1185,7 @@ static int pcmcia_dev_resume(struct device *dev) | |||
1178 | 1185 | ||
1179 | if (p_dev->device_no == p_dev->func) { | 1186 | if (p_dev->device_no == p_dev->func) { |
1180 | dev_dbg(dev, "requesting configuration\n"); | 1187 | dev_dbg(dev, "requesting configuration\n"); |
1181 | ret = pcmcia_request_configuration(p_dev, &p_dev->conf); | 1188 | ret = pcmcia_enable_device(p_dev); |
1182 | if (ret) | 1189 | if (ret) |
1183 | goto out; | 1190 | goto out; |
1184 | } | 1191 | } |
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 546d3024b6f0..6defd4a8168e 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c | |||
@@ -181,8 +181,7 @@ static struct pccard_operations electra_cf_ops = { | |||
181 | .set_mem_map = electra_cf_set_mem_map, | 181 | .set_mem_map = electra_cf_set_mem_map, |
182 | }; | 182 | }; |
183 | 183 | ||
184 | static int __devinit electra_cf_probe(struct platform_device *ofdev, | 184 | static int __devinit electra_cf_probe(struct platform_device *ofdev) |
185 | const struct of_device_id *match) | ||
186 | { | 185 | { |
187 | struct device *device = &ofdev->dev; | 186 | struct device *device = &ofdev->dev; |
188 | struct device_node *np = ofdev->dev.of_node; | 187 | struct device_node *np = ofdev->dev.of_node; |
@@ -356,7 +355,7 @@ static const struct of_device_id electra_cf_match[] = { | |||
356 | }; | 355 | }; |
357 | MODULE_DEVICE_TABLE(of, electra_cf_match); | 356 | MODULE_DEVICE_TABLE(of, electra_cf_match); |
358 | 357 | ||
359 | static struct of_platform_driver electra_cf_driver = { | 358 | static struct platform_driver electra_cf_driver = { |
360 | .driver = { | 359 | .driver = { |
361 | .name = (char *)driver_name, | 360 | .name = (char *)driver_name, |
362 | .owner = THIS_MODULE, | 361 | .owner = THIS_MODULE, |
@@ -368,13 +367,13 @@ static struct of_platform_driver electra_cf_driver = { | |||
368 | 367 | ||
369 | static int __init electra_cf_init(void) | 368 | static int __init electra_cf_init(void) |
370 | { | 369 | { |
371 | return of_register_platform_driver(&electra_cf_driver); | 370 | return platform_driver_register(&electra_cf_driver); |
372 | } | 371 | } |
373 | module_init(electra_cf_init); | 372 | module_init(electra_cf_init); |
374 | 373 | ||
375 | static void __exit electra_cf_exit(void) | 374 | static void __exit electra_cf_exit(void) |
376 | { | 375 | { |
377 | of_unregister_platform_driver(&electra_cf_driver); | 376 | platform_driver_unregister(&electra_cf_driver); |
378 | } | 377 | } |
379 | module_exit(electra_cf_exit); | 378 | module_exit(electra_cf_exit); |
380 | 379 | ||
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 05d0879ce935..3e447d0387b7 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | 17 | ||
18 | #include <pcmcia/ss.h> | 18 | #include <pcmcia/ss.h> |
19 | #include <pcmcia/cs.h> | ||
20 | 19 | ||
21 | #include <asm/system.h> | 20 | #include <asm/system.h> |
22 | #include <asm/io.h> | 21 | #include <asm/io.h> |
@@ -55,7 +54,7 @@ static struct pccard_operations i82092aa_operations = { | |||
55 | .set_mem_map = i82092aa_set_mem_map, | 54 | .set_mem_map = i82092aa_set_mem_map, |
56 | }; | 55 | }; |
57 | 56 | ||
58 | /* The card can do upto 4 sockets, allocate a structure for each of them */ | 57 | /* The card can do up to 4 sockets, allocate a structure for each of them */ |
59 | 58 | ||
60 | struct socket_info { | 59 | struct socket_info { |
61 | int number; | 60 | int number; |
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 61746bd598b3..72a033a2acdb 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <asm/system.h> | 51 | #include <asm/system.h> |
52 | 52 | ||
53 | #include <pcmcia/ss.h> | 53 | #include <pcmcia/ss.h> |
54 | #include <pcmcia/cs.h> | ||
55 | 54 | ||
56 | #include <linux/isapnp.h> | 55 | #include <linux/isapnp.h> |
57 | 56 | ||
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 24de49925863..2adb0106a039 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/system.h> | 27 | #include <asm/system.h> |
28 | 28 | ||
29 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
30 | #include <pcmcia/cs.h> | ||
31 | 30 | ||
32 | #undef MAX_IO_WIN /* FIXME */ | 31 | #undef MAX_IO_WIN /* FIXME */ |
33 | #define MAX_IO_WIN 1 | 32 | #define MAX_IO_WIN 1 |
diff --git a/drivers/pcmcia/m32r_cfc.h b/drivers/pcmcia/m32r_cfc.h index 8146e3bee2e8..f558e1adf954 100644 --- a/drivers/pcmcia/m32r_cfc.h +++ b/drivers/pcmcia/m32r_cfc.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #endif | 9 | #endif |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * M32R PC Card Controler | 12 | * M32R PC Card Controller |
13 | */ | 13 | */ |
14 | #define M32R_PCC0_BASE 0x00ef7000 | 14 | #define M32R_PCC0_BASE 0x00ef7000 |
15 | #define M32R_PCC1_BASE 0x00ef7020 | 15 | #define M32R_PCC1_BASE 0x00ef7020 |
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 8e4723844ad3..1511ff71c87b 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <asm/addrspace.h> | 28 | #include <asm/addrspace.h> |
29 | 29 | ||
30 | #include <pcmcia/ss.h> | 30 | #include <pcmcia/ss.h> |
31 | #include <pcmcia/cs.h> | ||
32 | 31 | ||
33 | /* XXX: should be moved into asm/irq.h */ | 32 | /* XXX: should be moved into asm/irq.h */ |
34 | #define PCC0_IRQ 24 | 33 | #define PCC0_IRQ 24 |
diff --git a/drivers/pcmcia/m32r_pcc.h b/drivers/pcmcia/m32r_pcc.h index e4fffe417ba9..f95c58563bc8 100644 --- a/drivers/pcmcia/m32r_pcc.h +++ b/drivers/pcmcia/m32r_pcc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | #define M32R_MAX_PCC 2 | 5 | #define M32R_MAX_PCC 2 |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * M32R PC Card Controler | 8 | * M32R PC Card Controller |
9 | */ | 9 | */ |
10 | #define M32R_PCC0_BASE 0x00ef7000 | 10 | #define M32R_PCC0_BASE 0x00ef7000 |
11 | #define M32R_PCC1_BASE 0x00ef7020 | 11 | #define M32R_PCC1_BASE 0x00ef7020 |
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index f0ecad99ce81..271a590a5f3c 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include <asm/irq.h> | 59 | #include <asm/irq.h> |
60 | #include <asm/fs_pd.h> | 60 | #include <asm/fs_pd.h> |
61 | 61 | ||
62 | #include <pcmcia/cs.h> | ||
63 | #include <pcmcia/ss.h> | 62 | #include <pcmcia/ss.h> |
64 | 63 | ||
65 | #define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args) | 64 | #define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args) |
@@ -1149,8 +1148,7 @@ static struct pccard_operations m8xx_services = { | |||
1149 | .set_mem_map = m8xx_set_mem_map, | 1148 | .set_mem_map = m8xx_set_mem_map, |
1150 | }; | 1149 | }; |
1151 | 1150 | ||
1152 | static int __init m8xx_probe(struct platform_device *ofdev, | 1151 | static int __init m8xx_probe(struct platform_device *ofdev) |
1153 | const struct of_device_id *match) | ||
1154 | { | 1152 | { |
1155 | struct pcmcia_win *w; | 1153 | struct pcmcia_win *w; |
1156 | unsigned int i, m, hwirq; | 1154 | unsigned int i, m, hwirq; |
@@ -1199,7 +1197,7 @@ static int __init m8xx_probe(struct platform_device *ofdev, | |||
1199 | out_be32(M8XX_PGCRX(1), | 1197 | out_be32(M8XX_PGCRX(1), |
1200 | M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16)); | 1198 | M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16)); |
1201 | 1199 | ||
1202 | /* intialize the fixed memory windows */ | 1200 | /* initialize the fixed memory windows */ |
1203 | 1201 | ||
1204 | for (i = 0; i < PCMCIA_SOCKETS_NO; i++) { | 1202 | for (i = 0; i < PCMCIA_SOCKETS_NO; i++) { |
1205 | for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) { | 1203 | for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) { |
@@ -1296,7 +1294,7 @@ static const struct of_device_id m8xx_pcmcia_match[] = { | |||
1296 | 1294 | ||
1297 | MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); | 1295 | MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); |
1298 | 1296 | ||
1299 | static struct of_platform_driver m8xx_pcmcia_driver = { | 1297 | static struct platform_driver m8xx_pcmcia_driver = { |
1300 | .driver = { | 1298 | .driver = { |
1301 | .name = driver_name, | 1299 | .name = driver_name, |
1302 | .owner = THIS_MODULE, | 1300 | .owner = THIS_MODULE, |
@@ -1308,12 +1306,12 @@ static struct of_platform_driver m8xx_pcmcia_driver = { | |||
1308 | 1306 | ||
1309 | static int __init m8xx_init(void) | 1307 | static int __init m8xx_init(void) |
1310 | { | 1308 | { |
1311 | return of_register_platform_driver(&m8xx_pcmcia_driver); | 1309 | return platform_driver_register(&m8xx_pcmcia_driver); |
1312 | } | 1310 | } |
1313 | 1311 | ||
1314 | static void __exit m8xx_exit(void) | 1312 | static void __exit m8xx_exit(void) |
1315 | { | 1313 | { |
1316 | of_unregister_platform_driver(&m8xx_pcmcia_driver); | 1314 | platform_driver_unregister(&m8xx_pcmcia_driver); |
1317 | } | 1315 | } |
1318 | 1316 | ||
1319 | module_init(m8xx_init); | 1317 | module_init(m8xx_init); |
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h index e74bebac2695..5096e92c7a4c 100644 --- a/drivers/pcmcia/o2micro.h +++ b/drivers/pcmcia/o2micro.h | |||
@@ -153,14 +153,14 @@ static int o2micro_override(struct yenta_socket *socket) | |||
153 | 153 | ||
154 | if (use_speedup) { | 154 | if (use_speedup) { |
155 | dev_info(&socket->dev->dev, | 155 | dev_info(&socket->dev->dev, |
156 | "O2: enabling read prefetch/write burst\n"); | 156 | "O2: enabling read prefetch/write burst. If you experience problems or performance issues, use the yenta_socket parameter 'o2_speedup=off'\n"); |
157 | config_writeb(socket, O2_RESERVED1, | 157 | config_writeb(socket, O2_RESERVED1, |
158 | a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); | 158 | a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); |
159 | config_writeb(socket, O2_RESERVED2, | 159 | config_writeb(socket, O2_RESERVED2, |
160 | b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); | 160 | b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); |
161 | } else { | 161 | } else { |
162 | dev_info(&socket->dev->dev, | 162 | dev_info(&socket->dev->dev, |
163 | "O2: disabling read prefetch/write burst\n"); | 163 | "O2: disabling read prefetch/write burst. If you experience problems or performance issues, use the yenta_socket parameter 'o2_speedup=on'\n"); |
164 | config_writeb(socket, O2_RESERVED1, | 164 | config_writeb(socket, O2_RESERVED1, |
165 | a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); | 165 | a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); |
166 | config_writeb(socket, O2_RESERVED2, | 166 | config_writeb(socket, O2_RESERVED2, |
diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c index 0ac54da15885..e2c92415b892 100644 --- a/drivers/pcmcia/pcmcia_cis.c +++ b/drivers/pcmcia/pcmcia_cis.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | 6 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. |
7 | * | 7 | * |
8 | * Copyright (C) 1999 David A. Hinds | 8 | * Copyright (C) 1999 David A. Hinds |
9 | * Copyright (C) 2004-2009 Dominik Brodowski | 9 | * Copyright (C) 2004-2010 Dominik Brodowski |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -22,7 +22,6 @@ | |||
22 | #include <pcmcia/cisreg.h> | 22 | #include <pcmcia/cisreg.h> |
23 | #include <pcmcia/cistpl.h> | 23 | #include <pcmcia/cistpl.h> |
24 | #include <pcmcia/ss.h> | 24 | #include <pcmcia/ss.h> |
25 | #include <pcmcia/cs.h> | ||
26 | #include <pcmcia/ds.h> | 25 | #include <pcmcia/ds.h> |
27 | #include "cs_internal.h" | 26 | #include "cs_internal.h" |
28 | 27 | ||
@@ -126,14 +125,24 @@ next_entry: | |||
126 | return ret; | 125 | return ret; |
127 | } | 126 | } |
128 | 127 | ||
128 | |||
129 | /** | ||
130 | * pcmcia_io_cfg_data_width() - convert cfgtable to data path width parameter | ||
131 | */ | ||
132 | static int pcmcia_io_cfg_data_width(unsigned int flags) | ||
133 | { | ||
134 | if (!(flags & CISTPL_IO_8BIT)) | ||
135 | return IO_DATA_PATH_WIDTH_16; | ||
136 | if (!(flags & CISTPL_IO_16BIT)) | ||
137 | return IO_DATA_PATH_WIDTH_8; | ||
138 | return IO_DATA_PATH_WIDTH_AUTO; | ||
139 | } | ||
140 | |||
141 | |||
129 | struct pcmcia_cfg_mem { | 142 | struct pcmcia_cfg_mem { |
130 | struct pcmcia_device *p_dev; | 143 | struct pcmcia_device *p_dev; |
144 | int (*conf_check) (struct pcmcia_device *p_dev, void *priv_data); | ||
131 | void *priv_data; | 145 | void *priv_data; |
132 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
133 | cistpl_cftable_entry_t *cfg, | ||
134 | cistpl_cftable_entry_t *dflt, | ||
135 | unsigned int vcc, | ||
136 | void *priv_data); | ||
137 | cisparse_t parse; | 146 | cisparse_t parse; |
138 | cistpl_cftable_entry_t dflt; | 147 | cistpl_cftable_entry_t dflt; |
139 | }; | 148 | }; |
@@ -147,25 +156,102 @@ struct pcmcia_cfg_mem { | |||
147 | */ | 156 | */ |
148 | static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) | 157 | static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) |
149 | { | 158 | { |
150 | cistpl_cftable_entry_t *cfg = &parse->cftable_entry; | ||
151 | struct pcmcia_cfg_mem *cfg_mem = priv; | 159 | struct pcmcia_cfg_mem *cfg_mem = priv; |
160 | struct pcmcia_device *p_dev = cfg_mem->p_dev; | ||
161 | cistpl_cftable_entry_t *cfg = &parse->cftable_entry; | ||
162 | cistpl_cftable_entry_t *dflt = &cfg_mem->dflt; | ||
163 | unsigned int flags = p_dev->config_flags; | ||
164 | unsigned int vcc = p_dev->socket->socket.Vcc; | ||
165 | |||
166 | dev_dbg(&p_dev->dev, "testing configuration %x, autoconf %x\n", | ||
167 | cfg->index, flags); | ||
152 | 168 | ||
153 | /* default values */ | 169 | /* default values */ |
154 | cfg_mem->p_dev->conf.ConfigIndex = cfg->index; | 170 | cfg_mem->p_dev->config_index = cfg->index; |
155 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | 171 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) |
156 | cfg_mem->dflt = *cfg; | 172 | cfg_mem->dflt = *cfg; |
157 | 173 | ||
158 | return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, | 174 | /* check for matching Vcc? */ |
159 | cfg_mem->p_dev->socket->socket.Vcc, | 175 | if (flags & CONF_AUTO_CHECK_VCC) { |
160 | cfg_mem->priv_data); | 176 | if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { |
177 | if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) | ||
178 | return -ENODEV; | ||
179 | } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { | ||
180 | if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) | ||
181 | return -ENODEV; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | /* set Vpp? */ | ||
186 | if (flags & CONF_AUTO_SET_VPP) { | ||
187 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) | ||
188 | p_dev->vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; | ||
189 | else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) | ||
190 | p_dev->vpp = | ||
191 | dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; | ||
192 | } | ||
193 | |||
194 | /* enable audio? */ | ||
195 | if ((flags & CONF_AUTO_AUDIO) && (cfg->flags & CISTPL_CFTABLE_AUDIO)) | ||
196 | p_dev->config_flags |= CONF_ENABLE_SPKR; | ||
197 | |||
198 | |||
199 | /* IO window settings? */ | ||
200 | if (flags & CONF_AUTO_SET_IO) { | ||
201 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; | ||
202 | int i = 0; | ||
203 | |||
204 | p_dev->resource[0]->start = p_dev->resource[0]->end = 0; | ||
205 | p_dev->resource[1]->start = p_dev->resource[1]->end = 0; | ||
206 | if (io->nwin == 0) | ||
207 | return -ENODEV; | ||
208 | |||
209 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | ||
210 | p_dev->resource[0]->flags |= | ||
211 | pcmcia_io_cfg_data_width(io->flags); | ||
212 | if (io->nwin > 1) { | ||
213 | /* For multifunction cards, by convention, we | ||
214 | * configure the network function with window 0, | ||
215 | * and serial with window 1 */ | ||
216 | i = (io->win[1].len > io->win[0].len); | ||
217 | p_dev->resource[1]->flags = p_dev->resource[0]->flags; | ||
218 | p_dev->resource[1]->start = io->win[1-i].base; | ||
219 | p_dev->resource[1]->end = io->win[1-i].len; | ||
220 | } | ||
221 | p_dev->resource[0]->start = io->win[i].base; | ||
222 | p_dev->resource[0]->end = io->win[i].len; | ||
223 | p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; | ||
224 | } | ||
225 | |||
226 | /* MEM window settings? */ | ||
227 | if (flags & CONF_AUTO_SET_IOMEM) { | ||
228 | /* so far, we only set one memory window */ | ||
229 | cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; | ||
230 | |||
231 | p_dev->resource[2]->start = p_dev->resource[2]->end = 0; | ||
232 | if (mem->nwin == 0) | ||
233 | return -ENODEV; | ||
234 | |||
235 | p_dev->resource[2]->start = mem->win[0].host_addr; | ||
236 | p_dev->resource[2]->end = mem->win[0].len; | ||
237 | if (p_dev->resource[2]->end < 0x1000) | ||
238 | p_dev->resource[2]->end = 0x1000; | ||
239 | p_dev->card_addr = mem->win[0].card_addr; | ||
240 | } | ||
241 | |||
242 | dev_dbg(&p_dev->dev, | ||
243 | "checking configuration %x: %pr %pr %pr (%d lines)\n", | ||
244 | p_dev->config_index, p_dev->resource[0], p_dev->resource[1], | ||
245 | p_dev->resource[2], p_dev->io_lines); | ||
246 | |||
247 | return cfg_mem->conf_check(p_dev, cfg_mem->priv_data); | ||
161 | } | 248 | } |
162 | 249 | ||
163 | /** | 250 | /** |
164 | * pcmcia_loop_config() - loop over configuration options | 251 | * pcmcia_loop_config() - loop over configuration options |
165 | * @p_dev: the struct pcmcia_device which we need to loop for. | 252 | * @p_dev: the struct pcmcia_device which we need to loop for. |
166 | * @conf_check: function to call for each configuration option. | 253 | * @conf_check: function to call for each configuration option. |
167 | * It gets passed the struct pcmcia_device, the CIS data | 254 | * It gets passed the struct pcmcia_device and private data |
168 | * describing the configuration option, and private data | ||
169 | * being passed to pcmcia_loop_config() | 255 | * being passed to pcmcia_loop_config() |
170 | * @priv_data: private data to be passed to the conf_check function. | 256 | * @priv_data: private data to be passed to the conf_check function. |
171 | * | 257 | * |
@@ -175,9 +261,6 @@ static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) | |||
175 | */ | 261 | */ |
176 | int pcmcia_loop_config(struct pcmcia_device *p_dev, | 262 | int pcmcia_loop_config(struct pcmcia_device *p_dev, |
177 | int (*conf_check) (struct pcmcia_device *p_dev, | 263 | int (*conf_check) (struct pcmcia_device *p_dev, |
178 | cistpl_cftable_entry_t *cfg, | ||
179 | cistpl_cftable_entry_t *dflt, | ||
180 | unsigned int vcc, | ||
181 | void *priv_data), | 264 | void *priv_data), |
182 | void *priv_data) | 265 | void *priv_data) |
183 | { | 266 | { |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 9ba4dade69a4..e8c19def1b0f 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | 6 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. |
7 | * | 7 | * |
8 | * Copyright (C) 1999 David A. Hinds | 8 | * Copyright (C) 1999 David A. Hinds |
9 | * Copyright (C) 2004-2005 Dominik Brodowski | 9 | * Copyright (C) 2004-2010 Dominik Brodowski |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | 27 | ||
28 | #include <pcmcia/ss.h> | 28 | #include <pcmcia/ss.h> |
29 | #include <pcmcia/cs.h> | ||
30 | #include <pcmcia/cistpl.h> | 29 | #include <pcmcia/cistpl.h> |
31 | #include <pcmcia/cisreg.h> | 30 | #include <pcmcia/cisreg.h> |
32 | #include <pcmcia/ds.h> | 31 | #include <pcmcia/ds.h> |
@@ -56,6 +55,12 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align, | |||
56 | } | 55 | } |
57 | 56 | ||
58 | 57 | ||
58 | /** | ||
59 | * release_io_space() - release IO ports allocated with alloc_io_space() | ||
60 | * @s: pcmcia socket | ||
61 | * @res: resource to release | ||
62 | * | ||
63 | */ | ||
59 | static void release_io_space(struct pcmcia_socket *s, struct resource *res) | 64 | static void release_io_space(struct pcmcia_socket *s, struct resource *res) |
60 | { | 65 | { |
61 | resource_size_t num = resource_size(res); | 66 | resource_size_t num = resource_size(res); |
@@ -81,9 +86,14 @@ static void release_io_space(struct pcmcia_socket *s, struct resource *res) | |||
81 | } | 86 | } |
82 | } | 87 | } |
83 | } | 88 | } |
84 | } /* release_io_space */ | 89 | } |
90 | |||
85 | 91 | ||
86 | /** alloc_io_space | 92 | /** |
93 | * alloc_io_space() - allocate IO ports for use by a PCMCIA device | ||
94 | * @s: pcmcia socket | ||
95 | * @res: resource to allocate (begin: begin, end: size) | ||
96 | * @lines: number of IO lines decoded by the PCMCIA card | ||
87 | * | 97 | * |
88 | * Special stuff for managing IO windows, because they are scarce | 98 | * Special stuff for managing IO windows, because they are scarce |
89 | */ | 99 | */ |
@@ -135,7 +145,7 @@ static int alloc_io_space(struct pcmcia_socket *s, struct resource *res, | |||
135 | } | 145 | } |
136 | dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res); | 146 | dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res); |
137 | return ret; | 147 | return ret; |
138 | } /* alloc_io_space */ | 148 | } |
139 | 149 | ||
140 | 150 | ||
141 | /** | 151 | /** |
@@ -163,19 +173,19 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev, | |||
163 | c = p_dev->function_config; | 173 | c = p_dev->function_config; |
164 | 174 | ||
165 | if (!(c->state & CONFIG_LOCKED)) { | 175 | if (!(c->state & CONFIG_LOCKED)) { |
166 | dev_dbg(&p_dev->dev, "Configuration isnt't locked\n"); | 176 | dev_dbg(&p_dev->dev, "Configuration isn't locked\n"); |
167 | mutex_unlock(&s->ops_mutex); | 177 | mutex_unlock(&s->ops_mutex); |
168 | return -EACCES; | 178 | return -EACCES; |
169 | } | 179 | } |
170 | 180 | ||
171 | addr = (c->ConfigBase + where) >> 1; | 181 | addr = (p_dev->config_base + where) >> 1; |
172 | 182 | ||
173 | ret = accessf(s, 1, addr, 1, val); | 183 | ret = accessf(s, 1, addr, 1, val); |
174 | 184 | ||
175 | mutex_unlock(&s->ops_mutex); | 185 | mutex_unlock(&s->ops_mutex); |
176 | 186 | ||
177 | return ret; | 187 | return ret; |
178 | } /* pcmcia_access_config */ | 188 | } |
179 | 189 | ||
180 | 190 | ||
181 | /** | 191 | /** |
@@ -204,11 +214,20 @@ int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val) | |||
204 | EXPORT_SYMBOL(pcmcia_write_config_byte); | 214 | EXPORT_SYMBOL(pcmcia_write_config_byte); |
205 | 215 | ||
206 | 216 | ||
207 | int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, | 217 | /** |
218 | * pcmcia_map_mem_page() - modify iomem window to point to a different offset | ||
219 | * @p_dev: pcmcia device | ||
220 | * @res: iomem resource already enabled by pcmcia_request_window() | ||
221 | * @offset: card_offset to map | ||
222 | * | ||
223 | * pcmcia_map_mem_page() modifies what can be read and written by accessing | ||
224 | * an iomem range previously enabled by pcmcia_request_window(), by setting | ||
225 | * the card_offset value to @offset. | ||
226 | */ | ||
227 | int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res, | ||
208 | unsigned int offset) | 228 | unsigned int offset) |
209 | { | 229 | { |
210 | struct pcmcia_socket *s = p_dev->socket; | 230 | struct pcmcia_socket *s = p_dev->socket; |
211 | struct resource *res = wh; | ||
212 | unsigned int w; | 231 | unsigned int w; |
213 | int ret; | 232 | int ret; |
214 | 233 | ||
@@ -223,98 +242,111 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, | |||
223 | dev_warn(&p_dev->dev, "failed to set_mem_map\n"); | 242 | dev_warn(&p_dev->dev, "failed to set_mem_map\n"); |
224 | mutex_unlock(&s->ops_mutex); | 243 | mutex_unlock(&s->ops_mutex); |
225 | return ret; | 244 | return ret; |
226 | } /* pcmcia_map_mem_page */ | 245 | } |
227 | EXPORT_SYMBOL(pcmcia_map_mem_page); | 246 | EXPORT_SYMBOL(pcmcia_map_mem_page); |
228 | 247 | ||
229 | 248 | ||
230 | /** pcmcia_modify_configuration | 249 | /** |
250 | * pcmcia_fixup_iowidth() - reduce io width to 8bit | ||
251 | * @p_dev: pcmcia device | ||
231 | * | 252 | * |
232 | * Modify a locked socket configuration | 253 | * pcmcia_fixup_iowidth() allows a PCMCIA device driver to reduce the |
254 | * IO width to 8bit after having called pcmcia_enable_device() | ||
255 | * previously. | ||
233 | */ | 256 | */ |
234 | int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | 257 | int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev) |
235 | modconf_t *mod) | ||
236 | { | 258 | { |
237 | struct pcmcia_socket *s; | 259 | struct pcmcia_socket *s = p_dev->socket; |
238 | config_t *c; | 260 | pccard_io_map io_off = { 0, 0, 0, 0, 1 }; |
239 | int ret; | 261 | pccard_io_map io_on; |
240 | 262 | int i, ret = 0; | |
241 | s = p_dev->socket; | ||
242 | 263 | ||
243 | mutex_lock(&s->ops_mutex); | 264 | mutex_lock(&s->ops_mutex); |
244 | c = p_dev->function_config; | ||
245 | 265 | ||
246 | if (!(s->state & SOCKET_PRESENT)) { | 266 | dev_dbg(&p_dev->dev, "fixup iowidth to 8bit\n"); |
247 | dev_dbg(&p_dev->dev, "No card present\n"); | 267 | |
248 | ret = -ENODEV; | 268 | if (!(s->state & SOCKET_PRESENT) || |
249 | goto unlock; | 269 | !(p_dev->function_config->state & CONFIG_LOCKED)) { |
250 | } | 270 | dev_dbg(&p_dev->dev, "No card? Config not locked?\n"); |
251 | if (!(c->state & CONFIG_LOCKED)) { | ||
252 | dev_dbg(&p_dev->dev, "Configuration isnt't locked\n"); | ||
253 | ret = -EACCES; | 271 | ret = -EACCES; |
254 | goto unlock; | 272 | goto unlock; |
255 | } | 273 | } |
256 | 274 | ||
257 | if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) { | 275 | io_on.speed = io_speed; |
258 | dev_dbg(&p_dev->dev, | 276 | for (i = 0; i < MAX_IO_WIN; i++) { |
259 | "changing Vcc or IRQ is not allowed at this time\n"); | 277 | if (!s->io[i].res) |
260 | ret = -EINVAL; | 278 | continue; |
261 | goto unlock; | 279 | io_off.map = i; |
262 | } | 280 | io_on.map = i; |
263 | 281 | ||
264 | /* We only allow changing Vpp1 and Vpp2 to the same value */ | 282 | io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8; |
265 | if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && | 283 | io_on.start = s->io[i].res->start; |
266 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { | 284 | io_on.stop = s->io[i].res->end; |
267 | if (mod->Vpp1 != mod->Vpp2) { | 285 | |
268 | dev_dbg(&p_dev->dev, | 286 | s->ops->set_io_map(s, &io_off); |
269 | "Vpp1 and Vpp2 must be the same\n"); | 287 | mdelay(40); |
270 | ret = -EINVAL; | 288 | s->ops->set_io_map(s, &io_on); |
271 | goto unlock; | ||
272 | } | ||
273 | s->socket.Vpp = mod->Vpp1; | ||
274 | if (s->ops->set_socket(s, &s->socket)) { | ||
275 | dev_printk(KERN_WARNING, &p_dev->dev, | ||
276 | "Unable to set VPP\n"); | ||
277 | ret = -EIO; | ||
278 | goto unlock; | ||
279 | } | ||
280 | } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || | ||
281 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { | ||
282 | dev_dbg(&p_dev->dev, | ||
283 | "changing Vcc is not allowed at this time\n"); | ||
284 | ret = -EINVAL; | ||
285 | goto unlock; | ||
286 | } | 289 | } |
290 | unlock: | ||
291 | mutex_unlock(&s->ops_mutex); | ||
287 | 292 | ||
288 | if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { | 293 | return ret; |
289 | pccard_io_map io_off = { 0, 0, 0, 0, 1 }; | 294 | } |
290 | pccard_io_map io_on; | 295 | EXPORT_SYMBOL(pcmcia_fixup_iowidth); |
291 | int i; | ||
292 | 296 | ||
293 | io_on.speed = io_speed; | ||
294 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
295 | if (!s->io[i].res) | ||
296 | continue; | ||
297 | io_off.map = i; | ||
298 | io_on.map = i; | ||
299 | 297 | ||
300 | io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8; | 298 | /** |
301 | io_on.start = s->io[i].res->start; | 299 | * pcmcia_fixup_vpp() - set Vpp to a new voltage level |
302 | io_on.stop = s->io[i].res->end; | 300 | * @p_dev: pcmcia device |
301 | * @new_vpp: new Vpp voltage | ||
302 | * | ||
303 | * pcmcia_fixup_vpp() allows a PCMCIA device driver to set Vpp to | ||
304 | * a new voltage level between calls to pcmcia_enable_device() | ||
305 | * and pcmcia_disable_device(). | ||
306 | */ | ||
307 | int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp) | ||
308 | { | ||
309 | struct pcmcia_socket *s = p_dev->socket; | ||
310 | int ret = 0; | ||
303 | 311 | ||
304 | s->ops->set_io_map(s, &io_off); | 312 | mutex_lock(&s->ops_mutex); |
305 | mdelay(40); | 313 | |
306 | s->ops->set_io_map(s, &io_on); | 314 | dev_dbg(&p_dev->dev, "fixup Vpp to %d\n", new_vpp); |
307 | } | 315 | |
316 | if (!(s->state & SOCKET_PRESENT) || | ||
317 | !(p_dev->function_config->state & CONFIG_LOCKED)) { | ||
318 | dev_dbg(&p_dev->dev, "No card? Config not locked?\n"); | ||
319 | ret = -EACCES; | ||
320 | goto unlock; | ||
321 | } | ||
322 | |||
323 | s->socket.Vpp = new_vpp; | ||
324 | if (s->ops->set_socket(s, &s->socket)) { | ||
325 | dev_warn(&p_dev->dev, "Unable to set VPP\n"); | ||
326 | ret = -EIO; | ||
327 | goto unlock; | ||
308 | } | 328 | } |
309 | ret = 0; | 329 | p_dev->vpp = new_vpp; |
330 | |||
310 | unlock: | 331 | unlock: |
311 | mutex_unlock(&s->ops_mutex); | 332 | mutex_unlock(&s->ops_mutex); |
312 | 333 | ||
313 | return ret; | 334 | return ret; |
314 | } /* modify_configuration */ | 335 | } |
315 | EXPORT_SYMBOL(pcmcia_modify_configuration); | 336 | EXPORT_SYMBOL(pcmcia_fixup_vpp); |
316 | 337 | ||
317 | 338 | ||
339 | /** | ||
340 | * pcmcia_release_configuration() - physically disable a PCMCIA device | ||
341 | * @p_dev: pcmcia device | ||
342 | * | ||
343 | * pcmcia_release_configuration() is the 1:1 counterpart to | ||
344 | * pcmcia_enable_device(): If a PCMCIA device is no longer used by any | ||
345 | * driver, the Vpp voltage is set to 0, IRQs will no longer be generated, | ||
346 | * and I/O ranges will be disabled. As pcmcia_release_io() and | ||
347 | * pcmcia_release_window() still need to be called, device drivers are | ||
348 | * expected to call pcmcia_disable_device() instead. | ||
349 | */ | ||
318 | int pcmcia_release_configuration(struct pcmcia_device *p_dev) | 350 | int pcmcia_release_configuration(struct pcmcia_device *p_dev) |
319 | { | 351 | { |
320 | pccard_io_map io = { 0, 0, 0, 0, 1 }; | 352 | pccard_io_map io = { 0, 0, 0, 0, 1 }; |
@@ -327,7 +359,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) | |||
327 | if (p_dev->_locked) { | 359 | if (p_dev->_locked) { |
328 | p_dev->_locked = 0; | 360 | p_dev->_locked = 0; |
329 | if (--(s->lock_count) == 0) { | 361 | if (--(s->lock_count) == 0) { |
330 | s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ | 362 | s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ |
331 | s->socket.Vpp = 0; | 363 | s->socket.Vpp = 0; |
332 | s->socket.io_irq = 0; | 364 | s->socket.io_irq = 0; |
333 | s->ops->set_socket(s, &s->socket); | 365 | s->ops->set_socket(s, &s->socket); |
@@ -349,16 +381,18 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) | |||
349 | mutex_unlock(&s->ops_mutex); | 381 | mutex_unlock(&s->ops_mutex); |
350 | 382 | ||
351 | return 0; | 383 | return 0; |
352 | } /* pcmcia_release_configuration */ | 384 | } |
353 | 385 | ||
354 | 386 | ||
355 | /** pcmcia_release_io | 387 | /** |
388 | * pcmcia_release_io() - release I/O allocated by a PCMCIA device | ||
389 | * @p_dev: pcmcia device | ||
356 | * | 390 | * |
357 | * Release_io() releases the I/O ranges allocated by a client. This | 391 | * pcmcia_release_io() releases the I/O ranges allocated by a PCMCIA |
358 | * may be invoked some time after a card ejection has already dumped | 392 | * device. This may be invoked some time after a card ejection has |
359 | * the actual socket configuration, so if the client is "stale", we | 393 | * already dumped the actual socket configuration, so if the client is |
360 | * don't bother checking the port ranges against the current socket | 394 | * "stale", we don't bother checking the port ranges against the |
361 | * values. | 395 | * current socket values. |
362 | */ | 396 | */ |
363 | static int pcmcia_release_io(struct pcmcia_device *p_dev) | 397 | static int pcmcia_release_io(struct pcmcia_device *p_dev) |
364 | { | 398 | { |
@@ -387,6 +421,14 @@ out: | |||
387 | } /* pcmcia_release_io */ | 421 | } /* pcmcia_release_io */ |
388 | 422 | ||
389 | 423 | ||
424 | /** | ||
425 | * pcmcia_release_window() - release reserved iomem for PCMCIA devices | ||
426 | * @p_dev: pcmcia device | ||
427 | * @res: iomem resource to release | ||
428 | * | ||
429 | * pcmcia_release_window() releases &struct resource *res which was | ||
430 | * previously reserved by calling pcmcia_request_window(). | ||
431 | */ | ||
390 | int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) | 432 | int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) |
391 | { | 433 | { |
392 | struct pcmcia_socket *s = p_dev->socket; | 434 | struct pcmcia_socket *s = p_dev->socket; |
@@ -420,6 +462,8 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) | |||
420 | kfree(win->res); | 462 | kfree(win->res); |
421 | win->res = NULL; | 463 | win->res = NULL; |
422 | } | 464 | } |
465 | res->start = res->end = 0; | ||
466 | res->flags = IORESOURCE_MEM; | ||
423 | p_dev->_win &= ~CLIENT_WIN_REQ(w); | 467 | p_dev->_win &= ~CLIENT_WIN_REQ(w); |
424 | mutex_unlock(&s->ops_mutex); | 468 | mutex_unlock(&s->ops_mutex); |
425 | 469 | ||
@@ -428,23 +472,30 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) | |||
428 | EXPORT_SYMBOL(pcmcia_release_window); | 472 | EXPORT_SYMBOL(pcmcia_release_window); |
429 | 473 | ||
430 | 474 | ||
431 | int pcmcia_request_configuration(struct pcmcia_device *p_dev, | 475 | /** |
432 | config_req_t *req) | 476 | * pcmcia_enable_device() - set up and activate a PCMCIA device |
477 | * @p_dev: the associated PCMCIA device | ||
478 | * | ||
479 | * pcmcia_enable_device() physically enables a PCMCIA device. It parses | ||
480 | * the flags passed to in @flags and stored in @p_dev->flags and sets up | ||
481 | * the Vpp voltage, enables the speaker line, I/O ports and store proper | ||
482 | * values to configuration registers. | ||
483 | */ | ||
484 | int pcmcia_enable_device(struct pcmcia_device *p_dev) | ||
433 | { | 485 | { |
434 | int i; | 486 | int i; |
435 | u_int base; | 487 | unsigned int base; |
436 | struct pcmcia_socket *s = p_dev->socket; | 488 | struct pcmcia_socket *s = p_dev->socket; |
437 | config_t *c; | 489 | config_t *c; |
438 | pccard_io_map iomap; | 490 | pccard_io_map iomap; |
491 | unsigned char status = 0; | ||
492 | unsigned char ext_status = 0; | ||
493 | unsigned char option = 0; | ||
494 | unsigned int flags = p_dev->config_flags; | ||
439 | 495 | ||
440 | if (!(s->state & SOCKET_PRESENT)) | 496 | if (!(s->state & SOCKET_PRESENT)) |
441 | return -ENODEV; | 497 | return -ENODEV; |
442 | 498 | ||
443 | if (req->IntType & INT_CARDBUS) { | ||
444 | dev_dbg(&p_dev->dev, "IntType may not be INT_CARDBUS\n"); | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | mutex_lock(&s->ops_mutex); | 499 | mutex_lock(&s->ops_mutex); |
449 | c = p_dev->function_config; | 500 | c = p_dev->function_config; |
450 | if (c->state & CONFIG_LOCKED) { | 501 | if (c->state & CONFIG_LOCKED) { |
@@ -454,7 +505,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
454 | } | 505 | } |
455 | 506 | ||
456 | /* Do power control. We don't allow changes in Vcc. */ | 507 | /* Do power control. We don't allow changes in Vcc. */ |
457 | s->socket.Vpp = req->Vpp; | 508 | s->socket.Vpp = p_dev->vpp; |
458 | if (s->ops->set_socket(s, &s->socket)) { | 509 | if (s->ops->set_socket(s, &s->socket)) { |
459 | mutex_unlock(&s->ops_mutex); | 510 | mutex_unlock(&s->ops_mutex); |
460 | dev_printk(KERN_WARNING, &p_dev->dev, | 511 | dev_printk(KERN_WARNING, &p_dev->dev, |
@@ -463,64 +514,76 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
463 | } | 514 | } |
464 | 515 | ||
465 | /* Pick memory or I/O card, DMA mode, interrupt */ | 516 | /* Pick memory or I/O card, DMA mode, interrupt */ |
466 | c->IntType = req->IntType; | 517 | if (p_dev->_io || flags & CONF_ENABLE_IRQ) |
467 | c->Attributes = req->Attributes; | 518 | flags |= CONF_ENABLE_IOCARD; |
468 | if (req->IntType & INT_MEMORY_AND_IO) | 519 | if (flags & CONF_ENABLE_IOCARD) |
469 | s->socket.flags |= SS_IOCARD; | 520 | s->socket.flags |= SS_IOCARD; |
470 | if (req->IntType & INT_ZOOMED_VIDEO) | 521 | if (flags & CONF_ENABLE_ZVCARD) |
471 | s->socket.flags |= SS_ZVCARD | SS_IOCARD; | 522 | s->socket.flags |= SS_ZVCARD | SS_IOCARD; |
472 | if (req->Attributes & CONF_ENABLE_DMA) | 523 | if (flags & CONF_ENABLE_SPKR) { |
473 | s->socket.flags |= SS_DMA_MODE; | ||
474 | if (req->Attributes & CONF_ENABLE_SPKR) | ||
475 | s->socket.flags |= SS_SPKR_ENA; | 524 | s->socket.flags |= SS_SPKR_ENA; |
476 | if (req->Attributes & CONF_ENABLE_IRQ) | 525 | status = CCSR_AUDIO_ENA; |
526 | if (!(p_dev->config_regs & PRESENT_STATUS)) | ||
527 | dev_warn(&p_dev->dev, "speaker requested, but " | ||
528 | "PRESENT_STATUS not set!\n"); | ||
529 | } | ||
530 | if (flags & CONF_ENABLE_IRQ) | ||
477 | s->socket.io_irq = s->pcmcia_irq; | 531 | s->socket.io_irq = s->pcmcia_irq; |
478 | else | 532 | else |
479 | s->socket.io_irq = 0; | 533 | s->socket.io_irq = 0; |
534 | if (flags & CONF_ENABLE_ESR) { | ||
535 | p_dev->config_regs |= PRESENT_EXT_STATUS; | ||
536 | ext_status = ESR_REQ_ATTN_ENA; | ||
537 | } | ||
480 | s->ops->set_socket(s, &s->socket); | 538 | s->ops->set_socket(s, &s->socket); |
481 | s->lock_count++; | 539 | s->lock_count++; |
482 | 540 | ||
541 | dev_dbg(&p_dev->dev, | ||
542 | "enable_device: V %d, flags %x, base %x, regs %x, idx %x\n", | ||
543 | p_dev->vpp, flags, p_dev->config_base, p_dev->config_regs, | ||
544 | p_dev->config_index); | ||
545 | |||
483 | /* Set up CIS configuration registers */ | 546 | /* Set up CIS configuration registers */ |
484 | base = c->ConfigBase = req->ConfigBase; | 547 | base = p_dev->config_base; |
485 | c->CardValues = req->Present; | 548 | if (p_dev->config_regs & PRESENT_COPY) { |
486 | if (req->Present & PRESENT_COPY) { | 549 | u16 tmp = 0; |
487 | c->Copy = req->Copy; | 550 | dev_dbg(&p_dev->dev, "clearing CISREG_SCR\n"); |
488 | pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy); | 551 | pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &tmp); |
489 | } | 552 | } |
490 | if (req->Present & PRESENT_OPTION) { | 553 | if (p_dev->config_regs & PRESENT_PIN_REPLACE) { |
554 | u16 tmp = 0; | ||
555 | dev_dbg(&p_dev->dev, "clearing CISREG_PRR\n"); | ||
556 | pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &tmp); | ||
557 | } | ||
558 | if (p_dev->config_regs & PRESENT_OPTION) { | ||
491 | if (s->functions == 1) { | 559 | if (s->functions == 1) { |
492 | c->Option = req->ConfigIndex & COR_CONFIG_MASK; | 560 | option = p_dev->config_index & COR_CONFIG_MASK; |
493 | } else { | 561 | } else { |
494 | c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK; | 562 | option = p_dev->config_index & COR_MFC_CONFIG_MASK; |
495 | c->Option |= COR_FUNC_ENA|COR_IREQ_ENA; | 563 | option |= COR_FUNC_ENA|COR_IREQ_ENA; |
496 | if (req->Present & PRESENT_IOBASE_0) | 564 | if (p_dev->config_regs & PRESENT_IOBASE_0) |
497 | c->Option |= COR_ADDR_DECODE; | 565 | option |= COR_ADDR_DECODE; |
498 | } | 566 | } |
499 | if ((req->Attributes & CONF_ENABLE_IRQ) && | 567 | if ((flags & CONF_ENABLE_IRQ) && |
500 | !(req->Attributes & CONF_ENABLE_PULSE_IRQ)) | 568 | !(flags & CONF_ENABLE_PULSE_IRQ)) |
501 | c->Option |= COR_LEVEL_REQ; | 569 | option |= COR_LEVEL_REQ; |
502 | pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); | 570 | pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &option); |
503 | mdelay(40); | 571 | mdelay(40); |
504 | } | 572 | } |
505 | if (req->Present & PRESENT_STATUS) { | 573 | if (p_dev->config_regs & PRESENT_STATUS) |
506 | c->Status = req->Status; | 574 | pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &status); |
507 | pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status); | 575 | |
508 | } | 576 | if (p_dev->config_regs & PRESENT_EXT_STATUS) |
509 | if (req->Present & PRESENT_PIN_REPLACE) { | 577 | pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, |
510 | c->Pin = req->Pin; | 578 | &ext_status); |
511 | pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin); | 579 | |
512 | } | 580 | if (p_dev->config_regs & PRESENT_IOBASE_0) { |
513 | if (req->Present & PRESENT_EXT_STATUS) { | ||
514 | c->ExtStatus = req->ExtStatus; | ||
515 | pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus); | ||
516 | } | ||
517 | if (req->Present & PRESENT_IOBASE_0) { | ||
518 | u8 b = c->io[0].start & 0xff; | 581 | u8 b = c->io[0].start & 0xff; |
519 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b); | 582 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b); |
520 | b = (c->io[0].start >> 8) & 0xff; | 583 | b = (c->io[0].start >> 8) & 0xff; |
521 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b); | 584 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b); |
522 | } | 585 | } |
523 | if (req->Present & PRESENT_IOSIZE) { | 586 | if (p_dev->config_regs & PRESENT_IOSIZE) { |
524 | u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1; | 587 | u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1; |
525 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b); | 588 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b); |
526 | } | 589 | } |
@@ -551,14 +614,15 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
551 | p_dev->_locked = 1; | 614 | p_dev->_locked = 1; |
552 | mutex_unlock(&s->ops_mutex); | 615 | mutex_unlock(&s->ops_mutex); |
553 | return 0; | 616 | return 0; |
554 | } /* pcmcia_request_configuration */ | 617 | } /* pcmcia_enable_device */ |
555 | EXPORT_SYMBOL(pcmcia_request_configuration); | 618 | EXPORT_SYMBOL(pcmcia_enable_device); |
556 | 619 | ||
557 | 620 | ||
558 | /** | 621 | /** |
559 | * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices | 622 | * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices |
623 | * @p_dev: the associated PCMCIA device | ||
560 | * | 624 | * |
561 | * pcmcia_request_io() attepts to reserve the IO port ranges specified in | 625 | * pcmcia_request_io() attempts to reserve the IO port ranges specified in |
562 | * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The | 626 | * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The |
563 | * "start" value is the requested start of the IO port resource; "end" | 627 | * "start" value is the requested start of the IO port resource; "end" |
564 | * reflects the number of ports requested. The number of IO lines requested | 628 | * reflects the number of ports requested. The number of IO lines requested |
@@ -622,11 +686,13 @@ EXPORT_SYMBOL(pcmcia_request_io); | |||
622 | 686 | ||
623 | /** | 687 | /** |
624 | * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device | 688 | * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device |
689 | * @p_dev: the associated PCMCIA device | ||
690 | * @handler: IRQ handler to register | ||
625 | * | 691 | * |
626 | * pcmcia_request_irq() is a wrapper around request_irq which will allow | 692 | * pcmcia_request_irq() is a wrapper around request_irq() which allows |
627 | * the PCMCIA core to clean up the registration in pcmcia_disable_device(). | 693 | * the PCMCIA core to clean up the registration in pcmcia_disable_device(). |
628 | * Drivers are free to use request_irq() directly, but then they need to | 694 | * Drivers are free to use request_irq() directly, but then they need to |
629 | * call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ | 695 | * call free_irq() themselfves, too. Also, only %IRQF_SHARED capable IRQ |
630 | * handlers are allowed. | 696 | * handlers are allowed. |
631 | */ | 697 | */ |
632 | int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, | 698 | int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, |
@@ -649,12 +715,14 @@ EXPORT_SYMBOL(pcmcia_request_irq); | |||
649 | 715 | ||
650 | /** | 716 | /** |
651 | * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first | 717 | * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first |
718 | * @p_dev: the associated PCMCIA device | ||
719 | * @handler: IRQ handler to register | ||
652 | * | 720 | * |
653 | * pcmcia_request_exclusive_irq() is a wrapper around request_irq which | 721 | * pcmcia_request_exclusive_irq() is a wrapper around request_irq() which |
654 | * attempts first to request an exclusive IRQ. If it fails, it also accepts | 722 | * attempts first to request an exclusive IRQ. If it fails, it also accepts |
655 | * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for | 723 | * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for |
656 | * IRQ sharing and either use request_irq directly (then they need to call | 724 | * IRQ sharing and either use request_irq directly (then they need to call |
657 | * free_irq themselves, too), or the pcmcia_request_irq() function. | 725 | * free_irq() themselves, too), or the pcmcia_request_irq() function. |
658 | */ | 726 | */ |
659 | int __must_check | 727 | int __must_check |
660 | __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, | 728 | __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, |
@@ -795,38 +863,47 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev) | |||
795 | } | 863 | } |
796 | 864 | ||
797 | 865 | ||
798 | /** pcmcia_request_window | 866 | /** |
867 | * pcmcia_request_window() - attempt to reserve iomem for PCMCIA devices | ||
868 | * @p_dev: the associated PCMCIA device | ||
869 | * @res: &struct resource pointing to p_dev->resource[2..5] | ||
870 | * @speed: access speed | ||
799 | * | 871 | * |
800 | * Request_window() establishes a mapping between card memory space | 872 | * pcmcia_request_window() attepts to reserve an iomem ranges specified in |
801 | * and system memory space. | 873 | * &struct resource @res pointing to one of the entries in |
874 | * &struct pcmcia_device @p_dev->resource[2..5]. The "start" value is the | ||
875 | * requested start of the IO mem resource; "end" reflects the size | ||
876 | * requested. | ||
802 | */ | 877 | */ |
803 | int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh) | 878 | int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res, |
879 | unsigned int speed) | ||
804 | { | 880 | { |
805 | struct pcmcia_socket *s = p_dev->socket; | 881 | struct pcmcia_socket *s = p_dev->socket; |
806 | pccard_mem_map *win; | 882 | pccard_mem_map *win; |
807 | u_long align; | 883 | u_long align; |
808 | struct resource *res; | ||
809 | int w; | 884 | int w; |
810 | 885 | ||
886 | dev_dbg(&p_dev->dev, "request_window %pR %d\n", res, speed); | ||
887 | |||
811 | if (!(s->state & SOCKET_PRESENT)) { | 888 | if (!(s->state & SOCKET_PRESENT)) { |
812 | dev_dbg(&p_dev->dev, "No card present\n"); | 889 | dev_dbg(&p_dev->dev, "No card present\n"); |
813 | return -ENODEV; | 890 | return -ENODEV; |
814 | } | 891 | } |
815 | 892 | ||
816 | /* Window size defaults to smallest available */ | 893 | /* Window size defaults to smallest available */ |
817 | if (req->Size == 0) | 894 | if (res->end == 0) |
818 | req->Size = s->map_size; | 895 | res->end = s->map_size; |
819 | align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; | 896 | align = (s->features & SS_CAP_MEM_ALIGN) ? res->end : s->map_size; |
820 | if (req->Size & (s->map_size-1)) { | 897 | if (res->end & (s->map_size-1)) { |
821 | dev_dbg(&p_dev->dev, "invalid map size\n"); | 898 | dev_dbg(&p_dev->dev, "invalid map size\n"); |
822 | return -EINVAL; | 899 | return -EINVAL; |
823 | } | 900 | } |
824 | if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || | 901 | if ((res->start && (s->features & SS_CAP_STATIC_MAP)) || |
825 | (req->Base & (align-1))) { | 902 | (res->start & (align-1))) { |
826 | dev_dbg(&p_dev->dev, "invalid base address\n"); | 903 | dev_dbg(&p_dev->dev, "invalid base address\n"); |
827 | return -EINVAL; | 904 | return -EINVAL; |
828 | } | 905 | } |
829 | if (req->Base) | 906 | if (res->start) |
830 | align = 0; | 907 | align = 0; |
831 | 908 | ||
832 | /* Allocate system memory window */ | 909 | /* Allocate system memory window */ |
@@ -843,7 +920,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
843 | win = &s->win[w]; | 920 | win = &s->win[w]; |
844 | 921 | ||
845 | if (!(s->features & SS_CAP_STATIC_MAP)) { | 922 | if (!(s->features & SS_CAP_STATIC_MAP)) { |
846 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, | 923 | win->res = pcmcia_find_mem_region(res->start, res->end, align, |
847 | 0, s); | 924 | 0, s); |
848 | if (!win->res) { | 925 | if (!win->res) { |
849 | dev_dbg(&p_dev->dev, "allocating mem region failed\n"); | 926 | dev_dbg(&p_dev->dev, "allocating mem region failed\n"); |
@@ -855,8 +932,8 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
855 | 932 | ||
856 | /* Configure the socket controller */ | 933 | /* Configure the socket controller */ |
857 | win->map = w+1; | 934 | win->map = w+1; |
858 | win->flags = req->Attributes; | 935 | win->flags = res->flags & WIN_FLAGS_MAP; |
859 | win->speed = req->AccessSpeed; | 936 | win->speed = speed; |
860 | win->card_start = 0; | 937 | win->card_start = 0; |
861 | 938 | ||
862 | if (s->ops->set_mem_map(s, win) != 0) { | 939 | if (s->ops->set_mem_map(s, win) != 0) { |
@@ -868,17 +945,14 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
868 | 945 | ||
869 | /* Return window handle */ | 946 | /* Return window handle */ |
870 | if (s->features & SS_CAP_STATIC_MAP) | 947 | if (s->features & SS_CAP_STATIC_MAP) |
871 | req->Base = win->static_start; | 948 | res->start = win->static_start; |
872 | else | 949 | else |
873 | req->Base = win->res->start; | 950 | res->start = win->res->start; |
874 | 951 | ||
875 | /* convert to new-style resources */ | 952 | /* convert to new-style resources */ |
876 | res = p_dev->resource[w + MAX_IO_WIN]; | 953 | res->end += res->start - 1; |
877 | res->start = req->Base; | 954 | res->flags &= ~WIN_FLAGS_REQ; |
878 | res->end = req->Base + req->Size - 1; | 955 | res->flags |= (win->map << 2) | IORESOURCE_MEM; |
879 | res->flags &= ~IORESOURCE_BITS; | ||
880 | res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2); | ||
881 | res->flags |= IORESOURCE_MEM; | ||
882 | res->parent = win->res; | 956 | res->parent = win->res; |
883 | if (win->res) | 957 | if (win->res) |
884 | request_resource(&iomem_resource, res); | 958 | request_resource(&iomem_resource, res); |
@@ -886,15 +960,30 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
886 | dev_dbg(&p_dev->dev, "request_window results in %pR\n", res); | 960 | dev_dbg(&p_dev->dev, "request_window results in %pR\n", res); |
887 | 961 | ||
888 | mutex_unlock(&s->ops_mutex); | 962 | mutex_unlock(&s->ops_mutex); |
889 | *wh = res; | ||
890 | 963 | ||
891 | return 0; | 964 | return 0; |
892 | } /* pcmcia_request_window */ | 965 | } /* pcmcia_request_window */ |
893 | EXPORT_SYMBOL(pcmcia_request_window); | 966 | EXPORT_SYMBOL(pcmcia_request_window); |
894 | 967 | ||
968 | |||
969 | /** | ||
970 | * pcmcia_disable_device() - disable and clean up a PCMCIA device | ||
971 | * @p_dev: the associated PCMCIA device | ||
972 | * | ||
973 | * pcmcia_disable_device() is the driver-callable counterpart to | ||
974 | * pcmcia_enable_device(): If a PCMCIA device is no longer used, | ||
975 | * drivers are expected to clean up and disable the device by calling | ||
976 | * this function. Any I/O ranges (iomem and ioports) will be released, | ||
977 | * the Vpp voltage will be set to 0, and IRQs will no longer be | ||
978 | * generated -- at least if there is no other card function (of | ||
979 | * multifunction devices) being used. | ||
980 | */ | ||
895 | void pcmcia_disable_device(struct pcmcia_device *p_dev) | 981 | void pcmcia_disable_device(struct pcmcia_device *p_dev) |
896 | { | 982 | { |
897 | int i; | 983 | int i; |
984 | |||
985 | dev_dbg(&p_dev->dev, "disabling device\n"); | ||
986 | |||
898 | for (i = 0; i < MAX_WIN; i++) { | 987 | for (i = 0; i < MAX_WIN; i++) { |
899 | struct resource *res = p_dev->resource[MAX_IO_WIN + i]; | 988 | struct resource *res = p_dev->resource[MAX_IO_WIN + i]; |
900 | if (res->flags & WIN_FLAGS_REQ) | 989 | if (res->flags & WIN_FLAGS_REQ) |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index deef6656ab7b..96c72e90b79c 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | 19 | ||
20 | #include <pcmcia/ss.h> | 20 | #include <pcmcia/ss.h> |
21 | #include <pcmcia/cs.h> | ||
22 | 21 | ||
23 | #include <asm/system.h> | 22 | #include <asm/system.h> |
24 | 23 | ||
@@ -726,17 +725,17 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
726 | 725 | ||
727 | return 0; | 726 | return 0; |
728 | 727 | ||
729 | err_out_free_res2: | 728 | err_out_free_res2: |
730 | if (irq_mode == 1) | 729 | if (irq_mode == 1) |
731 | free_irq(dev->irq, socket); | 730 | free_irq(dev->irq, socket); |
732 | else | 731 | else |
733 | del_timer_sync(&socket->poll_timer); | 732 | del_timer_sync(&socket->poll_timer); |
734 | err_out_free_res: | 733 | err_out_free_res: |
735 | pci_release_regions(dev); | 734 | pci_release_regions(dev); |
736 | err_out_disable: | 735 | err_out_disable: |
737 | pci_disable_device(dev); | 736 | pci_disable_device(dev); |
738 | 737 | ||
739 | err_out_free_mem: | 738 | err_out_free_mem: |
740 | kfree(socket); | 739 | kfree(socket); |
741 | return ret; | 740 | return ret; |
742 | } | 741 | } |
diff --git a/drivers/pcmcia/pd6729.h b/drivers/pcmcia/pd6729.h index 41418d394c55..c8e84bdece38 100644 --- a/drivers/pcmcia/pd6729.h +++ b/drivers/pcmcia/pd6729.h | |||
@@ -15,7 +15,7 @@ | |||
15 | struct pd6729_socket { | 15 | struct pd6729_socket { |
16 | int number; | 16 | int number; |
17 | int card_irq; | 17 | int card_irq; |
18 | unsigned long io_base; /* base io address of the socket */ | 18 | unsigned long io_base; /* base io address of the socket */ |
19 | struct pcmcia_socket socket; | 19 | struct pcmcia_socket socket; |
20 | struct timer_list poll_timer; | 20 | struct timer_list poll_timer; |
21 | }; | 21 | }; |
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c index dbbdd0063202..4c3e94c0ae85 100644 --- a/drivers/pcmcia/pxa2xx_balloon3.c +++ b/drivers/pcmcia/pxa2xx_balloon3.c | |||
@@ -25,6 +25,8 @@ | |||
25 | 25 | ||
26 | #include <mach/balloon3.h> | 26 | #include <mach/balloon3.h> |
27 | 27 | ||
28 | #include <asm/mach-types.h> | ||
29 | |||
28 | #include "soc_common.h" | 30 | #include "soc_common.h" |
29 | 31 | ||
30 | /* | 32 | /* |
@@ -39,12 +41,10 @@ static struct pcmcia_irqs irqs[] = { | |||
39 | static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 41 | static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
40 | { | 42 | { |
41 | uint16_t ver; | 43 | uint16_t ver; |
42 | int ret; | ||
43 | static void __iomem *fpga_ver; | ||
44 | 44 | ||
45 | ver = __raw_readw(BALLOON3_FPGA_VER); | 45 | ver = __raw_readw(BALLOON3_FPGA_VER); |
46 | if (ver > 0x0201) | 46 | if (ver < 0x4f08) |
47 | pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. " | 47 | pr_warn("The FPGA code, version 0x%04x, is too old. " |
48 | "PCMCIA/CF support might be broken in this version!", | 48 | "PCMCIA/CF support might be broken in this version!", |
49 | ver); | 49 | ver); |
50 | 50 | ||
@@ -97,8 +97,9 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
97 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 97 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
98 | const socket_state_t *state) | 98 | const socket_state_t *state) |
99 | { | 99 | { |
100 | __raw_writew((state->flags & SS_RESET) ? BALLOON3_CF_RESET : 0, | 100 | __raw_writew(BALLOON3_CF_RESET, BALLOON3_CF_CONTROL_REG | |
101 | BALLOON3_CF_CONTROL_REG); | 101 | ((state->flags & SS_RESET) ? |
102 | BALLOON3_FPGA_SETnCLR : 0)); | ||
102 | return 0; | 103 | return 0; |
103 | } | 104 | } |
104 | 105 | ||
@@ -128,6 +129,9 @@ static int __init balloon3_pcmcia_init(void) | |||
128 | { | 129 | { |
129 | int ret; | 130 | int ret; |
130 | 131 | ||
132 | if (!machine_is_balloon3()) | ||
133 | return -ENODEV; | ||
134 | |||
131 | balloon3_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | 135 | balloon3_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); |
132 | if (!balloon3_pcmcia_device) | 136 | if (!balloon3_pcmcia_device) |
133 | return -ENOMEM; | 137 | return -ENOMEM; |
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index ae07b4db8a6e..2c540542b5af 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | 27 | ||
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/smemc.h> | ||
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
@@ -116,37 +117,49 @@ static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz, | |||
116 | 117 | ||
117 | static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock ) | 118 | static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock ) |
118 | { | 119 | { |
119 | MCMEM(sock) = ((pxa2xx_mcxx_setup(speed, clock) | 120 | uint32_t val; |
121 | |||
122 | val = ((pxa2xx_mcxx_setup(speed, clock) | ||
120 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | 123 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) |
121 | | ((pxa2xx_mcxx_asst(speed, clock) | 124 | | ((pxa2xx_mcxx_asst(speed, clock) |
122 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | 125 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) |
123 | | ((pxa2xx_mcxx_hold(speed, clock) | 126 | | ((pxa2xx_mcxx_hold(speed, clock) |
124 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); | 127 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); |
125 | 128 | ||
129 | __raw_writel(val, MCMEM(sock)); | ||
130 | |||
126 | return 0; | 131 | return 0; |
127 | } | 132 | } |
128 | 133 | ||
129 | static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock ) | 134 | static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock ) |
130 | { | 135 | { |
131 | MCIO(sock) = ((pxa2xx_mcxx_setup(speed, clock) | 136 | uint32_t val; |
137 | |||
138 | val = ((pxa2xx_mcxx_setup(speed, clock) | ||
132 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | 139 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) |
133 | | ((pxa2xx_mcxx_asst(speed, clock) | 140 | | ((pxa2xx_mcxx_asst(speed, clock) |
134 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | 141 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) |
135 | | ((pxa2xx_mcxx_hold(speed, clock) | 142 | | ((pxa2xx_mcxx_hold(speed, clock) |
136 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); | 143 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); |
137 | 144 | ||
145 | __raw_writel(val, MCIO(sock)); | ||
146 | |||
138 | return 0; | 147 | return 0; |
139 | } | 148 | } |
140 | 149 | ||
141 | static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) | 150 | static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) |
142 | { | 151 | { |
143 | MCATT(sock) = ((pxa2xx_mcxx_setup(speed, clock) | 152 | uint32_t val; |
153 | |||
154 | val = ((pxa2xx_mcxx_setup(speed, clock) | ||
144 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) | 155 | & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT) |
145 | | ((pxa2xx_mcxx_asst(speed, clock) | 156 | | ((pxa2xx_mcxx_asst(speed, clock) |
146 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) | 157 | & MCXX_ASST_MASK) << MCXX_ASST_SHIFT) |
147 | | ((pxa2xx_mcxx_hold(speed, clock) | 158 | | ((pxa2xx_mcxx_hold(speed, clock) |
148 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); | 159 | & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); |
149 | 160 | ||
161 | __raw_writel(val, MCATT(sock)); | ||
162 | |||
150 | return 0; | 163 | return 0; |
151 | } | 164 | } |
152 | 165 | ||
@@ -166,8 +179,8 @@ static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int cl | |||
166 | 179 | ||
167 | static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) | 180 | static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) |
168 | { | 181 | { |
169 | unsigned int clk = get_memclk_frequency_10khz(); | 182 | unsigned long clk = clk_get_rate(skt->clk); |
170 | return pxa2xx_pcmcia_set_mcxx(skt, clk); | 183 | return pxa2xx_pcmcia_set_mcxx(skt, clk / 10000); |
171 | } | 184 | } |
172 | 185 | ||
173 | #ifdef CONFIG_CPU_FREQ | 186 | #ifdef CONFIG_CPU_FREQ |
@@ -202,22 +215,21 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, | |||
202 | } | 215 | } |
203 | #endif | 216 | #endif |
204 | 217 | ||
205 | static void pxa2xx_configure_sockets(struct device *dev) | 218 | void pxa2xx_configure_sockets(struct device *dev) |
206 | { | 219 | { |
207 | struct pcmcia_low_level *ops = dev->platform_data; | 220 | struct pcmcia_low_level *ops = dev->platform_data; |
208 | |||
209 | /* | 221 | /* |
210 | * We have at least one socket, so set MECR:CIT | 222 | * We have at least one socket, so set MECR:CIT |
211 | * (Card Is There) | 223 | * (Card Is There) |
212 | */ | 224 | */ |
213 | MECR |= MECR_CIT; | 225 | uint32_t mecr = MECR_CIT; |
214 | 226 | ||
215 | /* Set MECR:NOS (Number Of Sockets) */ | 227 | /* Set MECR:NOS (Number Of Sockets) */ |
216 | if ((ops->first + ops->nr) > 1 || | 228 | if ((ops->first + ops->nr) > 1 || |
217 | machine_is_viper() || machine_is_arcom_zeus()) | 229 | machine_is_viper() || machine_is_arcom_zeus()) |
218 | MECR |= MECR_NOS; | 230 | mecr |= MECR_NOS; |
219 | else | 231 | |
220 | MECR &= ~MECR_NOS; | 232 | __raw_writel(mecr, MECR); |
221 | } | 233 | } |
222 | 234 | ||
223 | static const char *skt_names[] = { | 235 | static const char *skt_names[] = { |
@@ -270,24 +282,41 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
270 | struct pcmcia_low_level *ops; | 282 | struct pcmcia_low_level *ops; |
271 | struct skt_dev_info *sinfo; | 283 | struct skt_dev_info *sinfo; |
272 | struct soc_pcmcia_socket *skt; | 284 | struct soc_pcmcia_socket *skt; |
285 | struct clk *clk; | ||
273 | 286 | ||
274 | ops = (struct pcmcia_low_level *)dev->dev.platform_data; | 287 | ops = (struct pcmcia_low_level *)dev->dev.platform_data; |
275 | if (!ops) | 288 | if (!ops) { |
289 | ret = -ENODEV; | ||
290 | goto err0; | ||
291 | } | ||
292 | |||
293 | if (cpu_is_pxa320() && ops->nr > 1) { | ||
294 | dev_err(&dev->dev, "pxa320 supports only one pcmcia slot"); | ||
295 | ret = -EINVAL; | ||
296 | goto err0; | ||
297 | } | ||
298 | |||
299 | clk = clk_get(&dev->dev, NULL); | ||
300 | if (!clk) | ||
276 | return -ENODEV; | 301 | return -ENODEV; |
277 | 302 | ||
278 | pxa2xx_drv_pcmcia_ops(ops); | 303 | pxa2xx_drv_pcmcia_ops(ops); |
279 | 304 | ||
280 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); | 305 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); |
281 | if (!sinfo) | 306 | if (!sinfo) { |
307 | clk_put(clk); | ||
282 | return -ENOMEM; | 308 | return -ENOMEM; |
309 | } | ||
283 | 310 | ||
284 | sinfo->nskt = ops->nr; | 311 | sinfo->nskt = ops->nr; |
312 | sinfo->clk = clk; | ||
285 | 313 | ||
286 | /* Initialize processor specific parameters */ | 314 | /* Initialize processor specific parameters */ |
287 | for (i = 0; i < ops->nr; i++) { | 315 | for (i = 0; i < ops->nr; i++) { |
288 | skt = &sinfo->skt[i]; | 316 | skt = &sinfo->skt[i]; |
289 | 317 | ||
290 | skt->nr = ops->first + i; | 318 | skt->nr = ops->first + i; |
319 | skt->clk = clk; | ||
291 | skt->ops = ops; | 320 | skt->ops = ops; |
292 | skt->socket.owner = ops->owner; | 321 | skt->socket.owner = ops->owner; |
293 | skt->socket.dev.parent = &dev->dev; | 322 | skt->socket.dev.parent = &dev->dev; |
@@ -295,18 +324,26 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
295 | 324 | ||
296 | ret = pxa2xx_drv_pcmcia_add_one(skt); | 325 | ret = pxa2xx_drv_pcmcia_add_one(skt); |
297 | if (ret) | 326 | if (ret) |
298 | break; | 327 | goto err1; |
299 | } | 328 | } |
300 | 329 | ||
301 | if (ret) { | 330 | if (ret) { |
302 | while (--i >= 0) | 331 | while (--i >= 0) |
303 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 332 | soc_pcmcia_remove_one(&sinfo->skt[i]); |
304 | kfree(sinfo); | 333 | kfree(sinfo); |
334 | clk_put(clk); | ||
305 | } else { | 335 | } else { |
306 | pxa2xx_configure_sockets(&dev->dev); | 336 | pxa2xx_configure_sockets(&dev->dev); |
307 | dev_set_drvdata(&dev->dev, sinfo); | 337 | dev_set_drvdata(&dev->dev, sinfo); |
308 | } | 338 | } |
309 | 339 | ||
340 | return 0; | ||
341 | |||
342 | err1: | ||
343 | while (--i >= 0) | ||
344 | soc_pcmcia_remove_one(&sinfo->skt[i]); | ||
345 | kfree(sinfo); | ||
346 | err0: | ||
310 | return ret; | 347 | return ret; |
311 | } | 348 | } |
312 | 349 | ||
@@ -320,6 +357,7 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) | |||
320 | for (i = 0; i < sinfo->nskt; i++) | 357 | for (i = 0; i < sinfo->nskt; i++) |
321 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 358 | soc_pcmcia_remove_one(&sinfo->skt[i]); |
322 | 359 | ||
360 | clk_put(sinfo->clk); | ||
323 | kfree(sinfo); | 361 | kfree(sinfo); |
324 | return 0; | 362 | return 0; |
325 | } | 363 | } |
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index bb62ea87b8f9..b609b45469ed 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h | |||
@@ -1,3 +1,4 @@ | |||
1 | int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); | 1 | int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); |
2 | void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); | 2 | void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); |
3 | void pxa2xx_configure_sockets(struct device *dev); | ||
3 | 4 | ||
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c new file mode 100644 index 000000000000..443cb7fc872d --- /dev/null +++ b/drivers/pcmcia/pxa2xx_colibri.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * linux/drivers/pcmcia/pxa2xx_colibri.c | ||
3 | * | ||
4 | * Driver for Toradex Colibri PXA270 CF socket | ||
5 | * | ||
6 | * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <asm/mach-types.h> | ||
20 | |||
21 | #include "soc_common.h" | ||
22 | |||
23 | #define COLIBRI270_RESET_GPIO 53 | ||
24 | #define COLIBRI270_PPEN_GPIO 107 | ||
25 | #define COLIBRI270_BVD1_GPIO 83 | ||
26 | #define COLIBRI270_BVD2_GPIO 82 | ||
27 | #define COLIBRI270_DETECT_GPIO 84 | ||
28 | #define COLIBRI270_READY_GPIO 1 | ||
29 | |||
30 | #define COLIBRI320_RESET_GPIO 77 | ||
31 | #define COLIBRI320_PPEN_GPIO 57 | ||
32 | #define COLIBRI320_BVD1_GPIO 53 | ||
33 | #define COLIBRI320_BVD2_GPIO 79 | ||
34 | #define COLIBRI320_DETECT_GPIO 81 | ||
35 | #define COLIBRI320_READY_GPIO 29 | ||
36 | |||
37 | enum { | ||
38 | DETECT = 0, | ||
39 | READY = 1, | ||
40 | BVD1 = 2, | ||
41 | BVD2 = 3, | ||
42 | PPEN = 4, | ||
43 | RESET = 5, | ||
44 | }; | ||
45 | |||
46 | /* Contents of this array are configured on-the-fly in init function */ | ||
47 | static struct gpio colibri_pcmcia_gpios[] = { | ||
48 | { 0, GPIOF_IN, "PCMCIA Detect" }, | ||
49 | { 0, GPIOF_IN, "PCMCIA Ready" }, | ||
50 | { 0, GPIOF_IN, "PCMCIA BVD1" }, | ||
51 | { 0, GPIOF_IN, "PCMCIA BVD2" }, | ||
52 | { 0, GPIOF_INIT_LOW, "PCMCIA PPEN" }, | ||
53 | { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
54 | }; | ||
55 | |||
56 | static struct pcmcia_irqs colibri_irqs[] = { | ||
57 | { | ||
58 | .sock = 0, | ||
59 | .str = "PCMCIA CD" | ||
60 | }, | ||
61 | }; | ||
62 | |||
63 | static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
64 | { | ||
65 | int ret; | ||
66 | |||
67 | ret = gpio_request_array(colibri_pcmcia_gpios, | ||
68 | ARRAY_SIZE(colibri_pcmcia_gpios)); | ||
69 | if (ret) | ||
70 | goto err1; | ||
71 | |||
72 | colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); | ||
73 | skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); | ||
74 | |||
75 | ret = soc_pcmcia_request_irqs(skt, colibri_irqs, | ||
76 | ARRAY_SIZE(colibri_irqs)); | ||
77 | if (ret) | ||
78 | goto err2; | ||
79 | |||
80 | return ret; | ||
81 | |||
82 | err2: | ||
83 | gpio_free_array(colibri_pcmcia_gpios, | ||
84 | ARRAY_SIZE(colibri_pcmcia_gpios)); | ||
85 | err1: | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
90 | { | ||
91 | gpio_free_array(colibri_pcmcia_gpios, | ||
92 | ARRAY_SIZE(colibri_pcmcia_gpios)); | ||
93 | } | ||
94 | |||
95 | static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | ||
96 | struct pcmcia_state *state) | ||
97 | { | ||
98 | |||
99 | state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio); | ||
100 | state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); | ||
101 | state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); | ||
102 | state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); | ||
103 | state->wrprot = 0; | ||
104 | state->vs_3v = 1; | ||
105 | state->vs_Xv = 0; | ||
106 | } | ||
107 | |||
108 | static int | ||
109 | colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | ||
110 | const socket_state_t *state) | ||
111 | { | ||
112 | gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio, | ||
113 | !(state->Vcc == 33 && state->Vpp < 50)); | ||
114 | gpio_set_value(colibri_pcmcia_gpios[RESET].gpio, | ||
115 | state->flags & SS_RESET); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void colibri_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
120 | { | ||
121 | } | ||
122 | |||
123 | static void colibri_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
124 | { | ||
125 | } | ||
126 | |||
127 | static struct pcmcia_low_level colibri_pcmcia_ops = { | ||
128 | .owner = THIS_MODULE, | ||
129 | |||
130 | .first = 0, | ||
131 | .nr = 1, | ||
132 | |||
133 | .hw_init = colibri_pcmcia_hw_init, | ||
134 | .hw_shutdown = colibri_pcmcia_hw_shutdown, | ||
135 | |||
136 | .socket_state = colibri_pcmcia_socket_state, | ||
137 | .configure_socket = colibri_pcmcia_configure_socket, | ||
138 | |||
139 | .socket_init = colibri_pcmcia_socket_init, | ||
140 | .socket_suspend = colibri_pcmcia_socket_suspend, | ||
141 | }; | ||
142 | |||
143 | static struct platform_device *colibri_pcmcia_device; | ||
144 | |||
145 | static int __init colibri_pcmcia_init(void) | ||
146 | { | ||
147 | int ret; | ||
148 | |||
149 | if (!machine_is_colibri() && !machine_is_colibri320()) | ||
150 | return -ENODEV; | ||
151 | |||
152 | colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | ||
153 | if (!colibri_pcmcia_device) | ||
154 | return -ENOMEM; | ||
155 | |||
156 | /* Colibri PXA270 */ | ||
157 | if (machine_is_colibri()) { | ||
158 | colibri_pcmcia_gpios[RESET].gpio = COLIBRI270_RESET_GPIO; | ||
159 | colibri_pcmcia_gpios[PPEN].gpio = COLIBRI270_PPEN_GPIO; | ||
160 | colibri_pcmcia_gpios[BVD1].gpio = COLIBRI270_BVD1_GPIO; | ||
161 | colibri_pcmcia_gpios[BVD2].gpio = COLIBRI270_BVD2_GPIO; | ||
162 | colibri_pcmcia_gpios[DETECT].gpio = COLIBRI270_DETECT_GPIO; | ||
163 | colibri_pcmcia_gpios[READY].gpio = COLIBRI270_READY_GPIO; | ||
164 | /* Colibri PXA320 */ | ||
165 | } else if (machine_is_colibri320()) { | ||
166 | colibri_pcmcia_gpios[RESET].gpio = COLIBRI320_RESET_GPIO; | ||
167 | colibri_pcmcia_gpios[PPEN].gpio = COLIBRI320_PPEN_GPIO; | ||
168 | colibri_pcmcia_gpios[BVD1].gpio = COLIBRI320_BVD1_GPIO; | ||
169 | colibri_pcmcia_gpios[BVD2].gpio = COLIBRI320_BVD2_GPIO; | ||
170 | colibri_pcmcia_gpios[DETECT].gpio = COLIBRI320_DETECT_GPIO; | ||
171 | colibri_pcmcia_gpios[READY].gpio = COLIBRI320_READY_GPIO; | ||
172 | } | ||
173 | |||
174 | ret = platform_device_add_data(colibri_pcmcia_device, | ||
175 | &colibri_pcmcia_ops, sizeof(colibri_pcmcia_ops)); | ||
176 | |||
177 | if (!ret) | ||
178 | ret = platform_device_add(colibri_pcmcia_device); | ||
179 | |||
180 | if (ret) | ||
181 | platform_device_put(colibri_pcmcia_device); | ||
182 | |||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | static void __exit colibri_pcmcia_exit(void) | ||
187 | { | ||
188 | platform_device_unregister(colibri_pcmcia_device); | ||
189 | } | ||
190 | |||
191 | module_init(colibri_pcmcia_init); | ||
192 | module_exit(colibri_pcmcia_exit); | ||
193 | |||
194 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); | ||
195 | MODULE_DESCRIPTION("PCMCIA support for Toradex Colibri PXA270/PXA320"); | ||
196 | MODULE_ALIAS("platform:pxa2xx-pcmcia"); | ||
197 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index b9f8c8fb42bd..c21888eebb58 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c | |||
@@ -187,7 +187,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
187 | * We need to hack around the const qualifier as | 187 | * We need to hack around the const qualifier as |
188 | * well to keep this ugly workaround localized and | 188 | * well to keep this ugly workaround localized and |
189 | * not force it to the rest of the code. Barf bags | 189 | * not force it to the rest of the code. Barf bags |
190 | * avaliable in the seat pocket in front of you! | 190 | * available in the seat pocket in front of you! |
191 | */ | 191 | */ |
192 | ((socket_state_t *)state)->Vcc = 50; | 192 | ((socket_state_t *)state)->Vcc = 50; |
193 | ((socket_state_t *)state)->Vpp = 50; | 193 | ((socket_state_t *)state)->Vpp = 50; |
@@ -226,6 +226,7 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev) | |||
226 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); | 226 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); |
227 | 227 | ||
228 | pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); | 228 | pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); |
229 | pxa2xx_configure_sockets(&sadev->dev); | ||
229 | ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, | 230 | ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, |
230 | pxa2xx_drv_pcmcia_add_one); | 231 | pxa2xx_drv_pcmcia_add_one); |
231 | } | 232 | } |
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index 6fb6f7f0672e..69f73670949a 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Driver for Palm LifeDrive PCMCIA | 4 | * Driver for Palm LifeDrive PCMCIA |
5 | * | 5 | * |
6 | * Copyright (C) 2006 Alex Osborne <ato@meshy.org> | 6 | * Copyright (C) 2006 Alex Osborne <ato@meshy.org> |
7 | * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> | 7 | * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -20,49 +20,27 @@ | |||
20 | #include <mach/palmld.h> | 20 | #include <mach/palmld.h> |
21 | #include "soc_common.h" | 21 | #include "soc_common.h" |
22 | 22 | ||
23 | static struct gpio palmld_pcmcia_gpios[] = { | ||
24 | { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, | ||
25 | { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
26 | { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
27 | }; | ||
28 | |||
23 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 29 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
24 | { | 30 | { |
25 | int ret; | 31 | int ret; |
26 | 32 | ||
27 | ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR"); | 33 | ret = gpio_request_array(palmld_pcmcia_gpios, |
28 | if (ret) | 34 | ARRAY_SIZE(palmld_pcmcia_gpios)); |
29 | goto err1; | ||
30 | ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0); | ||
31 | if (ret) | ||
32 | goto err2; | ||
33 | |||
34 | ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST"); | ||
35 | if (ret) | ||
36 | goto err2; | ||
37 | ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1); | ||
38 | if (ret) | ||
39 | goto err3; | ||
40 | |||
41 | ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY"); | ||
42 | if (ret) | ||
43 | goto err3; | ||
44 | ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY); | ||
45 | if (ret) | ||
46 | goto err4; | ||
47 | 35 | ||
48 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); | 36 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); |
49 | return 0; | ||
50 | 37 | ||
51 | err4: | ||
52 | gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); | ||
53 | err3: | ||
54 | gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); | ||
55 | err2: | ||
56 | gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); | ||
57 | err1: | ||
58 | return ret; | 38 | return ret; |
59 | } | 39 | } |
60 | 40 | ||
61 | static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 41 | static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
62 | { | 42 | { |
63 | gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); | 43 | gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios)); |
64 | gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); | ||
65 | gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); | ||
66 | } | 44 | } |
67 | 45 | ||
68 | static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 46 | static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c index 459a232d66be..d0ad6a76bbde 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Driver for Palm Tungsten|C PCMCIA | 4 | * Driver for Palm Tungsten|C PCMCIA |
5 | * | 5 | * |
6 | * Copyright (C) 2008 Alex Osborne <ato@meshy.org> | 6 | * Copyright (C) 2008 Alex Osborne <ato@meshy.org> |
7 | * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com> | 7 | * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -21,79 +21,30 @@ | |||
21 | #include <mach/palmtc.h> | 21 | #include <mach/palmtc.h> |
22 | #include "soc_common.h" | 22 | #include "soc_common.h" |
23 | 23 | ||
24 | static struct gpio palmtc_pcmcia_gpios[] = { | ||
25 | { GPIO_NR_PALMTC_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, | ||
26 | { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, | ||
27 | { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, | ||
28 | { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
29 | { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
30 | { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, | ||
31 | }; | ||
32 | |||
24 | static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 33 | static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
25 | { | 34 | { |
26 | int ret; | 35 | int ret; |
27 | 36 | ||
28 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1"); | 37 | ret = gpio_request_array(palmtc_pcmcia_gpios, |
29 | if (ret) | 38 | ARRAY_SIZE(palmtc_pcmcia_gpios)); |
30 | goto err1; | ||
31 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0); | ||
32 | if (ret) | ||
33 | goto err2; | ||
34 | |||
35 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2"); | ||
36 | if (ret) | ||
37 | goto err2; | ||
38 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0); | ||
39 | if (ret) | ||
40 | goto err3; | ||
41 | |||
42 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3"); | ||
43 | if (ret) | ||
44 | goto err3; | ||
45 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0); | ||
46 | if (ret) | ||
47 | goto err4; | ||
48 | |||
49 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST"); | ||
50 | if (ret) | ||
51 | goto err4; | ||
52 | ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1); | ||
53 | if (ret) | ||
54 | goto err5; | ||
55 | |||
56 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY"); | ||
57 | if (ret) | ||
58 | goto err5; | ||
59 | ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY); | ||
60 | if (ret) | ||
61 | goto err6; | ||
62 | |||
63 | ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY"); | ||
64 | if (ret) | ||
65 | goto err6; | ||
66 | ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY); | ||
67 | if (ret) | ||
68 | goto err7; | ||
69 | 39 | ||
70 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); | 40 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); |
71 | return 0; | ||
72 | 41 | ||
73 | err7: | ||
74 | gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); | ||
75 | err6: | ||
76 | gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); | ||
77 | err5: | ||
78 | gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); | ||
79 | err4: | ||
80 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); | ||
81 | err3: | ||
82 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); | ||
83 | err2: | ||
84 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); | ||
85 | err1: | ||
86 | return ret; | 42 | return ret; |
87 | } | 43 | } |
88 | 44 | ||
89 | static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 45 | static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
90 | { | 46 | { |
91 | gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); | 47 | gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios)); |
92 | gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); | ||
93 | gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); | ||
94 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); | ||
95 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); | ||
96 | gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); | ||
97 | } | 48 | } |
98 | 49 | ||
99 | static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 50 | static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c index b07b247a399f..1a2580450402 100644 --- a/drivers/pcmcia/pxa2xx_palmtx.c +++ b/drivers/pcmcia/pxa2xx_palmtx.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for Palm T|X PCMCIA | 4 | * Driver for Palm T|X PCMCIA |
5 | * | 5 | * |
6 | * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> | 6 | * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -13,67 +13,34 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/gpio.h> | ||
16 | 17 | ||
17 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
18 | |||
19 | #include <mach/gpio.h> | ||
20 | #include <mach/palmtx.h> | 19 | #include <mach/palmtx.h> |
21 | |||
22 | #include "soc_common.h" | 20 | #include "soc_common.h" |
23 | 21 | ||
22 | static struct gpio palmtx_pcmcia_gpios[] = { | ||
23 | { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, | ||
24 | { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, | ||
25 | { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | ||
26 | { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
27 | }; | ||
28 | |||
24 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 29 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
25 | { | 30 | { |
26 | int ret; | 31 | int ret; |
27 | 32 | ||
28 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1"); | 33 | ret = gpio_request_array(palmtx_pcmcia_gpios, |
29 | if (ret) | 34 | ARRAY_SIZE(palmtx_pcmcia_gpios)); |
30 | goto err1; | ||
31 | ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0); | ||
32 | if (ret) | ||
33 | goto err2; | ||
34 | |||
35 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2"); | ||
36 | if (ret) | ||
37 | goto err2; | ||
38 | ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0); | ||
39 | if (ret) | ||
40 | goto err3; | ||
41 | |||
42 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST"); | ||
43 | if (ret) | ||
44 | goto err3; | ||
45 | ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1); | ||
46 | if (ret) | ||
47 | goto err4; | ||
48 | |||
49 | ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY"); | ||
50 | if (ret) | ||
51 | goto err4; | ||
52 | ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY); | ||
53 | if (ret) | ||
54 | goto err5; | ||
55 | 35 | ||
56 | skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); | 36 | skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); |
57 | return 0; | ||
58 | 37 | ||
59 | err5: | ||
60 | gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); | ||
61 | err4: | ||
62 | gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); | ||
63 | err3: | ||
64 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); | ||
65 | err2: | ||
66 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); | ||
67 | err1: | ||
68 | return ret; | 38 | return ret; |
69 | } | 39 | } |
70 | 40 | ||
71 | static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 41 | static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
72 | { | 42 | { |
73 | gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); | 43 | gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios)); |
74 | gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); | ||
75 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); | ||
76 | gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); | ||
77 | } | 44 | } |
78 | 45 | ||
79 | static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 46 | static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 0ea3b29440e6..81af2b3bcc00 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -237,7 +237,7 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { | |||
237 | #ifdef CONFIG_SA1100_COLLIE | 237 | #ifdef CONFIG_SA1100_COLLIE |
238 | #include "sa11xx_base.h" | 238 | #include "sa11xx_base.h" |
239 | 239 | ||
240 | int __init pcmcia_collie_init(struct device *dev) | 240 | int __devinit pcmcia_collie_init(struct device *dev) |
241 | { | 241 | { |
242 | int ret = -ENODEV; | 242 | int ret = -ENODEV; |
243 | 243 | ||
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c index b7e596620db1..b829e655457b 100644 --- a/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/drivers/pcmcia/pxa2xx_trizeps4.c | |||
@@ -69,15 +69,15 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
69 | for (i = 0; i < ARRAY_SIZE(irqs); i++) { | 69 | for (i = 0; i < ARRAY_SIZE(irqs); i++) { |
70 | if (irqs[i].sock != skt->nr) | 70 | if (irqs[i].sock != skt->nr) |
71 | continue; | 71 | continue; |
72 | if (gpio_request(IRQ_TO_GPIO(irqs[i].irq), irqs[i].str) < 0) { | 72 | if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) { |
73 | pr_err("%s: sock %d unable to request gpio %d\n", | 73 | pr_err("%s: sock %d unable to request gpio %d\n", |
74 | __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq)); | 74 | __func__, skt->nr, irq_to_gpio(irqs[i].irq)); |
75 | ret = -EBUSY; | 75 | ret = -EBUSY; |
76 | goto error; | 76 | goto error; |
77 | } | 77 | } |
78 | if (gpio_direction_input(IRQ_TO_GPIO(irqs[i].irq)) < 0) { | 78 | if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) { |
79 | pr_err("%s: sock %d unable to set input gpio %d\n", | 79 | pr_err("%s: sock %d unable to set input gpio %d\n", |
80 | __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq)); | 80 | __func__, skt->nr, irq_to_gpio(irqs[i].irq)); |
81 | ret = -EINVAL; | 81 | ret = -EINVAL; |
82 | goto error; | 82 | goto error; |
83 | } | 83 | } |
@@ -86,7 +86,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
86 | 86 | ||
87 | error: | 87 | error: |
88 | for (; i >= 0; i--) { | 88 | for (; i >= 0; i--) { |
89 | gpio_free(IRQ_TO_GPIO(irqs[i].irq)); | 89 | gpio_free(irq_to_gpio(irqs[i].irq)); |
90 | } | 90 | } |
91 | return (ret); | 91 | return (ret); |
92 | } | 92 | } |
@@ -97,7 +97,7 @@ static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
97 | /* free allocated gpio's */ | 97 | /* free allocated gpio's */ |
98 | gpio_free(GPIO_PRDY); | 98 | gpio_free(GPIO_PRDY); |
99 | for (i = 0; i < ARRAY_SIZE(irqs); i++) | 99 | for (i = 0; i < ARRAY_SIZE(irqs); i++) |
100 | gpio_free(IRQ_TO_GPIO(irqs[i].irq)); | 100 | gpio_free(irq_to_gpio(irqs[i].irq)); |
101 | } | 101 | } |
102 | 102 | ||
103 | static unsigned long trizeps_pcmcia_status[2]; | 103 | static unsigned long trizeps_pcmcia_status[2]; |
@@ -226,6 +226,9 @@ static int __init trizeps_pcmcia_init(void) | |||
226 | { | 226 | { |
227 | int ret; | 227 | int ret; |
228 | 228 | ||
229 | if (!machine_is_trizeps4() && !machine_is_trizeps4wl()) | ||
230 | return -ENODEV; | ||
231 | |||
229 | trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | 232 | trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); |
230 | if (!trizeps_pcmcia_device) | 233 | if (!trizeps_pcmcia_device) |
231 | return -ENOMEM; | 234 | return -ENOMEM; |
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index 55627eccee8e..e956f659089a 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c | |||
@@ -3,8 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for Voipac PXA270 PCMCIA and CF sockets | 4 | * Driver for Voipac PXA270 PCMCIA and CF sockets |
5 | * | 5 | * |
6 | * Copyright (C) 2010 | 6 | * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com> |
7 | * Marek Vasut <marek.vasut@gmail.com> | ||
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -12,6 +11,7 @@ | |||
12 | * | 11 | * |
13 | */ | 12 | */ |
14 | 13 | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | 17 | ||
@@ -22,6 +22,19 @@ | |||
22 | 22 | ||
23 | #include "soc_common.h" | 23 | #include "soc_common.h" |
24 | 24 | ||
25 | static struct gpio vpac270_pcmcia_gpios[] = { | ||
26 | { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" }, | ||
27 | { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" }, | ||
28 | { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, | ||
29 | { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, | ||
30 | }; | ||
31 | |||
32 | static struct gpio vpac270_cf_gpios[] = { | ||
33 | { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" }, | ||
34 | { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" }, | ||
35 | { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, | ||
36 | }; | ||
37 | |||
25 | static struct pcmcia_irqs cd_irqs[] = { | 38 | static struct pcmcia_irqs cd_irqs[] = { |
26 | { | 39 | { |
27 | .sock = 0, | 40 | .sock = 0, |
@@ -40,96 +53,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
40 | int ret; | 53 | int ret; |
41 | 54 | ||
42 | if (skt->nr == 0) { | 55 | if (skt->nr == 0) { |
43 | ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD"); | 56 | ret = gpio_request_array(vpac270_pcmcia_gpios, |
44 | if (ret) | 57 | ARRAY_SIZE(vpac270_pcmcia_gpios)); |
45 | goto err1; | ||
46 | ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD); | ||
47 | if (ret) | ||
48 | goto err2; | ||
49 | |||
50 | ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY"); | ||
51 | if (ret) | ||
52 | goto err2; | ||
53 | ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY); | ||
54 | if (ret) | ||
55 | goto err3; | ||
56 | |||
57 | ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN"); | ||
58 | if (ret) | ||
59 | goto err3; | ||
60 | ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0); | ||
61 | if (ret) | ||
62 | goto err4; | ||
63 | |||
64 | ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET"); | ||
65 | if (ret) | ||
66 | goto err4; | ||
67 | ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0); | ||
68 | if (ret) | ||
69 | goto err5; | ||
70 | 58 | ||
71 | skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); | 59 | skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); |
72 | 60 | ||
73 | return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); | 61 | if (!ret) |
74 | 62 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); | |
75 | err5: | ||
76 | gpio_free(GPIO11_VPAC270_PCMCIA_RESET); | ||
77 | err4: | ||
78 | gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); | ||
79 | err3: | ||
80 | gpio_free(GPIO35_VPAC270_PCMCIA_RDY); | ||
81 | err2: | ||
82 | gpio_free(GPIO84_VPAC270_PCMCIA_CD); | ||
83 | err1: | ||
84 | return ret; | ||
85 | |||
86 | } else { | 63 | } else { |
87 | ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD"); | 64 | ret = gpio_request_array(vpac270_cf_gpios, |
88 | if (ret) | 65 | ARRAY_SIZE(vpac270_cf_gpios)); |
89 | goto err6; | ||
90 | ret = gpio_direction_input(GPIO17_VPAC270_CF_CD); | ||
91 | if (ret) | ||
92 | goto err7; | ||
93 | |||
94 | ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY"); | ||
95 | if (ret) | ||
96 | goto err7; | ||
97 | ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY); | ||
98 | if (ret) | ||
99 | goto err8; | ||
100 | |||
101 | ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET"); | ||
102 | if (ret) | ||
103 | goto err8; | ||
104 | ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0); | ||
105 | if (ret) | ||
106 | goto err9; | ||
107 | 66 | ||
108 | skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); | 67 | skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); |
109 | 68 | ||
110 | return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); | 69 | if (!ret) |
111 | 70 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); | |
112 | err9: | ||
113 | gpio_free(GPIO16_VPAC270_CF_RESET); | ||
114 | err8: | ||
115 | gpio_free(GPIO12_VPAC270_CF_RDY); | ||
116 | err7: | ||
117 | gpio_free(GPIO17_VPAC270_CF_CD); | ||
118 | err6: | ||
119 | return ret; | ||
120 | |||
121 | } | 71 | } |
72 | |||
73 | return ret; | ||
122 | } | 74 | } |
123 | 75 | ||
124 | static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 76 | static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
125 | { | 77 | { |
126 | gpio_free(GPIO11_VPAC270_PCMCIA_RESET); | 78 | if (skt->nr == 0) |
127 | gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); | 79 | gpio_free_array(vpac270_pcmcia_gpios, |
128 | gpio_free(GPIO35_VPAC270_PCMCIA_RDY); | 80 | ARRAY_SIZE(vpac270_pcmcia_gpios)); |
129 | gpio_free(GPIO84_VPAC270_PCMCIA_CD); | 81 | else |
130 | gpio_free(GPIO16_VPAC270_CF_RESET); | 82 | gpio_free_array(vpac270_cf_gpios, |
131 | gpio_free(GPIO12_VPAC270_CF_RDY); | 83 | ARRAY_SIZE(vpac270_cf_gpios)); |
132 | gpio_free(GPIO17_VPAC270_CF_CD); | ||
133 | } | 84 | } |
134 | 85 | ||
135 | static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 86 | static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c index 8510c35d2952..523eb691c30b 100644 --- a/drivers/pcmcia/rsrc_iodyn.c +++ b/drivers/pcmcia/rsrc_iodyn.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | 18 | ||
19 | #include <pcmcia/ss.h> | 19 | #include <pcmcia/ss.h> |
20 | #include <pcmcia/cs.h> | ||
21 | #include <pcmcia/cistpl.h> | 20 | #include <pcmcia/cistpl.h> |
22 | #include "cs_internal.h" | 21 | #include "cs_internal.h" |
23 | 22 | ||
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 4e80421fd908..aa628ed0e9f4 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | 18 | ||
19 | #include <pcmcia/ss.h> | 19 | #include <pcmcia/ss.h> |
20 | #include <pcmcia/cs.h> | ||
21 | #include <pcmcia/cistpl.h> | 20 | #include <pcmcia/cistpl.h> |
22 | #include "cs_internal.h" | 21 | #include "cs_internal.h" |
23 | 22 | ||
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 96f348b35fde..b187555d4388 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | 30 | ||
31 | #include <pcmcia/ss.h> | 31 | #include <pcmcia/ss.h> |
32 | #include <pcmcia/cs.h> | ||
33 | #include <pcmcia/cistpl.h> | 32 | #include <pcmcia/cistpl.h> |
34 | #include "cs_internal.h" | 33 | #include "cs_internal.h" |
35 | 34 | ||
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c index fd013a1ef47a..f1e882272ab0 100644 --- a/drivers/pcmcia/sa1100_assabet.c +++ b/drivers/pcmcia/sa1100_assabet.c | |||
@@ -130,7 +130,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = { | |||
130 | .socket_suspend = assabet_pcmcia_socket_suspend, | 130 | .socket_suspend = assabet_pcmcia_socket_suspend, |
131 | }; | 131 | }; |
132 | 132 | ||
133 | int pcmcia_assabet_init(struct device *dev) | 133 | int __devinit pcmcia_assabet_init(struct device *dev) |
134 | { | 134 | { |
135 | int ret = -ENODEV; | 135 | int ret = -ENODEV; |
136 | 136 | ||
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index 9bf088b17275..30560df8c76b 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c | |||
@@ -97,7 +97,7 @@ static struct pcmcia_low_level cerf_pcmcia_ops = { | |||
97 | .socket_suspend = cerf_pcmcia_socket_suspend, | 97 | .socket_suspend = cerf_pcmcia_socket_suspend, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | int __init pcmcia_cerf_init(struct device *dev) | 100 | int __devinit pcmcia_cerf_init(struct device *dev) |
101 | { | 101 | { |
102 | int ret = -ENODEV; | 102 | int ret = -ENODEV; |
103 | 103 | ||
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index e09851480295..2eea664bc079 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | 37 | ||
38 | #include <pcmcia/cs.h> | ||
39 | #include <pcmcia/ss.h> | 38 | #include <pcmcia/ss.h> |
40 | 39 | ||
41 | #include <asm/hardware/scoop.h> | 40 | #include <asm/hardware/scoop.h> |
@@ -44,7 +43,7 @@ | |||
44 | 43 | ||
45 | int __init pcmcia_collie_init(struct device *dev); | 44 | int __init pcmcia_collie_init(struct device *dev); |
46 | 45 | ||
47 | static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | 46 | static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) __devinitdata = { |
48 | #ifdef CONFIG_SA1100_ASSABET | 47 | #ifdef CONFIG_SA1100_ASSABET |
49 | pcmcia_assabet_init, | 48 | pcmcia_assabet_init, |
50 | #endif | 49 | #endif |
@@ -54,6 +53,9 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | |||
54 | #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600) | 53 | #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600) |
55 | pcmcia_h3600_init, | 54 | pcmcia_h3600_init, |
56 | #endif | 55 | #endif |
56 | #ifdef CONFIG_SA1100_NANOENGINE | ||
57 | pcmcia_nanoengine_init, | ||
58 | #endif | ||
57 | #ifdef CONFIG_SA1100_SHANNON | 59 | #ifdef CONFIG_SA1100_SHANNON |
58 | pcmcia_shannon_init, | 60 | pcmcia_shannon_init, |
59 | #endif | 61 | #endif |
@@ -65,7 +67,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | |||
65 | #endif | 67 | #endif |
66 | }; | 68 | }; |
67 | 69 | ||
68 | static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) | 70 | static int __devinit sa11x0_drv_pcmcia_probe(struct platform_device *dev) |
69 | { | 71 | { |
70 | int i, ret = -ENODEV; | 72 | int i, ret = -ENODEV; |
71 | 73 | ||
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h index 794f96a35bba..adb08dbc723f 100644 --- a/drivers/pcmcia/sa1100_generic.h +++ b/drivers/pcmcia/sa1100_generic.h | |||
@@ -13,6 +13,7 @@ extern int pcmcia_freebird_init(struct device *); | |||
13 | extern int pcmcia_gcplus_init(struct device *); | 13 | extern int pcmcia_gcplus_init(struct device *); |
14 | extern int pcmcia_graphicsmaster_init(struct device *); | 14 | extern int pcmcia_graphicsmaster_init(struct device *); |
15 | extern int pcmcia_h3600_init(struct device *); | 15 | extern int pcmcia_h3600_init(struct device *); |
16 | extern int pcmcia_nanoengine_init(struct device *); | ||
16 | extern int pcmcia_pangolin_init(struct device *); | 17 | extern int pcmcia_pangolin_init(struct device *); |
17 | extern int pcmcia_pfs168_init(struct device *); | 18 | extern int pcmcia_pfs168_init(struct device *); |
18 | extern int pcmcia_shannon_init(struct device *); | 19 | extern int pcmcia_shannon_init(struct device *); |
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index 56329ad575a9..edf8f0028898 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c | |||
@@ -219,7 +219,7 @@ struct pcmcia_low_level h3600_pcmcia_ops = { | |||
219 | .socket_suspend = h3600_pcmcia_socket_suspend, | 219 | .socket_suspend = h3600_pcmcia_socket_suspend, |
220 | }; | 220 | }; |
221 | 221 | ||
222 | int __init pcmcia_h3600_init(struct device *dev) | 222 | int __devinit pcmcia_h3600_init(struct device *dev) |
223 | { | 223 | { |
224 | int ret = -ENODEV; | 224 | int ret = -ENODEV; |
225 | 225 | ||
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c new file mode 100644 index 000000000000..93b9c9ba57c3 --- /dev/null +++ b/drivers/pcmcia/sa1100_nanoengine.c | |||
@@ -0,0 +1,219 @@ | |||
1 | /* | ||
2 | * drivers/pcmcia/sa1100_nanoengine.c | ||
3 | * | ||
4 | * PCMCIA implementation routines for BSI nanoEngine. | ||
5 | * | ||
6 | * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine | ||
7 | * board you should carefully read this: | ||
8 | * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/ | ||
9 | * | ||
10 | * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> | ||
11 | * | ||
12 | * Based on original work for kernel 2.4 by | ||
13 | * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License version 2 as | ||
17 | * published by the Free Software Foundation. | ||
18 | * | ||
19 | */ | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/irq.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/signal.h> | ||
28 | |||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/irq.h> | ||
31 | |||
32 | #include <mach/hardware.h> | ||
33 | #include <mach/nanoengine.h> | ||
34 | |||
35 | #include "sa1100_generic.h" | ||
36 | |||
37 | static struct pcmcia_irqs irqs_skt0[] = { | ||
38 | /* socket, IRQ, name */ | ||
39 | { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" }, | ||
40 | }; | ||
41 | |||
42 | static struct pcmcia_irqs irqs_skt1[] = { | ||
43 | /* socket, IRQ, name */ | ||
44 | { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" }, | ||
45 | }; | ||
46 | |||
47 | struct nanoengine_pins { | ||
48 | unsigned input_pins; | ||
49 | unsigned output_pins; | ||
50 | unsigned clear_outputs; | ||
51 | unsigned transition_pins; | ||
52 | unsigned pci_irq; | ||
53 | struct pcmcia_irqs *pcmcia_irqs; | ||
54 | unsigned pcmcia_irqs_size; | ||
55 | }; | ||
56 | |||
57 | static struct nanoengine_pins nano_skts[] = { | ||
58 | { | ||
59 | .input_pins = GPIO_PC_READY0 | GPIO_PC_CD0, | ||
60 | .output_pins = GPIO_PC_RESET0, | ||
61 | .clear_outputs = GPIO_PC_RESET0, | ||
62 | .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD0, | ||
63 | .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY0, | ||
64 | .pcmcia_irqs = irqs_skt0, | ||
65 | .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt0) | ||
66 | }, { | ||
67 | .input_pins = GPIO_PC_READY1 | GPIO_PC_CD1, | ||
68 | .output_pins = GPIO_PC_RESET1, | ||
69 | .clear_outputs = GPIO_PC_RESET1, | ||
70 | .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD1, | ||
71 | .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY1, | ||
72 | .pcmcia_irqs = irqs_skt1, | ||
73 | .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt1) | ||
74 | } | ||
75 | }; | ||
76 | |||
77 | unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts); | ||
78 | |||
79 | static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
80 | { | ||
81 | unsigned i = skt->nr; | ||
82 | |||
83 | if (i >= num_nano_pcmcia_sockets) | ||
84 | return -ENXIO; | ||
85 | |||
86 | GPDR &= ~nano_skts[i].input_pins; | ||
87 | GPDR |= nano_skts[i].output_pins; | ||
88 | GPCR = nano_skts[i].clear_outputs; | ||
89 | irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); | ||
90 | skt->socket.pci_irq = nano_skts[i].pci_irq; | ||
91 | |||
92 | return soc_pcmcia_request_irqs(skt, | ||
93 | nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Release all resources. | ||
98 | */ | ||
99 | static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
100 | { | ||
101 | unsigned i = skt->nr; | ||
102 | |||
103 | if (i >= num_nano_pcmcia_sockets) | ||
104 | return; | ||
105 | |||
106 | soc_pcmcia_free_irqs(skt, | ||
107 | nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | ||
108 | } | ||
109 | |||
110 | static int nanoengine_pcmcia_configure_socket( | ||
111 | struct soc_pcmcia_socket *skt, const socket_state_t *state) | ||
112 | { | ||
113 | unsigned reset; | ||
114 | unsigned i = skt->nr; | ||
115 | |||
116 | if (i >= num_nano_pcmcia_sockets) | ||
117 | return -ENXIO; | ||
118 | |||
119 | switch (i) { | ||
120 | case 0: | ||
121 | reset = GPIO_PC_RESET0; | ||
122 | break; | ||
123 | case 1: | ||
124 | reset = GPIO_PC_RESET1; | ||
125 | break; | ||
126 | default: | ||
127 | return -ENXIO; | ||
128 | } | ||
129 | |||
130 | if (state->flags & SS_RESET) | ||
131 | GPSR = reset; | ||
132 | else | ||
133 | GPCR = reset; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static void nanoengine_pcmcia_socket_state( | ||
139 | struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | ||
140 | { | ||
141 | unsigned long levels = GPLR; | ||
142 | unsigned i = skt->nr; | ||
143 | |||
144 | if (i >= num_nano_pcmcia_sockets) | ||
145 | return; | ||
146 | |||
147 | memset(state, 0, sizeof(struct pcmcia_state)); | ||
148 | switch (i) { | ||
149 | case 0: | ||
150 | state->ready = (levels & GPIO_PC_READY0) ? 1 : 0; | ||
151 | state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0; | ||
152 | break; | ||
153 | case 1: | ||
154 | state->ready = (levels & GPIO_PC_READY1) ? 1 : 0; | ||
155 | state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0; | ||
156 | break; | ||
157 | default: | ||
158 | return; | ||
159 | } | ||
160 | state->bvd1 = 1; | ||
161 | state->bvd2 = 1; | ||
162 | state->wrprot = 0; /* Not available */ | ||
163 | state->vs_3v = 1; /* Can only apply 3.3V */ | ||
164 | state->vs_Xv = 0; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * Enable card status IRQs on (re-)initialisation. This can | ||
169 | * be called at initialisation, power management event, or | ||
170 | * pcmcia event. | ||
171 | */ | ||
172 | static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
173 | { | ||
174 | unsigned i = skt->nr; | ||
175 | |||
176 | if (i >= num_nano_pcmcia_sockets) | ||
177 | return; | ||
178 | |||
179 | soc_pcmcia_enable_irqs(skt, | ||
180 | nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * Disable card status IRQs on suspend. | ||
185 | */ | ||
186 | static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
187 | { | ||
188 | unsigned i = skt->nr; | ||
189 | |||
190 | if (i >= num_nano_pcmcia_sockets) | ||
191 | return; | ||
192 | |||
193 | soc_pcmcia_disable_irqs(skt, | ||
194 | nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | ||
195 | } | ||
196 | |||
197 | static struct pcmcia_low_level nanoengine_pcmcia_ops = { | ||
198 | .owner = THIS_MODULE, | ||
199 | |||
200 | .hw_init = nanoengine_pcmcia_hw_init, | ||
201 | .hw_shutdown = nanoengine_pcmcia_hw_shutdown, | ||
202 | |||
203 | .configure_socket = nanoengine_pcmcia_configure_socket, | ||
204 | .socket_state = nanoengine_pcmcia_socket_state, | ||
205 | .socket_init = nanoengine_pcmcia_socket_init, | ||
206 | .socket_suspend = nanoengine_pcmcia_socket_suspend, | ||
207 | }; | ||
208 | |||
209 | int pcmcia_nanoengine_init(struct device *dev) | ||
210 | { | ||
211 | int ret = -ENODEV; | ||
212 | |||
213 | if (machine_is_nanoengine()) | ||
214 | ret = sa11xx_drv_pcmcia_probe( | ||
215 | dev, &nanoengine_pcmcia_ops, 0, 2); | ||
216 | |||
217 | return ret; | ||
218 | } | ||
219 | |||
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c index c4d51867a050..7ff1b43540b8 100644 --- a/drivers/pcmcia/sa1100_shannon.c +++ b/drivers/pcmcia/sa1100_shannon.c | |||
@@ -113,7 +113,7 @@ static struct pcmcia_low_level shannon_pcmcia_ops = { | |||
113 | .socket_suspend = shannon_pcmcia_socket_suspend, | 113 | .socket_suspend = shannon_pcmcia_socket_suspend, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | int __init pcmcia_shannon_init(struct device *dev) | 116 | int __devinit pcmcia_shannon_init(struct device *dev) |
117 | { | 117 | { |
118 | int ret = -ENODEV; | 118 | int ret = -ENODEV; |
119 | 119 | ||
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c index 05bd504e6f18..c998f7aaadbc 100644 --- a/drivers/pcmcia/sa1100_simpad.c +++ b/drivers/pcmcia/sa1100_simpad.c | |||
@@ -123,7 +123,7 @@ static struct pcmcia_low_level simpad_pcmcia_ops = { | |||
123 | .socket_suspend = simpad_pcmcia_socket_suspend, | 123 | .socket_suspend = simpad_pcmcia_socket_suspend, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | int __init pcmcia_simpad_init(struct device *dev) | 126 | int __devinit pcmcia_simpad_init(struct device *dev) |
127 | { | 127 | { |
128 | int ret = -ENODEV; | 128 | int ret = -ENODEV; |
129 | 129 | ||
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 6f1a86b43c60..768f9572a8c8 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c | |||
@@ -31,20 +31,20 @@ | |||
31 | ======================================================================*/ | 31 | ======================================================================*/ |
32 | 32 | ||
33 | 33 | ||
34 | #include <linux/module.h> | 34 | #include <linux/cpufreq.h> |
35 | #include <linux/moduleparam.h> | ||
36 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/io.h> | ||
38 | #include <linux/irq.h> | ||
37 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
38 | #include <linux/timer.h> | ||
39 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
41 | #include <linux/module.h> | ||
42 | #include <linux/moduleparam.h> | ||
40 | #include <linux/mutex.h> | 43 | #include <linux/mutex.h> |
41 | #include <linux/interrupt.h> | ||
42 | #include <linux/irq.h> | ||
43 | #include <linux/spinlock.h> | 44 | #include <linux/spinlock.h> |
44 | #include <linux/cpufreq.h> | 45 | #include <linux/timer.h> |
45 | 46 | ||
46 | #include <mach/hardware.h> | 47 | #include <mach/hardware.h> |
47 | #include <asm/io.h> | ||
48 | #include <asm/system.h> | 48 | #include <asm/system.h> |
49 | 49 | ||
50 | #include "soc_common.h" | 50 | #include "soc_common.h" |
@@ -57,18 +57,25 @@ module_param(pc_debug, int, 0644); | |||
57 | void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, | 57 | void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, |
58 | int lvl, const char *fmt, ...) | 58 | int lvl, const char *fmt, ...) |
59 | { | 59 | { |
60 | struct va_format vaf; | ||
60 | va_list args; | 61 | va_list args; |
61 | if (pc_debug > lvl) { | 62 | if (pc_debug > lvl) { |
62 | printk(KERN_DEBUG "skt%u: %s: ", skt->nr, func); | ||
63 | va_start(args, fmt); | 63 | va_start(args, fmt); |
64 | vprintk(fmt, args); | 64 | |
65 | vaf.fmt = fmt; | ||
66 | vaf.va = &args; | ||
67 | |||
68 | printk(KERN_DEBUG "skt%u: %s: %pV", skt->nr, func, &vaf); | ||
69 | |||
65 | va_end(args); | 70 | va_end(args); |
66 | } | 71 | } |
67 | } | 72 | } |
73 | EXPORT_SYMBOL(soc_pcmcia_debug); | ||
68 | 74 | ||
69 | #endif | 75 | #endif |
70 | 76 | ||
71 | #define to_soc_pcmcia_socket(x) container_of(x, struct soc_pcmcia_socket, socket) | 77 | #define to_soc_pcmcia_socket(x) \ |
78 | container_of(x, struct soc_pcmcia_socket, socket) | ||
72 | 79 | ||
73 | static unsigned short | 80 | static unsigned short |
74 | calc_speed(unsigned short *spds, int num, unsigned short dflt) | 81 | calc_speed(unsigned short *spds, int num, unsigned short dflt) |
@@ -85,11 +92,15 @@ calc_speed(unsigned short *spds, int num, unsigned short dflt) | |||
85 | return speed; | 92 | return speed; |
86 | } | 93 | } |
87 | 94 | ||
88 | void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, struct soc_pcmcia_timing *timing) | 95 | void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, |
96 | struct soc_pcmcia_timing *timing) | ||
89 | { | 97 | { |
90 | timing->io = calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS); | 98 | timing->io = |
91 | timing->mem = calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | 99 | calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS); |
92 | timing->attr = calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | 100 | timing->mem = |
101 | calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | ||
102 | timing->attr = | ||
103 | calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | ||
93 | } | 104 | } |
94 | EXPORT_SYMBOL(soc_common_pcmcia_get_timing); | 105 | EXPORT_SYMBOL(soc_common_pcmcia_get_timing); |
95 | 106 | ||
@@ -131,8 +142,8 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) | |||
131 | * | 142 | * |
132 | * Convert PCMCIA socket state to our socket configure structure. | 143 | * Convert PCMCIA socket state to our socket configure structure. |
133 | */ | 144 | */ |
134 | static int | 145 | static int soc_common_pcmcia_config_skt( |
135 | soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *state) | 146 | struct soc_pcmcia_socket *skt, socket_state_t *state) |
136 | { | 147 | { |
137 | int ret; | 148 | int ret; |
138 | 149 | ||
@@ -144,10 +155,11 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat | |||
144 | */ | 155 | */ |
145 | if (skt->irq_state != 1 && state->io_irq) { | 156 | if (skt->irq_state != 1 && state->io_irq) { |
146 | skt->irq_state = 1; | 157 | skt->irq_state = 1; |
147 | set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING); | 158 | irq_set_irq_type(skt->socket.pci_irq, |
159 | IRQ_TYPE_EDGE_FALLING); | ||
148 | } else if (skt->irq_state == 1 && state->io_irq == 0) { | 160 | } else if (skt->irq_state == 1 && state->io_irq == 0) { |
149 | skt->irq_state = 0; | 161 | skt->irq_state = 0; |
150 | set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE); | 162 | irq_set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE); |
151 | } | 163 | } |
152 | 164 | ||
153 | skt->cs_state = *state; | 165 | skt->cs_state = *state; |
@@ -298,24 +310,24 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) | |||
298 | * of power configuration, reset, &c. We also record the value of | 310 | * of power configuration, reset, &c. We also record the value of |
299 | * `state' in order to regurgitate it to the PCMCIA core later. | 311 | * `state' in order to regurgitate it to the PCMCIA core later. |
300 | */ | 312 | */ |
301 | static int | 313 | static int soc_common_pcmcia_set_socket( |
302 | soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | 314 | struct pcmcia_socket *sock, socket_state_t *state) |
303 | { | 315 | { |
304 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); | 316 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); |
305 | 317 | ||
306 | debug(skt, 2, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n", | 318 | debug(skt, 2, "mask: %s%s%s%s%s%s flags: %s%s%s%s%s%s Vcc %d Vpp %d irq %d\n", |
307 | (state->csc_mask==0)?"<NONE> ":"", | 319 | (state->csc_mask == 0) ? "<NONE> " : "", |
308 | (state->csc_mask&SS_DETECT)?"DETECT ":"", | 320 | (state->csc_mask & SS_DETECT) ? "DETECT " : "", |
309 | (state->csc_mask&SS_READY)?"READY ":"", | 321 | (state->csc_mask & SS_READY) ? "READY " : "", |
310 | (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", | 322 | (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "", |
311 | (state->csc_mask&SS_BATWARN)?"BATWARN ":"", | 323 | (state->csc_mask & SS_BATWARN) ? "BATWARN " : "", |
312 | (state->csc_mask&SS_STSCHG)?"STSCHG ":"", | 324 | (state->csc_mask & SS_STSCHG) ? "STSCHG " : "", |
313 | (state->flags==0)?"<NONE> ":"", | 325 | (state->flags == 0) ? "<NONE> " : "", |
314 | (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", | 326 | (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "", |
315 | (state->flags&SS_IOCARD)?"IOCARD ":"", | 327 | (state->flags & SS_IOCARD) ? "IOCARD " : "", |
316 | (state->flags&SS_RESET)?"RESET ":"", | 328 | (state->flags & SS_RESET) ? "RESET " : "", |
317 | (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", | 329 | (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "", |
318 | (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"", | 330 | (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "", |
319 | state->Vcc, state->Vpp, state->io_irq); | 331 | state->Vcc, state->Vpp, state->io_irq); |
320 | 332 | ||
321 | return soc_common_pcmcia_config_skt(skt, state); | 333 | return soc_common_pcmcia_config_skt(skt, state); |
@@ -330,8 +342,8 @@ soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
330 | * | 342 | * |
331 | * Returns: 0 on success, -1 on error | 343 | * Returns: 0 on success, -1 on error |
332 | */ | 344 | */ |
333 | static int | 345 | static int soc_common_pcmcia_set_io_map( |
334 | soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) | 346 | struct pcmcia_socket *sock, struct pccard_io_map *map) |
335 | { | 347 | { |
336 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); | 348 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); |
337 | unsigned short speed = map->speed; | 349 | unsigned short speed = map->speed; |
@@ -340,14 +352,14 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m | |||
340 | map->map, map->speed, (unsigned long long)map->start, | 352 | map->map, map->speed, (unsigned long long)map->start, |
341 | (unsigned long long)map->stop); | 353 | (unsigned long long)map->stop); |
342 | debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", | 354 | debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", |
343 | (map->flags==0)?"<NONE>":"", | 355 | (map->flags == 0) ? "<NONE>" : "", |
344 | (map->flags&MAP_ACTIVE)?"ACTIVE ":"", | 356 | (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", |
345 | (map->flags&MAP_16BIT)?"16BIT ":"", | 357 | (map->flags & MAP_16BIT) ? "16BIT " : "", |
346 | (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"", | 358 | (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", |
347 | (map->flags&MAP_0WS)?"0WS ":"", | 359 | (map->flags & MAP_0WS) ? "0WS " : "", |
348 | (map->flags&MAP_WRPROT)?"WRPROT ":"", | 360 | (map->flags & MAP_WRPROT) ? "WRPROT " : "", |
349 | (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"", | 361 | (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "", |
350 | (map->flags&MAP_PREFETCH)?"PREFETCH ":""); | 362 | (map->flags & MAP_PREFETCH) ? "PREFETCH " : ""); |
351 | 363 | ||
352 | if (map->map >= MAX_IO_WIN) { | 364 | if (map->map >= MAX_IO_WIN) { |
353 | printk(KERN_ERR "%s(): map (%d) out of range\n", __func__, | 365 | printk(KERN_ERR "%s(): map (%d) out of range\n", __func__, |
@@ -384,8 +396,8 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m | |||
384 | * | 396 | * |
385 | * Returns: 0 on success, -ERRNO on error | 397 | * Returns: 0 on success, -ERRNO on error |
386 | */ | 398 | */ |
387 | static int | 399 | static int soc_common_pcmcia_set_mem_map( |
388 | soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) | 400 | struct pcmcia_socket *sock, struct pccard_mem_map *map) |
389 | { | 401 | { |
390 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); | 402 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); |
391 | struct resource *res; | 403 | struct resource *res; |
@@ -394,14 +406,14 @@ soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map | |||
394 | debug(skt, 2, "map %u speed %u card_start %08x\n", | 406 | debug(skt, 2, "map %u speed %u card_start %08x\n", |
395 | map->map, map->speed, map->card_start); | 407 | map->map, map->speed, map->card_start); |
396 | debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", | 408 | debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", |
397 | (map->flags==0)?"<NONE>":"", | 409 | (map->flags == 0) ? "<NONE>" : "", |
398 | (map->flags&MAP_ACTIVE)?"ACTIVE ":"", | 410 | (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", |
399 | (map->flags&MAP_16BIT)?"16BIT ":"", | 411 | (map->flags & MAP_16BIT) ? "16BIT " : "", |
400 | (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"", | 412 | (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", |
401 | (map->flags&MAP_0WS)?"0WS ":"", | 413 | (map->flags & MAP_0WS) ? "0WS " : "", |
402 | (map->flags&MAP_WRPROT)?"WRPROT ":"", | 414 | (map->flags & MAP_WRPROT) ? "WRPROT " : "", |
403 | (map->flags&MAP_ATTRIB)?"ATTRIB ":"", | 415 | (map->flags & MAP_ATTRIB) ? "ATTRIB " : "", |
404 | (map->flags&MAP_USE_WAIT)?"USE_WAIT ":""); | 416 | (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : ""); |
405 | 417 | ||
406 | if (map->map >= MAX_WIN) | 418 | if (map->map >= MAX_WIN) |
407 | return -EINVAL; | 419 | return -EINVAL; |
@@ -456,8 +468,8 @@ static struct bittbl conf_bits[] = { | |||
456 | { SS_OUTPUT_ENA, "SS_OUTPUT_ENA" }, | 468 | { SS_OUTPUT_ENA, "SS_OUTPUT_ENA" }, |
457 | }; | 469 | }; |
458 | 470 | ||
459 | static void | 471 | static void dump_bits(char **p, const char *prefix, |
460 | dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, int sz) | 472 | unsigned int val, struct bittbl *bits, int sz) |
461 | { | 473 | { |
462 | char *b = *p; | 474 | char *b = *p; |
463 | int i; | 475 | int i; |
@@ -475,13 +487,14 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i | |||
475 | * | 487 | * |
476 | * Returns: the number of characters added to the buffer | 488 | * Returns: the number of characters added to the buffer |
477 | */ | 489 | */ |
478 | static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf) | 490 | static ssize_t show_status( |
491 | struct device *dev, struct device_attribute *attr, char *buf) | ||
479 | { | 492 | { |
480 | struct soc_pcmcia_socket *skt = | 493 | struct soc_pcmcia_socket *skt = |
481 | container_of(dev, struct soc_pcmcia_socket, socket.dev); | 494 | container_of(dev, struct soc_pcmcia_socket, socket.dev); |
482 | char *p = buf; | 495 | char *p = buf; |
483 | 496 | ||
484 | p+=sprintf(p, "slot : %d\n", skt->nr); | 497 | p += sprintf(p, "slot : %d\n", skt->nr); |
485 | 498 | ||
486 | dump_bits(&p, "status", skt->status, | 499 | dump_bits(&p, "status", skt->status, |
487 | status_bits, ARRAY_SIZE(status_bits)); | 500 | status_bits, ARRAY_SIZE(status_bits)); |
@@ -490,12 +503,12 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr, ch | |||
490 | dump_bits(&p, "cs_flags", skt->cs_state.flags, | 503 | dump_bits(&p, "cs_flags", skt->cs_state.flags, |
491 | conf_bits, ARRAY_SIZE(conf_bits)); | 504 | conf_bits, ARRAY_SIZE(conf_bits)); |
492 | 505 | ||
493 | p+=sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc); | 506 | p += sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc); |
494 | p+=sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp); | 507 | p += sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp); |
495 | p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, | 508 | p += sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, |
496 | skt->socket.pci_irq); | 509 | skt->socket.pci_irq); |
497 | if (skt->ops->show_timing) | 510 | if (skt->ops->show_timing) |
498 | p+=skt->ops->show_timing(skt, p); | 511 | p += skt->ops->show_timing(skt, p); |
499 | 512 | ||
500 | return p-buf; | 513 | return p-buf; |
501 | } | 514 | } |
@@ -524,7 +537,7 @@ int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, | |||
524 | IRQF_DISABLED, irqs[i].str, skt); | 537 | IRQF_DISABLED, irqs[i].str, skt); |
525 | if (res) | 538 | if (res) |
526 | break; | 539 | break; |
527 | set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); | 540 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); |
528 | } | 541 | } |
529 | 542 | ||
530 | if (res) { | 543 | if (res) { |
@@ -557,7 +570,7 @@ void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, | |||
557 | 570 | ||
558 | for (i = 0; i < nr; i++) | 571 | for (i = 0; i < nr; i++) |
559 | if (irqs[i].sock == skt->nr) | 572 | if (irqs[i].sock == skt->nr) |
560 | set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); | 573 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); |
561 | } | 574 | } |
562 | EXPORT_SYMBOL(soc_pcmcia_disable_irqs); | 575 | EXPORT_SYMBOL(soc_pcmcia_disable_irqs); |
563 | 576 | ||
@@ -568,8 +581,8 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, | |||
568 | 581 | ||
569 | for (i = 0; i < nr; i++) | 582 | for (i = 0; i < nr; i++) |
570 | if (irqs[i].sock == skt->nr) { | 583 | if (irqs[i].sock == skt->nr) { |
571 | set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING); | 584 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING); |
572 | set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH); | 585 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH); |
573 | } | 586 | } |
574 | } | 587 | } |
575 | EXPORT_SYMBOL(soc_pcmcia_enable_irqs); | 588 | EXPORT_SYMBOL(soc_pcmcia_enable_irqs); |
@@ -588,7 +601,7 @@ soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data) | |||
588 | 601 | ||
589 | mutex_lock(&soc_pcmcia_sockets_lock); | 602 | mutex_lock(&soc_pcmcia_sockets_lock); |
590 | list_for_each_entry(skt, &soc_pcmcia_sockets, node) | 603 | list_for_each_entry(skt, &soc_pcmcia_sockets, node) |
591 | if ( skt->ops->frequency_change ) | 604 | if (skt->ops->frequency_change) |
592 | ret += skt->ops->frequency_change(skt, val, freqs); | 605 | ret += skt->ops->frequency_change(skt, val, freqs); |
593 | mutex_unlock(&soc_pcmcia_sockets_lock); | 606 | mutex_unlock(&soc_pcmcia_sockets_lock); |
594 | 607 | ||
@@ -614,7 +627,8 @@ fs_initcall(soc_pcmcia_cpufreq_register); | |||
614 | 627 | ||
615 | static void soc_pcmcia_cpufreq_unregister(void) | 628 | static void soc_pcmcia_cpufreq_unregister(void) |
616 | { | 629 | { |
617 | cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); | 630 | cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, |
631 | CPUFREQ_TRANSITION_NOTIFIER); | ||
618 | } | 632 | } |
619 | module_exit(soc_pcmcia_cpufreq_unregister); | 633 | module_exit(soc_pcmcia_cpufreq_unregister); |
620 | 634 | ||
@@ -627,8 +641,6 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) | |||
627 | 641 | ||
628 | pcmcia_unregister_socket(&skt->socket); | 642 | pcmcia_unregister_socket(&skt->socket); |
629 | 643 | ||
630 | flush_scheduled_work(); | ||
631 | |||
632 | skt->ops->hw_shutdown(skt); | 644 | skt->ops->hw_shutdown(skt); |
633 | 645 | ||
634 | soc_common_pcmcia_config_skt(skt, &dead_socket); | 646 | soc_common_pcmcia_config_skt(skt, &dead_socket); |
@@ -720,8 +732,6 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) | |||
720 | pcmcia_unregister_socket(&skt->socket); | 732 | pcmcia_unregister_socket(&skt->socket); |
721 | 733 | ||
722 | out_err_7: | 734 | out_err_7: |
723 | flush_scheduled_work(); | ||
724 | |||
725 | skt->ops->hw_shutdown(skt); | 735 | skt->ops->hw_shutdown(skt); |
726 | out_err_6: | 736 | out_err_6: |
727 | list_del(&skt->node); | 737 | list_del(&skt->node); |
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 3fba3a679128..9daa73615c8b 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h | |||
@@ -10,8 +10,8 @@ | |||
10 | #define _ASM_ARCH_PCMCIA | 10 | #define _ASM_ARCH_PCMCIA |
11 | 11 | ||
12 | /* include the world */ | 12 | /* include the world */ |
13 | #include <linux/clk.h> | ||
13 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
14 | #include <pcmcia/cs.h> | ||
15 | #include <pcmcia/ss.h> | 15 | #include <pcmcia/ss.h> |
16 | #include <pcmcia/cistpl.h> | 16 | #include <pcmcia/cistpl.h> |
17 | 17 | ||
@@ -30,6 +30,7 @@ struct soc_pcmcia_socket { | |||
30 | * Info from low level handler | 30 | * Info from low level handler |
31 | */ | 31 | */ |
32 | unsigned int nr; | 32 | unsigned int nr; |
33 | struct clk *clk; | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * Core PCMCIA state | 36 | * Core PCMCIA state |
@@ -57,6 +58,7 @@ struct soc_pcmcia_socket { | |||
57 | 58 | ||
58 | struct skt_dev_info { | 59 | struct skt_dev_info { |
59 | int nskt; | 60 | int nskt; |
61 | struct clk *clk; | ||
60 | struct soc_pcmcia_socket skt[0]; | 62 | struct soc_pcmcia_socket skt[0]; |
61 | }; | 63 | }; |
62 | 64 | ||
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index cb0d3ace18bd..71aeed93037c 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
28 | 28 | ||
29 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
30 | #include <pcmcia/cs.h> | ||
31 | #include <pcmcia/cistpl.h> | 30 | #include <pcmcia/cistpl.h> |
32 | #include <pcmcia/cisreg.h> | 31 | #include <pcmcia/cisreg.h> |
33 | #include <pcmcia/ds.h> | 32 | #include <pcmcia/ds.h> |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index be0d841c7ebd..310160bffe38 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <asm/io.h> | 49 | #include <asm/io.h> |
50 | #include <asm/system.h> | 50 | #include <asm/system.h> |
51 | 51 | ||
52 | #include <pcmcia/cs.h> | ||
53 | #include <pcmcia/ss.h> | 52 | #include <pcmcia/ss.h> |
54 | #include "tcic.h" | 53 | #include "tcic.h" |
55 | 54 | ||
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 9ffa97d0b16c..a71789486cdf 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -691,7 +691,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
691 | /* | 691 | /* |
692 | * those are either single or dual slot CB with additional functions | 692 | * those are either single or dual slot CB with additional functions |
693 | * like 1394, smartcard reader, etc. check the TIEALL flag for them | 693 | * like 1394, smartcard reader, etc. check the TIEALL flag for them |
694 | * the TIEALL flag binds the IRQ of all functions toghether. | 694 | * the TIEALL flag binds the IRQ of all functions together. |
695 | * we catch the single slot variants later. | 695 | * we catch the single slot variants later. |
696 | */ | 696 | */ |
697 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | 697 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); |
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index 9b3c15827e5c..c6d36b3a6ce8 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c | |||
@@ -461,7 +461,7 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev, | |||
461 | { | 461 | { |
462 | vrc4173_socket_t *socket; | 462 | vrc4173_socket_t *socket; |
463 | unsigned long start, len, flags; | 463 | unsigned long start, len, flags; |
464 | int slot, err; | 464 | int slot, err, ret; |
465 | 465 | ||
466 | slot = vrc4173_cardu_slots++; | 466 | slot = vrc4173_cardu_slots++; |
467 | socket = &cardu_sockets[slot]; | 467 | socket = &cardu_sockets[slot]; |
@@ -474,43 +474,63 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev, | |||
474 | return err; | 474 | return err; |
475 | 475 | ||
476 | start = pci_resource_start(dev, 0); | 476 | start = pci_resource_start(dev, 0); |
477 | if (start == 0) | 477 | if (start == 0) { |
478 | return -ENODEV; | 478 | ret = -ENODEV; |
479 | goto disable; | ||
480 | } | ||
479 | 481 | ||
480 | len = pci_resource_len(dev, 0); | 482 | len = pci_resource_len(dev, 0); |
481 | if (len == 0) | 483 | if (len == 0) { |
482 | return -ENODEV; | 484 | ret = -ENODEV; |
485 | goto disable; | ||
486 | } | ||
483 | 487 | ||
484 | if (((flags = pci_resource_flags(dev, 0)) & IORESOURCE_MEM) == 0) | 488 | flags = pci_resource_flags(dev, 0); |
485 | return -EBUSY; | 489 | if ((flags & IORESOURCE_MEM) == 0) { |
490 | ret = -EBUSY; | ||
491 | goto disable; | ||
492 | } | ||
486 | 493 | ||
487 | if ((err = pci_request_regions(dev, socket->name)) < 0) | 494 | err = pci_request_regions(dev, socket->name); |
488 | return err; | 495 | if (err < 0) { |
496 | ret = err; | ||
497 | goto disable; | ||
498 | } | ||
489 | 499 | ||
490 | socket->base = ioremap(start, len); | 500 | socket->base = ioremap(start, len); |
491 | if (socket->base == NULL) | 501 | if (socket->base == NULL) { |
492 | return -ENODEV; | 502 | ret = -ENODEV; |
503 | goto release; | ||
504 | } | ||
493 | 505 | ||
494 | socket->dev = dev; | 506 | socket->dev = dev; |
495 | 507 | ||
496 | socket->pcmcia_socket = pcmcia_register_socket(slot, &cardu_operations, 1); | 508 | socket->pcmcia_socket = pcmcia_register_socket(slot, &cardu_operations, 1); |
497 | if (socket->pcmcia_socket == NULL) { | 509 | if (socket->pcmcia_socket == NULL) { |
498 | iounmap(socket->base); | 510 | ret = -ENOMEM; |
499 | socket->base = NULL; | 511 | goto unmap; |
500 | return -ENOMEM; | ||
501 | } | 512 | } |
502 | 513 | ||
503 | if (request_irq(dev->irq, cardu_interrupt, IRQF_SHARED, socket->name, socket) < 0) { | 514 | if (request_irq(dev->irq, cardu_interrupt, IRQF_SHARED, socket->name, socket) < 0) { |
504 | pcmcia_unregister_socket(socket->pcmcia_socket); | 515 | ret = -EBUSY; |
505 | socket->pcmcia_socket = NULL; | 516 | goto unregister; |
506 | iounmap(socket->base); | ||
507 | socket->base = NULL; | ||
508 | return -EBUSY; | ||
509 | } | 517 | } |
510 | 518 | ||
511 | printk(KERN_INFO "%s at %#08lx, IRQ %d\n", socket->name, start, dev->irq); | 519 | printk(KERN_INFO "%s at %#08lx, IRQ %d\n", socket->name, start, dev->irq); |
512 | 520 | ||
513 | return 0; | 521 | return 0; |
522 | |||
523 | unregister: | ||
524 | pcmcia_unregister_socket(socket->pcmcia_socket); | ||
525 | socket->pcmcia_socket = NULL; | ||
526 | unmap: | ||
527 | iounmap(socket->base); | ||
528 | socket->base = NULL; | ||
529 | release: | ||
530 | pci_release_regions(dev); | ||
531 | disable: | ||
532 | pci_disable_device(dev); | ||
533 | return ret; | ||
514 | } | 534 | } |
515 | 535 | ||
516 | static int __devinit vrc4173_cardu_setup(char *options) | 536 | static int __devinit vrc4173_cardu_setup(char *options) |
diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index fa88c360c37a..379f4218857d 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | 19 | ||
20 | #include <pcmcia/cs.h> | ||
21 | #include <pcmcia/ss.h> | 20 | #include <pcmcia/ss.h> |
22 | #include <pcmcia/cistpl.h> | 21 | #include <pcmcia/cistpl.h> |
23 | 22 | ||
@@ -275,7 +274,7 @@ static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev) | |||
275 | * edge detector. | 274 | * edge detector. |
276 | */ | 275 | */ |
277 | irq = gpio_to_irq(GPIO_CDA); | 276 | irq = gpio_to_irq(GPIO_CDA); |
278 | set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); | 277 | irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); |
279 | ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock); | 278 | ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock); |
280 | if (ret) { | 279 | if (ret) { |
281 | dev_err(&pdev->dev, "cannot setup cd irq\n"); | 280 | dev_err(&pdev->dev, "cannot setup cd irq\n"); |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 414d9a6f9a32..9dc565c615bd 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | 21 | ||
22 | #include <pcmcia/ss.h> | 22 | #include <pcmcia/ss.h> |
23 | #include <pcmcia/cs.h> | ||
24 | 23 | ||
25 | #include "yenta_socket.h" | 24 | #include "yenta_socket.h" |
26 | #include "i82365.h" | 25 | #include "i82365.h" |
@@ -1073,7 +1072,7 @@ static void yenta_config_init(struct yenta_socket *socket) | |||
1073 | * invisible during PCI scans because of a misconfigured subordinate number | 1072 | * invisible during PCI scans because of a misconfigured subordinate number |
1074 | * of the parent brige - some BIOSes seem to be too lazy to set it right. | 1073 | * of the parent brige - some BIOSes seem to be too lazy to set it right. |
1075 | * Does the fixup carefully by checking how far it can go without conflicts. | 1074 | * Does the fixup carefully by checking how far it can go without conflicts. |
1076 | * See http\://bugzilla.kernel.org/show_bug.cgi?id=2944 for more information. | 1075 | * See http://bugzilla.kernel.org/show_bug.cgi?id=2944 for more information. |
1077 | */ | 1076 | */ |
1078 | static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | 1077 | static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) |
1079 | { | 1078 | { |