diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/pcmcia | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/pcmcia')
57 files changed, 1116 insertions, 1353 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 8fd255f7ee4..6e318ce4113 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -155,14 +155,18 @@ config PCMCIA_M8XX | |||
155 | 155 | ||
156 | This driver is also available as a module called m8xx_pcmcia. | 156 | This driver is also available as a module called m8xx_pcmcia. |
157 | 157 | ||
158 | config PCMCIA_AU1X00 | ||
159 | tristate "Au1x00 pcmcia support" | ||
160 | depends on MIPS_ALCHEMY && PCMCIA | ||
161 | |||
158 | config PCMCIA_ALCHEMY_DEVBOARD | 162 | config PCMCIA_ALCHEMY_DEVBOARD |
159 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" | 163 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" |
160 | depends on MIPS_ALCHEMY && PCMCIA | 164 | depends on MIPS_ALCHEMY && PCMCIA |
161 | select 64BIT_PHYS_ADDR | 165 | select 64BIT_PHYS_ADDR |
162 | help | 166 | help |
163 | Enable this driver of you want PCMCIA support on your Alchemy | 167 | Enable this driver of you want PCMCIA support on your Alchemy |
164 | Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300 | 168 | Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200 board. |
165 | board. NOT suitable for the PB1000! | 169 | NOT suitable for the PB1000! |
166 | 170 | ||
167 | This driver is also available as a module called db1xxx_ss.ko | 171 | This driver is also available as a module called db1xxx_ss.ko |
168 | 172 | ||
@@ -183,14 +187,10 @@ config PCMCIA_BCM63XX | |||
183 | config PCMCIA_SOC_COMMON | 187 | config PCMCIA_SOC_COMMON |
184 | tristate | 188 | tristate |
185 | 189 | ||
186 | config PCMCIA_SA11XX_BASE | ||
187 | tristate | ||
188 | |||
189 | config PCMCIA_SA1100 | 190 | config PCMCIA_SA1100 |
190 | tristate "SA1100 support" | 191 | tristate "SA1100 support" |
191 | depends on ARM && ARCH_SA1100 && PCMCIA | 192 | depends on ARM && ARCH_SA1100 && PCMCIA |
192 | select PCMCIA_SOC_COMMON | 193 | select PCMCIA_SOC_COMMON |
193 | select PCMCIA_SA11XX_BASE | ||
194 | help | 194 | help |
195 | Say Y here to include support for SA11x0-based PCMCIA or CF | 195 | Say Y here to include support for SA11x0-based PCMCIA or CF |
196 | sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/ | 196 | sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/ |
@@ -200,9 +200,8 @@ config PCMCIA_SA1100 | |||
200 | 200 | ||
201 | config PCMCIA_SA1111 | 201 | config PCMCIA_SA1111 |
202 | tristate "SA1111 support" | 202 | tristate "SA1111 support" |
203 | depends on ARM && SA1111 && PCMCIA | 203 | depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA |
204 | select PCMCIA_SOC_COMMON | 204 | select PCMCIA_SOC_COMMON |
205 | select PCMCIA_SA11XX_BASE if ARCH_SA1100 | ||
206 | help | 205 | help |
207 | Say Y here to include support for SA1111-based PCMCIA or CF | 206 | Say Y here to include support for SA1111-based PCMCIA or CF |
208 | sockets, found on the Jornada 720, Graphicsmaster and other | 207 | sockets, found on the Jornada 720, Graphicsmaster and other |
@@ -217,8 +216,7 @@ config PCMCIA_PXA2XX | |||
217 | || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ | 216 | || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ |
218 | || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ | 217 | || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ |
219 | || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ | 218 | || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ |
220 | || MACH_COLIBRI320 || MACH_H4700) | 219 | || MACH_COLIBRI320) |
221 | select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111 | ||
222 | select PCMCIA_SOC_COMMON | 220 | select PCMCIA_SOC_COMMON |
223 | help | 221 | help |
224 | 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 7745b512a87..29935ea921d 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -25,11 +25,11 @@ obj-$(CONFIG_I82092) += i82092.o | |||
25 | obj-$(CONFIG_TCIC) += tcic.o | 25 | obj-$(CONFIG_TCIC) += tcic.o |
26 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o | 26 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o |
27 | obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o | 27 | obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o |
28 | obj-$(CONFIG_PCMCIA_SA11XX_BASE) += sa11xx_base.o | 28 | obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o |
29 | obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o | 29 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o |
30 | obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o | ||
31 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o | 30 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o |
32 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o | 31 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o |
32 | obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o | ||
33 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o | 33 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o |
34 | obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o | 34 | obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o |
35 | obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o | 35 | obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o |
@@ -39,11 +39,13 @@ obj-$(CONFIG_AT91_CF) += at91_cf.o | |||
39 | obj-$(CONFIG_ELECTRA_CF) += electra_cf.o | 39 | obj-$(CONFIG_ELECTRA_CF) += electra_cf.o |
40 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o | 40 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o |
41 | 41 | ||
42 | au1x00_ss-y += au1000_generic.o | ||
43 | au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o | ||
44 | |||
42 | sa1111_cs-y += sa1111_generic.o | 45 | sa1111_cs-y += sa1111_generic.o |
43 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1111_neponset.o | 46 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o |
44 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1111_badge4.o | 47 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o |
45 | sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1111_jornada720.o | 48 | sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o |
46 | sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o | ||
47 | 49 | ||
48 | sa1100_cs-y += sa1100_generic.o | 50 | sa1100_cs-y += sa1100_generic.o |
49 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o | 51 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o |
@@ -54,7 +56,9 @@ sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o | |||
54 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o | 56 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o |
55 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o | 57 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o |
56 | 58 | ||
59 | pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o | ||
57 | pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o | 60 | pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o |
61 | pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o | ||
58 | pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o | 62 | pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o |
59 | pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o | 63 | pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o |
60 | pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o | 64 | pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o |
@@ -69,7 +73,6 @@ pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o | |||
69 | pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o | 73 | pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o |
70 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o | 74 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI) += pxa2xx_colibri.o |
71 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI320) += pxa2xx_colibri.o | 75 | pxa2xx-obj-$(CONFIG_MACH_COLIBRI320) += pxa2xx_colibri.o |
72 | pxa2xx-obj-$(CONFIG_MACH_H4700) += pxa2xx_hx4700.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/at91_cf.c b/drivers/pcmcia/at91_cf.c index 01463c78184..4902206f53d 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -16,17 +16,16 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/gpio.h> | ||
20 | #include <linux/platform_data/atmel.h> | ||
21 | 19 | ||
22 | #include <pcmcia/ss.h> | 20 | #include <pcmcia/ss.h> |
23 | 21 | ||
24 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
25 | #include <asm/io.h> | 23 | #include <asm/io.h> |
26 | #include <asm/sizes.h> | 24 | #include <asm/sizes.h> |
25 | #include <asm/gpio.h> | ||
27 | 26 | ||
27 | #include <mach/board.h> | ||
28 | #include <mach/at91rm9200_mc.h> | 28 | #include <mach/at91rm9200_mc.h> |
29 | #include <mach/at91_ramc.h> | ||
30 | 29 | ||
31 | 30 | ||
32 | /* | 31 | /* |
@@ -70,7 +69,7 @@ static irqreturn_t at91_cf_irq(int irq, void *_cf) | |||
70 | { | 69 | { |
71 | struct at91_cf_socket *cf = _cf; | 70 | struct at91_cf_socket *cf = _cf; |
72 | 71 | ||
73 | if (irq == gpio_to_irq(cf->board->det_pin)) { | 72 | if (irq == cf->board->det_pin) { |
74 | unsigned present = at91_cf_present(cf); | 73 | unsigned present = at91_cf_present(cf); |
75 | 74 | ||
76 | /* kick pccard as needed */ | 75 | /* kick pccard as needed */ |
@@ -96,8 +95,8 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) | |||
96 | 95 | ||
97 | /* NOTE: CF is always 3VCARD */ | 96 | /* NOTE: CF is always 3VCARD */ |
98 | if (at91_cf_present(cf)) { | 97 | if (at91_cf_present(cf)) { |
99 | int rdy = gpio_is_valid(cf->board->irq_pin); /* RDY/nIRQ */ | 98 | int rdy = cf->board->irq_pin; /* RDY/nIRQ */ |
100 | int vcc = gpio_is_valid(cf->board->vcc_pin); | 99 | int vcc = cf->board->vcc_pin; |
101 | 100 | ||
102 | *sp = SS_DETECT | SS_3VCARD; | 101 | *sp = SS_DETECT | SS_3VCARD; |
103 | if (!rdy || gpio_get_value(rdy)) | 102 | if (!rdy || gpio_get_value(rdy)) |
@@ -118,7 +117,7 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) | |||
118 | cf = container_of(sock, struct at91_cf_socket, socket); | 117 | cf = container_of(sock, struct at91_cf_socket, socket); |
119 | 118 | ||
120 | /* switch Vcc if needed and possible */ | 119 | /* switch Vcc if needed and possible */ |
121 | if (gpio_is_valid(cf->board->vcc_pin)) { | 120 | if (cf->board->vcc_pin) { |
122 | switch (s->Vcc) { | 121 | switch (s->Vcc) { |
123 | case 0: | 122 | case 0: |
124 | gpio_set_value(cf->board->vcc_pin, 0); | 123 | gpio_set_value(cf->board->vcc_pin, 0); |
@@ -157,7 +156,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) | |||
157 | /* | 156 | /* |
158 | * Use 16 bit accesses unless/until we need 8-bit i/o space. | 157 | * Use 16 bit accesses unless/until we need 8-bit i/o space. |
159 | */ | 158 | */ |
160 | csr = at91_ramc_read(0, AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; | 159 | csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; |
161 | 160 | ||
162 | /* | 161 | /* |
163 | * NOTE: this CF controller ignores IOIS16, so we can't really do | 162 | * NOTE: this CF controller ignores IOIS16, so we can't really do |
@@ -176,7 +175,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) | |||
176 | csr |= AT91_SMC_DBW_16; | 175 | csr |= AT91_SMC_DBW_16; |
177 | pr_debug("%s: 16bit i/o bus\n", driver_name); | 176 | pr_debug("%s: 16bit i/o bus\n", driver_name); |
178 | } | 177 | } |
179 | at91_ramc_write(0, AT91_SMC_CSR(cf->board->chipselect), csr); | 178 | at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr); |
180 | 179 | ||
181 | io->start = cf->socket.io_offset; | 180 | io->start = cf->socket.io_offset; |
182 | io->stop = io->start + SZ_2K - 1; | 181 | io->stop = io->start + SZ_2K - 1; |
@@ -222,7 +221,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
222 | struct resource *io; | 221 | struct resource *io; |
223 | int status; | 222 | int status; |
224 | 223 | ||
225 | if (!board || !gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin)) | 224 | if (!board || !board->det_pin || !board->rst_pin) |
226 | return -ENODEV; | 225 | return -ENODEV; |
227 | 226 | ||
228 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 227 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -242,7 +241,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
242 | status = gpio_request(board->det_pin, "cf_det"); | 241 | status = gpio_request(board->det_pin, "cf_det"); |
243 | if (status < 0) | 242 | if (status < 0) |
244 | goto fail0; | 243 | goto fail0; |
245 | status = request_irq(gpio_to_irq(board->det_pin), at91_cf_irq, 0, driver_name, cf); | 244 | status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); |
246 | if (status < 0) | 245 | if (status < 0) |
247 | goto fail00; | 246 | goto fail00; |
248 | device_init_wakeup(&pdev->dev, 1); | 247 | device_init_wakeup(&pdev->dev, 1); |
@@ -251,7 +250,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
251 | if (status < 0) | 250 | if (status < 0) |
252 | goto fail0a; | 251 | goto fail0a; |
253 | 252 | ||
254 | if (gpio_is_valid(board->vcc_pin)) { | 253 | if (board->vcc_pin) { |
255 | status = gpio_request(board->vcc_pin, "cf_vcc"); | 254 | status = gpio_request(board->vcc_pin, "cf_vcc"); |
256 | if (status < 0) | 255 | if (status < 0) |
257 | goto fail0b; | 256 | goto fail0b; |
@@ -263,15 +262,15 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
263 | * unless we report that we handle everything (sigh). | 262 | * unless we report that we handle everything (sigh). |
264 | * (Note: DK board doesn't wire the IRQ pin...) | 263 | * (Note: DK board doesn't wire the IRQ pin...) |
265 | */ | 264 | */ |
266 | if (gpio_is_valid(board->irq_pin)) { | 265 | if (board->irq_pin) { |
267 | status = gpio_request(board->irq_pin, "cf_irq"); | 266 | status = gpio_request(board->irq_pin, "cf_irq"); |
268 | if (status < 0) | 267 | if (status < 0) |
269 | goto fail0c; | 268 | goto fail0c; |
270 | status = request_irq(gpio_to_irq(board->irq_pin), at91_cf_irq, | 269 | status = request_irq(board->irq_pin, at91_cf_irq, |
271 | IRQF_SHARED, driver_name, cf); | 270 | IRQF_SHARED, driver_name, cf); |
272 | if (status < 0) | 271 | if (status < 0) |
273 | goto fail0d; | 272 | goto fail0d; |
274 | cf->socket.pci_irq = gpio_to_irq(board->irq_pin); | 273 | cf->socket.pci_irq = board->irq_pin; |
275 | } else | 274 | } else |
276 | cf->socket.pci_irq = nr_irqs + 1; | 275 | cf->socket.pci_irq = nr_irqs + 1; |
277 | 276 | ||
@@ -290,7 +289,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
290 | } | 289 | } |
291 | 290 | ||
292 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, | 291 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, |
293 | gpio_to_irq(board->det_pin), gpio_to_irq(board->irq_pin)); | 292 | board->det_pin, board->irq_pin); |
294 | 293 | ||
295 | cf->socket.owner = THIS_MODULE; | 294 | cf->socket.owner = THIS_MODULE; |
296 | cf->socket.dev.parent = &pdev->dev; | 295 | cf->socket.dev.parent = &pdev->dev; |
@@ -312,19 +311,19 @@ fail2: | |||
312 | fail1: | 311 | fail1: |
313 | if (cf->socket.io_offset) | 312 | if (cf->socket.io_offset) |
314 | iounmap((void __iomem *) cf->socket.io_offset); | 313 | iounmap((void __iomem *) cf->socket.io_offset); |
315 | if (gpio_is_valid(board->irq_pin)) { | 314 | if (board->irq_pin) { |
316 | free_irq(gpio_to_irq(board->irq_pin), cf); | 315 | free_irq(board->irq_pin, cf); |
317 | fail0d: | 316 | fail0d: |
318 | gpio_free(board->irq_pin); | 317 | gpio_free(board->irq_pin); |
319 | } | 318 | } |
320 | fail0c: | 319 | fail0c: |
321 | if (gpio_is_valid(board->vcc_pin)) | 320 | if (board->vcc_pin) |
322 | gpio_free(board->vcc_pin); | 321 | gpio_free(board->vcc_pin); |
323 | fail0b: | 322 | fail0b: |
324 | gpio_free(board->rst_pin); | 323 | gpio_free(board->rst_pin); |
325 | fail0a: | 324 | fail0a: |
326 | device_init_wakeup(&pdev->dev, 0); | 325 | device_init_wakeup(&pdev->dev, 0); |
327 | free_irq(gpio_to_irq(board->det_pin), cf); | 326 | free_irq(board->det_pin, cf); |
328 | fail00: | 327 | fail00: |
329 | gpio_free(board->det_pin); | 328 | gpio_free(board->det_pin); |
330 | fail0: | 329 | fail0: |
@@ -341,15 +340,15 @@ static int __exit at91_cf_remove(struct platform_device *pdev) | |||
341 | pcmcia_unregister_socket(&cf->socket); | 340 | pcmcia_unregister_socket(&cf->socket); |
342 | release_mem_region(io->start, resource_size(io)); | 341 | release_mem_region(io->start, resource_size(io)); |
343 | iounmap((void __iomem *) cf->socket.io_offset); | 342 | iounmap((void __iomem *) cf->socket.io_offset); |
344 | if (gpio_is_valid(board->irq_pin)) { | 343 | if (board->irq_pin) { |
345 | free_irq(gpio_to_irq(board->irq_pin), cf); | 344 | free_irq(board->irq_pin, cf); |
346 | gpio_free(board->irq_pin); | 345 | gpio_free(board->irq_pin); |
347 | } | 346 | } |
348 | if (gpio_is_valid(board->vcc_pin)) | 347 | if (board->vcc_pin) |
349 | gpio_free(board->vcc_pin); | 348 | gpio_free(board->vcc_pin); |
350 | gpio_free(board->rst_pin); | 349 | gpio_free(board->rst_pin); |
351 | device_init_wakeup(&pdev->dev, 0); | 350 | device_init_wakeup(&pdev->dev, 0); |
352 | free_irq(gpio_to_irq(board->det_pin), cf); | 351 | free_irq(board->det_pin, cf); |
353 | gpio_free(board->det_pin); | 352 | gpio_free(board->det_pin); |
354 | kfree(cf); | 353 | kfree(cf); |
355 | return 0; | 354 | return 0; |
@@ -363,9 +362,9 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
363 | struct at91_cf_data *board = cf->board; | 362 | struct at91_cf_data *board = cf->board; |
364 | 363 | ||
365 | if (device_may_wakeup(&pdev->dev)) { | 364 | if (device_may_wakeup(&pdev->dev)) { |
366 | enable_irq_wake(gpio_to_irq(board->det_pin)); | 365 | enable_irq_wake(board->det_pin); |
367 | if (gpio_is_valid(board->irq_pin)) | 366 | if (board->irq_pin) |
368 | enable_irq_wake(gpio_to_irq(board->irq_pin)); | 367 | enable_irq_wake(board->irq_pin); |
369 | } | 368 | } |
370 | return 0; | 369 | return 0; |
371 | } | 370 | } |
@@ -376,9 +375,9 @@ static int at91_cf_resume(struct platform_device *pdev) | |||
376 | struct at91_cf_data *board = cf->board; | 375 | struct at91_cf_data *board = cf->board; |
377 | 376 | ||
378 | if (device_may_wakeup(&pdev->dev)) { | 377 | if (device_may_wakeup(&pdev->dev)) { |
379 | disable_irq_wake(gpio_to_irq(board->det_pin)); | 378 | disable_irq_wake(board->det_pin); |
380 | if (gpio_is_valid(board->irq_pin)) | 379 | if (board->irq_pin) |
381 | disable_irq_wake(gpio_to_irq(board->irq_pin)); | 380 | disable_irq_wake(board->irq_pin); |
382 | } | 381 | } |
383 | 382 | ||
384 | return 0; | 383 | return 0; |
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c index 0c6aac1232f..693577e0fef 100644 --- a/drivers/pcmcia/bcm63xx_pcmcia.c +++ b/drivers/pcmcia/bcm63xx_pcmcia.c | |||
@@ -323,7 +323,7 @@ static struct pccard_operations bcm63xx_pcmcia_operations = { | |||
323 | /* | 323 | /* |
324 | * register pcmcia socket to core | 324 | * register pcmcia socket to core |
325 | */ | 325 | */ |
326 | static int bcm63xx_drv_pcmcia_probe(struct platform_device *pdev) | 326 | static int __devinit bcm63xx_drv_pcmcia_probe(struct platform_device *pdev) |
327 | { | 327 | { |
328 | struct bcm63xx_pcmcia_socket *skt; | 328 | struct bcm63xx_pcmcia_socket *skt; |
329 | struct pcmcia_socket *sock; | 329 | struct pcmcia_socket *sock; |
@@ -436,7 +436,7 @@ err: | |||
436 | return ret; | 436 | return ret; |
437 | } | 437 | } |
438 | 438 | ||
439 | static int bcm63xx_drv_pcmcia_remove(struct platform_device *pdev) | 439 | static int __devexit bcm63xx_drv_pcmcia_remove(struct platform_device *pdev) |
440 | { | 440 | { |
441 | struct bcm63xx_pcmcia_socket *skt; | 441 | struct bcm63xx_pcmcia_socket *skt; |
442 | struct resource *res; | 442 | struct resource *res; |
@@ -453,7 +453,7 @@ static int bcm63xx_drv_pcmcia_remove(struct platform_device *pdev) | |||
453 | 453 | ||
454 | struct platform_driver bcm63xx_pcmcia_driver = { | 454 | struct platform_driver bcm63xx_pcmcia_driver = { |
455 | .probe = bcm63xx_drv_pcmcia_probe, | 455 | .probe = bcm63xx_drv_pcmcia_probe, |
456 | .remove = bcm63xx_drv_pcmcia_remove, | 456 | .remove = __devexit_p(bcm63xx_drv_pcmcia_remove), |
457 | .driver = { | 457 | .driver = { |
458 | .name = "bcm63xx_pcmcia", | 458 | .name = "bcm63xx_pcmcia", |
459 | .owner = THIS_MODULE, | 459 | .owner = THIS_MODULE, |
@@ -461,7 +461,7 @@ struct platform_driver bcm63xx_pcmcia_driver = { | |||
461 | }; | 461 | }; |
462 | 462 | ||
463 | #ifdef CONFIG_CARDBUS | 463 | #ifdef CONFIG_CARDBUS |
464 | static int bcm63xx_cb_probe(struct pci_dev *dev, | 464 | static int __devinit bcm63xx_cb_probe(struct pci_dev *dev, |
465 | const struct pci_device_id *id) | 465 | const struct pci_device_id *id) |
466 | { | 466 | { |
467 | /* keep pci device */ | 467 | /* keep pci device */ |
@@ -469,13 +469,13 @@ static int bcm63xx_cb_probe(struct pci_dev *dev, | |||
469 | return platform_driver_register(&bcm63xx_pcmcia_driver); | 469 | return platform_driver_register(&bcm63xx_pcmcia_driver); |
470 | } | 470 | } |
471 | 471 | ||
472 | static void bcm63xx_cb_exit(struct pci_dev *dev) | 472 | static void __devexit bcm63xx_cb_exit(struct pci_dev *dev) |
473 | { | 473 | { |
474 | platform_driver_unregister(&bcm63xx_pcmcia_driver); | 474 | platform_driver_unregister(&bcm63xx_pcmcia_driver); |
475 | bcm63xx_cb_dev = NULL; | 475 | bcm63xx_cb_dev = NULL; |
476 | } | 476 | } |
477 | 477 | ||
478 | static DEFINE_PCI_DEVICE_TABLE(bcm63xx_cb_table) = { | 478 | static struct pci_device_id bcm63xx_cb_table[] = { |
479 | { | 479 | { |
480 | .vendor = PCI_VENDOR_ID_BROADCOM, | 480 | .vendor = PCI_VENDOR_ID_BROADCOM, |
481 | .device = BCM6348_CPU_ID, | 481 | .device = BCM6348_CPU_ID, |
@@ -503,7 +503,7 @@ static struct pci_driver bcm63xx_cardbus_driver = { | |||
503 | .name = "bcm63xx_cardbus", | 503 | .name = "bcm63xx_cardbus", |
504 | .id_table = bcm63xx_cb_table, | 504 | .id_table = bcm63xx_cb_table, |
505 | .probe = bcm63xx_cb_probe, | 505 | .probe = bcm63xx_cb_probe, |
506 | .remove = bcm63xx_cb_exit, | 506 | .remove = __devexit_p(bcm63xx_cb_exit), |
507 | }; | 507 | }; |
508 | #endif | 508 | #endif |
509 | 509 | ||
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index ed3b522601b..49221395101 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c | |||
@@ -195,7 +195,7 @@ static struct pccard_operations bfin_cf_ops = { | |||
195 | 195 | ||
196 | /*--------------------------------------------------------------------------*/ | 196 | /*--------------------------------------------------------------------------*/ |
197 | 197 | ||
198 | static int bfin_cf_probe(struct platform_device *pdev) | 198 | static int __devinit bfin_cf_probe(struct platform_device *pdev) |
199 | { | 199 | { |
200 | struct bfin_cf_socket *cf; | 200 | struct bfin_cf_socket *cf; |
201 | struct resource *io_mem, *attr_mem; | 201 | struct resource *io_mem, *attr_mem; |
@@ -286,7 +286,7 @@ fail0: | |||
286 | return status; | 286 | return status; |
287 | } | 287 | } |
288 | 288 | ||
289 | static int bfin_cf_remove(struct platform_device *pdev) | 289 | static int __devexit bfin_cf_remove(struct platform_device *pdev) |
290 | { | 290 | { |
291 | struct bfin_cf_socket *cf = platform_get_drvdata(pdev); | 291 | struct bfin_cf_socket *cf = platform_get_drvdata(pdev); |
292 | 292 | ||
@@ -307,10 +307,21 @@ static struct platform_driver bfin_cf_driver = { | |||
307 | .owner = THIS_MODULE, | 307 | .owner = THIS_MODULE, |
308 | }, | 308 | }, |
309 | .probe = bfin_cf_probe, | 309 | .probe = bfin_cf_probe, |
310 | .remove = bfin_cf_remove, | 310 | .remove = __devexit_p(bfin_cf_remove), |
311 | }; | 311 | }; |
312 | 312 | ||
313 | module_platform_driver(bfin_cf_driver); | 313 | static int __init bfin_cf_init(void) |
314 | { | ||
315 | return platform_driver_register(&bfin_cf_driver); | ||
316 | } | ||
317 | |||
318 | static void __exit bfin_cf_exit(void) | ||
319 | { | ||
320 | platform_driver_unregister(&bfin_cf_driver); | ||
321 | } | ||
322 | |||
323 | module_init(bfin_cf_init); | ||
324 | module_exit(bfin_cf_exit); | ||
314 | 325 | ||
315 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 326 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
316 | MODULE_DESCRIPTION("BFIN CF/PCMCIA Driver"); | 327 | MODULE_DESCRIPTION("BFIN CF/PCMCIA Driver"); |
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 9d3ac998fc1..9a58862f140 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c | |||
@@ -73,7 +73,7 @@ int __ref cb_alloc(struct pcmcia_socket *s) | |||
73 | s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); | 73 | s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); |
74 | pci_fixup_cardbus(bus); | 74 | pci_fixup_cardbus(bus); |
75 | 75 | ||
76 | max = bus->busn_res.start; | 76 | max = bus->secondary; |
77 | for (pass = 0; pass < 2; pass++) | 77 | for (pass = 0; pass < 2; pass++) |
78 | list_for_each_entry(dev, &bus->devices, bus_list) | 78 | list_for_each_entry(dev, &bus->devices, bus_list) |
79 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 79 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
@@ -105,17 +105,8 @@ int __ref cb_alloc(struct pcmcia_socket *s) | |||
105 | */ | 105 | */ |
106 | void cb_free(struct pcmcia_socket *s) | 106 | void cb_free(struct pcmcia_socket *s) |
107 | { | 107 | { |
108 | struct pci_dev *bridge, *dev, *tmp; | 108 | struct pci_dev *bridge = s->cb_dev; |
109 | struct pci_bus *bus; | ||
110 | 109 | ||
111 | bridge = s->cb_dev; | 110 | if (bridge) |
112 | if (!bridge) | 111 | pci_remove_behind_bridge(bridge); |
113 | return; | ||
114 | |||
115 | bus = bridge->subordinate; | ||
116 | if (!bus) | ||
117 | return; | ||
118 | |||
119 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) | ||
120 | pci_stop_and_remove_bus_device(dev); | ||
121 | } | 112 | } |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 673c14ea11e..d9ea192c400 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/kthread.h> | 30 | #include <linux/kthread.h> |
31 | #include <linux/freezer.h> | 31 | #include <linux/freezer.h> |
32 | #include <asm/system.h> | ||
32 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
33 | 34 | ||
34 | #include <pcmcia/ss.h> | 35 | #include <pcmcia/ss.h> |
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index a31e69ea99f..01757f18a20 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | /* This is a fairly generic PCMCIA socket driver suitable for the | 8 | /* This is a fairly generic PCMCIA socket driver suitable for the |
9 | * following Alchemy Development boards: | 9 | * following Alchemy Development boards: |
10 | * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200, Db1300 | 10 | * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200. |
11 | * | 11 | * |
12 | * The Db1000 is used as a reference: Per-socket card-, carddetect- and | 12 | * The Db1000 is used as a reference: Per-socket card-, carddetect- and |
13 | * statuschange IRQs connected to SoC GPIOs, control and status register | 13 | * statuschange IRQs connected to SoC GPIOs, control and status register |
@@ -18,14 +18,12 @@ | |||
18 | * - Pb1100/Pb1500: single socket only; voltage key bits VS are | 18 | * - Pb1100/Pb1500: single socket only; voltage key bits VS are |
19 | * at STATUS[5:4] (instead of STATUS[1:0]). | 19 | * at STATUS[5:4] (instead of STATUS[1:0]). |
20 | * - Au1200-based: additional card-eject irqs, irqs not gpios! | 20 | * - Au1200-based: additional card-eject irqs, irqs not gpios! |
21 | * - Db1300: Db1200-like, no pwr ctrl, single socket (#1). | ||
22 | */ | 21 | */ |
23 | 22 | ||
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
26 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
27 | #include <linux/pm.h> | 26 | #include <linux/pm.h> |
28 | #include <linux/module.h> | ||
29 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
30 | #include <linux/resource.h> | 28 | #include <linux/resource.h> |
31 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
@@ -60,17 +58,11 @@ struct db1x_pcmcia_sock { | |||
60 | #define BOARD_TYPE_DEFAULT 0 /* most boards */ | 58 | #define BOARD_TYPE_DEFAULT 0 /* most boards */ |
61 | #define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */ | 59 | #define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */ |
62 | #define BOARD_TYPE_PB1100 2 /* VS bits slightly different */ | 60 | #define BOARD_TYPE_PB1100 2 /* VS bits slightly different */ |
63 | #define BOARD_TYPE_DB1300 3 /* no power control */ | ||
64 | int board_type; | 61 | int board_type; |
65 | }; | 62 | }; |
66 | 63 | ||
67 | #define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket) | 64 | #define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket) |
68 | 65 | ||
69 | static int db1300_card_inserted(struct db1x_pcmcia_sock *sock) | ||
70 | { | ||
71 | return bcsr_read(BCSR_SIGSTAT) & (1 << 8); | ||
72 | } | ||
73 | |||
74 | /* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */ | 66 | /* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */ |
75 | static int db1200_card_inserted(struct db1x_pcmcia_sock *sock) | 67 | static int db1200_card_inserted(struct db1x_pcmcia_sock *sock) |
76 | { | 68 | { |
@@ -91,8 +83,6 @@ static int db1x_card_inserted(struct db1x_pcmcia_sock *sock) | |||
91 | switch (sock->board_type) { | 83 | switch (sock->board_type) { |
92 | case BOARD_TYPE_DB1200: | 84 | case BOARD_TYPE_DB1200: |
93 | return db1200_card_inserted(sock); | 85 | return db1200_card_inserted(sock); |
94 | case BOARD_TYPE_DB1300: | ||
95 | return db1300_card_inserted(sock); | ||
96 | default: | 86 | default: |
97 | return db1000_card_inserted(sock); | 87 | return db1000_card_inserted(sock); |
98 | } | 88 | } |
@@ -169,22 +159,21 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) | |||
169 | * ejection handler have been registered and the currently | 159 | * ejection handler have been registered and the currently |
170 | * active one disabled. | 160 | * active one disabled. |
171 | */ | 161 | */ |
172 | if ((sock->board_type == BOARD_TYPE_DB1200) || | 162 | if (sock->board_type == BOARD_TYPE_DB1200) { |
173 | (sock->board_type == BOARD_TYPE_DB1300)) { | ||
174 | ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, | 163 | ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, |
175 | 0, "pcmcia_insert", sock); | 164 | IRQF_DISABLED, "pcmcia_insert", sock); |
176 | if (ret) | 165 | if (ret) |
177 | goto out1; | 166 | goto out1; |
178 | 167 | ||
179 | ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, | 168 | ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, |
180 | 0, "pcmcia_eject", sock); | 169 | IRQF_DISABLED, "pcmcia_eject", sock); |
181 | if (ret) { | 170 | if (ret) { |
182 | free_irq(sock->insert_irq, sock); | 171 | free_irq(sock->insert_irq, sock); |
183 | goto out1; | 172 | goto out1; |
184 | } | 173 | } |
185 | 174 | ||
186 | /* enable the currently silent one */ | 175 | /* enable the currently silent one */ |
187 | if (db1x_card_inserted(sock)) | 176 | if (db1200_card_inserted(sock)) |
188 | enable_irq(sock->eject_irq); | 177 | enable_irq(sock->eject_irq); |
189 | else | 178 | else |
190 | enable_irq(sock->insert_irq); | 179 | enable_irq(sock->insert_irq); |
@@ -280,8 +269,7 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt, | |||
280 | } | 269 | } |
281 | 270 | ||
282 | /* create new voltage code */ | 271 | /* create new voltage code */ |
283 | if (sock->board_type != BOARD_TYPE_DB1300) | 272 | cr_set |= ((v << 2) | p) << (sock->nr * 8); |
284 | cr_set |= ((v << 2) | p) << (sock->nr * 8); | ||
285 | 273 | ||
286 | changed = state->flags ^ sock->old_flags; | 274 | changed = state->flags ^ sock->old_flags; |
287 | 275 | ||
@@ -354,10 +342,6 @@ static int db1x_pcmcia_get_status(struct pcmcia_socket *skt, | |||
354 | /* if Vcc is not zero, we have applied power to a card */ | 342 | /* if Vcc is not zero, we have applied power to a card */ |
355 | status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0; | 343 | status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0; |
356 | 344 | ||
357 | /* DB1300: power always on, but don't tell when no card present */ | ||
358 | if ((sock->board_type == BOARD_TYPE_DB1300) && (status & SS_DETECT)) | ||
359 | status = SS_POWERON | SS_3VCARD | SS_DETECT; | ||
360 | |||
361 | /* reset de-asserted? then we're ready */ | 345 | /* reset de-asserted? then we're ready */ |
362 | status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET; | 346 | status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET; |
363 | 347 | ||
@@ -409,7 +393,7 @@ static struct pccard_operations db1x_pcmcia_operations = { | |||
409 | .set_mem_map = au1x00_pcmcia_set_mem_map, | 393 | .set_mem_map = au1x00_pcmcia_set_mem_map, |
410 | }; | 394 | }; |
411 | 395 | ||
412 | static int db1x_pcmcia_socket_probe(struct platform_device *pdev) | 396 | static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev) |
413 | { | 397 | { |
414 | struct db1x_pcmcia_sock *sock; | 398 | struct db1x_pcmcia_sock *sock; |
415 | struct resource *r; | 399 | struct resource *r; |
@@ -434,9 +418,6 @@ static int db1x_pcmcia_socket_probe(struct platform_device *pdev) | |||
434 | case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200: | 418 | case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200: |
435 | sock->board_type = BOARD_TYPE_DB1200; | 419 | sock->board_type = BOARD_TYPE_DB1200; |
436 | break; | 420 | break; |
437 | case BCSR_WHOAMI_DB1300: | ||
438 | sock->board_type = BOARD_TYPE_DB1300; | ||
439 | break; | ||
440 | default: | 421 | default: |
441 | printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid); | 422 | printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid); |
442 | ret = -ENODEV; | 423 | ret = -ENODEV; |
@@ -559,7 +540,7 @@ out0: | |||
559 | return ret; | 540 | return ret; |
560 | } | 541 | } |
561 | 542 | ||
562 | static int db1x_pcmcia_socket_remove(struct platform_device *pdev) | 543 | static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev) |
563 | { | 544 | { |
564 | struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev); | 545 | struct db1x_pcmcia_sock *sock = platform_get_drvdata(pdev); |
565 | 546 | ||
@@ -577,10 +558,21 @@ static struct platform_driver db1x_pcmcia_socket_driver = { | |||
577 | .owner = THIS_MODULE, | 558 | .owner = THIS_MODULE, |
578 | }, | 559 | }, |
579 | .probe = db1x_pcmcia_socket_probe, | 560 | .probe = db1x_pcmcia_socket_probe, |
580 | .remove = db1x_pcmcia_socket_remove, | 561 | .remove = __devexit_p(db1x_pcmcia_socket_remove), |
581 | }; | 562 | }; |
582 | 563 | ||
583 | module_platform_driver(db1x_pcmcia_socket_driver); | 564 | int __init db1x_pcmcia_socket_load(void) |
565 | { | ||
566 | return platform_driver_register(&db1x_pcmcia_socket_driver); | ||
567 | } | ||
568 | |||
569 | void __exit db1x_pcmcia_socket_unload(void) | ||
570 | { | ||
571 | platform_driver_unregister(&db1x_pcmcia_socket_driver); | ||
572 | } | ||
573 | |||
574 | module_init(db1x_pcmcia_socket_load); | ||
575 | module_exit(db1x_pcmcia_socket_unload); | ||
584 | 576 | ||
585 | MODULE_LICENSE("GPL"); | 577 | MODULE_LICENSE("GPL"); |
586 | MODULE_DESCRIPTION("PCMCIA Socket Services for Alchemy Db/Pb1x00 boards"); | 578 | MODULE_DESCRIPTION("PCMCIA Socket Services for Alchemy Db/Pb1x00 boards"); |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 2deacbb2ffd..749c2a16012 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -127,7 +127,10 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count) | |||
127 | list_add_tail(&dynid->node, &pdrv->dynids.list); | 127 | list_add_tail(&dynid->node, &pdrv->dynids.list); |
128 | mutex_unlock(&pdrv->dynids.lock); | 128 | mutex_unlock(&pdrv->dynids.lock); |
129 | 129 | ||
130 | retval = driver_attach(&pdrv->drv); | 130 | if (get_driver(&pdrv->drv)) { |
131 | retval = driver_attach(&pdrv->drv); | ||
132 | put_driver(&pdrv->drv); | ||
133 | } | ||
131 | 134 | ||
132 | if (retval) | 135 | if (retval) |
133 | return retval; | 136 | return retval; |
@@ -157,11 +160,6 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv) | |||
157 | return error; | 160 | return error; |
158 | } | 161 | } |
159 | 162 | ||
160 | static void | ||
161 | pcmcia_remove_newid_file(struct pcmcia_driver *drv) | ||
162 | { | ||
163 | driver_remove_file(&drv->drv, &driver_attr_new_id); | ||
164 | } | ||
165 | 163 | ||
166 | /** | 164 | /** |
167 | * pcmcia_register_driver - register a PCMCIA driver with the bus core | 165 | * pcmcia_register_driver - register a PCMCIA driver with the bus core |
@@ -206,7 +204,6 @@ EXPORT_SYMBOL(pcmcia_register_driver); | |||
206 | void pcmcia_unregister_driver(struct pcmcia_driver *driver) | 204 | void pcmcia_unregister_driver(struct pcmcia_driver *driver) |
207 | { | 205 | { |
208 | pr_debug("unregistering driver %s\n", driver->name); | 206 | pr_debug("unregistering driver %s\n", driver->name); |
209 | pcmcia_remove_newid_file(driver); | ||
210 | driver_unregister(&driver->drv); | 207 | driver_unregister(&driver->drv); |
211 | pcmcia_free_dynids(driver); | 208 | pcmcia_free_dynids(driver); |
212 | } | 209 | } |
@@ -920,6 +917,8 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) | |||
920 | return 0; | 917 | return 0; |
921 | } | 918 | } |
922 | 919 | ||
920 | #ifdef CONFIG_HOTPLUG | ||
921 | |||
923 | static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | 922 | static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
924 | { | 923 | { |
925 | struct pcmcia_device *p_dev; | 924 | struct pcmcia_device *p_dev; |
@@ -960,6 +959,15 @@ static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
960 | return 0; | 959 | return 0; |
961 | } | 960 | } |
962 | 961 | ||
962 | #else | ||
963 | |||
964 | static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
965 | { | ||
966 | return -ENODEV; | ||
967 | } | ||
968 | |||
969 | #endif | ||
970 | |||
963 | /************************ runtime PM support ***************************/ | 971 | /************************ runtime PM support ***************************/ |
964 | 972 | ||
965 | static int pcmcia_dev_suspend(struct device *dev, pm_message_t state); | 973 | static int pcmcia_dev_suspend(struct device *dev, pm_message_t state); |
@@ -1261,8 +1269,10 @@ static int pcmcia_bus_add(struct pcmcia_socket *skt) | |||
1261 | 1269 | ||
1262 | static int pcmcia_bus_early_resume(struct pcmcia_socket *skt) | 1270 | static int pcmcia_bus_early_resume(struct pcmcia_socket *skt) |
1263 | { | 1271 | { |
1264 | if (!verify_cis_cache(skt)) | 1272 | if (!verify_cis_cache(skt)) { |
1273 | pcmcia_put_socket(skt); | ||
1265 | return 0; | 1274 | return 0; |
1275 | } | ||
1266 | 1276 | ||
1267 | dev_dbg(&skt->dev, "cis mismatch - different card\n"); | 1277 | dev_dbg(&skt->dev, "cis mismatch - different card\n"); |
1268 | 1278 | ||
@@ -1318,7 +1328,7 @@ static struct pcmcia_callback pcmcia_bus_callback = { | |||
1318 | .resume = pcmcia_bus_resume, | 1328 | .resume = pcmcia_bus_resume, |
1319 | }; | 1329 | }; |
1320 | 1330 | ||
1321 | static int pcmcia_bus_add_socket(struct device *dev, | 1331 | static int __devinit pcmcia_bus_add_socket(struct device *dev, |
1322 | struct class_interface *class_intf) | 1332 | struct class_interface *class_intf) |
1323 | { | 1333 | { |
1324 | struct pcmcia_socket *socket = dev_get_drvdata(dev); | 1334 | struct pcmcia_socket *socket = dev_get_drvdata(dev); |
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index a007321ad31..06ad3e5e7d3 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c | |||
@@ -181,7 +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 electra_cf_probe(struct platform_device *ofdev) | 184 | static int __devinit electra_cf_probe(struct platform_device *ofdev) |
185 | { | 185 | { |
186 | struct device *device = &ofdev->dev; | 186 | struct device *device = &ofdev->dev; |
187 | struct device_node *np = ofdev->dev.of_node; | 187 | struct device_node *np = ofdev->dev.of_node; |
@@ -324,7 +324,7 @@ fail1: | |||
324 | 324 | ||
325 | } | 325 | } |
326 | 326 | ||
327 | static int electra_cf_remove(struct platform_device *ofdev) | 327 | static int __devexit electra_cf_remove(struct platform_device *ofdev) |
328 | { | 328 | { |
329 | struct device *device = &ofdev->dev; | 329 | struct device *device = &ofdev->dev; |
330 | struct electra_cf_socket *cf; | 330 | struct electra_cf_socket *cf; |
@@ -365,7 +365,17 @@ static struct platform_driver electra_cf_driver = { | |||
365 | .remove = electra_cf_remove, | 365 | .remove = electra_cf_remove, |
366 | }; | 366 | }; |
367 | 367 | ||
368 | module_platform_driver(electra_cf_driver); | 368 | static int __init electra_cf_init(void) |
369 | { | ||
370 | return platform_driver_register(&electra_cf_driver); | ||
371 | } | ||
372 | module_init(electra_cf_init); | ||
373 | |||
374 | static void __exit electra_cf_exit(void) | ||
375 | { | ||
376 | platform_driver_unregister(&electra_cf_driver); | ||
377 | } | ||
378 | module_exit(electra_cf_exit); | ||
369 | 379 | ||
370 | MODULE_LICENSE("GPL"); | 380 | MODULE_LICENSE("GPL"); |
371 | MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); | 381 | MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); |
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 3578e1ca97a..3e447d0387b 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <pcmcia/ss.h> | 18 | #include <pcmcia/ss.h> |
19 | 19 | ||
20 | #include <asm/system.h> | ||
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | 22 | ||
22 | #include "i82092aa.h" | 23 | #include "i82092aa.h" |
@@ -25,9 +26,14 @@ | |||
25 | MODULE_LICENSE("GPL"); | 26 | MODULE_LICENSE("GPL"); |
26 | 27 | ||
27 | /* PCI core routines */ | 28 | /* PCI core routines */ |
28 | static DEFINE_PCI_DEVICE_TABLE(i82092aa_pci_ids) = { | 29 | static struct pci_device_id i82092aa_pci_ids[] = { |
29 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82092AA_0) }, | 30 | { |
30 | { } | 31 | .vendor = PCI_VENDOR_ID_INTEL, |
32 | .device = PCI_DEVICE_ID_INTEL_82092AA_0, | ||
33 | .subvendor = PCI_ANY_ID, | ||
34 | .subdevice = PCI_ANY_ID, | ||
35 | }, | ||
36 | {} | ||
31 | }; | 37 | }; |
32 | MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); | 38 | MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); |
33 | 39 | ||
@@ -35,7 +41,7 @@ static struct pci_driver i82092aa_pci_driver = { | |||
35 | .name = "i82092aa", | 41 | .name = "i82092aa", |
36 | .id_table = i82092aa_pci_ids, | 42 | .id_table = i82092aa_pci_ids, |
37 | .probe = i82092aa_pci_probe, | 43 | .probe = i82092aa_pci_probe, |
38 | .remove = i82092aa_pci_remove, | 44 | .remove = __devexit_p(i82092aa_pci_remove), |
39 | }; | 45 | }; |
40 | 46 | ||
41 | 47 | ||
@@ -67,7 +73,7 @@ static struct socket_info sockets[MAX_SOCKETS]; | |||
67 | static int socket_count; /* shortcut */ | 73 | static int socket_count; /* shortcut */ |
68 | 74 | ||
69 | 75 | ||
70 | static int i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | 76 | static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
71 | { | 77 | { |
72 | unsigned char configbyte; | 78 | unsigned char configbyte; |
73 | int i, ret; | 79 | int i, ret; |
@@ -162,7 +168,7 @@ err_out_disable: | |||
162 | return ret; | 168 | return ret; |
163 | } | 169 | } |
164 | 170 | ||
165 | static void i82092aa_pci_remove(struct pci_dev *dev) | 171 | static void __devexit i82092aa_pci_remove(struct pci_dev *dev) |
166 | { | 172 | { |
167 | struct pcmcia_socket *socket = pci_get_drvdata(dev); | 173 | struct pcmcia_socket *socket = pci_get_drvdata(dev); |
168 | 174 | ||
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index e6f3d17dd2b..72a033a2acd 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/bitops.h> | 48 | #include <linux/bitops.h> |
49 | #include <asm/irq.h> | 49 | #include <asm/irq.h> |
50 | #include <asm/io.h> | 50 | #include <asm/io.h> |
51 | #include <asm/system.h> | ||
51 | 52 | ||
52 | #include <pcmcia/ss.h> | 53 | #include <pcmcia/ss.h> |
53 | 54 | ||
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index a26f38c6402..2adb0106a03 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/system.h> | ||
27 | 28 | ||
28 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
29 | 30 | ||
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 296514155cd..1511ff71c87 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/system.h> | ||
27 | #include <asm/addrspace.h> | 28 | #include <asm/addrspace.h> |
28 | 29 | ||
29 | #include <pcmcia/ss.h> | 30 | #include <pcmcia/ss.h> |
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index a3a851e4932..271a590a5f3 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/of_platform.h> | 52 | #include <linux/of_platform.h> |
53 | 53 | ||
54 | #include <asm/io.h> | 54 | #include <asm/io.h> |
55 | #include <asm/system.h> | ||
55 | #include <asm/time.h> | 56 | #include <asm/time.h> |
56 | #include <asm/mpc8xx.h> | 57 | #include <asm/mpc8xx.h> |
57 | #include <asm/8xx_immap.h> | 58 | #include <asm/8xx_immap.h> |
@@ -1303,4 +1304,15 @@ static struct platform_driver m8xx_pcmcia_driver = { | |||
1303 | .remove = m8xx_remove, | 1304 | .remove = m8xx_remove, |
1304 | }; | 1305 | }; |
1305 | 1306 | ||
1306 | module_platform_driver(m8xx_pcmcia_driver); | 1307 | static int __init m8xx_init(void) |
1308 | { | ||
1309 | return platform_driver_register(&m8xx_pcmcia_driver); | ||
1310 | } | ||
1311 | |||
1312 | static void __exit m8xx_exit(void) | ||
1313 | { | ||
1314 | platform_driver_unregister(&m8xx_pcmcia_driver); | ||
1315 | } | ||
1316 | |||
1317 | module_init(m8xx_init); | ||
1318 | module_exit(m8xx_exit); | ||
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 25c4b1993b3..0ad06a3bd56 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c | |||
@@ -24,8 +24,8 @@ | |||
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/sizes.h> | 25 | #include <asm/sizes.h> |
26 | 26 | ||
27 | #include <mach/mux.h> | 27 | #include <plat/mux.h> |
28 | #include <mach/tc.h> | 28 | #include <plat/tc.h> |
29 | 29 | ||
30 | 30 | ||
31 | /* NOTE: don't expect this to support many I/O cards. The 16xx chips have | 31 | /* NOTE: don't expect this to support many I/O cards. The 16xx chips have |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index b29d97e170a..96c72e90b79 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <pcmcia/ss.h> | 20 | #include <pcmcia/ss.h> |
21 | 21 | ||
22 | #include <asm/system.h> | ||
22 | 23 | ||
23 | #include "pd6729.h" | 24 | #include "pd6729.h" |
24 | #include "i82365.h" | 25 | #include "i82365.h" |
@@ -589,7 +590,7 @@ static int pd6729_check_irq(int irq) | |||
589 | return 0; | 590 | return 0; |
590 | } | 591 | } |
591 | 592 | ||
592 | static u_int pd6729_isa_scan(void) | 593 | static u_int __devinit pd6729_isa_scan(void) |
593 | { | 594 | { |
594 | u_int mask0, mask = 0; | 595 | u_int mask0, mask = 0; |
595 | int i; | 596 | int i; |
@@ -620,7 +621,7 @@ static u_int pd6729_isa_scan(void) | |||
620 | return mask; | 621 | return mask; |
621 | } | 622 | } |
622 | 623 | ||
623 | static int pd6729_pci_probe(struct pci_dev *dev, | 624 | static int __devinit pd6729_pci_probe(struct pci_dev *dev, |
624 | const struct pci_device_id *id) | 625 | const struct pci_device_id *id) |
625 | { | 626 | { |
626 | int i, j, ret; | 627 | int i, j, ret; |
@@ -739,7 +740,7 @@ err_out_free_mem: | |||
739 | return ret; | 740 | return ret; |
740 | } | 741 | } |
741 | 742 | ||
742 | static void pd6729_pci_remove(struct pci_dev *dev) | 743 | static void __devexit pd6729_pci_remove(struct pci_dev *dev) |
743 | { | 744 | { |
744 | int i; | 745 | int i; |
745 | struct pd6729_socket *socket = pci_get_drvdata(dev); | 746 | struct pd6729_socket *socket = pci_get_drvdata(dev); |
@@ -762,8 +763,13 @@ static void pd6729_pci_remove(struct pci_dev *dev) | |||
762 | kfree(socket); | 763 | kfree(socket); |
763 | } | 764 | } |
764 | 765 | ||
765 | static DEFINE_PCI_DEVICE_TABLE(pd6729_pci_ids) = { | 766 | static struct pci_device_id pd6729_pci_ids[] = { |
766 | { PCI_DEVICE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729) }, | 767 | { |
768 | .vendor = PCI_VENDOR_ID_CIRRUS, | ||
769 | .device = PCI_DEVICE_ID_CIRRUS_6729, | ||
770 | .subvendor = PCI_ANY_ID, | ||
771 | .subdevice = PCI_ANY_ID, | ||
772 | }, | ||
767 | { } | 773 | { } |
768 | }; | 774 | }; |
769 | MODULE_DEVICE_TABLE(pci, pd6729_pci_ids); | 775 | MODULE_DEVICE_TABLE(pci, pd6729_pci_ids); |
@@ -772,7 +778,7 @@ static struct pci_driver pd6729_pci_driver = { | |||
772 | .name = "pd6729", | 778 | .name = "pd6729", |
773 | .id_table = pd6729_pci_ids, | 779 | .id_table = pd6729_pci_ids, |
774 | .probe = pd6729_pci_probe, | 780 | .probe = pd6729_pci_probe, |
775 | .remove = pd6729_pci_remove, | 781 | .remove = __devexit_p(pd6729_pci_remove), |
776 | }; | 782 | }; |
777 | 783 | ||
778 | static int pd6729_module_init(void) | 784 | static int pd6729_module_init(void) |
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c index 2ef576c5b69..f56d7de7c75 100644 --- a/drivers/pcmcia/pxa2xx_balloon3.c +++ b/drivers/pcmcia/pxa2xx_balloon3.c | |||
@@ -29,6 +29,15 @@ | |||
29 | 29 | ||
30 | #include "soc_common.h" | 30 | #include "soc_common.h" |
31 | 31 | ||
32 | /* | ||
33 | * These are a list of interrupt sources that provokes a polled | ||
34 | * check of status | ||
35 | */ | ||
36 | static struct pcmcia_irqs irqs[] = { | ||
37 | { 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" }, | ||
38 | { 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" }, | ||
39 | }; | ||
40 | |||
32 | static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 41 | static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
33 | { | 42 | { |
34 | uint16_t ver; | 43 | uint16_t ver; |
@@ -40,12 +49,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
40 | ver); | 49 | ver); |
41 | 50 | ||
42 | skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ; | 51 | skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ; |
43 | skt->stat[SOC_STAT_CD].gpio = BALLOON3_GPIO_S0_CD; | 52 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
44 | skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; | 53 | } |
45 | skt->stat[SOC_STAT_BVD1].irq = BALLOON3_BP_NSTSCHG_IRQ; | ||
46 | skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG"; | ||
47 | 54 | ||
48 | return 0; | 55 | static void balloon3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
56 | { | ||
57 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
49 | } | 58 | } |
50 | 59 | ||
51 | static unsigned long balloon3_pcmcia_status[2] = { | 60 | static unsigned long balloon3_pcmcia_status[2] = { |
@@ -76,17 +85,19 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
76 | disable_irq(BALLOON3_BP_NSTSCHG_IRQ); | 85 | disable_irq(BALLOON3_BP_NSTSCHG_IRQ); |
77 | } | 86 | } |
78 | 87 | ||
88 | state->detect = !gpio_get_value(BALLOON3_GPIO_S0_CD); | ||
79 | state->ready = !!(status & BALLOON3_CF_nIRQ); | 89 | state->ready = !!(status & BALLOON3_CF_nIRQ); |
80 | state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1); | 90 | state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1); |
81 | state->bvd2 = 0; /* not available */ | 91 | state->bvd2 = 0; /* not available */ |
82 | state->vs_3v = 1; /* Always true its a CF card */ | 92 | state->vs_3v = 1; /* Always true its a CF card */ |
83 | state->vs_Xv = 0; /* not available */ | 93 | state->vs_Xv = 0; /* not available */ |
94 | state->wrprot = 0; /* not available */ | ||
84 | } | 95 | } |
85 | 96 | ||
86 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 97 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
87 | const socket_state_t *state) | 98 | const socket_state_t *state) |
88 | { | 99 | { |
89 | __raw_writew(BALLOON3_CF_RESET, BALLOON3_CF_CONTROL_REG + | 100 | __raw_writew(BALLOON3_CF_RESET, BALLOON3_CF_CONTROL_REG | |
90 | ((state->flags & SS_RESET) ? | 101 | ((state->flags & SS_RESET) ? |
91 | BALLOON3_FPGA_SETnCLR : 0)); | 102 | BALLOON3_FPGA_SETnCLR : 0)); |
92 | return 0; | 103 | return 0; |
@@ -95,6 +106,7 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
95 | static struct pcmcia_low_level balloon3_pcmcia_ops = { | 106 | static struct pcmcia_low_level balloon3_pcmcia_ops = { |
96 | .owner = THIS_MODULE, | 107 | .owner = THIS_MODULE, |
97 | .hw_init = balloon3_pcmcia_hw_init, | 108 | .hw_init = balloon3_pcmcia_hw_init, |
109 | .hw_shutdown = balloon3_pcmcia_hw_shutdown, | ||
98 | .socket_state = balloon3_pcmcia_socket_state, | 110 | .socket_state = balloon3_pcmcia_socket_state, |
99 | .configure_socket = balloon3_pcmcia_configure_socket, | 111 | .configure_socket = balloon3_pcmcia_configure_socket, |
100 | .first = 0, | 112 | .first = 0, |
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index cfec9dd18ff..2c540542b5a 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <mach/smemc.h> | 29 | #include <mach/smemc.h> |
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <asm/system.h> | ||
32 | #include <mach/pxa2xx-regs.h> | 33 | #include <mach/pxa2xx-regs.h> |
33 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
34 | 35 | ||
@@ -230,7 +231,6 @@ void pxa2xx_configure_sockets(struct device *dev) | |||
230 | 231 | ||
231 | __raw_writel(mecr, MECR); | 232 | __raw_writel(mecr, MECR); |
232 | } | 233 | } |
233 | EXPORT_SYMBOL(pxa2xx_configure_sockets); | ||
234 | 234 | ||
235 | static const char *skt_names[] = { | 235 | static const char *skt_names[] = { |
236 | "PCMCIA socket 0", | 236 | "PCMCIA socket 0", |
@@ -297,7 +297,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
297 | } | 297 | } |
298 | 298 | ||
299 | clk = clk_get(&dev->dev, NULL); | 299 | clk = clk_get(&dev->dev, NULL); |
300 | if (IS_ERR(clk)) | 300 | if (!clk) |
301 | return -ENODEV; | 301 | return -ENODEV; |
302 | 302 | ||
303 | pxa2xx_drv_pcmcia_ops(ops); | 303 | pxa2xx_drv_pcmcia_ops(ops); |
@@ -317,22 +317,31 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
317 | 317 | ||
318 | skt->nr = ops->first + i; | 318 | skt->nr = ops->first + i; |
319 | skt->clk = clk; | 319 | skt->clk = clk; |
320 | soc_pcmcia_init_one(skt, ops, &dev->dev); | 320 | skt->ops = ops; |
321 | skt->socket.owner = ops->owner; | ||
322 | skt->socket.dev.parent = &dev->dev; | ||
323 | skt->socket.pci_irq = NO_IRQ; | ||
321 | 324 | ||
322 | ret = pxa2xx_drv_pcmcia_add_one(skt); | 325 | ret = pxa2xx_drv_pcmcia_add_one(skt); |
323 | if (ret) | 326 | if (ret) |
324 | goto err1; | 327 | goto err1; |
325 | } | 328 | } |
326 | 329 | ||
327 | pxa2xx_configure_sockets(&dev->dev); | 330 | if (ret) { |
328 | dev_set_drvdata(&dev->dev, sinfo); | 331 | while (--i >= 0) |
332 | soc_pcmcia_remove_one(&sinfo->skt[i]); | ||
333 | kfree(sinfo); | ||
334 | clk_put(clk); | ||
335 | } else { | ||
336 | pxa2xx_configure_sockets(&dev->dev); | ||
337 | dev_set_drvdata(&dev->dev, sinfo); | ||
338 | } | ||
329 | 339 | ||
330 | return 0; | 340 | return 0; |
331 | 341 | ||
332 | err1: | 342 | err1: |
333 | while (--i >= 0) | 343 | while (--i >= 0) |
334 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 344 | soc_pcmcia_remove_one(&sinfo->skt[i]); |
335 | clk_put(clk); | ||
336 | kfree(sinfo); | 345 | kfree(sinfo); |
337 | err0: | 346 | err0: |
338 | return ret; | 347 | return ret; |
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c index da40908b29d..63f4d5211ed 100644 --- a/drivers/pcmcia/pxa2xx_cm_x255.c +++ b/drivers/pcmcia/pxa2xx_cm_x255.c | |||
@@ -14,7 +14,8 @@ | |||
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/export.h> | 17 | |
18 | #include <asm/mach-types.h> | ||
18 | 19 | ||
19 | #include "soc_common.h" | 20 | #include "soc_common.h" |
20 | 21 | ||
@@ -25,6 +26,17 @@ | |||
25 | #define GPIO_PCMCIA_S1_RDYINT (8) | 26 | #define GPIO_PCMCIA_S1_RDYINT (8) |
26 | #define GPIO_PCMCIA_RESET (9) | 27 | #define GPIO_PCMCIA_RESET (9) |
27 | 28 | ||
29 | #define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID) | ||
30 | #define PCMCIA_S1_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S1_CD_VALID) | ||
31 | #define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT) | ||
32 | #define PCMCIA_S1_RDYINT IRQ_GPIO(GPIO_PCMCIA_S1_RDYINT) | ||
33 | |||
34 | |||
35 | static struct pcmcia_irqs irqs[] = { | ||
36 | { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" }, | ||
37 | { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" }, | ||
38 | }; | ||
39 | |||
28 | static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 40 | static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
29 | { | 41 | { |
30 | int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); | 42 | int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); |
@@ -32,23 +44,17 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
32 | return ret; | 44 | return ret; |
33 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); | 45 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); |
34 | 46 | ||
35 | if (skt->nr == 0) { | 47 | skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; |
36 | skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID; | 48 | ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
37 | skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; | 49 | if (!ret) |
38 | skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT; | 50 | gpio_free(GPIO_PCMCIA_RESET); |
39 | skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; | ||
40 | } else { | ||
41 | skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID; | ||
42 | skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD"; | ||
43 | skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT; | ||
44 | skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY"; | ||
45 | } | ||
46 | 51 | ||
47 | return 0; | 52 | return ret; |
48 | } | 53 | } |
49 | 54 | ||
50 | static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) | 55 | static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) |
51 | { | 56 | { |
57 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
52 | gpio_free(GPIO_PCMCIA_RESET); | 58 | gpio_free(GPIO_PCMCIA_RESET); |
53 | } | 59 | } |
54 | 60 | ||
@@ -56,8 +62,16 @@ static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) | |||
56 | static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 62 | static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
57 | struct pcmcia_state *state) | 63 | struct pcmcia_state *state) |
58 | { | 64 | { |
65 | int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID; | ||
66 | int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT; | ||
67 | |||
68 | state->detect = !gpio_get_value(cd); | ||
69 | state->ready = !!gpio_get_value(rdy); | ||
70 | state->bvd1 = 1; | ||
71 | state->bvd2 = 1; | ||
59 | state->vs_3v = 0; | 72 | state->vs_3v = 0; |
60 | state->vs_Xv = 0; | 73 | state->vs_Xv = 0; |
74 | state->wrprot = 0; /* not available */ | ||
61 | } | 75 | } |
62 | 76 | ||
63 | 77 | ||
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index f59223f2307..6ee42b4c3e6 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c | |||
@@ -14,7 +14,8 @@ | |||
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/export.h> | 17 | |
18 | #include <asm/mach-types.h> | ||
18 | 19 | ||
19 | #include "soc_common.h" | 20 | #include "soc_common.h" |
20 | 21 | ||
@@ -22,6 +23,14 @@ | |||
22 | #define GPIO_PCMCIA_S0_RDYINT (82) | 23 | #define GPIO_PCMCIA_S0_RDYINT (82) |
23 | #define GPIO_PCMCIA_RESET (53) | 24 | #define GPIO_PCMCIA_RESET (53) |
24 | 25 | ||
26 | #define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID) | ||
27 | #define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT) | ||
28 | |||
29 | |||
30 | static struct pcmcia_irqs irqs[] = { | ||
31 | { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" }, | ||
32 | }; | ||
33 | |||
25 | static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 34 | static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
26 | { | 35 | { |
27 | int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); | 36 | int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); |
@@ -29,16 +38,17 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
29 | return ret; | 38 | return ret; |
30 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); | 39 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); |
31 | 40 | ||
32 | skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID; | 41 | skt->socket.pci_irq = PCMCIA_S0_RDYINT; |
33 | skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; | 42 | ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
34 | skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT; | 43 | if (!ret) |
35 | skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; | 44 | gpio_free(GPIO_PCMCIA_RESET); |
36 | 45 | ||
37 | return ret; | 46 | return ret; |
38 | } | 47 | } |
39 | 48 | ||
40 | static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) | 49 | static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) |
41 | { | 50 | { |
51 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
42 | gpio_free(GPIO_PCMCIA_RESET); | 52 | gpio_free(GPIO_PCMCIA_RESET); |
43 | } | 53 | } |
44 | 54 | ||
@@ -46,8 +56,13 @@ static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) | |||
46 | static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 56 | static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
47 | struct pcmcia_state *state) | 57 | struct pcmcia_state *state) |
48 | { | 58 | { |
59 | state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0; | ||
60 | state->ready = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1; | ||
61 | state->bvd1 = 1; | ||
62 | state->bvd2 = 1; | ||
49 | state->vs_3v = 0; | 63 | state->vs_3v = 0; |
50 | state->vs_Xv = 0; | 64 | state->vs_Xv = 0; |
65 | state->wrprot = 0; /* not available */ | ||
51 | } | 66 | } |
52 | 67 | ||
53 | 68 | ||
diff --git a/drivers/pcmcia/pxa2xx_cm_x2xx.c b/drivers/pcmcia/pxa2xx_cm_x2xx.c index 6e7dcfd22ed..4f09506ad8d 100644 --- a/drivers/pcmcia/pxa2xx_cm_x2xx.c +++ b/drivers/pcmcia/pxa2xx_cm_x2xx.c | |||
@@ -12,8 +12,9 @@ | |||
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | 14 | ||
15 | #include <asm/system.h> | ||
15 | #include <asm/mach-types.h> | 16 | #include <asm/mach-types.h> |
16 | #include <mach/hardware.h> | 17 | #include <mach/system.h> |
17 | 18 | ||
18 | int cmx255_pcmcia_init(void); | 19 | int cmx255_pcmcia_init(void); |
19 | int cmx270_pcmcia_init(void); | 20 | int cmx270_pcmcia_init(void); |
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index 4dee7b2a803..c6dec572a05 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c | |||
@@ -53,6 +53,13 @@ static struct gpio colibri_pcmcia_gpios[] = { | |||
53 | { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | 53 | { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct pcmcia_irqs colibri_irqs[] = { | ||
57 | { | ||
58 | .sock = 0, | ||
59 | .str = "PCMCIA CD" | ||
60 | }, | ||
61 | }; | ||
62 | |||
56 | static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 63 | static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
57 | { | 64 | { |
58 | int ret; | 65 | int ret; |
@@ -62,10 +69,19 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
62 | if (ret) | 69 | if (ret) |
63 | goto err1; | 70 | goto err1; |
64 | 71 | ||
72 | colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); | ||
65 | skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); | 73 | skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); |
66 | skt->stat[SOC_STAT_CD].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); | ||
67 | skt->stat[SOC_STAT_CD].name = "PCMCIA CD"; | ||
68 | 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)); | ||
69 | err1: | 85 | err1: |
70 | return ret; | 86 | return ret; |
71 | } | 87 | } |
@@ -84,6 +100,7 @@ static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
84 | state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); | 100 | state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); |
85 | state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); | 101 | state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); |
86 | state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); | 102 | state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); |
103 | state->wrprot = 0; | ||
87 | state->vs_3v = 1; | 104 | state->vs_3v = 1; |
88 | state->vs_Xv = 0; | 105 | state->vs_Xv = 0; |
89 | } | 106 | } |
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c index 8751a323b44..8bfbd4dca13 100644 --- a/drivers/pcmcia/pxa2xx_e740.c +++ b/drivers/pcmcia/pxa2xx_e740.c | |||
@@ -23,27 +23,50 @@ | |||
23 | 23 | ||
24 | #include "soc_common.h" | 24 | #include "soc_common.h" |
25 | 25 | ||
26 | static struct pcmcia_irqs cd_irqs[] = { | ||
27 | { | ||
28 | .sock = 0, | ||
29 | .irq = IRQ_GPIO(GPIO_E740_PCMCIA_CD0), | ||
30 | .str = "CF card detect" | ||
31 | }, | ||
32 | { | ||
33 | .sock = 1, | ||
34 | .irq = IRQ_GPIO(GPIO_E740_PCMCIA_CD1), | ||
35 | .str = "Wifi switch" | ||
36 | }, | ||
37 | }; | ||
38 | |||
26 | static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 39 | static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
27 | { | 40 | { |
28 | if (skt->nr == 0) { | 41 | skt->socket.pci_irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) : |
29 | skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0; | 42 | IRQ_GPIO(GPIO_E740_PCMCIA_RDY1); |
30 | skt->stat[SOC_STAT_CD].name = "CF card detect"; | ||
31 | skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0; | ||
32 | skt->stat[SOC_STAT_RDY].name = "CF ready"; | ||
33 | } else { | ||
34 | skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1; | ||
35 | skt->stat[SOC_STAT_CD].name = "Wifi switch"; | ||
36 | skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1; | ||
37 | skt->stat[SOC_STAT_RDY].name = "Wifi ready"; | ||
38 | } | ||
39 | 43 | ||
40 | return 0; | 44 | return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); |
45 | } | ||
46 | |||
47 | /* | ||
48 | * Release all resources. | ||
49 | */ | ||
50 | static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
51 | { | ||
52 | soc_pcmcia_free_irqs(skt, &cd_irqs[skt->nr], 1); | ||
41 | } | 53 | } |
42 | 54 | ||
43 | static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 55 | static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
44 | struct pcmcia_state *state) | 56 | struct pcmcia_state *state) |
45 | { | 57 | { |
58 | if (skt->nr == 0) { | ||
59 | state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD0) ? 0 : 1; | ||
60 | state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY0) ? 1 : 0; | ||
61 | } else { | ||
62 | state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD1) ? 0 : 1; | ||
63 | state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY1) ? 1 : 0; | ||
64 | } | ||
65 | |||
46 | state->vs_3v = 1; | 66 | state->vs_3v = 1; |
67 | state->bvd1 = 1; | ||
68 | state->bvd2 = 1; | ||
69 | state->wrprot = 0; | ||
47 | state->vs_Xv = 0; | 70 | state->vs_Xv = 0; |
48 | } | 71 | } |
49 | 72 | ||
@@ -83,11 +106,32 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
83 | return 0; | 106 | return 0; |
84 | } | 107 | } |
85 | 108 | ||
109 | /* | ||
110 | * Enable card status IRQs on (re-)initialisation. This can | ||
111 | * be called at initialisation, power management event, or | ||
112 | * pcmcia event. | ||
113 | */ | ||
114 | static void e740_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
115 | { | ||
116 | soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs)); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Disable card status IRQs on suspend. | ||
121 | */ | ||
122 | static void e740_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
123 | { | ||
124 | soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs)); | ||
125 | } | ||
126 | |||
86 | static struct pcmcia_low_level e740_pcmcia_ops = { | 127 | static struct pcmcia_low_level e740_pcmcia_ops = { |
87 | .owner = THIS_MODULE, | 128 | .owner = THIS_MODULE, |
88 | .hw_init = e740_pcmcia_hw_init, | 129 | .hw_init = e740_pcmcia_hw_init, |
130 | .hw_shutdown = e740_pcmcia_hw_shutdown, | ||
89 | .socket_state = e740_pcmcia_socket_state, | 131 | .socket_state = e740_pcmcia_socket_state, |
90 | .configure_socket = e740_pcmcia_configure_socket, | 132 | .configure_socket = e740_pcmcia_configure_socket, |
133 | .socket_init = e740_pcmcia_socket_init, | ||
134 | .socket_suspend = e740_pcmcia_socket_suspend, | ||
91 | .nr = 2, | 135 | .nr = 2, |
92 | }; | 136 | }; |
93 | 137 | ||
diff --git a/drivers/pcmcia/pxa2xx_hx4700.c b/drivers/pcmcia/pxa2xx_hx4700.c deleted file mode 100644 index 7dfef3ee5b5..00000000000 --- a/drivers/pcmcia/pxa2xx_hx4700.c +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/err.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/irq.h> | ||
14 | |||
15 | #include <asm/mach-types.h> | ||
16 | #include <mach/hx4700.h> | ||
17 | |||
18 | #include "soc_common.h" | ||
19 | |||
20 | static struct gpio gpios[] = { | ||
21 | { GPIO114_HX4700_CF_RESET, GPIOF_OUT_INIT_LOW, "CF reset" }, | ||
22 | { EGPIO4_CF_3V3_ON, GPIOF_OUT_INIT_LOW, "CF 3.3V enable" }, | ||
23 | }; | ||
24 | |||
25 | static int hx4700_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
26 | { | ||
27 | int ret; | ||
28 | |||
29 | ret = gpio_request_array(gpios, ARRAY_SIZE(gpios)); | ||
30 | if (ret) | ||
31 | goto out; | ||
32 | |||
33 | /* | ||
34 | * IRQ type must be set before soc_pcmcia_hw_init() calls request_irq(). | ||
35 | * The asic3 default IRQ type is level trigger low level detect, exactly | ||
36 | * the the signal present on GPIOD4_CF_nCD when a CF card is inserted. | ||
37 | * If the IRQ type is not changed, the asic3 interrupt handler will loop | ||
38 | * repeatedly because it is unable to clear the level trigger interrupt. | ||
39 | */ | ||
40 | irq_set_irq_type(gpio_to_irq(GPIOD4_CF_nCD), IRQ_TYPE_EDGE_BOTH); | ||
41 | |||
42 | skt->stat[SOC_STAT_CD].gpio = GPIOD4_CF_nCD; | ||
43 | skt->stat[SOC_STAT_CD].name = "PCMCIA CD"; | ||
44 | skt->stat[SOC_STAT_RDY].gpio = GPIO60_HX4700_CF_RNB; | ||
45 | skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; | ||
46 | |||
47 | out: | ||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | static void hx4700_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
52 | { | ||
53 | gpio_free_array(gpios, ARRAY_SIZE(gpios)); | ||
54 | } | ||
55 | |||
56 | static void hx4700_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | ||
57 | struct pcmcia_state *state) | ||
58 | { | ||
59 | state->vs_3v = 1; | ||
60 | state->vs_Xv = 0; | ||
61 | } | ||
62 | |||
63 | static int hx4700_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | ||
64 | const socket_state_t *state) | ||
65 | { | ||
66 | switch (state->Vcc) { | ||
67 | case 0: | ||
68 | gpio_set_value(EGPIO4_CF_3V3_ON, 0); | ||
69 | break; | ||
70 | case 33: | ||
71 | gpio_set_value(EGPIO4_CF_3V3_ON, 1); | ||
72 | break; | ||
73 | default: | ||
74 | printk(KERN_ERR "pcmcia: Unsupported Vcc: %d\n", state->Vcc); | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | |||
78 | gpio_set_value(GPIO114_HX4700_CF_RESET, (state->flags & SS_RESET) != 0); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static struct pcmcia_low_level hx4700_pcmcia_ops = { | ||
84 | .owner = THIS_MODULE, | ||
85 | .nr = 1, | ||
86 | .hw_init = hx4700_pcmcia_hw_init, | ||
87 | .hw_shutdown = hx4700_pcmcia_hw_shutdown, | ||
88 | .socket_state = hx4700_pcmcia_socket_state, | ||
89 | .configure_socket = hx4700_pcmcia_configure_socket, | ||
90 | }; | ||
91 | |||
92 | static struct platform_device *hx4700_pcmcia_device; | ||
93 | |||
94 | static int __init hx4700_pcmcia_init(void) | ||
95 | { | ||
96 | struct platform_device *pdev; | ||
97 | |||
98 | if (!machine_is_h4700()) | ||
99 | return -ENODEV; | ||
100 | |||
101 | pdev = platform_device_register_data(NULL, "pxa2xx-pcmcia", -1, | ||
102 | &hx4700_pcmcia_ops, sizeof(hx4700_pcmcia_ops)); | ||
103 | if (IS_ERR(pdev)) | ||
104 | return PTR_ERR(pdev); | ||
105 | |||
106 | hx4700_pcmcia_device = pdev; | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static void __exit hx4700_pcmcia_exit(void) | ||
112 | { | ||
113 | platform_device_unregister(hx4700_pcmcia_device); | ||
114 | } | ||
115 | |||
116 | module_init(hx4700_pcmcia_init); | ||
117 | module_exit(hx4700_pcmcia_exit); | ||
118 | |||
119 | MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>"); | ||
120 | MODULE_DESCRIPTION("HP iPAQ hx4700 PCMCIA driver"); | ||
121 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index 7e32e25cdcb..aded706c0b9 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c | |||
@@ -30,26 +30,27 @@ | |||
30 | #include "soc_common.h" | 30 | #include "soc_common.h" |
31 | 31 | ||
32 | 32 | ||
33 | static struct pcmcia_irqs irqs[] = { | ||
34 | { 0, MAINSTONE_S0_CD_IRQ, "PCMCIA0 CD" }, | ||
35 | { 1, MAINSTONE_S1_CD_IRQ, "PCMCIA1 CD" }, | ||
36 | { 0, MAINSTONE_S0_STSCHG_IRQ, "PCMCIA0 STSCHG" }, | ||
37 | { 1, MAINSTONE_S1_STSCHG_IRQ, "PCMCIA1 STSCHG" }, | ||
38 | }; | ||
39 | |||
33 | static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 40 | static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
34 | { | 41 | { |
35 | /* | 42 | /* |
36 | * Setup default state of GPIO outputs | 43 | * Setup default state of GPIO outputs |
37 | * before we enable them as outputs. | 44 | * before we enable them as outputs. |
38 | */ | 45 | */ |
39 | if (skt->nr == 0) { | 46 | |
40 | skt->socket.pci_irq = MAINSTONE_S0_IRQ; | 47 | skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ; |
41 | skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ; | 48 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
42 | skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; | 49 | } |
43 | skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ; | 50 | |
44 | skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG"; | 51 | static void mst_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
45 | } else { | 52 | { |
46 | skt->socket.pci_irq = MAINSTONE_S1_IRQ; | 53 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
47 | skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ; | ||
48 | skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD"; | ||
49 | skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ; | ||
50 | skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG"; | ||
51 | } | ||
52 | return 0; | ||
53 | } | 54 | } |
54 | 55 | ||
55 | static unsigned long mst_pcmcia_status[2]; | 56 | static unsigned long mst_pcmcia_status[2]; |
@@ -83,6 +84,7 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
83 | state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0; | 84 | state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0; |
84 | state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1; | 85 | state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1; |
85 | state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1; | 86 | state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1; |
87 | state->wrprot = 0; /* not available */ | ||
86 | } | 88 | } |
87 | 89 | ||
88 | static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 90 | static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
@@ -129,6 +131,7 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
129 | static struct pcmcia_low_level mst_pcmcia_ops __initdata = { | 131 | static struct pcmcia_low_level mst_pcmcia_ops __initdata = { |
130 | .owner = THIS_MODULE, | 132 | .owner = THIS_MODULE, |
131 | .hw_init = mst_pcmcia_hw_init, | 133 | .hw_init = mst_pcmcia_hw_init, |
134 | .hw_shutdown = mst_pcmcia_hw_shutdown, | ||
132 | .socket_state = mst_pcmcia_socket_state, | 135 | .socket_state = mst_pcmcia_socket_state, |
133 | .configure_socket = mst_pcmcia_configure_socket, | 136 | .configure_socket = mst_pcmcia_configure_socket, |
134 | .nr = 2, | 137 | .nr = 2, |
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index ed7d4dbc39f..d589ad1dcd4 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c | |||
@@ -23,6 +23,7 @@ | |||
23 | static struct gpio palmld_pcmcia_gpios[] = { | 23 | static struct gpio palmld_pcmcia_gpios[] = { |
24 | { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, | 24 | { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, |
25 | { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | 25 | { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, |
26 | { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 29 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
@@ -32,8 +33,7 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
32 | ret = gpio_request_array(palmld_pcmcia_gpios, | 33 | ret = gpio_request_array(palmld_pcmcia_gpios, |
33 | ARRAY_SIZE(palmld_pcmcia_gpios)); | 34 | ARRAY_SIZE(palmld_pcmcia_gpios)); |
34 | 35 | ||
35 | skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY; | 36 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); |
36 | skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; | ||
37 | 37 | ||
38 | return ret; | 38 | return ret; |
39 | } | 39 | } |
@@ -47,6 +47,10 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
47 | struct pcmcia_state *state) | 47 | struct pcmcia_state *state) |
48 | { | 48 | { |
49 | state->detect = 1; /* always inserted */ | 49 | state->detect = 1; /* always inserted */ |
50 | state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY); | ||
51 | state->bvd1 = 1; | ||
52 | state->bvd2 = 1; | ||
53 | state->wrprot = 0; | ||
50 | state->vs_3v = 1; | 54 | state->vs_3v = 1; |
51 | state->vs_Xv = 0; | 55 | state->vs_Xv = 0; |
52 | } | 56 | } |
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c index 81225a7a8cb..9c6a04b2f71 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c | |||
@@ -26,6 +26,7 @@ static struct gpio palmtc_pcmcia_gpios[] = { | |||
26 | { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, | 26 | { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, |
27 | { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, | 27 | { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, |
28 | { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | 28 | { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, |
29 | { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
29 | { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, | 30 | { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, |
30 | }; | 31 | }; |
31 | 32 | ||
@@ -36,8 +37,7 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
36 | ret = gpio_request_array(palmtc_pcmcia_gpios, | 37 | ret = gpio_request_array(palmtc_pcmcia_gpios, |
37 | ARRAY_SIZE(palmtc_pcmcia_gpios)); | 38 | ARRAY_SIZE(palmtc_pcmcia_gpios)); |
38 | 39 | ||
39 | skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY; | 40 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); |
40 | skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; | ||
41 | 41 | ||
42 | return ret; | 42 | return ret; |
43 | } | 43 | } |
@@ -51,6 +51,10 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
51 | struct pcmcia_state *state) | 51 | struct pcmcia_state *state) |
52 | { | 52 | { |
53 | state->detect = 1; /* always inserted */ | 53 | state->detect = 1; /* always inserted */ |
54 | state->ready = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY); | ||
55 | state->bvd1 = 1; | ||
56 | state->bvd2 = 1; | ||
57 | state->wrprot = 0; | ||
54 | state->vs_3v = 1; | 58 | state->vs_3v = 1; |
55 | state->vs_Xv = 0; | 59 | state->vs_Xv = 0; |
56 | } | 60 | } |
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c index 069b6bbcf31..80645a688ee 100644 --- a/drivers/pcmcia/pxa2xx_palmtx.c +++ b/drivers/pcmcia/pxa2xx_palmtx.c | |||
@@ -23,6 +23,7 @@ static struct gpio palmtx_pcmcia_gpios[] = { | |||
23 | { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, | 23 | { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, |
24 | { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, | 24 | { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, |
25 | { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, | 25 | { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, |
26 | { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 29 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
@@ -32,8 +33,7 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
32 | ret = gpio_request_array(palmtx_pcmcia_gpios, | 33 | ret = gpio_request_array(palmtx_pcmcia_gpios, |
33 | ARRAY_SIZE(palmtx_pcmcia_gpios)); | 34 | ARRAY_SIZE(palmtx_pcmcia_gpios)); |
34 | 35 | ||
35 | skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTX_PCMCIA_READY; | 36 | skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); |
36 | skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; | ||
37 | 37 | ||
38 | return ret; | 38 | return ret; |
39 | } | 39 | } |
@@ -47,6 +47,10 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
47 | struct pcmcia_state *state) | 47 | struct pcmcia_state *state) |
48 | { | 48 | { |
49 | state->detect = 1; /* always inserted */ | 49 | state->detect = 1; /* always inserted */ |
50 | state->ready = !!gpio_get_value(GPIO_NR_PALMTX_PCMCIA_READY); | ||
51 | state->bvd1 = 1; | ||
52 | state->bvd2 = 1; | ||
53 | state->wrprot = 0; | ||
50 | state->vs_3v = 1; | 54 | state->vs_3v = 1; |
51 | state->vs_Xv = 0; | 55 | state->vs_Xv = 0; |
52 | } | 56 | } |
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 89ebd8c7663..69ae2fd2240 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -46,9 +46,21 @@ static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) | |||
46 | 46 | ||
47 | static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 47 | static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
48 | { | 48 | { |
49 | int ret; | ||
50 | |||
51 | /* Register interrupts */ | ||
49 | if (SCOOP_DEV[skt->nr].cd_irq >= 0) { | 52 | if (SCOOP_DEV[skt->nr].cd_irq >= 0) { |
50 | skt->stat[SOC_STAT_CD].irq = SCOOP_DEV[skt->nr].cd_irq; | 53 | struct pcmcia_irqs cd_irq; |
51 | skt->stat[SOC_STAT_CD].name = SCOOP_DEV[skt->nr].cd_irq_str; | 54 | |
55 | cd_irq.sock = skt->nr; | ||
56 | cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; | ||
57 | cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; | ||
58 | ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); | ||
59 | |||
60 | if (ret) { | ||
61 | printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); | ||
62 | return ret; | ||
63 | } | ||
52 | } | 64 | } |
53 | 65 | ||
54 | skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; | 66 | skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; |
@@ -56,6 +68,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
56 | return 0; | 68 | return 0; |
57 | } | 69 | } |
58 | 70 | ||
71 | static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
72 | { | ||
73 | if (SCOOP_DEV[skt->nr].cd_irq >= 0) { | ||
74 | struct pcmcia_irqs cd_irq; | ||
75 | |||
76 | cd_irq.sock = skt->nr; | ||
77 | cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; | ||
78 | cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; | ||
79 | soc_pcmcia_free_irqs(skt, &cd_irq, 1); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | |||
59 | static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 84 | static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
60 | struct pcmcia_state *state) | 85 | struct pcmcia_state *state) |
61 | { | 86 | { |
@@ -194,9 +219,10 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | |||
194 | sharpsl_pcmcia_init_reset(skt); | 219 | sharpsl_pcmcia_init_reset(skt); |
195 | } | 220 | } |
196 | 221 | ||
197 | static struct pcmcia_low_level sharpsl_pcmcia_ops = { | 222 | static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { |
198 | .owner = THIS_MODULE, | 223 | .owner = THIS_MODULE, |
199 | .hw_init = sharpsl_pcmcia_hw_init, | 224 | .hw_init = sharpsl_pcmcia_hw_init, |
225 | .hw_shutdown = sharpsl_pcmcia_hw_shutdown, | ||
200 | .socket_state = sharpsl_pcmcia_socket_state, | 226 | .socket_state = sharpsl_pcmcia_socket_state, |
201 | .configure_socket = sharpsl_pcmcia_configure_socket, | 227 | .configure_socket = sharpsl_pcmcia_configure_socket, |
202 | .socket_init = sharpsl_pcmcia_socket_init, | 228 | .socket_init = sharpsl_pcmcia_socket_init, |
@@ -208,7 +234,7 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops = { | |||
208 | #ifdef CONFIG_SA1100_COLLIE | 234 | #ifdef CONFIG_SA1100_COLLIE |
209 | #include "sa11xx_base.h" | 235 | #include "sa11xx_base.h" |
210 | 236 | ||
211 | int pcmcia_collie_init(struct device *dev) | 237 | int __devinit pcmcia_collie_init(struct device *dev) |
212 | { | 238 | { |
213 | int ret = -ENODEV; | 239 | int ret = -ENODEV; |
214 | 240 | ||
diff --git a/drivers/pcmcia/pxa2xx_stargate2.c b/drivers/pcmcia/pxa2xx_stargate2.c index 1d73c4401fd..939622251df 100644 --- a/drivers/pcmcia/pxa2xx_stargate2.c +++ b/drivers/pcmcia/pxa2xx_stargate2.c | |||
@@ -33,6 +33,10 @@ | |||
33 | #define SG2_S0_GPIO_DETECT 53 | 33 | #define SG2_S0_GPIO_DETECT 53 |
34 | #define SG2_S0_GPIO_READY 81 | 34 | #define SG2_S0_GPIO_READY 81 |
35 | 35 | ||
36 | static struct pcmcia_irqs irqs[] = { | ||
37 | { 0, IRQ_GPIO(SG2_S0_GPIO_DETECT), "PCMCIA0 CD" }, | ||
38 | }; | ||
39 | |||
36 | static struct gpio sg2_pcmcia_gpios[] = { | 40 | static struct gpio sg2_pcmcia_gpios[] = { |
37 | { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" }, | 41 | { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" }, |
38 | { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" }, | 42 | { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" }, |
@@ -40,20 +44,25 @@ static struct gpio sg2_pcmcia_gpios[] = { | |||
40 | 44 | ||
41 | static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 45 | static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
42 | { | 46 | { |
43 | skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT; | 47 | skt->socket.pci_irq = IRQ_GPIO(SG2_S0_GPIO_READY); |
44 | skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; | 48 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
45 | skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY; | 49 | } |
46 | skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; | 50 | |
47 | return 0; | 51 | static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
52 | { | ||
53 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
48 | } | 54 | } |
49 | 55 | ||
50 | static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 56 | static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
51 | struct pcmcia_state *state) | 57 | struct pcmcia_state *state) |
52 | { | 58 | { |
59 | state->detect = !gpio_get_value(SG2_S0_GPIO_DETECT); | ||
60 | state->ready = !!gpio_get_value(SG2_S0_GPIO_READY); | ||
53 | state->bvd1 = 0; /* not available - battery detect on card */ | 61 | state->bvd1 = 0; /* not available - battery detect on card */ |
54 | state->bvd2 = 0; /* not available */ | 62 | state->bvd2 = 0; /* not available */ |
55 | state->vs_3v = 1; /* not available - voltage detect for card */ | 63 | state->vs_3v = 1; /* not available - voltage detect for card */ |
56 | state->vs_Xv = 0; /* not available */ | 64 | state->vs_Xv = 0; /* not available */ |
65 | state->wrprot = 0; /* not available - write protect */ | ||
57 | } | 66 | } |
58 | 67 | ||
59 | static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 68 | static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
@@ -83,11 +92,24 @@ static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
83 | return 0; | 92 | return 0; |
84 | } | 93 | } |
85 | 94 | ||
95 | static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
96 | { | ||
97 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
98 | } | ||
99 | |||
100 | static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
101 | { | ||
102 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
103 | } | ||
104 | |||
86 | static struct pcmcia_low_level sg2_pcmcia_ops __initdata = { | 105 | static struct pcmcia_low_level sg2_pcmcia_ops __initdata = { |
87 | .owner = THIS_MODULE, | 106 | .owner = THIS_MODULE, |
88 | .hw_init = sg2_pcmcia_hw_init, | 107 | .hw_init = sg2_pcmcia_hw_init, |
108 | .hw_shutdown = sg2_pcmcia_hw_shutdown, | ||
89 | .socket_state = sg2_pcmcia_socket_state, | 109 | .socket_state = sg2_pcmcia_socket_state, |
90 | .configure_socket = sg2_pcmcia_configure_socket, | 110 | .configure_socket = sg2_pcmcia_configure_socket, |
111 | .socket_init = sg2_pcmcia_socket_init, | ||
112 | .socket_suspend = sg2_pcmcia_socket_suspend, | ||
91 | .nr = 1, | 113 | .nr = 1, |
92 | }; | 114 | }; |
93 | 115 | ||
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c index d326ba1fa1c..57ddb969d88 100644 --- a/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/drivers/pcmcia/pxa2xx_trizeps4.c | |||
@@ -29,17 +29,31 @@ | |||
29 | 29 | ||
30 | extern void board_pcmcia_power(int power); | 30 | extern void board_pcmcia_power(int power); |
31 | 31 | ||
32 | static struct pcmcia_irqs irqs[] = { | ||
33 | { 0, IRQ_GPIO(GPIO_PCD), "cs0_cd" } | ||
34 | /* on other baseboards we can have more inputs */ | ||
35 | }; | ||
36 | |||
32 | static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 37 | static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
33 | { | 38 | { |
39 | int ret, i; | ||
34 | /* we dont have voltage/card/ready detection | 40 | /* we dont have voltage/card/ready detection |
35 | * so we dont need interrupts for it | 41 | * so we dont need interrupts for it |
36 | */ | 42 | */ |
37 | switch (skt->nr) { | 43 | switch (skt->nr) { |
38 | case 0: | 44 | case 0: |
39 | skt->stat[SOC_STAT_CD].gpio = GPIO_PCD; | 45 | if (gpio_request(GPIO_PRDY, "cf_irq") < 0) { |
40 | skt->stat[SOC_STAT_CD].name = "cs0_cd"; | 46 | pr_err("%s: sock %d unable to request gpio %d\n", __func__, |
41 | skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY; | 47 | skt->nr, GPIO_PRDY); |
42 | skt->stat[SOC_STAT_RDY].name = "cs0_rdy"; | 48 | return -EBUSY; |
49 | } | ||
50 | if (gpio_direction_input(GPIO_PRDY) < 0) { | ||
51 | pr_err("%s: sock %d unable to set input gpio %d\n", __func__, | ||
52 | skt->nr, GPIO_PRDY); | ||
53 | gpio_free(GPIO_PRDY); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | skt->socket.pci_irq = IRQ_GPIO(GPIO_PRDY); | ||
43 | break; | 57 | break; |
44 | default: | 58 | default: |
45 | break; | 59 | break; |
@@ -47,7 +61,39 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
47 | /* release the reset of this card */ | 61 | /* release the reset of this card */ |
48 | pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq); | 62 | pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq); |
49 | 63 | ||
50 | return 0; | 64 | /* supplementory irqs for the socket */ |
65 | for (i = 0; i < ARRAY_SIZE(irqs); i++) { | ||
66 | if (irqs[i].sock != skt->nr) | ||
67 | continue; | ||
68 | if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) { | ||
69 | pr_err("%s: sock %d unable to request gpio %d\n", | ||
70 | __func__, skt->nr, irq_to_gpio(irqs[i].irq)); | ||
71 | ret = -EBUSY; | ||
72 | goto error; | ||
73 | } | ||
74 | if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) { | ||
75 | pr_err("%s: sock %d unable to set input gpio %d\n", | ||
76 | __func__, skt->nr, irq_to_gpio(irqs[i].irq)); | ||
77 | ret = -EINVAL; | ||
78 | goto error; | ||
79 | } | ||
80 | } | ||
81 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
82 | |||
83 | error: | ||
84 | for (; i >= 0; i--) { | ||
85 | gpio_free(irq_to_gpio(irqs[i].irq)); | ||
86 | } | ||
87 | return (ret); | ||
88 | } | ||
89 | |||
90 | static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
91 | { | ||
92 | int i; | ||
93 | /* free allocated gpio's */ | ||
94 | gpio_free(GPIO_PRDY); | ||
95 | for (i = 0; i < ARRAY_SIZE(irqs); i++) | ||
96 | gpio_free(irq_to_gpio(irqs[i].irq)); | ||
51 | } | 97 | } |
52 | 98 | ||
53 | static unsigned long trizeps_pcmcia_status[2]; | 99 | static unsigned long trizeps_pcmcia_status[2]; |
@@ -71,10 +117,13 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
71 | switch (skt->nr) { | 117 | switch (skt->nr) { |
72 | case 0: | 118 | case 0: |
73 | /* just fill in fix states */ | 119 | /* just fill in fix states */ |
120 | state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1; | ||
121 | state->ready = gpio_get_value(GPIO_PRDY) ? 1 : 0; | ||
74 | state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0; | 122 | state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0; |
75 | state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0; | 123 | state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0; |
76 | state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1; | 124 | state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1; |
77 | state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1; | 125 | state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1; |
126 | state->wrprot = 0; /* not available */ | ||
78 | break; | 127 | break; |
79 | 128 | ||
80 | #ifndef CONFIG_MACH_TRIZEPS_CONXS | 129 | #ifndef CONFIG_MACH_TRIZEPS_CONXS |
@@ -86,6 +135,7 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
86 | state->bvd2 = 0; | 135 | state->bvd2 = 0; |
87 | state->vs_3v = 0; | 136 | state->vs_3v = 0; |
88 | state->vs_Xv = 0; | 137 | state->vs_Xv = 0; |
138 | state->wrprot = 0; | ||
89 | break; | 139 | break; |
90 | 140 | ||
91 | #endif | 141 | #endif |
@@ -153,6 +203,7 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | |||
153 | static struct pcmcia_low_level trizeps_pcmcia_ops = { | 203 | static struct pcmcia_low_level trizeps_pcmcia_ops = { |
154 | .owner = THIS_MODULE, | 204 | .owner = THIS_MODULE, |
155 | .hw_init = trizeps_pcmcia_hw_init, | 205 | .hw_init = trizeps_pcmcia_hw_init, |
206 | .hw_shutdown = trizeps_pcmcia_hw_shutdown, | ||
156 | .socket_state = trizeps_pcmcia_socket_state, | 207 | .socket_state = trizeps_pcmcia_socket_state, |
157 | .configure_socket = trizeps_pcmcia_configure_socket, | 208 | .configure_socket = trizeps_pcmcia_configure_socket, |
158 | .socket_init = trizeps_pcmcia_socket_init, | 209 | .socket_init = trizeps_pcmcia_socket_init, |
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c index a76f495953a..1064b1c2869 100644 --- a/drivers/pcmcia/pxa2xx_viper.c +++ b/drivers/pcmcia/pxa2xx_viper.c | |||
@@ -25,13 +25,20 @@ | |||
25 | 25 | ||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | 27 | ||
28 | #include <linux/platform_data/pcmcia-pxa2xx_viper.h> | 28 | #include <mach/arcom-pcmcia.h> |
29 | 29 | ||
30 | #include "soc_common.h" | 30 | #include "soc_common.h" |
31 | #include "pxa2xx_base.h" | 31 | #include "pxa2xx_base.h" |
32 | 32 | ||
33 | static struct platform_device *arcom_pcmcia_dev; | 33 | static struct platform_device *arcom_pcmcia_dev; |
34 | 34 | ||
35 | static struct pcmcia_irqs irqs[] = { | ||
36 | { | ||
37 | .sock = 0, | ||
38 | .str = "PCMCIA_CD", | ||
39 | }, | ||
40 | }; | ||
41 | |||
35 | static inline struct arcom_pcmcia_pdata *viper_get_pdata(void) | 42 | static inline struct arcom_pcmcia_pdata *viper_get_pdata(void) |
36 | { | 43 | { |
37 | return arcom_pcmcia_dev->dev.platform_data; | 44 | return arcom_pcmcia_dev->dev.platform_data; |
@@ -42,28 +49,38 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
42 | struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); | 49 | struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); |
43 | unsigned long flags; | 50 | unsigned long flags; |
44 | 51 | ||
45 | skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio; | 52 | skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio); |
46 | skt->stat[SOC_STAT_CD].name = "PCMCIA_CD"; | 53 | irqs[0].irq = gpio_to_irq(pdata->cd_gpio); |
47 | skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio; | 54 | |
48 | skt->stat[SOC_STAT_RDY].name = "CF ready"; | 55 | if (gpio_request(pdata->cd_gpio, "CF detect")) |
56 | goto err_request_cd; | ||
57 | |||
58 | if (gpio_request(pdata->rdy_gpio, "CF ready")) | ||
59 | goto err_request_rdy; | ||
49 | 60 | ||
50 | if (gpio_request(pdata->pwr_gpio, "CF power")) | 61 | if (gpio_request(pdata->pwr_gpio, "CF power")) |
51 | goto err_request_pwr; | 62 | goto err_request_pwr; |
52 | 63 | ||
53 | local_irq_save(flags); | 64 | local_irq_save(flags); |
54 | 65 | ||
55 | if (gpio_direction_output(pdata->pwr_gpio, 0)) { | 66 | if (gpio_direction_output(pdata->pwr_gpio, 0) || |
67 | gpio_direction_input(pdata->cd_gpio) || | ||
68 | gpio_direction_input(pdata->rdy_gpio)) { | ||
56 | local_irq_restore(flags); | 69 | local_irq_restore(flags); |
57 | goto err_dir; | 70 | goto err_dir; |
58 | } | 71 | } |
59 | 72 | ||
60 | local_irq_restore(flags); | 73 | local_irq_restore(flags); |
61 | 74 | ||
62 | return 0; | 75 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
63 | 76 | ||
64 | err_dir: | 77 | err_dir: |
65 | gpio_free(pdata->pwr_gpio); | 78 | gpio_free(pdata->pwr_gpio); |
66 | err_request_pwr: | 79 | err_request_pwr: |
80 | gpio_free(pdata->rdy_gpio); | ||
81 | err_request_rdy: | ||
82 | gpio_free(pdata->cd_gpio); | ||
83 | err_request_cd: | ||
67 | dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n"); | 84 | dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n"); |
68 | return -1; | 85 | return -1; |
69 | } | 86 | } |
@@ -75,12 +92,22 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
75 | { | 92 | { |
76 | struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); | 93 | struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); |
77 | 94 | ||
95 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
78 | gpio_free(pdata->pwr_gpio); | 96 | gpio_free(pdata->pwr_gpio); |
97 | gpio_free(pdata->rdy_gpio); | ||
98 | gpio_free(pdata->cd_gpio); | ||
79 | } | 99 | } |
80 | 100 | ||
81 | static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 101 | static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
82 | struct pcmcia_state *state) | 102 | struct pcmcia_state *state) |
83 | { | 103 | { |
104 | struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); | ||
105 | |||
106 | state->detect = !gpio_get_value(pdata->cd_gpio); | ||
107 | state->ready = !!gpio_get_value(pdata->rdy_gpio); | ||
108 | state->bvd1 = 1; | ||
109 | state->bvd2 = 1; | ||
110 | state->wrprot = 0; | ||
84 | state->vs_3v = 1; /* Can only apply 3.3V */ | 111 | state->vs_3v = 1; /* Can only apply 3.3V */ |
85 | state->vs_Xv = 0; | 112 | state->vs_Xv = 0; |
86 | } | 113 | } |
@@ -177,7 +204,18 @@ static struct platform_driver viper_pcmcia_driver = { | |||
177 | .id_table = viper_pcmcia_id_table, | 204 | .id_table = viper_pcmcia_id_table, |
178 | }; | 205 | }; |
179 | 206 | ||
180 | module_platform_driver(viper_pcmcia_driver); | 207 | static int __init viper_pcmcia_init(void) |
208 | { | ||
209 | return platform_driver_register(&viper_pcmcia_driver); | ||
210 | } | ||
211 | |||
212 | static void __exit viper_pcmcia_exit(void) | ||
213 | { | ||
214 | return platform_driver_unregister(&viper_pcmcia_driver); | ||
215 | } | ||
216 | |||
217 | module_init(viper_pcmcia_init); | ||
218 | module_exit(viper_pcmcia_exit); | ||
181 | 219 | ||
182 | MODULE_DEVICE_TABLE(platform, viper_pcmcia_id_table); | 220 | MODULE_DEVICE_TABLE(platform, viper_pcmcia_id_table); |
183 | MODULE_LICENSE("GPL"); | 221 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index a47dcd24a26..e956f659089 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c | |||
@@ -17,20 +17,37 @@ | |||
17 | 17 | ||
18 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
19 | 19 | ||
20 | #include <asm/gpio.h> | 20 | #include <mach/gpio.h> |
21 | #include <mach/vpac270.h> | 21 | #include <mach/vpac270.h> |
22 | 22 | ||
23 | #include "soc_common.h" | 23 | #include "soc_common.h" |
24 | 24 | ||
25 | static struct gpio vpac270_pcmcia_gpios[] = { | 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" }, | ||
26 | { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, | 28 | { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, |
27 | { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, | 29 | { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, |
28 | }; | 30 | }; |
29 | 31 | ||
30 | static struct gpio vpac270_cf_gpios[] = { | 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" }, | ||
31 | { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, | 35 | { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, |
32 | }; | 36 | }; |
33 | 37 | ||
38 | static struct pcmcia_irqs cd_irqs[] = { | ||
39 | { | ||
40 | .sock = 0, | ||
41 | .irq = IRQ_GPIO(GPIO84_VPAC270_PCMCIA_CD), | ||
42 | .str = "PCMCIA CD" | ||
43 | }, | ||
44 | { | ||
45 | .sock = 1, | ||
46 | .irq = IRQ_GPIO(GPIO17_VPAC270_CF_CD), | ||
47 | .str = "CF CD" | ||
48 | }, | ||
49 | }; | ||
50 | |||
34 | static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 51 | static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
35 | { | 52 | { |
36 | int ret; | 53 | int ret; |
@@ -39,18 +56,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
39 | ret = gpio_request_array(vpac270_pcmcia_gpios, | 56 | ret = gpio_request_array(vpac270_pcmcia_gpios, |
40 | ARRAY_SIZE(vpac270_pcmcia_gpios)); | 57 | ARRAY_SIZE(vpac270_pcmcia_gpios)); |
41 | 58 | ||
42 | skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD; | 59 | skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); |
43 | skt->stat[SOC_STAT_CD].name = "PCMCIA CD"; | 60 | |
44 | skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY; | 61 | if (!ret) |
45 | skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; | 62 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); |
46 | } else { | 63 | } else { |
47 | ret = gpio_request_array(vpac270_cf_gpios, | 64 | ret = gpio_request_array(vpac270_cf_gpios, |
48 | ARRAY_SIZE(vpac270_cf_gpios)); | 65 | ARRAY_SIZE(vpac270_cf_gpios)); |
49 | 66 | ||
50 | skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD; | 67 | skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); |
51 | skt->stat[SOC_STAT_CD].name = "CF CD"; | 68 | |
52 | skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY; | 69 | if (!ret) |
53 | skt->stat[SOC_STAT_RDY].name = "CF Ready"; | 70 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); |
54 | } | 71 | } |
55 | 72 | ||
56 | return ret; | 73 | return ret; |
@@ -69,6 +86,16 @@ static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
69 | static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 86 | static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
70 | struct pcmcia_state *state) | 87 | struct pcmcia_state *state) |
71 | { | 88 | { |
89 | if (skt->nr == 0) { | ||
90 | state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD); | ||
91 | state->ready = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY); | ||
92 | } else { | ||
93 | state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD); | ||
94 | state->ready = !!gpio_get_value(GPIO12_VPAC270_CF_RDY); | ||
95 | } | ||
96 | state->bvd1 = 1; | ||
97 | state->bvd2 = 1; | ||
98 | state->wrprot = 0; | ||
72 | state->vs_3v = 1; | 99 | state->vs_3v = 1; |
73 | state->vs_Xv = 0; | 100 | state->vs_Xv = 0; |
74 | } | 101 | } |
@@ -90,6 +117,14 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
90 | return 0; | 117 | return 0; |
91 | } | 118 | } |
92 | 119 | ||
120 | static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
121 | { | ||
122 | } | ||
123 | |||
124 | static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
125 | { | ||
126 | } | ||
127 | |||
93 | static struct pcmcia_low_level vpac270_pcmcia_ops = { | 128 | static struct pcmcia_low_level vpac270_pcmcia_ops = { |
94 | .owner = THIS_MODULE, | 129 | .owner = THIS_MODULE, |
95 | 130 | ||
@@ -101,6 +136,9 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = { | |||
101 | 136 | ||
102 | .socket_state = vpac270_pcmcia_socket_state, | 137 | .socket_state = vpac270_pcmcia_socket_state, |
103 | .configure_socket = vpac270_pcmcia_configure_socket, | 138 | .configure_socket = vpac270_pcmcia_configure_socket, |
139 | |||
140 | .socket_init = vpac270_pcmcia_socket_init, | ||
141 | .socket_suspend = vpac270_pcmcia_socket_suspend, | ||
104 | }; | 142 | }; |
105 | 143 | ||
106 | static struct platform_device *vpac270_pcmcia_device; | 144 | static struct platform_device *vpac270_pcmcia_device; |
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 430a9ac5609..9da9656242a 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -1199,7 +1199,7 @@ static const struct attribute_group rsrc_attributes = { | |||
1199 | .attrs = pccard_rsrc_attributes, | 1199 | .attrs = pccard_rsrc_attributes, |
1200 | }; | 1200 | }; |
1201 | 1201 | ||
1202 | static int pccard_sysfs_add_rsrc(struct device *dev, | 1202 | static int __devinit pccard_sysfs_add_rsrc(struct device *dev, |
1203 | struct class_interface *class_intf) | 1203 | struct class_interface *class_intf) |
1204 | { | 1204 | { |
1205 | struct pcmcia_socket *s = dev_get_drvdata(dev); | 1205 | struct pcmcia_socket *s = dev_get_drvdata(dev); |
@@ -1209,7 +1209,7 @@ static int pccard_sysfs_add_rsrc(struct device *dev, | |||
1209 | return sysfs_create_group(&dev->kobj, &rsrc_attributes); | 1209 | return sysfs_create_group(&dev->kobj, &rsrc_attributes); |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | static void pccard_sysfs_remove_rsrc(struct device *dev, | 1212 | static void __devexit pccard_sysfs_remove_rsrc(struct device *dev, |
1213 | struct class_interface *class_intf) | 1213 | struct class_interface *class_intf) |
1214 | { | 1214 | { |
1215 | struct pcmcia_socket *s = dev_get_drvdata(dev); | 1215 | struct pcmcia_socket *s = dev_get_drvdata(dev); |
@@ -1222,7 +1222,7 @@ static void pccard_sysfs_remove_rsrc(struct device *dev, | |||
1222 | static struct class_interface pccard_rsrc_interface __refdata = { | 1222 | static struct class_interface pccard_rsrc_interface __refdata = { |
1223 | .class = &pcmcia_socket_class, | 1223 | .class = &pcmcia_socket_class, |
1224 | .add_dev = &pccard_sysfs_add_rsrc, | 1224 | .add_dev = &pccard_sysfs_add_rsrc, |
1225 | .remove_dev = &pccard_sysfs_remove_rsrc, | 1225 | .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc), |
1226 | }; | 1226 | }; |
1227 | 1227 | ||
1228 | static int __init nonstatic_sysfs_init(void) | 1228 | static int __init nonstatic_sysfs_init(void) |
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c index 44cfc4416e5..f1e882272ab 100644 --- a/drivers/pcmcia/sa1100_assabet.c +++ b/drivers/pcmcia/sa1100_assabet.c | |||
@@ -10,30 +10,46 @@ | |||
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/gpio.h> | ||
14 | 13 | ||
14 | #include <mach/hardware.h> | ||
15 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
16 | #include <asm/irq.h> | ||
17 | #include <asm/signal.h> | ||
16 | #include <mach/assabet.h> | 18 | #include <mach/assabet.h> |
17 | 19 | ||
18 | #include "sa1100_generic.h" | 20 | #include "sa1100_generic.h" |
19 | 21 | ||
22 | static struct pcmcia_irqs irqs[] = { | ||
23 | { 1, ASSABET_IRQ_GPIO_CF_CD, "CF CD" }, | ||
24 | { 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" }, | ||
25 | { 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" }, | ||
26 | }; | ||
27 | |||
20 | static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
21 | { | 29 | { |
22 | skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD; | 30 | skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; |
23 | skt->stat[SOC_STAT_CD].name = "CF CD"; | ||
24 | skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1; | ||
25 | skt->stat[SOC_STAT_BVD1].name = "CF BVD1"; | ||
26 | skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2; | ||
27 | skt->stat[SOC_STAT_BVD2].name = "CF BVD2"; | ||
28 | skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ; | ||
29 | skt->stat[SOC_STAT_RDY].name = "CF RDY"; | ||
30 | 31 | ||
31 | return 0; | 32 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
33 | } | ||
34 | |||
35 | /* | ||
36 | * Release all resources. | ||
37 | */ | ||
38 | static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
39 | { | ||
40 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
32 | } | 41 | } |
33 | 42 | ||
34 | static void | 43 | static void |
35 | assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 44 | assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
36 | { | 45 | { |
46 | unsigned long levels = GPLR; | ||
47 | |||
48 | state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1; | ||
49 | state->ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0; | ||
50 | state->bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0; | ||
51 | state->bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0; | ||
52 | state->wrprot = 0; /* Not available on Assabet. */ | ||
37 | state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ | 53 | state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ |
38 | state->vs_Xv = 0; | 54 | state->vs_Xv = 0; |
39 | } | 55 | } |
@@ -62,24 +78,38 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat | |||
62 | return -1; | 78 | return -1; |
63 | } | 79 | } |
64 | 80 | ||
65 | /* Silently ignore Vpp, speaker enable. */ | 81 | /* Silently ignore Vpp, output enable, speaker enable. */ |
66 | 82 | ||
67 | if (state->flags & SS_RESET) | 83 | if (state->flags & SS_RESET) |
68 | mask |= ASSABET_BCR_CF_RST; | 84 | mask |= ASSABET_BCR_CF_RST; |
69 | if (!(state->flags & SS_OUTPUT_ENA)) | ||
70 | mask |= ASSABET_BCR_CF_BUS_OFF; | ||
71 | 85 | ||
72 | ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR | | 86 | ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask); |
73 | ASSABET_BCR_CF_BUS_OFF, mask); | ||
74 | 87 | ||
75 | return 0; | 88 | return 0; |
76 | } | 89 | } |
77 | 90 | ||
78 | /* | 91 | /* |
92 | * Enable card status IRQs on (re-)initialisation. This can | ||
93 | * be called at initialisation, power management event, or | ||
94 | * pcmcia event. | ||
95 | */ | ||
96 | static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
97 | { | ||
98 | /* | ||
99 | * Enable CF bus | ||
100 | */ | ||
101 | ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF); | ||
102 | |||
103 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
104 | } | ||
105 | |||
106 | /* | ||
79 | * Disable card status IRQs on suspend. | 107 | * Disable card status IRQs on suspend. |
80 | */ | 108 | */ |
81 | static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 109 | static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
82 | { | 110 | { |
111 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
112 | |||
83 | /* | 113 | /* |
84 | * Tristate the CF bus signals. Also assert CF | 114 | * Tristate the CF bus signals. Also assert CF |
85 | * reset as per user guide page 4-11. | 115 | * reset as per user guide page 4-11. |
@@ -89,13 +119,18 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | |||
89 | 119 | ||
90 | static struct pcmcia_low_level assabet_pcmcia_ops = { | 120 | static struct pcmcia_low_level assabet_pcmcia_ops = { |
91 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
122 | |||
92 | .hw_init = assabet_pcmcia_hw_init, | 123 | .hw_init = assabet_pcmcia_hw_init, |
124 | .hw_shutdown = assabet_pcmcia_hw_shutdown, | ||
125 | |||
93 | .socket_state = assabet_pcmcia_socket_state, | 126 | .socket_state = assabet_pcmcia_socket_state, |
94 | .configure_socket = assabet_pcmcia_configure_socket, | 127 | .configure_socket = assabet_pcmcia_configure_socket, |
128 | |||
129 | .socket_init = assabet_pcmcia_socket_init, | ||
95 | .socket_suspend = assabet_pcmcia_socket_suspend, | 130 | .socket_suspend = assabet_pcmcia_socket_suspend, |
96 | }; | 131 | }; |
97 | 132 | ||
98 | int pcmcia_assabet_init(struct device *dev) | 133 | int __devinit pcmcia_assabet_init(struct device *dev) |
99 | { | 134 | { |
100 | int ret = -ENODEV; | 135 | int ret = -ENODEV; |
101 | 136 | ||
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index b3774e5d039..30560df8c76 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <linux/gpio.h> | ||
14 | 13 | ||
15 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
16 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
@@ -20,34 +19,34 @@ | |||
20 | 19 | ||
21 | #define CERF_SOCKET 1 | 20 | #define CERF_SOCKET 1 |
22 | 21 | ||
22 | static struct pcmcia_irqs irqs[] = { | ||
23 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_CD, "CF_CD" }, | ||
24 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" }, | ||
25 | { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" } | ||
26 | }; | ||
27 | |||
23 | static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
24 | { | 29 | { |
25 | int ret; | 30 | skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; |
26 | |||
27 | ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET"); | ||
28 | if (ret) | ||
29 | return ret; | ||
30 | |||
31 | skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD; | ||
32 | skt->stat[SOC_STAT_CD].name = "CF_CD"; | ||
33 | skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1; | ||
34 | skt->stat[SOC_STAT_BVD1].name = "CF_BVD1"; | ||
35 | skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2; | ||
36 | skt->stat[SOC_STAT_BVD2].name = "CF_BVD2"; | ||
37 | skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ; | ||
38 | skt->stat[SOC_STAT_RDY].name = "CF_IRQ"; | ||
39 | 31 | ||
40 | return 0; | 32 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
41 | } | 33 | } |
42 | 34 | ||
43 | static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 35 | static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
44 | { | 36 | { |
45 | gpio_free(CERF_GPIO_CF_RESET); | 37 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
46 | } | 38 | } |
47 | 39 | ||
48 | static void | 40 | static void |
49 | cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 41 | cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
50 | { | 42 | { |
43 | unsigned long levels = GPLR; | ||
44 | |||
45 | state->detect = (levels & CERF_GPIO_CF_CD) ?0:1; | ||
46 | state->ready = (levels & CERF_GPIO_CF_IRQ) ?1:0; | ||
47 | state->bvd1 = (levels & CERF_GPIO_CF_BVD1)?1:0; | ||
48 | state->bvd2 = (levels & CERF_GPIO_CF_BVD2)?1:0; | ||
49 | state->wrprot = 0; | ||
51 | state->vs_3v = 1; | 50 | state->vs_3v = 1; |
52 | state->vs_Xv = 0; | 51 | state->vs_Xv = 0; |
53 | } | 52 | } |
@@ -68,20 +67,37 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
68 | return -1; | 67 | return -1; |
69 | } | 68 | } |
70 | 69 | ||
71 | gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET)); | 70 | if (state->flags & SS_RESET) { |
71 | GPSR = CERF_GPIO_CF_RESET; | ||
72 | } else { | ||
73 | GPCR = CERF_GPIO_CF_RESET; | ||
74 | } | ||
72 | 75 | ||
73 | return 0; | 76 | return 0; |
74 | } | 77 | } |
75 | 78 | ||
79 | static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
80 | { | ||
81 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
82 | } | ||
83 | |||
84 | static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
85 | { | ||
86 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
87 | } | ||
88 | |||
76 | static struct pcmcia_low_level cerf_pcmcia_ops = { | 89 | static struct pcmcia_low_level cerf_pcmcia_ops = { |
77 | .owner = THIS_MODULE, | 90 | .owner = THIS_MODULE, |
78 | .hw_init = cerf_pcmcia_hw_init, | 91 | .hw_init = cerf_pcmcia_hw_init, |
79 | .hw_shutdown = cerf_pcmcia_hw_shutdown, | 92 | .hw_shutdown = cerf_pcmcia_hw_shutdown, |
80 | .socket_state = cerf_pcmcia_socket_state, | 93 | .socket_state = cerf_pcmcia_socket_state, |
81 | .configure_socket = cerf_pcmcia_configure_socket, | 94 | .configure_socket = cerf_pcmcia_configure_socket, |
95 | |||
96 | .socket_init = cerf_pcmcia_socket_init, | ||
97 | .socket_suspend = cerf_pcmcia_socket_suspend, | ||
82 | }; | 98 | }; |
83 | 99 | ||
84 | int pcmcia_cerf_init(struct device *dev) | 100 | int __devinit pcmcia_cerf_init(struct device *dev) |
85 | { | 101 | { |
86 | int ret = -ENODEV; | 102 | int ret = -ENODEV; |
87 | 103 | ||
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index ff8a027a4af..2eea664bc07 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c | |||
@@ -43,7 +43,7 @@ | |||
43 | 43 | ||
44 | int __init pcmcia_collie_init(struct device *dev); | 44 | int __init pcmcia_collie_init(struct device *dev); |
45 | 45 | ||
46 | static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | 46 | static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) __devinitdata = { |
47 | #ifdef CONFIG_SA1100_ASSABET | 47 | #ifdef CONFIG_SA1100_ASSABET |
48 | pcmcia_assabet_init, | 48 | pcmcia_assabet_init, |
49 | #endif | 49 | #endif |
@@ -67,7 +67,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | |||
67 | #endif | 67 | #endif |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) | 70 | static int __devinit sa11x0_drv_pcmcia_probe(struct platform_device *dev) |
71 | { | 71 | { |
72 | int i, ret = -ENODEV; | 72 | int i, ret = -ENODEV; |
73 | 73 | ||
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index 431d8b07cba..edf8f002889 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c | |||
@@ -19,20 +19,36 @@ | |||
19 | 19 | ||
20 | #include "sa1100_generic.h" | 20 | #include "sa1100_generic.h" |
21 | 21 | ||
22 | static struct pcmcia_irqs irqs[] = { | ||
23 | { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */ | ||
24 | { .sock = 1, .str = "PCMCIA CD1" } | ||
25 | }; | ||
26 | |||
22 | static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 27 | static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
23 | { | 28 | { |
24 | int err; | 29 | int err; |
25 | 30 | ||
26 | switch (skt->nr) { | 31 | switch (skt->nr) { |
27 | case 0: | 32 | case 0: |
28 | skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0; | 33 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0"); |
29 | skt->stat[SOC_STAT_CD].name = "PCMCIA CD0"; | 34 | if (err) |
30 | skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0; | 35 | goto err00; |
31 | skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0"; | 36 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0); |
37 | if (err) | ||
38 | goto err01; | ||
39 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0); | ||
32 | 40 | ||
33 | err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); | 41 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0"); |
34 | if (err) | 42 | if (err) |
35 | goto err01; | 43 | goto err01; |
44 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0); | ||
45 | if (err) | ||
46 | goto err02; | ||
47 | irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0); | ||
48 | |||
49 | err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); | ||
50 | if (err) | ||
51 | goto err02; | ||
36 | err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0); | 52 | err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0); |
37 | if (err) | 53 | if (err) |
38 | goto err03; | 54 | goto err03; |
@@ -54,12 +70,30 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
54 | err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0); | 70 | err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0); |
55 | if (err) | 71 | if (err) |
56 | goto err06; | 72 | goto err06; |
73 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
74 | if (err) | ||
75 | goto err06; | ||
57 | break; | 76 | break; |
58 | case 1: | 77 | case 1: |
59 | skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1; | 78 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1"); |
60 | skt->stat[SOC_STAT_CD].name = "PCMCIA CD1"; | 79 | if (err) |
61 | skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1; | 80 | goto err10; |
62 | skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1"; | 81 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1); |
82 | if (err) | ||
83 | goto err11; | ||
84 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1); | ||
85 | |||
86 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1"); | ||
87 | if (err) | ||
88 | goto err11; | ||
89 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1); | ||
90 | if (err) | ||
91 | goto err12; | ||
92 | irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1); | ||
93 | |||
94 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
95 | if (err) | ||
96 | goto err12; | ||
63 | break; | 97 | break; |
64 | } | 98 | } |
65 | return 0; | 99 | return 0; |
@@ -68,12 +102,19 @@ err06: gpio_free(H3XXX_EGPIO_CARD_RESET); | |||
68 | err05: gpio_free(H3XXX_EGPIO_OPT_RESET); | 102 | err05: gpio_free(H3XXX_EGPIO_OPT_RESET); |
69 | err04: gpio_free(H3XXX_EGPIO_OPT_ON); | 103 | err04: gpio_free(H3XXX_EGPIO_OPT_ON); |
70 | err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); | 104 | err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); |
105 | err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0); | ||
71 | err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | 106 | err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); |
72 | return err; | 107 | err00: return err; |
108 | |||
109 | err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0); | ||
110 | err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | ||
111 | err10: return err; | ||
73 | } | 112 | } |
74 | 113 | ||
75 | static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 114 | static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
76 | { | 115 | { |
116 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
117 | |||
77 | switch (skt->nr) { | 118 | switch (skt->nr) { |
78 | case 0: | 119 | case 0: |
79 | /* Disable CF bus: */ | 120 | /* Disable CF bus: */ |
@@ -85,8 +126,12 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
85 | gpio_free(H3XXX_EGPIO_OPT_RESET); | 126 | gpio_free(H3XXX_EGPIO_OPT_RESET); |
86 | gpio_free(H3XXX_EGPIO_OPT_ON); | 127 | gpio_free(H3XXX_EGPIO_OPT_ON); |
87 | gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); | 128 | gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); |
129 | gpio_free(H3XXX_GPIO_PCMCIA_CD0); | ||
130 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | ||
88 | break; | 131 | break; |
89 | case 1: | 132 | case 1: |
133 | gpio_free(H3XXX_GPIO_PCMCIA_CD1); | ||
134 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ1); | ||
90 | break; | 135 | break; |
91 | } | 136 | } |
92 | } | 137 | } |
@@ -94,10 +139,27 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
94 | static void | 139 | static void |
95 | h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 140 | h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
96 | { | 141 | { |
97 | state->bvd1 = 0; | 142 | switch (skt->nr) { |
98 | state->bvd2 = 0; | 143 | case 0: |
99 | state->vs_3v = 0; | 144 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0); |
100 | state->vs_Xv = 0; | 145 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0); |
146 | state->bvd1 = 0; | ||
147 | state->bvd2 = 0; | ||
148 | state->wrprot = 0; /* Not available on H3600. */ | ||
149 | state->vs_3v = 0; | ||
150 | state->vs_Xv = 0; | ||
151 | break; | ||
152 | |||
153 | case 1: | ||
154 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1); | ||
155 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1); | ||
156 | state->bvd1 = 0; | ||
157 | state->bvd2 = 0; | ||
158 | state->wrprot = 0; /* Not available on H3600. */ | ||
159 | state->vs_3v = 0; | ||
160 | state->vs_Xv = 0; | ||
161 | break; | ||
162 | } | ||
101 | } | 163 | } |
102 | 164 | ||
103 | static int | 165 | static int |
@@ -124,10 +186,14 @@ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | |||
124 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0); | 186 | gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0); |
125 | 187 | ||
126 | msleep(10); | 188 | msleep(10); |
189 | |||
190 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
127 | } | 191 | } |
128 | 192 | ||
129 | static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 193 | static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
130 | { | 194 | { |
195 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
196 | |||
131 | /* | 197 | /* |
132 | * FIXME: This doesn't fit well. We don't have the mechanism in | 198 | * FIXME: This doesn't fit well. We don't have the mechanism in |
133 | * the generic PCMCIA layer to deal with the idea of two sockets | 199 | * the generic PCMCIA layer to deal with the idea of two sockets |
@@ -153,7 +219,7 @@ struct pcmcia_low_level h3600_pcmcia_ops = { | |||
153 | .socket_suspend = h3600_pcmcia_socket_suspend, | 219 | .socket_suspend = h3600_pcmcia_socket_suspend, |
154 | }; | 220 | }; |
155 | 221 | ||
156 | int pcmcia_h3600_init(struct device *dev) | 222 | int __devinit pcmcia_h3600_init(struct device *dev) |
157 | { | 223 | { |
158 | int ret = -ENODEV; | 224 | int ret = -ENODEV; |
159 | 225 | ||
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c index 35c30ff41e8..93b9c9ba57c 100644 --- a/drivers/pcmcia/sa1100_nanoengine.c +++ b/drivers/pcmcia/sa1100_nanoengine.c | |||
@@ -19,7 +19,6 @@ | |||
19 | */ | 19 | */ |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/gpio.h> | ||
23 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
24 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
25 | #include <linux/init.h> | 24 | #include <linux/init.h> |
@@ -35,23 +34,43 @@ | |||
35 | 34 | ||
36 | #include "sa1100_generic.h" | 35 | #include "sa1100_generic.h" |
37 | 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 | |||
38 | struct nanoengine_pins { | 47 | struct nanoengine_pins { |
48 | unsigned input_pins; | ||
39 | unsigned output_pins; | 49 | unsigned output_pins; |
40 | unsigned clear_outputs; | 50 | unsigned clear_outputs; |
41 | int gpio_rst; | 51 | unsigned transition_pins; |
42 | int gpio_cd; | 52 | unsigned pci_irq; |
43 | int gpio_rdy; | 53 | struct pcmcia_irqs *pcmcia_irqs; |
54 | unsigned pcmcia_irqs_size; | ||
44 | }; | 55 | }; |
45 | 56 | ||
46 | static struct nanoengine_pins nano_skts[] = { | 57 | static struct nanoengine_pins nano_skts[] = { |
47 | { | 58 | { |
48 | .gpio_rst = GPIO_PC_RESET0, | 59 | .input_pins = GPIO_PC_READY0 | GPIO_PC_CD0, |
49 | .gpio_cd = GPIO_PC_CD0, | 60 | .output_pins = GPIO_PC_RESET0, |
50 | .gpio_rdy = GPIO_PC_READY0, | 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) | ||
51 | }, { | 66 | }, { |
52 | .gpio_rst = GPIO_PC_RESET1, | 67 | .input_pins = GPIO_PC_READY1 | GPIO_PC_CD1, |
53 | .gpio_cd = GPIO_PC_CD1, | 68 | .output_pins = GPIO_PC_RESET1, |
54 | .gpio_rdy = GPIO_PC_READY1, | 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) | ||
55 | } | 74 | } |
56 | }; | 75 | }; |
57 | 76 | ||
@@ -60,38 +79,58 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts); | |||
60 | static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 79 | static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
61 | { | 80 | { |
62 | unsigned i = skt->nr; | 81 | unsigned i = skt->nr; |
63 | int ret; | ||
64 | 82 | ||
65 | if (i >= num_nano_pcmcia_sockets) | 83 | if (i >= num_nano_pcmcia_sockets) |
66 | return -ENXIO; | 84 | return -ENXIO; |
67 | 85 | ||
68 | ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW, | 86 | GPDR &= ~nano_skts[i].input_pins; |
69 | i ? "PC RST1" : "PC RST0"); | 87 | GPDR |= nano_skts[i].output_pins; |
70 | if (ret) | 88 | GPCR = nano_skts[i].clear_outputs; |
71 | return ret; | 89 | irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); |
72 | 90 | skt->socket.pci_irq = nano_skts[i].pci_irq; | |
73 | skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd; | ||
74 | skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0"; | ||
75 | skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy; | ||
76 | skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0"; | ||
77 | 91 | ||
78 | return 0; | 92 | return soc_pcmcia_request_irqs(skt, |
93 | nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | ||
79 | } | 94 | } |
80 | 95 | ||
96 | /* | ||
97 | * Release all resources. | ||
98 | */ | ||
81 | static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 99 | static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
82 | { | 100 | { |
83 | gpio_free(nano_skts[skt->nr].gpio_rst); | 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); | ||
84 | } | 108 | } |
85 | 109 | ||
86 | static int nanoengine_pcmcia_configure_socket( | 110 | static int nanoengine_pcmcia_configure_socket( |
87 | struct soc_pcmcia_socket *skt, const socket_state_t *state) | 111 | struct soc_pcmcia_socket *skt, const socket_state_t *state) |
88 | { | 112 | { |
113 | unsigned reset; | ||
89 | unsigned i = skt->nr; | 114 | unsigned i = skt->nr; |
90 | 115 | ||
91 | if (i >= num_nano_pcmcia_sockets) | 116 | if (i >= num_nano_pcmcia_sockets) |
92 | return -ENXIO; | 117 | return -ENXIO; |
93 | 118 | ||
94 | gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET)); | 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; | ||
95 | 134 | ||
96 | return 0; | 135 | return 0; |
97 | } | 136 | } |
@@ -99,17 +138,62 @@ static int nanoengine_pcmcia_configure_socket( | |||
99 | static void nanoengine_pcmcia_socket_state( | 138 | static void nanoengine_pcmcia_socket_state( |
100 | struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 139 | struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
101 | { | 140 | { |
141 | unsigned long levels = GPLR; | ||
102 | unsigned i = skt->nr; | 142 | unsigned i = skt->nr; |
103 | 143 | ||
104 | if (i >= num_nano_pcmcia_sockets) | 144 | if (i >= num_nano_pcmcia_sockets) |
105 | return; | 145 | return; |
106 | 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 | } | ||
107 | state->bvd1 = 1; | 160 | state->bvd1 = 1; |
108 | state->bvd2 = 1; | 161 | state->bvd2 = 1; |
162 | state->wrprot = 0; /* Not available */ | ||
109 | state->vs_3v = 1; /* Can only apply 3.3V */ | 163 | state->vs_3v = 1; /* Can only apply 3.3V */ |
110 | state->vs_Xv = 0; | 164 | state->vs_Xv = 0; |
111 | } | 165 | } |
112 | 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 | |||
113 | static struct pcmcia_low_level nanoengine_pcmcia_ops = { | 197 | static struct pcmcia_low_level nanoengine_pcmcia_ops = { |
114 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
115 | 199 | ||
@@ -118,6 +202,8 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = { | |||
118 | 202 | ||
119 | .configure_socket = nanoengine_pcmcia_configure_socket, | 203 | .configure_socket = nanoengine_pcmcia_configure_socket, |
120 | .socket_state = nanoengine_pcmcia_socket_state, | 204 | .socket_state = nanoengine_pcmcia_socket_state, |
205 | .socket_init = nanoengine_pcmcia_socket_init, | ||
206 | .socket_suspend = nanoengine_pcmcia_socket_suspend, | ||
121 | }; | 207 | }; |
122 | 208 | ||
123 | int pcmcia_nanoengine_init(struct device *dev) | 209 | int pcmcia_nanoengine_init(struct device *dev) |
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c index b07a2dc3296..7ff1b43540b 100644 --- a/drivers/pcmcia/sa1100_shannon.c +++ b/drivers/pcmcia/sa1100_shannon.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/device.h> | 9 | #include <linux/device.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/io.h> | ||
12 | 11 | ||
13 | #include <mach/hardware.h> | 12 | #include <mach/hardware.h> |
14 | #include <asm/mach-types.h> | 13 | #include <asm/mach-types.h> |
@@ -16,35 +15,40 @@ | |||
16 | #include <asm/irq.h> | 15 | #include <asm/irq.h> |
17 | #include "sa1100_generic.h" | 16 | #include "sa1100_generic.h" |
18 | 17 | ||
18 | static struct pcmcia_irqs irqs[] = { | ||
19 | { 0, SHANNON_IRQ_GPIO_EJECT_0, "PCMCIA_CD_0" }, | ||
20 | { 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" }, | ||
21 | }; | ||
22 | |||
19 | static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 23 | static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
20 | { | 24 | { |
21 | /* All those are inputs */ | 25 | /* All those are inputs */ |
22 | GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) | | 26 | GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | |
23 | GPIO_GPIO(SHANNON_GPIO_EJECT_1) | | 27 | SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); |
24 | GPIO_GPIO(SHANNON_GPIO_RDY_0) | | 28 | GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | |
25 | GPIO_GPIO(SHANNON_GPIO_RDY_1)); | 29 | SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); |
26 | |||
27 | if (skt->nr == 0) { | ||
28 | skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0; | ||
29 | skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0"; | ||
30 | skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0; | ||
31 | skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0"; | ||
32 | } else { | ||
33 | skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1; | ||
34 | skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1"; | ||
35 | skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1; | ||
36 | skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1"; | ||
37 | } | ||
38 | 30 | ||
39 | return 0; | 31 | skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; |
32 | |||
33 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
34 | } | ||
35 | |||
36 | static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
37 | { | ||
38 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
40 | } | 39 | } |
41 | 40 | ||
42 | static void | 41 | static void |
43 | shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 42 | shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
44 | struct pcmcia_state *state) | 43 | struct pcmcia_state *state) |
45 | { | 44 | { |
45 | unsigned long levels = GPLR; | ||
46 | |||
46 | switch (skt->nr) { | 47 | switch (skt->nr) { |
47 | case 0: | 48 | case 0: |
49 | state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1; | ||
50 | state->ready = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0; | ||
51 | state->wrprot = 0; /* Not available on Shannon. */ | ||
48 | state->bvd1 = 1; | 52 | state->bvd1 = 1; |
49 | state->bvd2 = 1; | 53 | state->bvd2 = 1; |
50 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ | 54 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ |
@@ -52,6 +56,9 @@ shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | |||
52 | break; | 56 | break; |
53 | 57 | ||
54 | case 1: | 58 | case 1: |
59 | state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1; | ||
60 | state->ready = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0; | ||
61 | state->wrprot = 0; /* Not available on Shannon. */ | ||
55 | state->bvd1 = 1; | 62 | state->bvd1 = 1; |
56 | state->bvd2 = 1; | 63 | state->bvd2 = 1; |
57 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ | 64 | state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ |
@@ -85,14 +92,28 @@ shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
85 | return 0; | 92 | return 0; |
86 | } | 93 | } |
87 | 94 | ||
95 | static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
96 | { | ||
97 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
98 | } | ||
99 | |||
100 | static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
101 | { | ||
102 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
103 | } | ||
104 | |||
88 | static struct pcmcia_low_level shannon_pcmcia_ops = { | 105 | static struct pcmcia_low_level shannon_pcmcia_ops = { |
89 | .owner = THIS_MODULE, | 106 | .owner = THIS_MODULE, |
90 | .hw_init = shannon_pcmcia_hw_init, | 107 | .hw_init = shannon_pcmcia_hw_init, |
108 | .hw_shutdown = shannon_pcmcia_hw_shutdown, | ||
91 | .socket_state = shannon_pcmcia_socket_state, | 109 | .socket_state = shannon_pcmcia_socket_state, |
92 | .configure_socket = shannon_pcmcia_configure_socket, | 110 | .configure_socket = shannon_pcmcia_configure_socket, |
111 | |||
112 | .socket_init = shannon_pcmcia_socket_init, | ||
113 | .socket_suspend = shannon_pcmcia_socket_suspend, | ||
93 | }; | 114 | }; |
94 | 115 | ||
95 | int pcmcia_shannon_init(struct device *dev) | 116 | int __devinit pcmcia_shannon_init(struct device *dev) |
96 | { | 117 | { |
97 | int ret = -ENODEV; | 118 | int ret = -ENODEV; |
98 | 119 | ||
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c index 73fd37968b6..c998f7aaadb 100644 --- a/drivers/pcmcia/sa1100_simpad.c +++ b/drivers/pcmcia/sa1100_simpad.c | |||
@@ -15,40 +15,47 @@ | |||
15 | #include <mach/simpad.h> | 15 | #include <mach/simpad.h> |
16 | #include "sa1100_generic.h" | 16 | #include "sa1100_generic.h" |
17 | 17 | ||
18 | extern long get_cs3_shadow(void); | ||
19 | extern void set_cs3_bit(int value); | ||
20 | extern void clear_cs3_bit(int value); | ||
21 | |||
22 | static struct pcmcia_irqs irqs[] = { | ||
23 | { 1, IRQ_GPIO_CF_CD, "CF_CD" }, | ||
24 | }; | ||
25 | |||
18 | static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 26 | static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
19 | { | 27 | { |
20 | 28 | ||
21 | simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); | 29 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); |
22 | 30 | ||
23 | skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD; | 31 | skt->socket.pci_irq = IRQ_GPIO_CF_IRQ; |
24 | skt->stat[SOC_STAT_CD].name = "CF_CD"; | ||
25 | skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ; | ||
26 | skt->stat[SOC_STAT_RDY].name = "CF_RDY"; | ||
27 | 32 | ||
28 | return 0; | 33 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
29 | } | 34 | } |
30 | 35 | ||
31 | static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 36 | static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
32 | { | 37 | { |
38 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
39 | |||
33 | /* Disable CF bus: */ | 40 | /* Disable CF bus: */ |
34 | /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/ | 41 | //set_cs3_bit(PCMCIA_BUFF_DIS); |
35 | simpad_clear_cs3_bit(PCMCIA_RESET); | 42 | clear_cs3_bit(PCMCIA_RESET); |
36 | } | 43 | } |
37 | 44 | ||
38 | static void | 45 | static void |
39 | simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 46 | simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, |
40 | struct pcmcia_state *state) | 47 | struct pcmcia_state *state) |
41 | { | 48 | { |
42 | long cs3reg = simpad_get_cs3_ro(); | 49 | unsigned long levels = GPLR; |
43 | 50 | long cs3reg = get_cs3_shadow(); | |
44 | /* the detect signal is inverted - fix that up here */ | 51 | |
45 | state->detect = !state->detect; | 52 | state->detect=((levels & GPIO_CF_CD)==0)?1:0; |
46 | 53 | state->ready=(levels & GPIO_CF_IRQ)?1:0; | |
47 | state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ | 54 | state->bvd1=1; /* Not available on Simpad. */ |
48 | state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ | 55 | state->bvd2=1; /* Not available on Simpad. */ |
49 | 56 | state->wrprot=0; /* Not available on Simpad. */ | |
50 | if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) == | 57 | |
51 | (PCMCIA_VS1|PCMCIA_VS2)) { | 58 | if((cs3reg & 0x0c) == 0x0c) { |
52 | state->vs_3v=0; | 59 | state->vs_3v=0; |
53 | state->vs_Xv=0; | 60 | state->vs_Xv=0; |
54 | } else { | 61 | } else { |
@@ -68,23 +75,23 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
68 | /* Murphy: see table of MIC2562a-1 */ | 75 | /* Murphy: see table of MIC2562a-1 */ |
69 | switch (state->Vcc) { | 76 | switch (state->Vcc) { |
70 | case 0: | 77 | case 0: |
71 | simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); | 78 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); |
72 | break; | 79 | break; |
73 | 80 | ||
74 | case 33: | 81 | case 33: |
75 | simpad_clear_cs3_bit(VCC_3V_EN|EN1); | 82 | clear_cs3_bit(VCC_3V_EN|EN1); |
76 | simpad_set_cs3_bit(VCC_5V_EN|EN0); | 83 | set_cs3_bit(VCC_5V_EN|EN0); |
77 | break; | 84 | break; |
78 | 85 | ||
79 | case 50: | 86 | case 50: |
80 | simpad_clear_cs3_bit(VCC_5V_EN|EN1); | 87 | clear_cs3_bit(VCC_5V_EN|EN1); |
81 | simpad_set_cs3_bit(VCC_3V_EN|EN0); | 88 | set_cs3_bit(VCC_3V_EN|EN0); |
82 | break; | 89 | break; |
83 | 90 | ||
84 | default: | 91 | default: |
85 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | 92 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", |
86 | __func__, state->Vcc); | 93 | __func__, state->Vcc); |
87 | simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); | 94 | clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); |
88 | local_irq_restore(flags); | 95 | local_irq_restore(flags); |
89 | return -1; | 96 | return -1; |
90 | } | 97 | } |
@@ -95,9 +102,15 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
95 | return 0; | 102 | return 0; |
96 | } | 103 | } |
97 | 104 | ||
105 | static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
106 | { | ||
107 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
108 | } | ||
109 | |||
98 | static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 110 | static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) |
99 | { | 111 | { |
100 | simpad_set_cs3_bit(PCMCIA_RESET); | 112 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
113 | set_cs3_bit(PCMCIA_RESET); | ||
101 | } | 114 | } |
102 | 115 | ||
103 | static struct pcmcia_low_level simpad_pcmcia_ops = { | 116 | static struct pcmcia_low_level simpad_pcmcia_ops = { |
@@ -106,10 +119,11 @@ static struct pcmcia_low_level simpad_pcmcia_ops = { | |||
106 | .hw_shutdown = simpad_pcmcia_hw_shutdown, | 119 | .hw_shutdown = simpad_pcmcia_hw_shutdown, |
107 | .socket_state = simpad_pcmcia_socket_state, | 120 | .socket_state = simpad_pcmcia_socket_state, |
108 | .configure_socket = simpad_pcmcia_configure_socket, | 121 | .configure_socket = simpad_pcmcia_configure_socket, |
122 | .socket_init = simpad_pcmcia_socket_init, | ||
109 | .socket_suspend = simpad_pcmcia_socket_suspend, | 123 | .socket_suspend = simpad_pcmcia_socket_suspend, |
110 | }; | 124 | }; |
111 | 125 | ||
112 | int pcmcia_simpad_init(struct device *dev) | 126 | int __devinit pcmcia_simpad_init(struct device *dev) |
113 | { | 127 | { |
114 | int ret = -ENODEV; | 128 | int ret = -ENODEV; |
115 | 129 | ||
diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c deleted file mode 100644 index 4d206f4dd67..00000000000 --- a/drivers/pcmcia/sa1111_badge4.c +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/pcmcia/sa1100_badge4.c | ||
3 | * | ||
4 | * BadgePAD 4 PCMCIA specific routines | ||
5 | * | ||
6 | * Christopher Hoover <ch@hpl.hp.com> | ||
7 | * | ||
8 | * Copyright (C) 2002 Hewlett-Packard Company | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/init.h> | ||
20 | |||
21 | #include <mach/hardware.h> | ||
22 | #include <asm/mach-types.h> | ||
23 | #include <mach/badge4.h> | ||
24 | #include <asm/hardware/sa1111.h> | ||
25 | |||
26 | #include "sa1111_generic.h" | ||
27 | |||
28 | /* | ||
29 | * BadgePAD 4 Details | ||
30 | * | ||
31 | * PCM Vcc: | ||
32 | * | ||
33 | * PCM Vcc on BadgePAD 4 can be jumpered for 3v3 (short pins 1 and 3 | ||
34 | * on JP6) or 5v0 (short pins 3 and 5 on JP6). | ||
35 | * | ||
36 | * PCM Vpp: | ||
37 | * | ||
38 | * PCM Vpp on BadgePAD 4 can be jumpered for 12v0 (short pins 4 and 6 | ||
39 | * on JP6) or tied to PCM Vcc (short pins 2 and 4 on JP6). N.B., | ||
40 | * 12v0 operation requires that the power supply actually supply 12v0 | ||
41 | * via pin 7 of JP7. | ||
42 | * | ||
43 | * CF Vcc: | ||
44 | * | ||
45 | * CF Vcc on BadgePAD 4 can be jumpered either for 3v3 (short pins 1 | ||
46 | * and 2 on JP10) or 5v0 (short pins 2 and 3 on JP10). | ||
47 | * | ||
48 | * Unfortunately there's no way programmatically to determine how a | ||
49 | * given board is jumpered. This code assumes a default jumpering | ||
50 | * as described below. | ||
51 | * | ||
52 | * If the defaults aren't correct, you may override them with a pcmv | ||
53 | * setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf vcc>. The units are | ||
54 | * tenths of volts; e.g. pcmv=33,120,50 indicates 3v3 PCM Vcc, 12v0 | ||
55 | * PCM Vpp, and 5v0 CF Vcc. | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | static int badge4_pcmvcc = 50; /* pins 3 and 5 jumpered on JP6 */ | ||
60 | static int badge4_pcmvpp = 50; /* pins 2 and 4 jumpered on JP6 */ | ||
61 | static int badge4_cfvcc = 33; /* pins 1 and 2 jumpered on JP10 */ | ||
62 | |||
63 | static void complain_about_jumpering(const char *whom, | ||
64 | const char *supply, | ||
65 | int given, int wanted) | ||
66 | { | ||
67 | printk(KERN_ERR | ||
68 | "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation" | ||
69 | "; re-jumper the board and/or use pcmv=xx,xx,xx\n", | ||
70 | whom, supply, | ||
71 | wanted / 10, wanted % 10, | ||
72 | supply, | ||
73 | given / 10, given % 10); | ||
74 | } | ||
75 | |||
76 | static int | ||
77 | badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | ||
78 | { | ||
79 | int ret; | ||
80 | |||
81 | switch (skt->nr) { | ||
82 | case 0: | ||
83 | if ((state->Vcc != 0) && | ||
84 | (state->Vcc != badge4_pcmvcc)) { | ||
85 | complain_about_jumpering(__func__, "pcmvcc", | ||
86 | badge4_pcmvcc, state->Vcc); | ||
87 | // Apply power regardless of the jumpering. | ||
88 | // return -1; | ||
89 | } | ||
90 | if ((state->Vpp != 0) && | ||
91 | (state->Vpp != badge4_pcmvpp)) { | ||
92 | complain_about_jumpering(__func__, "pcmvpp", | ||
93 | badge4_pcmvpp, state->Vpp); | ||
94 | return -1; | ||
95 | } | ||
96 | break; | ||
97 | |||
98 | case 1: | ||
99 | if ((state->Vcc != 0) && | ||
100 | (state->Vcc != badge4_cfvcc)) { | ||
101 | complain_about_jumpering(__func__, "cfvcc", | ||
102 | badge4_cfvcc, state->Vcc); | ||
103 | return -1; | ||
104 | } | ||
105 | break; | ||
106 | |||
107 | default: | ||
108 | return -1; | ||
109 | } | ||
110 | |||
111 | ret = sa1111_pcmcia_configure_socket(skt, state); | ||
112 | if (ret == 0) { | ||
113 | unsigned long flags; | ||
114 | int need5V; | ||
115 | |||
116 | local_irq_save(flags); | ||
117 | |||
118 | need5V = ((state->Vcc == 50) || (state->Vpp == 50)); | ||
119 | |||
120 | badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V); | ||
121 | |||
122 | local_irq_restore(flags); | ||
123 | } | ||
124 | |||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | static struct pcmcia_low_level badge4_pcmcia_ops = { | ||
129 | .owner = THIS_MODULE, | ||
130 | .configure_socket = badge4_pcmcia_configure_socket, | ||
131 | .first = 0, | ||
132 | .nr = 2, | ||
133 | }; | ||
134 | |||
135 | int pcmcia_badge4_init(struct device *dev) | ||
136 | { | ||
137 | int ret = -ENODEV; | ||
138 | |||
139 | if (machine_is_badge4()) { | ||
140 | printk(KERN_INFO | ||
141 | "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", | ||
142 | __func__, | ||
143 | badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); | ||
144 | |||
145 | sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); | ||
146 | ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, | ||
147 | sa11xx_drv_pcmcia_add_one); | ||
148 | } | ||
149 | |||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | static int __init pcmv_setup(char *s) | ||
154 | { | ||
155 | int v[4]; | ||
156 | |||
157 | s = get_options(s, ARRAY_SIZE(v), v); | ||
158 | |||
159 | if (v[0] >= 1) badge4_pcmvcc = v[1]; | ||
160 | if (v[0] >= 2) badge4_pcmvpp = v[2]; | ||
161 | if (v[0] >= 3) badge4_cfvcc = v[3]; | ||
162 | |||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | __setup("pcmv=", pcmv_setup); | ||
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 65b02c3e14c..59866905ea3 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c | |||
@@ -22,40 +22,6 @@ | |||
22 | 22 | ||
23 | #include "sa1111_generic.h" | 23 | #include "sa1111_generic.h" |
24 | 24 | ||
25 | /* | ||
26 | * These are offsets from the above base. | ||
27 | */ | ||
28 | #define PCCR 0x0000 | ||
29 | #define PCSSR 0x0004 | ||
30 | #define PCSR 0x0008 | ||
31 | |||
32 | #define PCSR_S0_READY (1<<0) | ||
33 | #define PCSR_S1_READY (1<<1) | ||
34 | #define PCSR_S0_DETECT (1<<2) | ||
35 | #define PCSR_S1_DETECT (1<<3) | ||
36 | #define PCSR_S0_VS1 (1<<4) | ||
37 | #define PCSR_S0_VS2 (1<<5) | ||
38 | #define PCSR_S1_VS1 (1<<6) | ||
39 | #define PCSR_S1_VS2 (1<<7) | ||
40 | #define PCSR_S0_WP (1<<8) | ||
41 | #define PCSR_S1_WP (1<<9) | ||
42 | #define PCSR_S0_BVD1 (1<<10) | ||
43 | #define PCSR_S0_BVD2 (1<<11) | ||
44 | #define PCSR_S1_BVD1 (1<<12) | ||
45 | #define PCSR_S1_BVD2 (1<<13) | ||
46 | |||
47 | #define PCCR_S0_RST (1<<0) | ||
48 | #define PCCR_S1_RST (1<<1) | ||
49 | #define PCCR_S0_FLT (1<<2) | ||
50 | #define PCCR_S1_FLT (1<<3) | ||
51 | #define PCCR_S0_PWAITEN (1<<4) | ||
52 | #define PCCR_S1_PWAITEN (1<<5) | ||
53 | #define PCCR_S0_PSE (1<<6) | ||
54 | #define PCCR_S1_PSE (1<<7) | ||
55 | |||
56 | #define PCSSR_S0_SLEEP (1<<0) | ||
57 | #define PCSSR_S1_SLEEP (1<<1) | ||
58 | |||
59 | #define IDX_IRQ_S0_READY_NINT (0) | 25 | #define IDX_IRQ_S0_READY_NINT (0) |
60 | #define IDX_IRQ_S0_CD_VALID (1) | 26 | #define IDX_IRQ_S0_CD_VALID (1) |
61 | #define IDX_IRQ_S0_BVD1_STSCHG (2) | 27 | #define IDX_IRQ_S0_BVD1_STSCHG (2) |
@@ -63,10 +29,27 @@ | |||
63 | #define IDX_IRQ_S1_CD_VALID (4) | 29 | #define IDX_IRQ_S1_CD_VALID (4) |
64 | #define IDX_IRQ_S1_BVD1_STSCHG (5) | 30 | #define IDX_IRQ_S1_BVD1_STSCHG (5) |
65 | 31 | ||
32 | static struct pcmcia_irqs irqs[] = { | ||
33 | { 0, NO_IRQ, "SA1111 PCMCIA card detect" }, | ||
34 | { 0, NO_IRQ, "SA1111 PCMCIA BVD1" }, | ||
35 | { 1, NO_IRQ, "SA1111 CF card detect" }, | ||
36 | { 1, NO_IRQ, "SA1111 CF BVD1" }, | ||
37 | }; | ||
38 | |||
39 | static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
40 | { | ||
41 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
42 | } | ||
43 | |||
44 | static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
45 | { | ||
46 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
47 | } | ||
48 | |||
66 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 49 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
67 | { | 50 | { |
68 | struct sa1111_pcmcia_socket *s = to_skt(skt); | 51 | struct sa1111_pcmcia_socket *s = to_skt(skt); |
69 | unsigned long status = sa1111_readl(s->dev->mapbase + PCSR); | 52 | unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR); |
70 | 53 | ||
71 | switch (skt->nr) { | 54 | switch (skt->nr) { |
72 | case 0: | 55 | case 0: |
@@ -122,22 +105,35 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s | |||
122 | pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; | 105 | pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; |
123 | 106 | ||
124 | local_irq_save(flags); | 107 | local_irq_save(flags); |
125 | val = sa1111_readl(s->dev->mapbase + PCCR); | 108 | val = sa1111_readl(s->dev->mapbase + SA1111_PCCR); |
126 | val &= ~pccr_skt_mask; | 109 | val &= ~pccr_skt_mask; |
127 | val |= pccr_set_mask & pccr_skt_mask; | 110 | val |= pccr_set_mask & pccr_skt_mask; |
128 | sa1111_writel(val, s->dev->mapbase + PCCR); | 111 | sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); |
129 | local_irq_restore(flags); | 112 | local_irq_restore(flags); |
130 | 113 | ||
131 | return 0; | 114 | return 0; |
132 | } | 115 | } |
133 | 116 | ||
117 | void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
118 | { | ||
119 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
120 | } | ||
121 | |||
122 | static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
123 | { | ||
124 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
125 | } | ||
126 | |||
134 | int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | 127 | int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, |
135 | int (*add)(struct soc_pcmcia_socket *)) | 128 | int (*add)(struct soc_pcmcia_socket *)) |
136 | { | 129 | { |
137 | struct sa1111_pcmcia_socket *s; | 130 | struct sa1111_pcmcia_socket *s; |
138 | int i, ret = 0; | 131 | int i, ret = 0; |
139 | 132 | ||
133 | ops->hw_init = sa1111_pcmcia_hw_init; | ||
134 | ops->hw_shutdown = sa1111_pcmcia_hw_shutdown; | ||
140 | ops->socket_state = sa1111_pcmcia_socket_state; | 135 | ops->socket_state = sa1111_pcmcia_socket_state; |
136 | ops->socket_suspend = sa1111_pcmcia_socket_suspend; | ||
141 | 137 | ||
142 | for (i = 0; i < ops->nr; i++) { | 138 | for (i = 0; i < ops->nr; i++) { |
143 | s = kzalloc(sizeof(*s), GFP_KERNEL); | 139 | s = kzalloc(sizeof(*s), GFP_KERNEL); |
@@ -145,21 +141,13 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | |||
145 | return -ENOMEM; | 141 | return -ENOMEM; |
146 | 142 | ||
147 | s->soc.nr = ops->first + i; | 143 | s->soc.nr = ops->first + i; |
148 | soc_pcmcia_init_one(&s->soc, ops, &dev->dev); | 144 | s->soc.ops = ops; |
145 | s->soc.socket.owner = ops->owner; | ||
146 | s->soc.socket.dev.parent = &dev->dev; | ||
147 | s->soc.socket.pci_irq = s->soc.nr ? | ||
148 | dev->irq[IDX_IRQ_S0_READY_NINT] : | ||
149 | dev->irq[IDX_IRQ_S1_READY_NINT]; | ||
149 | s->dev = dev; | 150 | s->dev = dev; |
150 | if (s->soc.nr) { | ||
151 | s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT]; | ||
152 | s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; | ||
153 | s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect"; | ||
154 | s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; | ||
155 | s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1"; | ||
156 | } else { | ||
157 | s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT]; | ||
158 | s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; | ||
159 | s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect"; | ||
160 | s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; | ||
161 | s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1"; | ||
162 | } | ||
163 | 151 | ||
164 | ret = add(&s->soc); | 152 | ret = add(&s->soc); |
165 | if (ret == 0) { | 153 | if (ret == 0) { |
@@ -175,26 +163,26 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | |||
175 | static int pcmcia_probe(struct sa1111_dev *dev) | 163 | static int pcmcia_probe(struct sa1111_dev *dev) |
176 | { | 164 | { |
177 | void __iomem *base; | 165 | void __iomem *base; |
178 | int ret; | ||
179 | |||
180 | ret = sa1111_enable_device(dev); | ||
181 | if (ret) | ||
182 | return ret; | ||
183 | 166 | ||
184 | dev_set_drvdata(&dev->dev, NULL); | 167 | dev_set_drvdata(&dev->dev, NULL); |
185 | 168 | ||
186 | if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) { | 169 | if (!request_mem_region(dev->res.start, 512, |
187 | sa1111_disable_device(dev); | 170 | SA1111_DRIVER_NAME(dev))) |
188 | return -EBUSY; | 171 | return -EBUSY; |
189 | } | ||
190 | 172 | ||
191 | base = dev->mapbase; | 173 | base = dev->mapbase; |
192 | 174 | ||
175 | /* Initialize PCMCIA IRQs */ | ||
176 | irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; | ||
177 | irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; | ||
178 | irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; | ||
179 | irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; | ||
180 | |||
193 | /* | 181 | /* |
194 | * Initialise the suspend state. | 182 | * Initialise the suspend state. |
195 | */ | 183 | */ |
196 | sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); | 184 | sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR); |
197 | sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); | 185 | sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR); |
198 | 186 | ||
199 | #ifdef CONFIG_SA1100_BADGE4 | 187 | #ifdef CONFIG_SA1100_BADGE4 |
200 | pcmcia_badge4_init(&dev->dev); | 188 | pcmcia_badge4_init(&dev->dev); |
@@ -211,20 +199,18 @@ static int pcmcia_probe(struct sa1111_dev *dev) | |||
211 | return 0; | 199 | return 0; |
212 | } | 200 | } |
213 | 201 | ||
214 | static int pcmcia_remove(struct sa1111_dev *dev) | 202 | static int __devexit pcmcia_remove(struct sa1111_dev *dev) |
215 | { | 203 | { |
216 | struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev); | 204 | struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev); |
217 | 205 | ||
218 | dev_set_drvdata(&dev->dev, NULL); | 206 | dev_set_drvdata(&dev->dev, NULL); |
219 | 207 | ||
220 | for (; s; s = next) { | 208 | for (; next = s->next, s; s = next) { |
221 | next = s->next; | ||
222 | soc_pcmcia_remove_one(&s->soc); | 209 | soc_pcmcia_remove_one(&s->soc); |
223 | kfree(s); | 210 | kfree(s); |
224 | } | 211 | } |
225 | 212 | ||
226 | release_mem_region(dev->res.start, 512); | 213 | release_mem_region(dev->res.start, 512); |
227 | sa1111_disable_device(dev); | ||
228 | return 0; | 214 | return 0; |
229 | } | 215 | } |
230 | 216 | ||
@@ -234,7 +220,7 @@ static struct sa1111_driver pcmcia_driver = { | |||
234 | }, | 220 | }, |
235 | .devid = SA1111_DEVID_PCMCIA, | 221 | .devid = SA1111_DEVID_PCMCIA, |
236 | .probe = pcmcia_probe, | 222 | .probe = pcmcia_probe, |
237 | .remove = pcmcia_remove, | 223 | .remove = __devexit_p(pcmcia_remove), |
238 | }; | 224 | }; |
239 | 225 | ||
240 | static int __init sa1111_drv_pcmcia_init(void) | 226 | static int __init sa1111_drv_pcmcia_init(void) |
diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h index f6376e34a7e..02dc8577cda 100644 --- a/drivers/pcmcia/sa1111_generic.h +++ b/drivers/pcmcia/sa1111_generic.h | |||
@@ -17,6 +17,7 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | |||
17 | 17 | ||
18 | extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); | 18 | extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); |
19 | extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); | 19 | extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); |
20 | extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *); | ||
20 | 21 | ||
21 | extern int pcmcia_badge4_init(struct device *); | 22 | extern int pcmcia_badge4_init(struct device *); |
22 | extern int pcmcia_jornada720_init(struct device *); | 23 | extern int pcmcia_jornada720_init(struct device *); |
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c deleted file mode 100644 index 3baa3ef0968..00000000000 --- a/drivers/pcmcia/sa1111_jornada720.c +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/pcmcia/sa1100_jornada720.c | ||
3 | * | ||
4 | * Jornada720 PCMCIA specific routines | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/device.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/init.h> | ||
12 | |||
13 | #include <mach/hardware.h> | ||
14 | #include <asm/hardware/sa1111.h> | ||
15 | #include <asm/mach-types.h> | ||
16 | |||
17 | #include "sa1111_generic.h" | ||
18 | |||
19 | /* Does SOCKET1_3V actually do anything? */ | ||
20 | #define SOCKET0_POWER GPIO_GPIO0 | ||
21 | #define SOCKET0_3V GPIO_GPIO2 | ||
22 | #define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3) | ||
23 | #define SOCKET1_3V GPIO_GPIO3 | ||
24 | |||
25 | static int | ||
26 | jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | ||
27 | { | ||
28 | struct sa1111_pcmcia_socket *s = to_skt(skt); | ||
29 | unsigned int pa_dwr_mask, pa_dwr_set; | ||
30 | int ret; | ||
31 | |||
32 | printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__, | ||
33 | skt->nr, state->Vcc, state->Vpp); | ||
34 | |||
35 | switch (skt->nr) { | ||
36 | case 0: | ||
37 | pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V; | ||
38 | |||
39 | switch (state->Vcc) { | ||
40 | default: | ||
41 | case 0: | ||
42 | pa_dwr_set = 0; | ||
43 | break; | ||
44 | case 33: | ||
45 | pa_dwr_set = SOCKET0_POWER | SOCKET0_3V; | ||
46 | break; | ||
47 | case 50: | ||
48 | pa_dwr_set = SOCKET0_POWER; | ||
49 | break; | ||
50 | } | ||
51 | break; | ||
52 | |||
53 | case 1: | ||
54 | pa_dwr_mask = SOCKET1_POWER; | ||
55 | |||
56 | switch (state->Vcc) { | ||
57 | default: | ||
58 | case 0: | ||
59 | pa_dwr_set = 0; | ||
60 | break; | ||
61 | case 33: | ||
62 | pa_dwr_set = SOCKET1_POWER; | ||
63 | break; | ||
64 | case 50: | ||
65 | pa_dwr_set = SOCKET1_POWER; | ||
66 | break; | ||
67 | } | ||
68 | break; | ||
69 | |||
70 | default: | ||
71 | return -1; | ||
72 | } | ||
73 | |||
74 | if (state->Vpp != state->Vcc && state->Vpp != 0) { | ||
75 | printk(KERN_ERR "%s(): slot cannot support VPP %u\n", | ||
76 | __func__, state->Vpp); | ||
77 | return -EPERM; | ||
78 | } | ||
79 | |||
80 | ret = sa1111_pcmcia_configure_socket(skt, state); | ||
81 | if (ret == 0) | ||
82 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); | ||
83 | |||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | static struct pcmcia_low_level jornada720_pcmcia_ops = { | ||
88 | .owner = THIS_MODULE, | ||
89 | .configure_socket = jornada720_pcmcia_configure_socket, | ||
90 | .first = 0, | ||
91 | .nr = 2, | ||
92 | }; | ||
93 | |||
94 | int pcmcia_jornada720_init(struct device *dev) | ||
95 | { | ||
96 | int ret = -ENODEV; | ||
97 | |||
98 | if (machine_is_jornada720()) { | ||
99 | unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; | ||
100 | |||
101 | GRER |= 0x00000002; | ||
102 | |||
103 | /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ | ||
104 | sa1111_set_io_dir(dev, pin, 0, 0); | ||
105 | sa1111_set_io(dev, pin, 0); | ||
106 | sa1111_set_sleep_io(dev, pin, 0); | ||
107 | |||
108 | sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); | ||
109 | ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops, | ||
110 | sa11xx_drv_pcmcia_add_one); | ||
111 | } | ||
112 | |||
113 | return ret; | ||
114 | } | ||
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c deleted file mode 100644 index c5caf579045..00000000000 --- a/drivers/pcmcia/sa1111_lubbock.c +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/pcmcia/pxa2xx_lubbock.c | ||
3 | * | ||
4 | * Author: George Davis | ||
5 | * Created: Jan 10, 2002 | ||
6 | * Copyright: MontaVista Software Inc. | ||
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 | * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c | ||
13 | * | ||
14 | * Lubbock PCMCIA specific routines. | ||
15 | * | ||
16 | */ | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <asm/hardware/sa1111.h> | ||
26 | #include <asm/mach-types.h> | ||
27 | #include <mach/lubbock.h> | ||
28 | |||
29 | #include "sa1111_generic.h" | ||
30 | |||
31 | static int | ||
32 | lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | ||
33 | const socket_state_t *state) | ||
34 | { | ||
35 | struct sa1111_pcmcia_socket *s = to_skt(skt); | ||
36 | unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set; | ||
37 | int ret = 0; | ||
38 | |||
39 | pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0; | ||
40 | |||
41 | /* Lubbock uses the Maxim MAX1602, with the following connections: | ||
42 | * | ||
43 | * Socket 0 (PCMCIA): | ||
44 | * MAX1602 Lubbock Register | ||
45 | * Pin Signal | ||
46 | * ----- ------- ---------------------- | ||
47 | * A0VPP S0_PWR0 SA-1111 GPIO A<0> | ||
48 | * A1VPP S0_PWR1 SA-1111 GPIO A<1> | ||
49 | * A0VCC S0_PWR2 SA-1111 GPIO A<2> | ||
50 | * A1VCC S0_PWR3 SA-1111 GPIO A<3> | ||
51 | * VX VCC | ||
52 | * VY +3.3V | ||
53 | * 12IN +12V | ||
54 | * CODE +3.3V Cirrus Code, CODE = High (VY) | ||
55 | * | ||
56 | * Socket 1 (CF): | ||
57 | * MAX1602 Lubbock Register | ||
58 | * Pin Signal | ||
59 | * ----- ------- ---------------------- | ||
60 | * A0VPP GND VPP is not connected | ||
61 | * A1VPP GND VPP is not connected | ||
62 | * A0VCC S1_PWR0 MISC_WR<14> | ||
63 | * A1VCC S1_PWR1 MISC_WR<15> | ||
64 | * VX VCC | ||
65 | * VY +3.3V | ||
66 | * 12IN GND VPP is not connected | ||
67 | * CODE +3.3V Cirrus Code, CODE = High (VY) | ||
68 | * | ||
69 | */ | ||
70 | |||
71 | again: | ||
72 | switch (skt->nr) { | ||
73 | case 0: | ||
74 | pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; | ||
75 | |||
76 | switch (state->Vcc) { | ||
77 | case 0: /* Hi-Z */ | ||
78 | break; | ||
79 | |||
80 | case 33: /* VY */ | ||
81 | pa_dwr_set |= GPIO_A3; | ||
82 | break; | ||
83 | |||
84 | case 50: /* VX */ | ||
85 | pa_dwr_set |= GPIO_A2; | ||
86 | break; | ||
87 | |||
88 | default: | ||
89 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | ||
90 | __func__, state->Vcc); | ||
91 | ret = -1; | ||
92 | } | ||
93 | |||
94 | switch (state->Vpp) { | ||
95 | case 0: /* Hi-Z */ | ||
96 | break; | ||
97 | |||
98 | case 120: /* 12IN */ | ||
99 | pa_dwr_set |= GPIO_A1; | ||
100 | break; | ||
101 | |||
102 | default: /* VCC */ | ||
103 | if (state->Vpp == state->Vcc) | ||
104 | pa_dwr_set |= GPIO_A0; | ||
105 | else { | ||
106 | printk(KERN_ERR "%s(): unrecognized Vpp %u\n", | ||
107 | __func__, state->Vpp); | ||
108 | ret = -1; | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | break; | ||
113 | |||
114 | case 1: | ||
115 | misc_mask = (1 << 15) | (1 << 14); | ||
116 | |||
117 | switch (state->Vcc) { | ||
118 | case 0: /* Hi-Z */ | ||
119 | break; | ||
120 | |||
121 | case 33: /* VY */ | ||
122 | misc_set |= 1 << 15; | ||
123 | break; | ||
124 | |||
125 | case 50: /* VX */ | ||
126 | misc_set |= 1 << 14; | ||
127 | break; | ||
128 | |||
129 | default: | ||
130 | printk(KERN_ERR "%s(): unrecognized Vcc %u\n", | ||
131 | __func__, state->Vcc); | ||
132 | ret = -1; | ||
133 | break; | ||
134 | } | ||
135 | |||
136 | if (state->Vpp != state->Vcc && state->Vpp != 0) { | ||
137 | printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", | ||
138 | __func__, state->Vpp); | ||
139 | ret = -1; | ||
140 | break; | ||
141 | } | ||
142 | break; | ||
143 | |||
144 | default: | ||
145 | ret = -1; | ||
146 | } | ||
147 | |||
148 | if (ret == 0) | ||
149 | ret = sa1111_pcmcia_configure_socket(skt, state); | ||
150 | |||
151 | if (ret == 0) { | ||
152 | lubbock_set_misc_wr(misc_mask, misc_set); | ||
153 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); | ||
154 | } | ||
155 | |||
156 | #if 1 | ||
157 | if (ret == 0 && state->Vcc == 33) { | ||
158 | struct pcmcia_state new_state; | ||
159 | |||
160 | /* | ||
161 | * HACK ALERT: | ||
162 | * We can't sense the voltage properly on Lubbock before | ||
163 | * actually applying some power to the socket (catch 22). | ||
164 | * Resense the socket Voltage Sense pins after applying | ||
165 | * socket power. | ||
166 | * | ||
167 | * Note: It takes about 2.5ms for the MAX1602 VCC output | ||
168 | * to rise. | ||
169 | */ | ||
170 | mdelay(3); | ||
171 | |||
172 | sa1111_pcmcia_socket_state(skt, &new_state); | ||
173 | |||
174 | if (!new_state.vs_3v && !new_state.vs_Xv) { | ||
175 | /* | ||
176 | * Switch to 5V, Configure socket with 5V voltage | ||
177 | */ | ||
178 | lubbock_set_misc_wr(misc_mask, 0); | ||
179 | sa1111_set_io(s->dev, pa_dwr_mask, 0); | ||
180 | |||
181 | /* | ||
182 | * It takes about 100ms to turn off Vcc. | ||
183 | */ | ||
184 | mdelay(100); | ||
185 | |||
186 | /* | ||
187 | * We need to hack around the const qualifier as | ||
188 | * well to keep this ugly workaround localized and | ||
189 | * not force it to the rest of the code. Barf bags | ||
190 | * available in the seat pocket in front of you! | ||
191 | */ | ||
192 | ((socket_state_t *)state)->Vcc = 50; | ||
193 | ((socket_state_t *)state)->Vpp = 50; | ||
194 | goto again; | ||
195 | } | ||
196 | } | ||
197 | #endif | ||
198 | |||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | static struct pcmcia_low_level lubbock_pcmcia_ops = { | ||
203 | .owner = THIS_MODULE, | ||
204 | .configure_socket = lubbock_pcmcia_configure_socket, | ||
205 | .first = 0, | ||
206 | .nr = 2, | ||
207 | }; | ||
208 | |||
209 | #include "pxa2xx_base.h" | ||
210 | |||
211 | int pcmcia_lubbock_init(struct sa1111_dev *sadev) | ||
212 | { | ||
213 | int ret = -ENODEV; | ||
214 | |||
215 | if (machine_is_lubbock()) { | ||
216 | /* | ||
217 | * Set GPIO_A<3:0> to be outputs for the MAX1600, | ||
218 | * and switch to standby mode. | ||
219 | */ | ||
220 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); | ||
221 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | ||
222 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | ||
223 | |||
224 | /* Set CF Socket 1 power to standby mode. */ | ||
225 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); | ||
226 | |||
227 | pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); | ||
228 | pxa2xx_configure_sockets(&sadev->dev); | ||
229 | ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, | ||
230 | pxa2xx_drv_pcmcia_add_one); | ||
231 | } | ||
232 | |||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c deleted file mode 100644 index 1d78739c4c0..00000000000 --- a/drivers/pcmcia/sa1111_neponset.c +++ /dev/null | |||
@@ -1,129 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/pcmcia/sa1100_neponset.c | ||
3 | * | ||
4 | * Neponset PCMCIA specific routines | ||
5 | */ | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/device.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/init.h> | ||
11 | |||
12 | #include <mach/hardware.h> | ||
13 | #include <asm/mach-types.h> | ||
14 | #include <mach/neponset.h> | ||
15 | #include <asm/hardware/sa1111.h> | ||
16 | |||
17 | #include "sa1111_generic.h" | ||
18 | |||
19 | /* | ||
20 | * Neponset uses the Maxim MAX1600, with the following connections: | ||
21 | * | ||
22 | * MAX1600 Neponset | ||
23 | * | ||
24 | * A0VCC SA-1111 GPIO A<1> | ||
25 | * A1VCC SA-1111 GPIO A<0> | ||
26 | * A0VPP CPLD NCR A0VPP | ||
27 | * A1VPP CPLD NCR A1VPP | ||
28 | * B0VCC SA-1111 GPIO A<2> | ||
29 | * B1VCC SA-1111 GPIO A<3> | ||
30 | * B0VPP ground (slot B is CF) | ||
31 | * B1VPP ground (slot B is CF) | ||
32 | * | ||
33 | * VX VCC (5V) | ||
34 | * VY VCC3_3 (3.3V) | ||
35 | * 12INA 12V | ||
36 | * 12INB ground (slot B is CF) | ||
37 | * | ||
38 | * The MAX1600 CODE pin is tied to ground, placing the device in | ||
39 | * "Standard Intel code" mode. Refer to the Maxim data sheet for | ||
40 | * the corresponding truth table. | ||
41 | */ | ||
42 | |||
43 | static int | ||
44 | neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) | ||
45 | { | ||
46 | struct sa1111_pcmcia_socket *s = to_skt(skt); | ||
47 | unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set; | ||
48 | int ret; | ||
49 | |||
50 | switch (skt->nr) { | ||
51 | case 0: | ||
52 | pa_dwr_mask = GPIO_A0 | GPIO_A1; | ||
53 | ncr_mask = NCR_A0VPP | NCR_A1VPP; | ||
54 | |||
55 | if (state->Vpp == 0) | ||
56 | ncr_set = 0; | ||
57 | else if (state->Vpp == 120) | ||
58 | ncr_set = NCR_A1VPP; | ||
59 | else if (state->Vpp == state->Vcc) | ||
60 | ncr_set = NCR_A0VPP; | ||
61 | else { | ||
62 | printk(KERN_ERR "%s(): unrecognized VPP %u\n", | ||
63 | __func__, state->Vpp); | ||
64 | return -1; | ||
65 | } | ||
66 | break; | ||
67 | |||
68 | case 1: | ||
69 | pa_dwr_mask = GPIO_A2 | GPIO_A3; | ||
70 | ncr_mask = 0; | ||
71 | ncr_set = 0; | ||
72 | |||
73 | if (state->Vpp != state->Vcc && state->Vpp != 0) { | ||
74 | printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n", | ||
75 | __func__, state->Vpp); | ||
76 | return -1; | ||
77 | } | ||
78 | break; | ||
79 | |||
80 | default: | ||
81 | return -1; | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * pa_dwr_set is the mask for selecting Vcc on both sockets. | ||
86 | * pa_dwr_mask selects which bits (and therefore socket) we change. | ||
87 | */ | ||
88 | switch (state->Vcc) { | ||
89 | default: | ||
90 | case 0: pa_dwr_set = 0; break; | ||
91 | case 33: pa_dwr_set = GPIO_A1|GPIO_A2; break; | ||
92 | case 50: pa_dwr_set = GPIO_A0|GPIO_A3; break; | ||
93 | } | ||
94 | |||
95 | ret = sa1111_pcmcia_configure_socket(skt, state); | ||
96 | if (ret == 0) { | ||
97 | neponset_ncr_frob(ncr_mask, ncr_set); | ||
98 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); | ||
99 | } | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | static struct pcmcia_low_level neponset_pcmcia_ops = { | ||
105 | .owner = THIS_MODULE, | ||
106 | .configure_socket = neponset_pcmcia_configure_socket, | ||
107 | .first = 0, | ||
108 | .nr = 2, | ||
109 | }; | ||
110 | |||
111 | int pcmcia_neponset_init(struct sa1111_dev *sadev) | ||
112 | { | ||
113 | int ret = -ENODEV; | ||
114 | |||
115 | if (machine_is_assabet()) { | ||
116 | /* | ||
117 | * Set GPIO_A<3:0> to be outputs for the MAX1600, | ||
118 | * and switch to standby mode. | ||
119 | */ | ||
120 | sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); | ||
121 | sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | ||
122 | sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); | ||
123 | sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); | ||
124 | ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, | ||
125 | sa11xx_drv_pcmcia_add_one); | ||
126 | } | ||
127 | |||
128 | return ret; | ||
129 | } | ||
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 6eecd7cddf5..0c62fe31a40 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
43 | #include <asm/irq.h> | 43 | #include <asm/irq.h> |
44 | #include <asm/system.h> | ||
44 | 45 | ||
45 | #include "soc_common.h" | 46 | #include "soc_common.h" |
46 | #include "sa11xx_base.h" | 47 | #include "sa11xx_base.h" |
@@ -235,7 +236,10 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
235 | skt = &sinfo->skt[i]; | 236 | skt = &sinfo->skt[i]; |
236 | 237 | ||
237 | skt->nr = first + i; | 238 | skt->nr = first + i; |
238 | soc_pcmcia_init_one(skt, ops, dev); | 239 | skt->ops = ops; |
240 | skt->socket.owner = ops->owner; | ||
241 | skt->socket.dev.parent = dev; | ||
242 | skt->socket.pci_irq = NO_IRQ; | ||
239 | 243 | ||
240 | ret = sa11xx_drv_pcmcia_add_one(skt); | 244 | ret = sa11xx_drv_pcmcia_add_one(skt); |
241 | if (ret) | 245 | if (ret) |
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index a2bc6ee1702..a0a9c2aa8d7 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | 33 | ||
34 | #include <linux/cpufreq.h> | 34 | #include <linux/cpufreq.h> |
35 | #include <linux/gpio.h> | ||
36 | #include <linux/init.h> | 35 | #include <linux/init.h> |
37 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
38 | #include <linux/io.h> | 37 | #include <linux/io.h> |
@@ -46,11 +45,10 @@ | |||
46 | #include <linux/timer.h> | 45 | #include <linux/timer.h> |
47 | 46 | ||
48 | #include <mach/hardware.h> | 47 | #include <mach/hardware.h> |
48 | #include <asm/system.h> | ||
49 | 49 | ||
50 | #include "soc_common.h" | 50 | #include "soc_common.h" |
51 | 51 | ||
52 | static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev); | ||
53 | |||
54 | #ifdef CONFIG_PCMCIA_DEBUG | 52 | #ifdef CONFIG_PCMCIA_DEBUG |
55 | 53 | ||
56 | static int pc_debug; | 54 | static int pc_debug; |
@@ -106,93 +104,6 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, | |||
106 | } | 104 | } |
107 | EXPORT_SYMBOL(soc_common_pcmcia_get_timing); | 105 | EXPORT_SYMBOL(soc_common_pcmcia_get_timing); |
108 | 106 | ||
109 | static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt, | ||
110 | unsigned int nr) | ||
111 | { | ||
112 | unsigned int i; | ||
113 | |||
114 | for (i = 0; i < nr; i++) { | ||
115 | if (skt->stat[i].irq) | ||
116 | free_irq(skt->stat[i].irq, skt); | ||
117 | if (gpio_is_valid(skt->stat[i].gpio)) | ||
118 | gpio_free(skt->stat[i].gpio); | ||
119 | } | ||
120 | |||
121 | if (skt->ops->hw_shutdown) | ||
122 | skt->ops->hw_shutdown(skt); | ||
123 | } | ||
124 | |||
125 | static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
126 | { | ||
127 | __soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat)); | ||
128 | } | ||
129 | |||
130 | static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
131 | { | ||
132 | int ret = 0, i; | ||
133 | |||
134 | if (skt->ops->hw_init) { | ||
135 | ret = skt->ops->hw_init(skt); | ||
136 | if (ret) | ||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) { | ||
141 | if (gpio_is_valid(skt->stat[i].gpio)) { | ||
142 | int irq; | ||
143 | |||
144 | ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN, | ||
145 | skt->stat[i].name); | ||
146 | if (ret) { | ||
147 | __soc_pcmcia_hw_shutdown(skt, i); | ||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | irq = gpio_to_irq(skt->stat[i].gpio); | ||
152 | |||
153 | if (i == SOC_STAT_RDY) | ||
154 | skt->socket.pci_irq = irq; | ||
155 | else | ||
156 | skt->stat[i].irq = irq; | ||
157 | } | ||
158 | |||
159 | if (skt->stat[i].irq) { | ||
160 | ret = request_irq(skt->stat[i].irq, | ||
161 | soc_common_pcmcia_interrupt, | ||
162 | IRQF_TRIGGER_NONE, | ||
163 | skt->stat[i].name, skt); | ||
164 | if (ret) { | ||
165 | if (gpio_is_valid(skt->stat[i].gpio)) | ||
166 | gpio_free(skt->stat[i].gpio); | ||
167 | __soc_pcmcia_hw_shutdown(skt, i); | ||
168 | return ret; | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | |||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt) | ||
177 | { | ||
178 | int i; | ||
179 | |||
180 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) | ||
181 | if (skt->stat[i].irq) { | ||
182 | irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING); | ||
183 | irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt) | ||
188 | { | ||
189 | int i; | ||
190 | |||
191 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) | ||
192 | if (skt->stat[i].irq) | ||
193 | irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE); | ||
194 | } | ||
195 | |||
196 | static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) | 107 | static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) |
197 | { | 108 | { |
198 | struct pcmcia_state state; | 109 | struct pcmcia_state state; |
@@ -200,22 +111,6 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) | |||
200 | 111 | ||
201 | memset(&state, 0, sizeof(struct pcmcia_state)); | 112 | memset(&state, 0, sizeof(struct pcmcia_state)); |
202 | 113 | ||
203 | /* Make battery voltage state report 'good' */ | ||
204 | state.bvd1 = 1; | ||
205 | state.bvd2 = 1; | ||
206 | |||
207 | /* CD is active low by default */ | ||
208 | if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio)) | ||
209 | state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio); | ||
210 | |||
211 | /* RDY and BVD are active high by default */ | ||
212 | if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio)) | ||
213 | state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio); | ||
214 | if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio)) | ||
215 | state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio); | ||
216 | if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio)) | ||
217 | state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio); | ||
218 | |||
219 | skt->ops->socket_state(skt, &state); | 114 | skt->ops->socket_state(skt, &state); |
220 | 115 | ||
221 | stat = state.detect ? SS_DETECT : 0; | 116 | stat = state.detect ? SS_DETECT : 0; |
@@ -293,7 +188,6 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock) | |||
293 | debug(skt, 2, "initializing socket\n"); | 188 | debug(skt, 2, "initializing socket\n"); |
294 | if (skt->ops->socket_init) | 189 | if (skt->ops->socket_init) |
295 | skt->ops->socket_init(skt); | 190 | skt->ops->socket_init(skt); |
296 | soc_pcmcia_hw_enable(skt); | ||
297 | return 0; | 191 | return 0; |
298 | } | 192 | } |
299 | 193 | ||
@@ -313,7 +207,6 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock) | |||
313 | 207 | ||
314 | debug(skt, 2, "suspending socket\n"); | 208 | debug(skt, 2, "suspending socket\n"); |
315 | 209 | ||
316 | soc_pcmcia_hw_disable(skt); | ||
317 | if (skt->ops->socket_suspend) | 210 | if (skt->ops->socket_suspend) |
318 | skt->ops->socket_suspend(skt); | 211 | skt->ops->socket_suspend(skt); |
319 | 212 | ||
@@ -633,6 +526,69 @@ static struct pccard_operations soc_common_pcmcia_operations = { | |||
633 | }; | 526 | }; |
634 | 527 | ||
635 | 528 | ||
529 | int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, | ||
530 | struct pcmcia_irqs *irqs, int nr) | ||
531 | { | ||
532 | int i, res = 0; | ||
533 | |||
534 | for (i = 0; i < nr; i++) { | ||
535 | if (irqs[i].sock != skt->nr) | ||
536 | continue; | ||
537 | res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt, | ||
538 | IRQF_DISABLED, irqs[i].str, skt); | ||
539 | if (res) | ||
540 | break; | ||
541 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); | ||
542 | } | ||
543 | |||
544 | if (res) { | ||
545 | printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n", | ||
546 | irqs[i].irq, res); | ||
547 | |||
548 | while (i--) | ||
549 | if (irqs[i].sock == skt->nr) | ||
550 | free_irq(irqs[i].irq, skt); | ||
551 | } | ||
552 | return res; | ||
553 | } | ||
554 | EXPORT_SYMBOL(soc_pcmcia_request_irqs); | ||
555 | |||
556 | void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, | ||
557 | struct pcmcia_irqs *irqs, int nr) | ||
558 | { | ||
559 | int i; | ||
560 | |||
561 | for (i = 0; i < nr; i++) | ||
562 | if (irqs[i].sock == skt->nr) | ||
563 | free_irq(irqs[i].irq, skt); | ||
564 | } | ||
565 | EXPORT_SYMBOL(soc_pcmcia_free_irqs); | ||
566 | |||
567 | void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, | ||
568 | struct pcmcia_irqs *irqs, int nr) | ||
569 | { | ||
570 | int i; | ||
571 | |||
572 | for (i = 0; i < nr; i++) | ||
573 | if (irqs[i].sock == skt->nr) | ||
574 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); | ||
575 | } | ||
576 | EXPORT_SYMBOL(soc_pcmcia_disable_irqs); | ||
577 | |||
578 | void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, | ||
579 | struct pcmcia_irqs *irqs, int nr) | ||
580 | { | ||
581 | int i; | ||
582 | |||
583 | for (i = 0; i < nr; i++) | ||
584 | if (irqs[i].sock == skt->nr) { | ||
585 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING); | ||
586 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH); | ||
587 | } | ||
588 | } | ||
589 | EXPORT_SYMBOL(soc_pcmcia_enable_irqs); | ||
590 | |||
591 | |||
636 | static LIST_HEAD(soc_pcmcia_sockets); | 592 | static LIST_HEAD(soc_pcmcia_sockets); |
637 | static DEFINE_MUTEX(soc_pcmcia_sockets_lock); | 593 | static DEFINE_MUTEX(soc_pcmcia_sockets_lock); |
638 | 594 | ||
@@ -679,21 +635,6 @@ module_exit(soc_pcmcia_cpufreq_unregister); | |||
679 | 635 | ||
680 | #endif | 636 | #endif |
681 | 637 | ||
682 | void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, | ||
683 | struct pcmcia_low_level *ops, struct device *dev) | ||
684 | { | ||
685 | int i; | ||
686 | |||
687 | skt->ops = ops; | ||
688 | skt->socket.owner = ops->owner; | ||
689 | skt->socket.dev.parent = dev; | ||
690 | skt->socket.pci_irq = NO_IRQ; | ||
691 | |||
692 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) | ||
693 | skt->stat[i].gpio = -EINVAL; | ||
694 | } | ||
695 | EXPORT_SYMBOL(soc_pcmcia_init_one); | ||
696 | |||
697 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) | 638 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) |
698 | { | 639 | { |
699 | mutex_lock(&soc_pcmcia_sockets_lock); | 640 | mutex_lock(&soc_pcmcia_sockets_lock); |
@@ -701,9 +642,8 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) | |||
701 | 642 | ||
702 | pcmcia_unregister_socket(&skt->socket); | 643 | pcmcia_unregister_socket(&skt->socket); |
703 | 644 | ||
704 | soc_pcmcia_hw_shutdown(skt); | 645 | skt->ops->hw_shutdown(skt); |
705 | 646 | ||
706 | /* should not be required; violates some lowlevel drivers */ | ||
707 | soc_common_pcmcia_config_skt(skt, &dead_socket); | 647 | soc_common_pcmcia_config_skt(skt, &dead_socket); |
708 | 648 | ||
709 | list_del(&skt->node); | 649 | list_del(&skt->node); |
@@ -760,7 +700,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) | |||
760 | */ | 700 | */ |
761 | skt->ops->set_timing(skt); | 701 | skt->ops->set_timing(skt); |
762 | 702 | ||
763 | ret = soc_pcmcia_hw_init(skt); | 703 | ret = skt->ops->hw_init(skt); |
764 | if (ret) | 704 | if (ret) |
765 | goto out_err_6; | 705 | goto out_err_6; |
766 | 706 | ||
@@ -793,7 +733,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) | |||
793 | pcmcia_unregister_socket(&skt->socket); | 733 | pcmcia_unregister_socket(&skt->socket); |
794 | 734 | ||
795 | out_err_7: | 735 | out_err_7: |
796 | soc_pcmcia_hw_shutdown(skt); | 736 | skt->ops->hw_shutdown(skt); |
797 | out_err_6: | 737 | out_err_6: |
798 | list_del(&skt->node); | 738 | list_del(&skt->node); |
799 | mutex_unlock(&soc_pcmcia_sockets_lock); | 739 | mutex_unlock(&soc_pcmcia_sockets_lock); |
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index e6fcbea5b68..9daa73615c8 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h | |||
@@ -50,16 +50,6 @@ struct soc_pcmcia_socket { | |||
50 | struct resource res_attr; | 50 | struct resource res_attr; |
51 | void __iomem *virt_io; | 51 | void __iomem *virt_io; |
52 | 52 | ||
53 | struct { | ||
54 | int gpio; | ||
55 | unsigned int irq; | ||
56 | const char *name; | ||
57 | } stat[4]; | ||
58 | #define SOC_STAT_CD 0 /* Card detect */ | ||
59 | #define SOC_STAT_BVD1 1 /* BATDEAD / IOSTSCHG */ | ||
60 | #define SOC_STAT_BVD2 2 /* BATWARN / IOSPKR */ | ||
61 | #define SOC_STAT_RDY 3 /* Ready / Interrupt */ | ||
62 | |||
63 | unsigned int irq_state; | 53 | unsigned int irq_state; |
64 | 54 | ||
65 | struct timer_list poll_timer; | 55 | struct timer_list poll_timer; |
@@ -125,16 +115,25 @@ struct pcmcia_low_level { | |||
125 | }; | 115 | }; |
126 | 116 | ||
127 | 117 | ||
118 | struct pcmcia_irqs { | ||
119 | int sock; | ||
120 | int irq; | ||
121 | const char *str; | ||
122 | }; | ||
123 | |||
128 | struct soc_pcmcia_timing { | 124 | struct soc_pcmcia_timing { |
129 | unsigned short io; | 125 | unsigned short io; |
130 | unsigned short mem; | 126 | unsigned short mem; |
131 | unsigned short attr; | 127 | unsigned short attr; |
132 | }; | 128 | }; |
133 | 129 | ||
130 | extern int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
131 | extern void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
132 | extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
133 | extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
134 | extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); | 134 | extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); |
135 | 135 | ||
136 | void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, | 136 | |
137 | struct pcmcia_low_level *ops, struct device *dev); | ||
138 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); | 137 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); |
139 | int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); | 138 | int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); |
140 | 139 | ||
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index d6881514d38..71aeed93037 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <asm/system.h> | ||
26 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
27 | 28 | ||
28 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index cbe15fc3741..310160bffe3 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/bitops.h> | 47 | #include <linux/bitops.h> |
48 | 48 | ||
49 | #include <asm/io.h> | 49 | #include <asm/io.h> |
50 | #include <asm/system.h> | ||
50 | 51 | ||
51 | #include <pcmcia/ss.h> | 52 | #include <pcmcia/ss.h> |
52 | #include "tcic.h" | 53 | #include "tcic.h" |
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 75806be344e..86e4a1a3c64 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c | |||
@@ -564,7 +564,7 @@ static inline void reserve_using_irq(int slot) | |||
564 | vrc4171_irq_mask &= ~(1 << irq); | 564 | vrc4171_irq_mask &= ~(1 << irq); |
565 | } | 565 | } |
566 | 566 | ||
567 | static int vrc4171_add_sockets(void) | 567 | static int __devinit vrc4171_add_sockets(void) |
568 | { | 568 | { |
569 | vrc4171_socket_t *socket; | 569 | vrc4171_socket_t *socket; |
570 | int slot, retval; | 570 | int slot, retval; |
@@ -631,7 +631,7 @@ static void vrc4171_remove_sockets(void) | |||
631 | } | 631 | } |
632 | } | 632 | } |
633 | 633 | ||
634 | static int vrc4171_card_setup(char *options) | 634 | static int __devinit vrc4171_card_setup(char *options) |
635 | { | 635 | { |
636 | if (options == NULL || *options == '\0') | 636 | if (options == NULL || *options == '\0') |
637 | return 1; | 637 | return 1; |
@@ -712,7 +712,7 @@ static struct platform_driver vrc4171_card_driver = { | |||
712 | }, | 712 | }, |
713 | }; | 713 | }; |
714 | 714 | ||
715 | static int vrc4171_card_init(void) | 715 | static int __devinit vrc4171_card_init(void) |
716 | { | 716 | { |
717 | int retval; | 717 | int retval; |
718 | 718 | ||
@@ -746,7 +746,7 @@ static int vrc4171_card_init(void) | |||
746 | return 0; | 746 | return 0; |
747 | } | 747 | } |
748 | 748 | ||
749 | static void vrc4171_card_exit(void) | 749 | static void __devexit vrc4171_card_exit(void) |
750 | { | 750 | { |
751 | free_irq(vrc4171_irq, vrc4171_sockets); | 751 | free_irq(vrc4171_irq, vrc4171_sockets); |
752 | vrc4171_remove_sockets(); | 752 | vrc4171_remove_sockets(); |
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index d92692056e2..c6d36b3a6ce 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c | |||
@@ -456,7 +456,7 @@ static void cardu_interrupt(int irq, void *dev_id) | |||
456 | } | 456 | } |
457 | } | 457 | } |
458 | 458 | ||
459 | static int vrc4173_cardu_probe(struct pci_dev *dev, | 459 | static int __devinit vrc4173_cardu_probe(struct pci_dev *dev, |
460 | const struct pci_device_id *ent) | 460 | const struct pci_device_id *ent) |
461 | { | 461 | { |
462 | vrc4173_socket_t *socket; | 462 | vrc4173_socket_t *socket; |
@@ -533,7 +533,7 @@ disable: | |||
533 | return ret; | 533 | return ret; |
534 | } | 534 | } |
535 | 535 | ||
536 | static int vrc4173_cardu_setup(char *options) | 536 | static int __devinit vrc4173_cardu_setup(char *options) |
537 | { | 537 | { |
538 | if (options == NULL || *options == '\0') | 538 | if (options == NULL || *options == '\0') |
539 | return 1; | 539 | return 1; |
@@ -563,8 +563,11 @@ static int vrc4173_cardu_setup(char *options) | |||
563 | 563 | ||
564 | __setup("vrc4173_cardu=", vrc4173_cardu_setup); | 564 | __setup("vrc4173_cardu=", vrc4173_cardu_setup); |
565 | 565 | ||
566 | static DEFINE_PCI_DEVICE_TABLE(vrc4173_cardu_id_table) = { | 566 | static struct pci_device_id vrc4173_cardu_id_table[] __devinitdata = { |
567 | { PCI_DEVICE(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NAPCCARD) }, | 567 | { .vendor = PCI_VENDOR_ID_NEC, |
568 | .device = PCI_DEVICE_ID_NEC_NAPCCARD, | ||
569 | .subvendor = PCI_ANY_ID, | ||
570 | .subdevice = PCI_ANY_ID, }, | ||
568 | {0, } | 571 | {0, } |
569 | }; | 572 | }; |
570 | 573 | ||
@@ -574,14 +577,14 @@ static struct pci_driver vrc4173_cardu_driver = { | |||
574 | .id_table = vrc4173_cardu_id_table, | 577 | .id_table = vrc4173_cardu_id_table, |
575 | }; | 578 | }; |
576 | 579 | ||
577 | static int vrc4173_cardu_init(void) | 580 | static int __devinit vrc4173_cardu_init(void) |
578 | { | 581 | { |
579 | vrc4173_cardu_slots = 0; | 582 | vrc4173_cardu_slots = 0; |
580 | 583 | ||
581 | return pci_register_driver(&vrc4173_cardu_driver); | 584 | return pci_register_driver(&vrc4173_cardu_driver); |
582 | } | 585 | } |
583 | 586 | ||
584 | static void vrc4173_cardu_exit(void) | 587 | static void __devexit vrc4173_cardu_exit(void) |
585 | { | 588 | { |
586 | pci_unregister_driver(&vrc4173_cardu_driver); | 589 | pci_unregister_driver(&vrc4173_cardu_driver); |
587 | } | 590 | } |
diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index 95f5b270ad4..379f4218857 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <pcmcia/cistpl.h> | 21 | #include <pcmcia/cistpl.h> |
22 | 22 | ||
23 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
24 | #include <asm/system.h> | ||
24 | #include <asm/mach-au1x00/au1000.h> | 25 | #include <asm/mach-au1x00/au1000.h> |
25 | 26 | ||
26 | #define MEM_MAP_SIZE 0x400000 | 27 | #define MEM_MAP_SIZE 0x400000 |
@@ -204,7 +205,7 @@ static struct pccard_operations xxs1500_pcmcia_operations = { | |||
204 | .set_mem_map = au1x00_pcmcia_set_mem_map, | 205 | .set_mem_map = au1x00_pcmcia_set_mem_map, |
205 | }; | 206 | }; |
206 | 207 | ||
207 | static int xxs1500_pcmcia_probe(struct platform_device *pdev) | 208 | static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev) |
208 | { | 209 | { |
209 | struct xxs1500_pcmcia_sock *sock; | 210 | struct xxs1500_pcmcia_sock *sock; |
210 | struct resource *r; | 211 | struct resource *r; |
@@ -299,7 +300,7 @@ out0: | |||
299 | return ret; | 300 | return ret; |
300 | } | 301 | } |
301 | 302 | ||
302 | static int xxs1500_pcmcia_remove(struct platform_device *pdev) | 303 | static int __devexit xxs1500_pcmcia_remove(struct platform_device *pdev) |
303 | { | 304 | { |
304 | struct xxs1500_pcmcia_sock *sock = platform_get_drvdata(pdev); | 305 | struct xxs1500_pcmcia_sock *sock = platform_get_drvdata(pdev); |
305 | 306 | ||
@@ -317,10 +318,21 @@ static struct platform_driver xxs1500_pcmcia_socket_driver = { | |||
317 | .owner = THIS_MODULE, | 318 | .owner = THIS_MODULE, |
318 | }, | 319 | }, |
319 | .probe = xxs1500_pcmcia_probe, | 320 | .probe = xxs1500_pcmcia_probe, |
320 | .remove = xxs1500_pcmcia_remove, | 321 | .remove = __devexit_p(xxs1500_pcmcia_remove), |
321 | }; | 322 | }; |
322 | 323 | ||
323 | module_platform_driver(xxs1500_pcmcia_socket_driver); | 324 | int __init xxs1500_pcmcia_socket_load(void) |
325 | { | ||
326 | return platform_driver_register(&xxs1500_pcmcia_socket_driver); | ||
327 | } | ||
328 | |||
329 | void __exit xxs1500_pcmcia_socket_unload(void) | ||
330 | { | ||
331 | platform_driver_unregister(&xxs1500_pcmcia_socket_driver); | ||
332 | } | ||
333 | |||
334 | module_init(xxs1500_pcmcia_socket_load); | ||
335 | module_exit(xxs1500_pcmcia_socket_unload); | ||
324 | 336 | ||
325 | MODULE_LICENSE("GPL"); | 337 | MODULE_LICENSE("GPL"); |
326 | MODULE_DESCRIPTION("PCMCIA Socket Services for MyCable XXS1500 systems"); | 338 | MODULE_DESCRIPTION("PCMCIA Socket Services for MyCable XXS1500 systems"); |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 6b4ff099fb1..9dc565c615b 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -24,15 +24,15 @@ | |||
24 | #include "yenta_socket.h" | 24 | #include "yenta_socket.h" |
25 | #include "i82365.h" | 25 | #include "i82365.h" |
26 | 26 | ||
27 | static bool disable_clkrun; | 27 | static int disable_clkrun; |
28 | module_param(disable_clkrun, bool, 0444); | 28 | module_param(disable_clkrun, bool, 0444); |
29 | MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option"); | 29 | MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option"); |
30 | 30 | ||
31 | static bool isa_probe = 1; | 31 | static int isa_probe = 1; |
32 | module_param(isa_probe, bool, 0444); | 32 | module_param(isa_probe, bool, 0444); |
33 | MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing"); | 33 | MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing"); |
34 | 34 | ||
35 | static bool pwr_irqs_off; | 35 | static int pwr_irqs_off; |
36 | module_param(pwr_irqs_off, bool, 0644); | 36 | module_param(pwr_irqs_off, bool, 0644); |
37 | MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!"); | 37 | MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!"); |
38 | 38 | ||
@@ -783,7 +783,7 @@ static void yenta_free_resources(struct yenta_socket *socket) | |||
783 | /* | 783 | /* |
784 | * Close it down - release our resources and go home.. | 784 | * Close it down - release our resources and go home.. |
785 | */ | 785 | */ |
786 | static void yenta_close(struct pci_dev *dev) | 786 | static void __devexit yenta_close(struct pci_dev *dev) |
787 | { | 787 | { |
788 | struct yenta_socket *sock = pci_get_drvdata(dev); | 788 | struct yenta_socket *sock = pci_get_drvdata(dev); |
789 | 789 | ||
@@ -1048,8 +1048,8 @@ static void yenta_config_init(struct yenta_socket *socket) | |||
1048 | config_writeb(socket, PCI_LATENCY_TIMER, 168); | 1048 | config_writeb(socket, PCI_LATENCY_TIMER, 168); |
1049 | config_writel(socket, PCI_PRIMARY_BUS, | 1049 | config_writel(socket, PCI_PRIMARY_BUS, |
1050 | (176 << 24) | /* sec. latency timer */ | 1050 | (176 << 24) | /* sec. latency timer */ |
1051 | ((unsigned int)dev->subordinate->busn_res.end << 16) | /* subordinate bus */ | 1051 | (dev->subordinate->subordinate << 16) | /* subordinate bus */ |
1052 | ((unsigned int)dev->subordinate->busn_res.start << 8) | /* secondary bus */ | 1052 | (dev->subordinate->secondary << 8) | /* secondary bus */ |
1053 | dev->subordinate->primary); /* primary bus */ | 1053 | dev->subordinate->primary); /* primary bus */ |
1054 | 1054 | ||
1055 | /* | 1055 | /* |
@@ -1086,14 +1086,14 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | |||
1086 | struct pci_bus *bridge_to_fix = cardbus_bridge->parent; | 1086 | struct pci_bus *bridge_to_fix = cardbus_bridge->parent; |
1087 | 1087 | ||
1088 | /* Check bus numbers are already set up correctly: */ | 1088 | /* Check bus numbers are already set up correctly: */ |
1089 | if (bridge_to_fix->busn_res.end >= cardbus_bridge->busn_res.end) | 1089 | if (bridge_to_fix->subordinate >= cardbus_bridge->subordinate) |
1090 | return; /* The subordinate number is ok, nothing to do */ | 1090 | return; /* The subordinate number is ok, nothing to do */ |
1091 | 1091 | ||
1092 | if (!bridge_to_fix->parent) | 1092 | if (!bridge_to_fix->parent) |
1093 | return; /* Root bridges are ok */ | 1093 | return; /* Root bridges are ok */ |
1094 | 1094 | ||
1095 | /* stay within the limits of the bus range of the parent: */ | 1095 | /* stay within the limits of the bus range of the parent: */ |
1096 | upper_limit = bridge_to_fix->parent->busn_res.end; | 1096 | upper_limit = bridge_to_fix->parent->subordinate; |
1097 | 1097 | ||
1098 | /* check the bus ranges of all silbling bridges to prevent overlap */ | 1098 | /* check the bus ranges of all silbling bridges to prevent overlap */ |
1099 | list_for_each(tmp, &bridge_to_fix->parent->children) { | 1099 | list_for_each(tmp, &bridge_to_fix->parent->children) { |
@@ -1104,36 +1104,36 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | |||
1104 | * current upper limit, set the new upper limit to | 1104 | * current upper limit, set the new upper limit to |
1105 | * the bus number below the silbling's range: | 1105 | * the bus number below the silbling's range: |
1106 | */ | 1106 | */ |
1107 | if (silbling->busn_res.start > bridge_to_fix->busn_res.end | 1107 | if (silbling->secondary > bridge_to_fix->subordinate |
1108 | && silbling->busn_res.start <= upper_limit) | 1108 | && silbling->secondary <= upper_limit) |
1109 | upper_limit = silbling->busn_res.start - 1; | 1109 | upper_limit = silbling->secondary - 1; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /* Show that the wanted subordinate number is not possible: */ | 1112 | /* Show that the wanted subordinate number is not possible: */ |
1113 | if (cardbus_bridge->busn_res.end > upper_limit) | 1113 | if (cardbus_bridge->subordinate > upper_limit) |
1114 | dev_printk(KERN_WARNING, &cardbus_bridge->dev, | 1114 | dev_printk(KERN_WARNING, &cardbus_bridge->dev, |
1115 | "Upper limit for fixing this " | 1115 | "Upper limit for fixing this " |
1116 | "bridge's parent bridge: #%02x\n", upper_limit); | 1116 | "bridge's parent bridge: #%02x\n", upper_limit); |
1117 | 1117 | ||
1118 | /* If we have room to increase the bridge's subordinate number, */ | 1118 | /* If we have room to increase the bridge's subordinate number, */ |
1119 | if (bridge_to_fix->busn_res.end < upper_limit) { | 1119 | if (bridge_to_fix->subordinate < upper_limit) { |
1120 | 1120 | ||
1121 | /* use the highest number of the hidden bus, within limits */ | 1121 | /* use the highest number of the hidden bus, within limits */ |
1122 | unsigned char subordinate_to_assign = | 1122 | unsigned char subordinate_to_assign = |
1123 | min_t(int, cardbus_bridge->busn_res.end, upper_limit); | 1123 | min(cardbus_bridge->subordinate, upper_limit); |
1124 | 1124 | ||
1125 | dev_printk(KERN_INFO, &bridge_to_fix->dev, | 1125 | dev_printk(KERN_INFO, &bridge_to_fix->dev, |
1126 | "Raising subordinate bus# of parent " | 1126 | "Raising subordinate bus# of parent " |
1127 | "bus (#%02x) from #%02x to #%02x\n", | 1127 | "bus (#%02x) from #%02x to #%02x\n", |
1128 | bridge_to_fix->number, | 1128 | bridge_to_fix->number, |
1129 | (int)bridge_to_fix->busn_res.end, subordinate_to_assign); | 1129 | bridge_to_fix->subordinate, subordinate_to_assign); |
1130 | 1130 | ||
1131 | /* Save the new subordinate in the bus struct of the bridge */ | 1131 | /* Save the new subordinate in the bus struct of the bridge */ |
1132 | bridge_to_fix->busn_res.end = subordinate_to_assign; | 1132 | bridge_to_fix->subordinate = subordinate_to_assign; |
1133 | 1133 | ||
1134 | /* and update the PCI config space with the new subordinate */ | 1134 | /* and update the PCI config space with the new subordinate */ |
1135 | pci_write_config_byte(bridge_to_fix->self, | 1135 | pci_write_config_byte(bridge_to_fix->self, |
1136 | PCI_SUBORDINATE_BUS, bridge_to_fix->busn_res.end); | 1136 | PCI_SUBORDINATE_BUS, bridge_to_fix->subordinate); |
1137 | } | 1137 | } |
1138 | } | 1138 | } |
1139 | 1139 | ||
@@ -1142,7 +1142,7 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | |||
1142 | * interrupt, and that we can map the cardbus area. Fill in the | 1142 | * interrupt, and that we can map the cardbus area. Fill in the |
1143 | * socket information structure.. | 1143 | * socket information structure.. |
1144 | */ | 1144 | */ |
1145 | static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id) | 1145 | static int __devinit yenta_probe(struct pci_dev *dev, const struct pci_device_id *id) |
1146 | { | 1146 | { |
1147 | struct yenta_socket *socket; | 1147 | struct yenta_socket *socket; |
1148 | int ret; | 1148 | int ret; |
@@ -1352,7 +1352,7 @@ static const struct dev_pm_ops yenta_pm_ops = { | |||
1352 | .driver_data = CARDBUS_TYPE_##type, \ | 1352 | .driver_data = CARDBUS_TYPE_##type, \ |
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | static DEFINE_PCI_DEVICE_TABLE(yenta_table) = { | 1355 | static struct pci_device_id yenta_table[] = { |
1356 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1031, TI), | 1356 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1031, TI), |
1357 | 1357 | ||
1358 | /* | 1358 | /* |
@@ -1435,7 +1435,7 @@ static struct pci_driver yenta_cardbus_driver = { | |||
1435 | .name = "yenta_cardbus", | 1435 | .name = "yenta_cardbus", |
1436 | .id_table = yenta_table, | 1436 | .id_table = yenta_table, |
1437 | .probe = yenta_probe, | 1437 | .probe = yenta_probe, |
1438 | .remove = yenta_close, | 1438 | .remove = __devexit_p(yenta_close), |
1439 | .driver.pm = YENTA_PM_OPS, | 1439 | .driver.pm = YENTA_PM_OPS, |
1440 | }; | 1440 | }; |
1441 | 1441 | ||