diff options
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/Kconfig | 32 | ||||
-rw-r--r-- | drivers/pcmcia/au1000_generic.c | 21 | ||||
-rw-r--r-- | drivers/pcmcia/cistpl.c | 36 | ||||
-rw-r--r-- | drivers/pcmcia/cs.c | 112 | ||||
-rw-r--r-- | drivers/pcmcia/cs_internal.h | 4 | ||||
-rw-r--r-- | drivers/pcmcia/ds.c | 401 | ||||
-rw-r--r-- | drivers/pcmcia/hd64465_ss.c | 13 | ||||
-rw-r--r-- | drivers/pcmcia/i82092.c | 73 | ||||
-rw-r--r-- | drivers/pcmcia/i82092aa.h | 1 | ||||
-rw-r--r-- | drivers/pcmcia/i82365.c | 83 | ||||
-rw-r--r-- | drivers/pcmcia/m32r_cfc.c | 32 | ||||
-rw-r--r-- | drivers/pcmcia/m32r_pcc.c | 20 | ||||
-rw-r--r-- | drivers/pcmcia/m8xx_pcmcia.c | 114 | ||||
-rw-r--r-- | drivers/pcmcia/pd6729.c | 74 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_mainstone.c | 3 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_sharpsl.c | 3 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_mgr.c | 108 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 140 | ||||
-rw-r--r-- | drivers/pcmcia/soc_common.c | 23 | ||||
-rw-r--r-- | drivers/pcmcia/socket_sysfs.c | 30 | ||||
-rw-r--r-- | drivers/pcmcia/tcic.c | 61 | ||||
-rw-r--r-- | drivers/pcmcia/ti113x.h | 4 | ||||
-rw-r--r-- | drivers/pcmcia/vrc4171_card.c | 70 | ||||
-rw-r--r-- | drivers/pcmcia/vrc4173_cardu.c | 43 | ||||
-rw-r--r-- | drivers/pcmcia/yenta_socket.c | 140 |
25 files changed, 616 insertions, 1025 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 309eb557f9a3..1f4ad0e7836e 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -116,6 +116,31 @@ config YENTA | |||
116 | 116 | ||
117 | If unsure, say Y. | 117 | If unsure, say Y. |
118 | 118 | ||
119 | config YENTA_O2 | ||
120 | default y | ||
121 | bool "Special initialization for O2Micro bridges" if EMBEDDED | ||
122 | depends on YENTA | ||
123 | |||
124 | config YENTA_RICOH | ||
125 | default y | ||
126 | bool "Special initialization for Ricoh bridges" if EMBEDDED | ||
127 | depends on YENTA | ||
128 | |||
129 | config YENTA_TI | ||
130 | default y | ||
131 | bool "Special initialization for TI and EnE bridges" if EMBEDDED | ||
132 | depends on YENTA | ||
133 | |||
134 | config YENTA_ENE_TUNE | ||
135 | default y | ||
136 | bool "Auto-tune EnE bridges for CB cards" if EMBEDDED | ||
137 | depends on YENTA_TI && CARDBUS | ||
138 | |||
139 | config YENTA_TOSHIBA | ||
140 | default y | ||
141 | bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED | ||
142 | depends on YENTA | ||
143 | |||
119 | config PD6729 | 144 | config PD6729 |
120 | tristate "Cirrus PD6729 compatible bridge support" | 145 | tristate "Cirrus PD6729 compatible bridge support" |
121 | depends on PCMCIA && PCI | 146 | depends on PCMCIA && PCI |
@@ -157,7 +182,7 @@ config TCIC | |||
157 | config PCMCIA_M8XX | 182 | config PCMCIA_M8XX |
158 | tristate "MPC8xx PCMCIA support" | 183 | tristate "MPC8xx PCMCIA support" |
159 | depends on PCMCIA && PPC && 8xx | 184 | depends on PCMCIA && PPC && 8xx |
160 | select PCCARD_NONSTATIC | 185 | select PCCARD_IODYN |
161 | help | 186 | help |
162 | Say Y here to include support for PowerPC 8xx series PCMCIA | 187 | Say Y here to include support for PowerPC 8xx series PCMCIA |
163 | controller. | 188 | controller. |
@@ -200,7 +225,7 @@ config PCMCIA_PXA2XX | |||
200 | 225 | ||
201 | config PCMCIA_PROBE | 226 | config PCMCIA_PROBE |
202 | bool | 227 | bool |
203 | default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X | 228 | default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC |
204 | 229 | ||
205 | config M32R_PCC | 230 | config M32R_PCC |
206 | bool "M32R PCMCIA I/F" | 231 | bool "M32R PCMCIA I/F" |
@@ -241,6 +266,9 @@ config OMAP_CF | |||
241 | config PCCARD_NONSTATIC | 266 | config PCCARD_NONSTATIC |
242 | tristate | 267 | tristate |
243 | 268 | ||
269 | config PCCARD_IODYN | ||
270 | bool | ||
271 | |||
244 | endif # PCCARD | 272 | endif # PCCARD |
245 | 273 | ||
246 | endmenu | 274 | endmenu |
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 87302c548c24..971a35281649 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c | |||
@@ -241,23 +241,6 @@ au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) | |||
241 | return 0; | 241 | return 0; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* au1x00_pcmcia_get_socket() | ||
245 | * Implements the get_socket() operation for the in-kernel PCMCIA | ||
246 | * service (formerly SS_GetSocket in Card Services). Not a very | ||
247 | * exciting routine. | ||
248 | * | ||
249 | * Returns: 0 | ||
250 | */ | ||
251 | static int | ||
252 | au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
253 | { | ||
254 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
255 | |||
256 | debug("for sock %u\n", skt->nr); | ||
257 | *state = skt->cs_state; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | /* au1x00_pcmcia_set_socket() | 244 | /* au1x00_pcmcia_set_socket() |
262 | * Implements the set_socket() operation for the in-kernel PCMCIA | 245 | * Implements the set_socket() operation for the in-kernel PCMCIA |
263 | * service (formerly SS_SetSocket in Card Services). We more or | 246 | * service (formerly SS_SetSocket in Card Services). We more or |
@@ -352,7 +335,6 @@ static struct pccard_operations au1x00_pcmcia_operations = { | |||
352 | .init = au1x00_pcmcia_sock_init, | 335 | .init = au1x00_pcmcia_sock_init, |
353 | .suspend = au1x00_pcmcia_suspend, | 336 | .suspend = au1x00_pcmcia_suspend, |
354 | .get_status = au1x00_pcmcia_get_status, | 337 | .get_status = au1x00_pcmcia_get_status, |
355 | .get_socket = au1x00_pcmcia_get_socket, | ||
356 | .set_socket = au1x00_pcmcia_set_socket, | 338 | .set_socket = au1x00_pcmcia_set_socket, |
357 | .set_io_map = au1x00_pcmcia_set_io_map, | 339 | .set_io_map = au1x00_pcmcia_set_io_map, |
358 | .set_mem_map = au1x00_pcmcia_set_mem_map, | 340 | .set_mem_map = au1x00_pcmcia_set_mem_map, |
@@ -372,13 +354,12 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
372 | struct skt_dev_info *sinfo; | 354 | struct skt_dev_info *sinfo; |
373 | int ret, i; | 355 | int ret, i; |
374 | 356 | ||
375 | sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL); | 357 | sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL); |
376 | if (!sinfo) { | 358 | if (!sinfo) { |
377 | ret = -ENOMEM; | 359 | ret = -ENOMEM; |
378 | goto out; | 360 | goto out; |
379 | } | 361 | } |
380 | 362 | ||
381 | memset(sinfo, 0, sizeof(struct skt_dev_info)); | ||
382 | sinfo->nskt = nr; | 363 | sinfo->nskt = nr; |
383 | 364 | ||
384 | /* | 365 | /* |
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 2dc3e611a9a3..120fa8da6392 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
@@ -60,9 +60,9 @@ static const u_int exponent[] = { | |||
60 | 60 | ||
61 | /* Parameters that can be set with 'insmod' */ | 61 | /* Parameters that can be set with 'insmod' */ |
62 | 62 | ||
63 | #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) | 63 | /* 16-bit CIS? */ |
64 | 64 | static int cis_width; | |
65 | INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ | 65 | module_param(cis_width, int, 0444); |
66 | 66 | ||
67 | void release_cis_mem(struct pcmcia_socket *s) | 67 | void release_cis_mem(struct pcmcia_socket *s) |
68 | { | 68 | { |
@@ -463,7 +463,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple) | |||
463 | /* Get indirect link from the MFC tuple */ | 463 | /* Get indirect link from the MFC tuple */ |
464 | read_cis_cache(s, LINK_SPACE(tuple->Flags), | 464 | read_cis_cache(s, LINK_SPACE(tuple->Flags), |
465 | tuple->LinkOffset, 5, link); | 465 | tuple->LinkOffset, 5, link); |
466 | ofs = le32_to_cpu(*(u_int *)(link+1)); | 466 | ofs = le32_to_cpu(*(__le32 *)(link+1)); |
467 | SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); | 467 | SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); |
468 | /* Move to the next indirect link */ | 468 | /* Move to the next indirect link */ |
469 | tuple->LinkOffset += 5; | 469 | tuple->LinkOffset += 5; |
@@ -671,8 +671,8 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) | |||
671 | if (tuple->TupleDataLen < 5) | 671 | if (tuple->TupleDataLen < 5) |
672 | return CS_BAD_TUPLE; | 672 | return CS_BAD_TUPLE; |
673 | p = (u_char *)tuple->TupleData; | 673 | p = (u_char *)tuple->TupleData; |
674 | csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(u_short *)p)-2; | 674 | csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2; |
675 | csum->len = le16_to_cpu(*(u_short *)(p + 2)); | 675 | csum->len = le16_to_cpu(*(__le16 *)(p + 2)); |
676 | csum->sum = *(p+4); | 676 | csum->sum = *(p+4); |
677 | return CS_SUCCESS; | 677 | return CS_SUCCESS; |
678 | } | 678 | } |
@@ -683,7 +683,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) | |||
683 | { | 683 | { |
684 | if (tuple->TupleDataLen < 4) | 684 | if (tuple->TupleDataLen < 4) |
685 | return CS_BAD_TUPLE; | 685 | return CS_BAD_TUPLE; |
686 | link->addr = le32_to_cpu(*(u_int *)tuple->TupleData); | 686 | link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData); |
687 | return CS_SUCCESS; | 687 | return CS_SUCCESS; |
688 | } | 688 | } |
689 | 689 | ||
@@ -702,7 +702,7 @@ static int parse_longlink_mfc(tuple_t *tuple, | |||
702 | return CS_BAD_TUPLE; | 702 | return CS_BAD_TUPLE; |
703 | for (i = 0; i < link->nfn; i++) { | 703 | for (i = 0; i < link->nfn; i++) { |
704 | link->fn[i].space = *p; p++; | 704 | link->fn[i].space = *p; p++; |
705 | link->fn[i].addr = le32_to_cpu(*(u_int *)p); p += 4; | 705 | link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4; |
706 | } | 706 | } |
707 | return CS_SUCCESS; | 707 | return CS_SUCCESS; |
708 | } | 708 | } |
@@ -789,10 +789,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) | |||
789 | 789 | ||
790 | static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) | 790 | static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) |
791 | { | 791 | { |
792 | u_short *p; | 792 | __le16 *p; |
793 | if (tuple->TupleDataLen < 4) | 793 | if (tuple->TupleDataLen < 4) |
794 | return CS_BAD_TUPLE; | 794 | return CS_BAD_TUPLE; |
795 | p = (u_short *)tuple->TupleData; | 795 | p = (__le16 *)tuple->TupleData; |
796 | m->manf = le16_to_cpu(p[0]); | 796 | m->manf = le16_to_cpu(p[0]); |
797 | m->card = le16_to_cpu(p[1]); | 797 | m->card = le16_to_cpu(p[1]); |
798 | return CS_SUCCESS; | 798 | return CS_SUCCESS; |
@@ -1093,7 +1093,7 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
1093 | break; | 1093 | break; |
1094 | case 0x20: | 1094 | case 0x20: |
1095 | entry->mem.nwin = 1; | 1095 | entry->mem.nwin = 1; |
1096 | entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; | 1096 | entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8; |
1097 | entry->mem.win[0].card_addr = 0; | 1097 | entry->mem.win[0].card_addr = 0; |
1098 | entry->mem.win[0].host_addr = 0; | 1098 | entry->mem.win[0].host_addr = 0; |
1099 | p += 2; | 1099 | p += 2; |
@@ -1101,9 +1101,9 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
1101 | break; | 1101 | break; |
1102 | case 0x40: | 1102 | case 0x40: |
1103 | entry->mem.nwin = 1; | 1103 | entry->mem.nwin = 1; |
1104 | entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; | 1104 | entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8; |
1105 | entry->mem.win[0].card_addr = | 1105 | entry->mem.win[0].card_addr = |
1106 | le16_to_cpu(*(u_short *)(p+2)) << 8; | 1106 | le16_to_cpu(*(__le16 *)(p+2)) << 8; |
1107 | entry->mem.win[0].host_addr = 0; | 1107 | entry->mem.win[0].host_addr = 0; |
1108 | p += 4; | 1108 | p += 4; |
1109 | if (p > q) return CS_BAD_TUPLE; | 1109 | if (p > q) return CS_BAD_TUPLE; |
@@ -1140,7 +1140,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar) | |||
1140 | p = (u_char *)tuple->TupleData; | 1140 | p = (u_char *)tuple->TupleData; |
1141 | bar->attr = *p; | 1141 | bar->attr = *p; |
1142 | p += 2; | 1142 | p += 2; |
1143 | bar->size = le32_to_cpu(*(u_int *)p); | 1143 | bar->size = le32_to_cpu(*(__le32 *)p); |
1144 | return CS_SUCCESS; | 1144 | return CS_SUCCESS; |
1145 | } | 1145 | } |
1146 | 1146 | ||
@@ -1153,7 +1153,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) | |||
1153 | return CS_BAD_TUPLE; | 1153 | return CS_BAD_TUPLE; |
1154 | config->last_idx = *(++p); | 1154 | config->last_idx = *(++p); |
1155 | p++; | 1155 | p++; |
1156 | config->base = le32_to_cpu(*(u_int *)p); | 1156 | config->base = le32_to_cpu(*(__le32 *)p); |
1157 | config->subtuples = tuple->TupleDataLen - 6; | 1157 | config->subtuples = tuple->TupleDataLen - 6; |
1158 | return CS_SUCCESS; | 1158 | return CS_SUCCESS; |
1159 | } | 1159 | } |
@@ -1269,7 +1269,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) | |||
1269 | 1269 | ||
1270 | v2->vers = p[0]; | 1270 | v2->vers = p[0]; |
1271 | v2->comply = p[1]; | 1271 | v2->comply = p[1]; |
1272 | v2->dindex = le16_to_cpu(*(u_short *)(p+2)); | 1272 | v2->dindex = le16_to_cpu(*(__le16 *)(p+2)); |
1273 | v2->vspec8 = p[6]; | 1273 | v2->vspec8 = p[6]; |
1274 | v2->vspec9 = p[7]; | 1274 | v2->vspec9 = p[7]; |
1275 | v2->nhdr = p[8]; | 1275 | v2->nhdr = p[8]; |
@@ -1310,8 +1310,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) | |||
1310 | 1310 | ||
1311 | fmt->type = p[0]; | 1311 | fmt->type = p[0]; |
1312 | fmt->edc = p[1]; | 1312 | fmt->edc = p[1]; |
1313 | fmt->offset = le32_to_cpu(*(u_int *)(p+2)); | 1313 | fmt->offset = le32_to_cpu(*(__le32 *)(p+2)); |
1314 | fmt->length = le32_to_cpu(*(u_int *)(p+6)); | 1314 | fmt->length = le32_to_cpu(*(__le32 *)(p+6)); |
1315 | 1315 | ||
1316 | return CS_SUCCESS; | 1316 | return CS_SUCCESS; |
1317 | } | 1317 | } |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index a30aa74304a2..613f2f1fbfdd 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -309,41 +309,6 @@ struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr) | |||
309 | } | 309 | } |
310 | EXPORT_SYMBOL(pcmcia_get_socket_by_nr); | 310 | EXPORT_SYMBOL(pcmcia_get_socket_by_nr); |
311 | 311 | ||
312 | |||
313 | /** | ||
314 | * socket_setup() and shutdown_socket() are called by the main event | ||
315 | * handler when card insertion and removal events are received. | ||
316 | * socket_setup() turns on socket power and resets the socket, in two stages. | ||
317 | * shutdown_socket() unconfigures a socket and turns off socket power. | ||
318 | */ | ||
319 | static void shutdown_socket(struct pcmcia_socket *s) | ||
320 | { | ||
321 | cs_dbg(s, 1, "shutdown_socket\n"); | ||
322 | |||
323 | /* Blank out the socket state */ | ||
324 | s->socket = dead_socket; | ||
325 | s->ops->init(s); | ||
326 | s->ops->set_socket(s, &s->socket); | ||
327 | s->irq.AssignedIRQ = s->irq.Config = 0; | ||
328 | s->lock_count = 0; | ||
329 | destroy_cis_cache(s); | ||
330 | #ifdef CONFIG_CARDBUS | ||
331 | cb_free(s); | ||
332 | #endif | ||
333 | s->functions = 0; | ||
334 | kfree(s->config); | ||
335 | s->config = NULL; | ||
336 | |||
337 | { | ||
338 | int status; | ||
339 | s->ops->get_status(s, &status); | ||
340 | if (status & SS_POWERON) { | ||
341 | printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); | ||
342 | } | ||
343 | } | ||
344 | } /* shutdown_socket */ | ||
345 | |||
346 | |||
347 | /** | 312 | /** |
348 | * The central event handler. Send_event() sends an event to the | 313 | * The central event handler. Send_event() sends an event to the |
349 | * 16-bit subsystem, which then calls the relevant device drivers. | 314 | * 16-bit subsystem, which then calls the relevant device drivers. |
@@ -383,17 +348,6 @@ static void socket_remove_drivers(struct pcmcia_socket *skt) | |||
383 | send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); | 348 | send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); |
384 | } | 349 | } |
385 | 350 | ||
386 | static void socket_shutdown(struct pcmcia_socket *skt) | ||
387 | { | ||
388 | cs_dbg(skt, 4, "shutdown\n"); | ||
389 | |||
390 | socket_remove_drivers(skt); | ||
391 | skt->state &= SOCKET_INUSE|SOCKET_PRESENT; | ||
392 | msleep(shutdown_delay * 10); | ||
393 | skt->state &= SOCKET_INUSE; | ||
394 | shutdown_socket(skt); | ||
395 | } | ||
396 | |||
397 | static int socket_reset(struct pcmcia_socket *skt) | 351 | static int socket_reset(struct pcmcia_socket *skt) |
398 | { | 352 | { |
399 | int status, i; | 353 | int status, i; |
@@ -424,6 +378,45 @@ static int socket_reset(struct pcmcia_socket *skt) | |||
424 | return CS_GENERAL_FAILURE; | 378 | return CS_GENERAL_FAILURE; |
425 | } | 379 | } |
426 | 380 | ||
381 | /** | ||
382 | * socket_setup() and socket_shutdown() are called by the main event handler | ||
383 | * when card insertion and removal events are received. | ||
384 | * socket_setup() turns on socket power and resets the socket, in two stages. | ||
385 | * socket_shutdown() unconfigures a socket and turns off socket power. | ||
386 | */ | ||
387 | static void socket_shutdown(struct pcmcia_socket *s) | ||
388 | { | ||
389 | int status; | ||
390 | |||
391 | cs_dbg(s, 4, "shutdown\n"); | ||
392 | |||
393 | socket_remove_drivers(s); | ||
394 | s->state &= SOCKET_INUSE | SOCKET_PRESENT; | ||
395 | msleep(shutdown_delay * 10); | ||
396 | s->state &= SOCKET_INUSE; | ||
397 | |||
398 | /* Blank out the socket state */ | ||
399 | s->socket = dead_socket; | ||
400 | s->ops->init(s); | ||
401 | s->ops->set_socket(s, &s->socket); | ||
402 | s->irq.AssignedIRQ = s->irq.Config = 0; | ||
403 | s->lock_count = 0; | ||
404 | destroy_cis_cache(s); | ||
405 | #ifdef CONFIG_CARDBUS | ||
406 | cb_free(s); | ||
407 | #endif | ||
408 | s->functions = 0; | ||
409 | kfree(s->config); | ||
410 | s->config = NULL; | ||
411 | |||
412 | s->ops->get_status(s, &status); | ||
413 | if (status & SS_POWERON) { | ||
414 | printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); | ||
415 | } | ||
416 | |||
417 | cs_socket_put(s); | ||
418 | } | ||
419 | |||
427 | static int socket_setup(struct pcmcia_socket *skt, int initial_delay) | 420 | static int socket_setup(struct pcmcia_socket *skt, int initial_delay) |
428 | { | 421 | { |
429 | int status, i; | 422 | int status, i; |
@@ -529,7 +522,6 @@ static int socket_insert(struct pcmcia_socket *skt) | |||
529 | send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); | 522 | send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); |
530 | } else { | 523 | } else { |
531 | socket_shutdown(skt); | 524 | socket_shutdown(skt); |
532 | cs_socket_put(skt); | ||
533 | } | 525 | } |
534 | 526 | ||
535 | return ret; | 527 | return ret; |
@@ -593,7 +585,6 @@ static int socket_resume(struct pcmcia_socket *skt) | |||
593 | } | 585 | } |
594 | } else { | 586 | } else { |
595 | socket_shutdown(skt); | 587 | socket_shutdown(skt); |
596 | cs_socket_put(skt); | ||
597 | } | 588 | } |
598 | 589 | ||
599 | skt->state &= ~SOCKET_SUSPEND; | 590 | skt->state &= ~SOCKET_SUSPEND; |
@@ -605,7 +596,6 @@ static void socket_remove(struct pcmcia_socket *skt) | |||
605 | { | 596 | { |
606 | printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); | 597 | printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); |
607 | socket_shutdown(skt); | 598 | socket_shutdown(skt); |
608 | cs_socket_put(skt); | ||
609 | } | 599 | } |
610 | 600 | ||
611 | /* | 601 | /* |
@@ -780,8 +770,13 @@ int pccard_reset_card(struct pcmcia_socket *skt) | |||
780 | ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW); | 770 | ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW); |
781 | if (ret == 0) { | 771 | if (ret == 0) { |
782 | send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); | 772 | send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); |
783 | if (socket_reset(skt) == CS_SUCCESS) | 773 | if (skt->callback) |
774 | skt->callback->suspend(skt); | ||
775 | if (socket_reset(skt) == CS_SUCCESS) { | ||
784 | send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); | 776 | send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); |
777 | if (skt->callback) | ||
778 | skt->callback->resume(skt); | ||
779 | } | ||
785 | } | 780 | } |
786 | 781 | ||
787 | ret = CS_SUCCESS; | 782 | ret = CS_SUCCESS; |
@@ -812,6 +807,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) | |||
812 | ret = CS_UNSUPPORTED_FUNCTION; | 807 | ret = CS_UNSUPPORTED_FUNCTION; |
813 | break; | 808 | break; |
814 | } | 809 | } |
810 | if (skt->callback) { | ||
811 | ret = skt->callback->suspend(skt); | ||
812 | if (ret) | ||
813 | break; | ||
814 | } | ||
815 | ret = socket_suspend(skt); | 815 | ret = socket_suspend(skt); |
816 | } while (0); | 816 | } while (0); |
817 | up(&skt->skt_sem); | 817 | up(&skt->skt_sem); |
@@ -838,6 +838,8 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) | |||
838 | break; | 838 | break; |
839 | } | 839 | } |
840 | ret = socket_resume(skt); | 840 | ret = socket_resume(skt); |
841 | if (!ret && skt->callback) | ||
842 | skt->callback->resume(skt); | ||
841 | } while (0); | 843 | } while (0); |
842 | up(&skt->skt_sem); | 844 | up(&skt->skt_sem); |
843 | 845 | ||
@@ -901,14 +903,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) | |||
901 | EXPORT_SYMBOL(pcmcia_insert_card); | 903 | EXPORT_SYMBOL(pcmcia_insert_card); |
902 | 904 | ||
903 | 905 | ||
904 | static int pcmcia_socket_hotplug(struct class_device *dev, char **envp, | 906 | static int pcmcia_socket_uevent(struct class_device *dev, char **envp, |
905 | int num_envp, char *buffer, int buffer_size) | 907 | int num_envp, char *buffer, int buffer_size) |
906 | { | 908 | { |
907 | struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); | 909 | struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); |
908 | int i = 0, length = 0; | 910 | int i = 0, length = 0; |
909 | 911 | ||
910 | if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, | 912 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, |
911 | &length, "SOCKET_NO=%u", s->sock)) | 913 | &length, "SOCKET_NO=%u", s->sock)) |
912 | return -ENOMEM; | 914 | return -ENOMEM; |
913 | 915 | ||
914 | envp[i] = NULL; | 916 | envp[i] = NULL; |
@@ -927,7 +929,7 @@ static void pcmcia_release_socket_class(struct class *data) | |||
927 | 929 | ||
928 | struct class pcmcia_socket_class = { | 930 | struct class pcmcia_socket_class = { |
929 | .name = "pcmcia_socket", | 931 | .name = "pcmcia_socket", |
930 | .hotplug = pcmcia_socket_hotplug, | 932 | .uevent = pcmcia_socket_uevent, |
931 | .release = pcmcia_release_socket, | 933 | .release = pcmcia_release_socket, |
932 | .class_release = pcmcia_release_socket_class, | 934 | .class_release = pcmcia_release_socket_class, |
933 | }; | 935 | }; |
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 55867bc7f199..7b37eba35bf1 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
@@ -117,7 +117,7 @@ int verify_cis_cache(struct pcmcia_socket *s); | |||
117 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse); | 117 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse); |
118 | 118 | ||
119 | /* In rsrc_mgr */ | 119 | /* In rsrc_mgr */ |
120 | void pcmcia_validate_mem(struct pcmcia_socket *s); | 120 | int pcmcia_validate_mem(struct pcmcia_socket *s); |
121 | struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align, | 121 | struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align, |
122 | struct pcmcia_socket *s); | 122 | struct pcmcia_socket *s); |
123 | int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start, | 123 | int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start, |
@@ -143,6 +143,8 @@ struct pcmcia_callback{ | |||
143 | struct module *owner; | 143 | struct module *owner; |
144 | int (*event) (struct pcmcia_socket *s, event_t event, int priority); | 144 | int (*event) (struct pcmcia_socket *s, event_t event, int priority); |
145 | void (*requery) (struct pcmcia_socket *s); | 145 | void (*requery) (struct pcmcia_socket *s); |
146 | int (*suspend) (struct pcmcia_socket *s); | ||
147 | int (*resume) (struct pcmcia_socket *s); | ||
146 | }; | 148 | }; |
147 | 149 | ||
148 | int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); | 150 | int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 7f8219f3fd9e..0252582b91cd 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -57,8 +57,6 @@ module_param_named(pc_debug, ds_pc_debug, int, 0644); | |||
57 | 57 | ||
58 | spinlock_t pcmcia_dev_list_lock; | 58 | spinlock_t pcmcia_dev_list_lock; |
59 | 59 | ||
60 | static int unbind_request(struct pcmcia_socket *s); | ||
61 | |||
62 | /*====================================================================*/ | 60 | /*====================================================================*/ |
63 | 61 | ||
64 | /* code which was in cs.c before */ | 62 | /* code which was in cs.c before */ |
@@ -205,7 +203,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | |||
205 | unsigned int i; | 203 | unsigned int i; |
206 | u32 hash; | 204 | u32 hash; |
207 | 205 | ||
208 | if (!p_drv->attach || !p_drv->event || !p_drv->detach) | 206 | if (!p_drv->probe || !p_drv->remove) |
209 | printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " | 207 | printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " |
210 | "function\n", p_drv->drv.name); | 208 | "function\n", p_drv->drv.name); |
211 | 209 | ||
@@ -266,12 +264,10 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
266 | if (fw->size >= CISTPL_MAX_CIS_SIZE) | 264 | if (fw->size >= CISTPL_MAX_CIS_SIZE) |
267 | goto release; | 265 | goto release; |
268 | 266 | ||
269 | cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL); | 267 | cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); |
270 | if (!cis) | 268 | if (!cis) |
271 | goto release; | 269 | goto release; |
272 | 270 | ||
273 | memset(cis, 0, sizeof(cisdump_t)); | ||
274 | |||
275 | cis->Length = fw->size + 1; | 271 | cis->Length = fw->size + 1; |
276 | memcpy(cis->Data, fw->data, fw->size); | 272 | memcpy(cis->Data, fw->data, fw->size); |
277 | 273 | ||
@@ -363,6 +359,7 @@ static int pcmcia_device_probe(struct device * dev) | |||
363 | { | 359 | { |
364 | struct pcmcia_device *p_dev; | 360 | struct pcmcia_device *p_dev; |
365 | struct pcmcia_driver *p_drv; | 361 | struct pcmcia_driver *p_drv; |
362 | struct pcmcia_socket *s; | ||
366 | int ret = 0; | 363 | int ret = 0; |
367 | 364 | ||
368 | dev = get_device(dev); | 365 | dev = get_device(dev); |
@@ -371,25 +368,38 @@ static int pcmcia_device_probe(struct device * dev) | |||
371 | 368 | ||
372 | p_dev = to_pcmcia_dev(dev); | 369 | p_dev = to_pcmcia_dev(dev); |
373 | p_drv = to_pcmcia_drv(dev->driver); | 370 | p_drv = to_pcmcia_drv(dev->driver); |
371 | s = p_dev->socket; | ||
374 | 372 | ||
375 | if (!try_module_get(p_drv->owner)) { | 373 | if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) { |
376 | ret = -EINVAL; | 374 | ret = -EINVAL; |
377 | goto put_dev; | 375 | goto put_dev; |
378 | } | 376 | } |
379 | 377 | ||
380 | if (p_drv->attach) { | 378 | p_dev->state &= ~CLIENT_UNBOUND; |
381 | p_dev->instance = p_drv->attach(); | 379 | |
382 | if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) { | 380 | /* set up the device configuration, if it hasn't been done before */ |
383 | printk(KERN_NOTICE "ds: unable to create instance " | 381 | if (!s->functions) { |
384 | "of '%s'!\n", p_drv->drv.name); | 382 | cistpl_longlink_mfc_t mfc; |
385 | ret = -EINVAL; | 383 | if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, |
384 | &mfc) == CS_SUCCESS) | ||
385 | s->functions = mfc.nfn; | ||
386 | else | ||
387 | s->functions = 1; | ||
388 | s->config = kzalloc(sizeof(config_t) * s->functions, | ||
389 | GFP_KERNEL); | ||
390 | if (!s->config) { | ||
391 | ret = -ENOMEM; | ||
392 | goto put_module; | ||
386 | } | 393 | } |
387 | } | 394 | } |
388 | 395 | ||
396 | ret = p_drv->probe(p_dev); | ||
397 | |||
398 | put_module: | ||
389 | if (ret) | 399 | if (ret) |
390 | module_put(p_drv->owner); | 400 | module_put(p_drv->owner); |
391 | put_dev: | 401 | put_dev: |
392 | if ((ret) || !(p_drv->attach)) | 402 | if (ret) |
393 | put_device(dev); | 403 | put_device(dev); |
394 | return (ret); | 404 | return (ret); |
395 | } | 405 | } |
@@ -399,24 +409,66 @@ static int pcmcia_device_remove(struct device * dev) | |||
399 | { | 409 | { |
400 | struct pcmcia_device *p_dev; | 410 | struct pcmcia_device *p_dev; |
401 | struct pcmcia_driver *p_drv; | 411 | struct pcmcia_driver *p_drv; |
412 | int i; | ||
402 | 413 | ||
403 | /* detach the "instance" */ | 414 | /* detach the "instance" */ |
404 | p_dev = to_pcmcia_dev(dev); | 415 | p_dev = to_pcmcia_dev(dev); |
405 | p_drv = to_pcmcia_drv(dev->driver); | 416 | p_drv = to_pcmcia_drv(dev->driver); |
417 | if (!p_drv) | ||
418 | return 0; | ||
406 | 419 | ||
407 | if (p_drv) { | 420 | if (p_drv->remove) |
408 | if ((p_drv->detach) && (p_dev->instance)) { | 421 | p_drv->remove(p_dev); |
409 | p_drv->detach(p_dev->instance); | 422 | |
410 | /* from pcmcia_probe_device */ | 423 | /* check for proper unloading */ |
411 | put_device(&p_dev->dev); | 424 | if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) |
412 | } | 425 | printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", |
413 | module_put(p_drv->owner); | 426 | p_drv->drv.name); |
414 | } | 427 | |
428 | for (i = 0; i < MAX_WIN; i++) | ||
429 | if (p_dev->state & CLIENT_WIN_REQ(i)) | ||
430 | printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", | ||
431 | p_drv->drv.name); | ||
432 | |||
433 | /* references from pcmcia_probe_device */ | ||
434 | p_dev->state = CLIENT_UNBOUND; | ||
435 | pcmcia_put_dev(p_dev); | ||
436 | module_put(p_drv->owner); | ||
415 | 437 | ||
416 | return 0; | 438 | return 0; |
417 | } | 439 | } |
418 | 440 | ||
419 | 441 | ||
442 | /* | ||
443 | * Removes a PCMCIA card from the device tree and socket list. | ||
444 | */ | ||
445 | static void pcmcia_card_remove(struct pcmcia_socket *s) | ||
446 | { | ||
447 | struct pcmcia_device *p_dev; | ||
448 | unsigned long flags; | ||
449 | |||
450 | ds_dbg(2, "unbind_request(%d)\n", s->sock); | ||
451 | |||
452 | s->device_count = 0; | ||
453 | |||
454 | for (;;) { | ||
455 | /* unregister all pcmcia_devices registered with this socket*/ | ||
456 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | ||
457 | if (list_empty(&s->devices_list)) { | ||
458 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
459 | return; | ||
460 | } | ||
461 | p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); | ||
462 | list_del(&p_dev->socket_device_list); | ||
463 | p_dev->state |= CLIENT_STALE; | ||
464 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
465 | |||
466 | device_unregister(&p_dev->dev); | ||
467 | } | ||
468 | |||
469 | return; | ||
470 | } /* unbind_request */ | ||
471 | |||
420 | 472 | ||
421 | /* | 473 | /* |
422 | * pcmcia_device_query -- determine information about a pcmcia device | 474 | * pcmcia_device_query -- determine information about a pcmcia device |
@@ -517,10 +569,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
517 | if (s->device_count == 2) | 569 | if (s->device_count == 2) |
518 | goto err_put; | 570 | goto err_put; |
519 | 571 | ||
520 | p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL); | 572 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); |
521 | if (!p_dev) | 573 | if (!p_dev) |
522 | goto err_put; | 574 | goto err_put; |
523 | memset(p_dev, 0, sizeof(struct pcmcia_device)); | ||
524 | 575 | ||
525 | p_dev->socket = s; | 576 | p_dev->socket = s; |
526 | p_dev->device_no = (s->device_count++); | 577 | p_dev->device_no = (s->device_count++); |
@@ -583,7 +634,9 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
583 | if (!(s->resource_setup_done)) | 634 | if (!(s->resource_setup_done)) |
584 | return -EAGAIN; /* try again, but later... */ | 635 | return -EAGAIN; /* try again, but later... */ |
585 | 636 | ||
586 | pcmcia_validate_mem(s); | 637 | if (pcmcia_validate_mem(s)) |
638 | return -EAGAIN; /* try again, but later... */ | ||
639 | |||
587 | ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); | 640 | ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); |
588 | if (ret || !cisinfo.Chains) { | 641 | if (ret || !cisinfo.Chains) { |
589 | ds_dbg(0, "invalid CIS or invalid resources\n"); | 642 | ds_dbg(0, "invalid CIS or invalid resources\n"); |
@@ -779,8 +832,8 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { | |||
779 | 832 | ||
780 | #ifdef CONFIG_HOTPLUG | 833 | #ifdef CONFIG_HOTPLUG |
781 | 834 | ||
782 | static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, | 835 | static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, |
783 | char *buffer, int buffer_size) | 836 | char *buffer, int buffer_size) |
784 | { | 837 | { |
785 | struct pcmcia_device *p_dev; | 838 | struct pcmcia_device *p_dev; |
786 | int i, length = 0; | 839 | int i, length = 0; |
@@ -800,31 +853,31 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, | |||
800 | 853 | ||
801 | i = 0; | 854 | i = 0; |
802 | 855 | ||
803 | if (add_hotplug_env_var(envp, num_envp, &i, | 856 | if (add_uevent_var(envp, num_envp, &i, |
804 | buffer, buffer_size, &length, | 857 | buffer, buffer_size, &length, |
805 | "SOCKET_NO=%u", | 858 | "SOCKET_NO=%u", |
806 | p_dev->socket->sock)) | 859 | p_dev->socket->sock)) |
807 | return -ENOMEM; | 860 | return -ENOMEM; |
808 | 861 | ||
809 | if (add_hotplug_env_var(envp, num_envp, &i, | 862 | if (add_uevent_var(envp, num_envp, &i, |
810 | buffer, buffer_size, &length, | 863 | buffer, buffer_size, &length, |
811 | "DEVICE_NO=%02X", | 864 | "DEVICE_NO=%02X", |
812 | p_dev->device_no)) | 865 | p_dev->device_no)) |
813 | return -ENOMEM; | 866 | return -ENOMEM; |
814 | 867 | ||
815 | if (add_hotplug_env_var(envp, num_envp, &i, | 868 | if (add_uevent_var(envp, num_envp, &i, |
816 | buffer, buffer_size, &length, | 869 | buffer, buffer_size, &length, |
817 | "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X" | 870 | "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X" |
818 | "pa%08Xpb%08Xpc%08Xpd%08X", | 871 | "pa%08Xpb%08Xpc%08Xpd%08X", |
819 | p_dev->has_manf_id ? p_dev->manf_id : 0, | 872 | p_dev->has_manf_id ? p_dev->manf_id : 0, |
820 | p_dev->has_card_id ? p_dev->card_id : 0, | 873 | p_dev->has_card_id ? p_dev->card_id : 0, |
821 | p_dev->has_func_id ? p_dev->func_id : 0, | 874 | p_dev->has_func_id ? p_dev->func_id : 0, |
822 | p_dev->func, | 875 | p_dev->func, |
823 | p_dev->device_no, | 876 | p_dev->device_no, |
824 | hash[0], | 877 | hash[0], |
825 | hash[1], | 878 | hash[1], |
826 | hash[2], | 879 | hash[2], |
827 | hash[3])) | 880 | hash[3])) |
828 | return -ENOMEM; | 881 | return -ENOMEM; |
829 | 882 | ||
830 | envp[i] = NULL; | 883 | envp[i] = NULL; |
@@ -834,7 +887,7 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, | |||
834 | 887 | ||
835 | #else | 888 | #else |
836 | 889 | ||
837 | static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, | 890 | static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, |
838 | char *buffer, int buffer_size) | 891 | char *buffer, int buffer_size) |
839 | { | 892 | { |
840 | return -ENODEV; | 893 | return -ENODEV; |
@@ -918,55 +971,84 @@ static struct device_attribute pcmcia_dev_attrs[] = { | |||
918 | __ATTR_NULL, | 971 | __ATTR_NULL, |
919 | }; | 972 | }; |
920 | 973 | ||
974 | /* PM support, also needed for reset */ | ||
921 | 975 | ||
922 | /*====================================================================== | 976 | static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) |
977 | { | ||
978 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | ||
979 | struct pcmcia_driver *p_drv = NULL; | ||
923 | 980 | ||
924 | The card status event handler. | 981 | if (dev->driver) |
925 | 982 | p_drv = to_pcmcia_drv(dev->driver); | |
926 | ======================================================================*/ | ||
927 | 983 | ||
928 | struct send_event_data { | 984 | if (p_drv && p_drv->suspend) |
929 | struct pcmcia_socket *skt; | 985 | return p_drv->suspend(p_dev); |
930 | event_t event; | ||
931 | int priority; | ||
932 | }; | ||
933 | 986 | ||
934 | static int send_event_callback(struct device *dev, void * _data) | 987 | return 0; |
988 | } | ||
989 | |||
990 | |||
991 | static int pcmcia_dev_resume(struct device * dev) | ||
935 | { | 992 | { |
936 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 993 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
937 | struct pcmcia_driver *p_drv; | 994 | struct pcmcia_driver *p_drv = NULL; |
938 | struct send_event_data *data = _data; | ||
939 | 995 | ||
940 | /* we get called for all sockets, but may only pass the event | 996 | if (dev->driver) |
941 | * for drivers _on the affected socket_ */ | 997 | p_drv = to_pcmcia_drv(dev->driver); |
942 | if (p_dev->socket != data->skt) | ||
943 | return 0; | ||
944 | 998 | ||
945 | p_drv = to_pcmcia_drv(p_dev->dev.driver); | 999 | if (p_drv && p_drv->resume) |
946 | if (!p_drv) | 1000 | return p_drv->resume(p_dev); |
1001 | |||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | |||
1006 | static int pcmcia_bus_suspend_callback(struct device *dev, void * _data) | ||
1007 | { | ||
1008 | struct pcmcia_socket *skt = _data; | ||
1009 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | ||
1010 | |||
1011 | if (p_dev->socket != skt) | ||
947 | return 0; | 1012 | return 0; |
948 | 1013 | ||
949 | if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) | 1014 | return dpm_runtime_suspend(dev, PMSG_SUSPEND); |
1015 | } | ||
1016 | |||
1017 | static int pcmcia_bus_resume_callback(struct device *dev, void * _data) | ||
1018 | { | ||
1019 | struct pcmcia_socket *skt = _data; | ||
1020 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | ||
1021 | |||
1022 | if (p_dev->socket != skt) | ||
950 | return 0; | 1023 | return 0; |
951 | 1024 | ||
952 | if (p_drv->event) | 1025 | dpm_runtime_resume(dev); |
953 | return p_drv->event(data->event, data->priority, | 1026 | |
954 | &p_dev->event_callback_args); | 1027 | return 0; |
1028 | } | ||
955 | 1029 | ||
1030 | static int pcmcia_bus_resume(struct pcmcia_socket *skt) | ||
1031 | { | ||
1032 | bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); | ||
956 | return 0; | 1033 | return 0; |
957 | } | 1034 | } |
958 | 1035 | ||
959 | static int send_event(struct pcmcia_socket *s, event_t event, int priority) | 1036 | static int pcmcia_bus_suspend(struct pcmcia_socket *skt) |
960 | { | 1037 | { |
961 | struct send_event_data private; | 1038 | if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, |
1039 | pcmcia_bus_suspend_callback)) { | ||
1040 | pcmcia_bus_resume(skt); | ||
1041 | return -EIO; | ||
1042 | } | ||
1043 | return 0; | ||
1044 | } | ||
962 | 1045 | ||
963 | private.skt = s; | ||
964 | private.event = event; | ||
965 | private.priority = priority; | ||
966 | 1046 | ||
967 | return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback); | 1047 | /*====================================================================== |
968 | } /* send_event */ | ||
969 | 1048 | ||
1049 | The card status event handler. | ||
1050 | |||
1051 | ======================================================================*/ | ||
970 | 1052 | ||
971 | /* Normally, the event is passed to individual drivers after | 1053 | /* Normally, the event is passed to individual drivers after |
972 | * informing userspace. Only for CS_EVENT_CARD_REMOVAL this | 1054 | * informing userspace. Only for CS_EVENT_CARD_REMOVAL this |
@@ -976,20 +1058,17 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority) | |||
976 | static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | 1058 | static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) |
977 | { | 1059 | { |
978 | struct pcmcia_socket *s = pcmcia_get_socket(skt); | 1060 | struct pcmcia_socket *s = pcmcia_get_socket(skt); |
979 | int ret = 0; | ||
980 | 1061 | ||
981 | ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", | 1062 | ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", |
982 | event, priority, skt); | 1063 | event, priority, skt); |
983 | |||
984 | switch (event) { | ||
985 | 1064 | ||
1065 | switch (event) { | ||
986 | case CS_EVENT_CARD_REMOVAL: | 1066 | case CS_EVENT_CARD_REMOVAL: |
987 | s->pcmcia_state.present = 0; | 1067 | s->pcmcia_state.present = 0; |
988 | send_event(skt, event, priority); | 1068 | pcmcia_card_remove(skt); |
989 | unbind_request(skt); | ||
990 | handle_event(skt, event); | 1069 | handle_event(skt, event); |
991 | break; | 1070 | break; |
992 | 1071 | ||
993 | case CS_EVENT_CARD_INSERTION: | 1072 | case CS_EVENT_CARD_INSERTION: |
994 | s->pcmcia_state.present = 1; | 1073 | s->pcmcia_state.present = 1; |
995 | pcmcia_card_add(skt); | 1074 | pcmcia_card_add(skt); |
@@ -997,12 +1076,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
997 | break; | 1076 | break; |
998 | 1077 | ||
999 | case CS_EVENT_EJECTION_REQUEST: | 1078 | case CS_EVENT_EJECTION_REQUEST: |
1000 | ret = send_event(skt, event, priority); | ||
1001 | break; | 1079 | break; |
1002 | 1080 | ||
1081 | case CS_EVENT_PM_SUSPEND: | ||
1082 | case CS_EVENT_PM_RESUME: | ||
1083 | case CS_EVENT_RESET_PHYSICAL: | ||
1084 | case CS_EVENT_CARD_RESET: | ||
1003 | default: | 1085 | default: |
1004 | handle_event(skt, event); | 1086 | handle_event(skt, event); |
1005 | send_event(skt, event, priority); | ||
1006 | break; | 1087 | break; |
1007 | } | 1088 | } |
1008 | 1089 | ||
@@ -1012,152 +1093,12 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1012 | } /* ds_event */ | 1093 | } /* ds_event */ |
1013 | 1094 | ||
1014 | 1095 | ||
1015 | |||
1016 | int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req) | ||
1017 | { | ||
1018 | struct pcmcia_socket *s = NULL; | ||
1019 | struct pcmcia_device *p_dev = NULL; | ||
1020 | struct pcmcia_driver *p_drv = NULL; | ||
1021 | |||
1022 | /* Look for unbound client with matching dev_info */ | ||
1023 | down_read(&pcmcia_socket_list_rwsem); | ||
1024 | list_for_each_entry(s, &pcmcia_socket_list, socket_list) { | ||
1025 | unsigned long flags; | ||
1026 | |||
1027 | if (s->state & SOCKET_CARDBUS) | ||
1028 | continue; | ||
1029 | |||
1030 | s = pcmcia_get_socket(s); | ||
1031 | if (!s) | ||
1032 | continue; | ||
1033 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | ||
1034 | list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { | ||
1035 | p_dev = pcmcia_get_dev(p_dev); | ||
1036 | if (!p_dev) | ||
1037 | continue; | ||
1038 | if (!(p_dev->state & CLIENT_UNBOUND) || | ||
1039 | (!p_dev->dev.driver)) { | ||
1040 | pcmcia_put_dev(p_dev); | ||
1041 | continue; | ||
1042 | } | ||
1043 | p_drv = to_pcmcia_drv(p_dev->dev.driver); | ||
1044 | if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) { | ||
1045 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
1046 | goto found; | ||
1047 | } | ||
1048 | pcmcia_put_dev(p_dev); | ||
1049 | } | ||
1050 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
1051 | pcmcia_put_socket(s); | ||
1052 | } | ||
1053 | found: | ||
1054 | up_read(&pcmcia_socket_list_rwsem); | ||
1055 | if (!p_dev) | ||
1056 | return -ENODEV; | ||
1057 | |||
1058 | pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */ | ||
1059 | |||
1060 | *handle = p_dev; | ||
1061 | p_dev->state &= ~CLIENT_UNBOUND; | ||
1062 | p_dev->event_callback_args = req->event_callback_args; | ||
1063 | p_dev->event_callback_args.client_handle = p_dev; | ||
1064 | |||
1065 | |||
1066 | if (!s->functions) { | ||
1067 | cistpl_longlink_mfc_t mfc; | ||
1068 | if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc) | ||
1069 | == CS_SUCCESS) | ||
1070 | s->functions = mfc.nfn; | ||
1071 | else | ||
1072 | s->functions = 1; | ||
1073 | s->config = kmalloc(sizeof(config_t) * s->functions, | ||
1074 | GFP_KERNEL); | ||
1075 | if (!s->config) | ||
1076 | goto out_no_resource; | ||
1077 | memset(s->config, 0, sizeof(config_t) * s->functions); | ||
1078 | } | ||
1079 | |||
1080 | ds_dbg(1, "register_client(): client 0x%p, dev %s\n", | ||
1081 | p_dev, p_dev->dev.bus_id); | ||
1082 | |||
1083 | if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { | ||
1084 | if (p_drv->event) | ||
1085 | p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW, | ||
1086 | &p_dev->event_callback_args); | ||
1087 | |||
1088 | } | ||
1089 | |||
1090 | return CS_SUCCESS; | ||
1091 | |||
1092 | out_no_resource: | ||
1093 | pcmcia_put_dev(p_dev); | ||
1094 | return CS_OUT_OF_RESOURCE; | ||
1095 | } /* register_client */ | ||
1096 | EXPORT_SYMBOL(pcmcia_register_client); | ||
1097 | |||
1098 | |||
1099 | /* unbind _all_ devices attached to a given pcmcia_bus_socket. The | ||
1100 | * drivers have been called with EVENT_CARD_REMOVAL before. | ||
1101 | */ | ||
1102 | static int unbind_request(struct pcmcia_socket *s) | ||
1103 | { | ||
1104 | struct pcmcia_device *p_dev; | ||
1105 | unsigned long flags; | ||
1106 | |||
1107 | ds_dbg(2, "unbind_request(%d)\n", s->sock); | ||
1108 | |||
1109 | s->device_count = 0; | ||
1110 | |||
1111 | for (;;) { | ||
1112 | /* unregister all pcmcia_devices registered with this socket*/ | ||
1113 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | ||
1114 | if (list_empty(&s->devices_list)) { | ||
1115 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
1116 | return 0; | ||
1117 | } | ||
1118 | p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); | ||
1119 | list_del(&p_dev->socket_device_list); | ||
1120 | p_dev->state |= CLIENT_STALE; | ||
1121 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
1122 | |||
1123 | device_unregister(&p_dev->dev); | ||
1124 | } | ||
1125 | |||
1126 | return 0; | ||
1127 | } /* unbind_request */ | ||
1128 | |||
1129 | int pcmcia_deregister_client(struct pcmcia_device *p_dev) | ||
1130 | { | ||
1131 | struct pcmcia_socket *s; | ||
1132 | int i; | ||
1133 | |||
1134 | s = p_dev->socket; | ||
1135 | ds_dbg(1, "deregister_client(%p)\n", p_dev); | ||
1136 | |||
1137 | if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) | ||
1138 | goto warn_out; | ||
1139 | for (i = 0; i < MAX_WIN; i++) | ||
1140 | if (p_dev->state & CLIENT_WIN_REQ(i)) | ||
1141 | goto warn_out; | ||
1142 | |||
1143 | if (p_dev->state & CLIENT_STALE) { | ||
1144 | p_dev->state &= ~CLIENT_STALE; | ||
1145 | pcmcia_put_dev(p_dev); | ||
1146 | } else { | ||
1147 | p_dev->state = CLIENT_UNBOUND; | ||
1148 | } | ||
1149 | |||
1150 | return CS_SUCCESS; | ||
1151 | warn_out: | ||
1152 | printk(KERN_WARNING "ds: deregister_client was called too early.\n"); | ||
1153 | return CS_IN_USE; | ||
1154 | } /* deregister_client */ | ||
1155 | EXPORT_SYMBOL(pcmcia_deregister_client); | ||
1156 | |||
1157 | static struct pcmcia_callback pcmcia_bus_callback = { | 1096 | static struct pcmcia_callback pcmcia_bus_callback = { |
1158 | .owner = THIS_MODULE, | 1097 | .owner = THIS_MODULE, |
1159 | .event = ds_event, | 1098 | .event = ds_event, |
1160 | .requery = pcmcia_bus_rescan, | 1099 | .requery = pcmcia_bus_rescan, |
1100 | .suspend = pcmcia_bus_suspend, | ||
1101 | .resume = pcmcia_bus_resume, | ||
1161 | }; | 1102 | }; |
1162 | 1103 | ||
1163 | static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, | 1104 | static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, |
@@ -1223,9 +1164,11 @@ static struct class_interface pcmcia_bus_interface = { | |||
1223 | 1164 | ||
1224 | struct bus_type pcmcia_bus_type = { | 1165 | struct bus_type pcmcia_bus_type = { |
1225 | .name = "pcmcia", | 1166 | .name = "pcmcia", |
1226 | .hotplug = pcmcia_bus_hotplug, | 1167 | .uevent = pcmcia_bus_uevent, |
1227 | .match = pcmcia_bus_match, | 1168 | .match = pcmcia_bus_match, |
1228 | .dev_attrs = pcmcia_dev_attrs, | 1169 | .dev_attrs = pcmcia_dev_attrs, |
1170 | .suspend = pcmcia_dev_suspend, | ||
1171 | .resume = pcmcia_dev_resume, | ||
1229 | }; | 1172 | }; |
1230 | 1173 | ||
1231 | 1174 | ||
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index 561706ba4499..b39435bbfaeb 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c | |||
@@ -417,18 +417,6 @@ static int hs_get_status(struct pcmcia_socket *s, u_int *value) | |||
417 | 417 | ||
418 | /*============================================================*/ | 418 | /*============================================================*/ |
419 | 419 | ||
420 | static int hs_get_socket(struct pcmcia_socket *s, socket_state_t *state) | ||
421 | { | ||
422 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); | ||
423 | |||
424 | DPRINTK("hs_get_socket(%d)\n", sock); | ||
425 | |||
426 | *state = sp->state; | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | /*============================================================*/ | ||
431 | |||
432 | static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state) | 420 | static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state) |
433 | { | 421 | { |
434 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); | 422 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); |
@@ -749,7 +737,6 @@ static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs) | |||
749 | static struct pccard_operations hs_operations = { | 737 | static struct pccard_operations hs_operations = { |
750 | .init = hs_init, | 738 | .init = hs_init, |
751 | .get_status = hs_get_status, | 739 | .get_status = hs_get_status, |
752 | .get_socket = hs_get_socket, | ||
753 | .set_socket = hs_set_socket, | 740 | .set_socket = hs_set_socket, |
754 | .set_io_map = hs_set_io_map, | 741 | .set_io_map = hs_set_io_map, |
755 | .set_mem_map = hs_set_mem_map, | 742 | .set_mem_map = hs_set_mem_map, |
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index f3fdc748659d..7979c85df3dc 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c | |||
@@ -66,7 +66,6 @@ static struct pci_driver i82092aa_pci_drv = { | |||
66 | static struct pccard_operations i82092aa_operations = { | 66 | static struct pccard_operations i82092aa_operations = { |
67 | .init = i82092aa_init, | 67 | .init = i82092aa_init, |
68 | .get_status = i82092aa_get_status, | 68 | .get_status = i82092aa_get_status, |
69 | .get_socket = i82092aa_get_socket, | ||
70 | .set_socket = i82092aa_set_socket, | 69 | .set_socket = i82092aa_set_socket, |
71 | .set_io_map = i82092aa_set_io_map, | 70 | .set_io_map = i82092aa_set_io_map, |
72 | .set_mem_map = i82092aa_set_mem_map, | 71 | .set_mem_map = i82092aa_set_mem_map, |
@@ -482,78 +481,6 @@ static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value) | |||
482 | } | 481 | } |
483 | 482 | ||
484 | 483 | ||
485 | static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state) | ||
486 | { | ||
487 | unsigned int sock = container_of(socket, struct socket_info, socket)->number; | ||
488 | unsigned char reg,vcc,vpp; | ||
489 | |||
490 | enter("i82092aa_get_socket"); | ||
491 | state->flags = 0; | ||
492 | state->Vcc = 0; | ||
493 | state->Vpp = 0; | ||
494 | state->io_irq = 0; | ||
495 | state->csc_mask = 0; | ||
496 | |||
497 | /* First the power status of the socket */ | ||
498 | reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */ | ||
499 | |||
500 | if (reg & I365_PWR_AUTO) | ||
501 | state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */ | ||
502 | |||
503 | if (reg & I365_PWR_OUT) | ||
504 | state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ | ||
505 | |||
506 | vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; | ||
507 | |||
508 | if (reg & I365_VCC_5V) { /* Can still be 3.3V, in this case the Vcc value will be overwritten later */ | ||
509 | state->Vcc = 50; | ||
510 | |||
511 | if (vpp == I365_VPP1_5V) | ||
512 | state->Vpp = 50; | ||
513 | if (vpp == I365_VPP1_12V) | ||
514 | state->Vpp = 120; | ||
515 | |||
516 | } | ||
517 | |||
518 | if ((reg & I365_VCC_3V)==I365_VCC_3V) | ||
519 | state->Vcc = 33; | ||
520 | |||
521 | |||
522 | /* Now the IO card, RESET flags and IO interrupt */ | ||
523 | |||
524 | reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */ | ||
525 | |||
526 | if ((reg & I365_PC_RESET)==0) | ||
527 | state->flags |= SS_RESET; | ||
528 | if (reg & I365_PC_IOCARD) | ||
529 | state->flags |= SS_IOCARD; /* This is an IO card */ | ||
530 | |||
531 | /* Set the IRQ number */ | ||
532 | if (sockets[sock].dev!=NULL) | ||
533 | state->io_irq = sockets[sock].dev->irq; | ||
534 | |||
535 | /* Card status change */ | ||
536 | reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */ | ||
537 | |||
538 | if (reg & I365_CSC_DETECT) | ||
539 | state->csc_mask |= SS_DETECT; /* Card detect is enabled */ | ||
540 | |||
541 | if (state->flags & SS_IOCARD) {/* IO Cards behave different */ | ||
542 | if (reg & I365_CSC_STSCHG) | ||
543 | state->csc_mask |= SS_STSCHG; | ||
544 | } else { | ||
545 | if (reg & I365_CSC_BVD1) | ||
546 | state->csc_mask |= SS_BATDEAD; | ||
547 | if (reg & I365_CSC_BVD2) | ||
548 | state->csc_mask |= SS_BATWARN; | ||
549 | if (reg & I365_CSC_READY) | ||
550 | state->csc_mask |= SS_READY; | ||
551 | } | ||
552 | |||
553 | leave("i82092aa_get_socket"); | ||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state) | 484 | static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state) |
558 | { | 485 | { |
559 | unsigned int sock = container_of(socket, struct socket_info, socket)->number; | 486 | unsigned int sock = container_of(socket, struct socket_info, socket)->number; |
diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h index b98cac7bda9f..9c14599d0673 100644 --- a/drivers/pcmcia/i82092aa.h +++ b/drivers/pcmcia/i82092aa.h | |||
@@ -29,7 +29,6 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs); | |||
29 | 29 | ||
30 | 30 | ||
31 | static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value); | 31 | static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value); |
32 | static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state); | ||
33 | static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state); | 32 | static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state); |
34 | static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io); | 33 | static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io); |
35 | static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem); | 34 | static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem); |
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 4d56bc9926d6..35a92d1e4945 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -940,78 +940,6 @@ static int i365_get_status(u_short sock, u_int *value) | |||
940 | 940 | ||
941 | /*====================================================================*/ | 941 | /*====================================================================*/ |
942 | 942 | ||
943 | static int i365_get_socket(u_short sock, socket_state_t *state) | ||
944 | { | ||
945 | struct i82365_socket *t = &socket[sock]; | ||
946 | u_char reg, vcc, vpp; | ||
947 | |||
948 | reg = i365_get(sock, I365_POWER); | ||
949 | state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; | ||
950 | state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; | ||
951 | vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; | ||
952 | state->Vcc = state->Vpp = 0; | ||
953 | if (t->flags & IS_CIRRUS) { | ||
954 | if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) { | ||
955 | if (reg & I365_VCC_5V) state->Vcc = 33; | ||
956 | if (vpp == I365_VPP1_5V) state->Vpp = 33; | ||
957 | } else { | ||
958 | if (reg & I365_VCC_5V) state->Vcc = 50; | ||
959 | if (vpp == I365_VPP1_5V) state->Vpp = 50; | ||
960 | } | ||
961 | if (vpp == I365_VPP1_12V) state->Vpp = 120; | ||
962 | } else if (t->flags & IS_VG_PWR) { | ||
963 | if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) { | ||
964 | if (reg & I365_VCC_5V) state->Vcc = 33; | ||
965 | if (vpp == I365_VPP1_5V) state->Vpp = 33; | ||
966 | } else { | ||
967 | if (reg & I365_VCC_5V) state->Vcc = 50; | ||
968 | if (vpp == I365_VPP1_5V) state->Vpp = 50; | ||
969 | } | ||
970 | if (vpp == I365_VPP1_12V) state->Vpp = 120; | ||
971 | } else if (t->flags & IS_DF_PWR) { | ||
972 | if (vcc == I365_VCC_3V) state->Vcc = 33; | ||
973 | if (vcc == I365_VCC_5V) state->Vcc = 50; | ||
974 | if (vpp == I365_VPP1_5V) state->Vpp = 50; | ||
975 | if (vpp == I365_VPP1_12V) state->Vpp = 120; | ||
976 | } else { | ||
977 | if (reg & I365_VCC_5V) { | ||
978 | state->Vcc = 50; | ||
979 | if (vpp == I365_VPP1_5V) state->Vpp = 50; | ||
980 | if (vpp == I365_VPP1_12V) state->Vpp = 120; | ||
981 | } | ||
982 | } | ||
983 | |||
984 | /* IO card, RESET flags, IO interrupt */ | ||
985 | reg = i365_get(sock, I365_INTCTL); | ||
986 | state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; | ||
987 | if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD; | ||
988 | state->io_irq = reg & I365_IRQ_MASK; | ||
989 | |||
990 | /* speaker control */ | ||
991 | if (t->flags & IS_CIRRUS) { | ||
992 | if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA) | ||
993 | state->flags |= SS_SPKR_ENA; | ||
994 | } | ||
995 | |||
996 | /* Card status change mask */ | ||
997 | reg = i365_get(sock, I365_CSCINT); | ||
998 | state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; | ||
999 | if (state->flags & SS_IOCARD) | ||
1000 | state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; | ||
1001 | else { | ||
1002 | state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; | ||
1003 | state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; | ||
1004 | state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; | ||
1005 | } | ||
1006 | |||
1007 | debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " | ||
1008 | "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, | ||
1009 | state->Vcc, state->Vpp, state->io_irq, state->csc_mask); | ||
1010 | return 0; | ||
1011 | } /* i365_get_socket */ | ||
1012 | |||
1013 | /*====================================================================*/ | ||
1014 | |||
1015 | static int i365_set_socket(u_short sock, socket_state_t *state) | 943 | static int i365_set_socket(u_short sock, socket_state_t *state) |
1016 | { | 944 | { |
1017 | struct i82365_socket *t = &socket[sock]; | 945 | struct i82365_socket *t = &socket[sock]; |
@@ -1265,16 +1193,6 @@ static int pcic_get_status(struct pcmcia_socket *s, u_int *value) | |||
1265 | LOCKED(i365_get_status(sock, value)); | 1193 | LOCKED(i365_get_status(sock, value)); |
1266 | } | 1194 | } |
1267 | 1195 | ||
1268 | static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state) | ||
1269 | { | ||
1270 | unsigned int sock = container_of(s, struct i82365_socket, socket)->number; | ||
1271 | |||
1272 | if (socket[sock].flags & IS_ALIVE) | ||
1273 | return -EINVAL; | ||
1274 | |||
1275 | LOCKED(i365_get_socket(sock, state)); | ||
1276 | } | ||
1277 | |||
1278 | static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state) | 1196 | static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state) |
1279 | { | 1197 | { |
1280 | unsigned int sock = container_of(s, struct i82365_socket, socket)->number; | 1198 | unsigned int sock = container_of(s, struct i82365_socket, socket)->number; |
@@ -1324,7 +1242,6 @@ static int pcic_init(struct pcmcia_socket *s) | |||
1324 | static struct pccard_operations pcic_operations = { | 1242 | static struct pccard_operations pcic_operations = { |
1325 | .init = pcic_init, | 1243 | .init = pcic_init, |
1326 | .get_status = pcic_get_status, | 1244 | .get_status = pcic_get_status, |
1327 | .get_socket = pcic_get_socket, | ||
1328 | .set_socket = pcic_set_socket, | 1245 | .set_socket = pcic_set_socket, |
1329 | .set_io_map = pcic_set_io_map, | 1246 | .set_io_map = pcic_set_io_map, |
1330 | .set_mem_map = pcic_set_mem_map, | 1247 | .set_mem_map = pcic_set_mem_map, |
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 078579ae6359..071cf485e1a3 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c | |||
@@ -480,25 +480,6 @@ static int _pcc_get_status(u_short sock, u_int *value) | |||
480 | 480 | ||
481 | /*====================================================================*/ | 481 | /*====================================================================*/ |
482 | 482 | ||
483 | static int _pcc_get_socket(u_short sock, socket_state_t *state) | ||
484 | { | ||
485 | // pcc_socket_t *t = &socket[sock]; | ||
486 | |||
487 | state->flags = 0; | ||
488 | state->csc_mask = SS_DETECT; | ||
489 | state->csc_mask |= SS_READY; | ||
490 | state->io_irq = 0; | ||
491 | state->Vcc = 33; /* 3.3V fixed */ | ||
492 | state->Vpp = 33; | ||
493 | |||
494 | debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " | ||
495 | "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, | ||
496 | state->Vcc, state->Vpp, state->io_irq, state->csc_mask); | ||
497 | return 0; | ||
498 | } /* _get_socket */ | ||
499 | |||
500 | /*====================================================================*/ | ||
501 | |||
502 | static int _pcc_set_socket(u_short sock, socket_state_t *state) | 483 | static int _pcc_set_socket(u_short sock, socket_state_t *state) |
503 | { | 484 | { |
504 | debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " | 485 | debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " |
@@ -667,18 +648,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value) | |||
667 | LOCKED(_pcc_get_status(sock, value)); | 648 | LOCKED(_pcc_get_status(sock, value)); |
668 | } | 649 | } |
669 | 650 | ||
670 | static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state) | ||
671 | { | ||
672 | unsigned int sock = container_of(s, struct pcc_socket, socket)->number; | ||
673 | |||
674 | if (socket[sock].flags & IS_ALIVE) { | ||
675 | debug(3, "m32r_cfc: pcc_get_socket: sock(%d) -EINVAL\n", sock); | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | debug(3, "m32r_cfc: pcc_get_socket: sock(%d)\n", sock); | ||
679 | LOCKED(_pcc_get_socket(sock, state)); | ||
680 | } | ||
681 | |||
682 | static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) | 651 | static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) |
683 | { | 652 | { |
684 | unsigned int sock = container_of(s, struct pcc_socket, socket)->number; | 653 | unsigned int sock = container_of(s, struct pcc_socket, socket)->number; |
@@ -724,7 +693,6 @@ static int pcc_init(struct pcmcia_socket *s) | |||
724 | static struct pccard_operations pcc_operations = { | 693 | static struct pccard_operations pcc_operations = { |
725 | .init = pcc_init, | 694 | .init = pcc_init, |
726 | .get_status = pcc_get_status, | 695 | .get_status = pcc_get_status, |
727 | .get_socket = pcc_get_socket, | ||
728 | .set_socket = pcc_set_socket, | 696 | .set_socket = pcc_set_socket, |
729 | .set_io_map = pcc_set_io_map, | 697 | .set_io_map = pcc_set_io_map, |
730 | .set_mem_map = pcc_set_mem_map, | 698 | .set_mem_map = pcc_set_mem_map, |
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 356a6fb416a1..70d5f0748d55 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c | |||
@@ -429,16 +429,6 @@ static int _pcc_get_status(u_short sock, u_int *value) | |||
429 | 429 | ||
430 | /*====================================================================*/ | 430 | /*====================================================================*/ |
431 | 431 | ||
432 | static int _pcc_get_socket(u_short sock, socket_state_t *state) | ||
433 | { | ||
434 | debug(3, "m32r-pcc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " | ||
435 | "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, | ||
436 | state->Vcc, state->Vpp, state->io_irq, state->csc_mask); | ||
437 | return 0; | ||
438 | } /* _get_socket */ | ||
439 | |||
440 | /*====================================================================*/ | ||
441 | |||
442 | static int _pcc_set_socket(u_short sock, socket_state_t *state) | 432 | static int _pcc_set_socket(u_short sock, socket_state_t *state) |
443 | { | 433 | { |
444 | u_long reg = 0; | 434 | u_long reg = 0; |
@@ -641,15 +631,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value) | |||
641 | LOCKED(_pcc_get_status(sock, value)); | 631 | LOCKED(_pcc_get_status(sock, value)); |
642 | } | 632 | } |
643 | 633 | ||
644 | static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state) | ||
645 | { | ||
646 | unsigned int sock = container_of(s, struct pcc_socket, socket)->number; | ||
647 | |||
648 | if (socket[sock].flags & IS_ALIVE) | ||
649 | return -EINVAL; | ||
650 | LOCKED(_pcc_get_socket(sock, state)); | ||
651 | } | ||
652 | |||
653 | static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) | 634 | static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) |
654 | { | 635 | { |
655 | unsigned int sock = container_of(s, struct pcc_socket, socket)->number; | 636 | unsigned int sock = container_of(s, struct pcc_socket, socket)->number; |
@@ -687,7 +668,6 @@ static int pcc_init(struct pcmcia_socket *s) | |||
687 | static struct pccard_operations pcc_operations = { | 668 | static struct pccard_operations pcc_operations = { |
688 | .init = pcc_init, | 669 | .init = pcc_init, |
689 | .get_status = pcc_get_status, | 670 | .get_status = pcc_get_status, |
690 | .get_socket = pcc_get_socket, | ||
691 | .set_socket = pcc_set_socket, | 671 | .set_socket = pcc_set_socket, |
692 | .set_io_map = pcc_set_io_map, | 672 | .set_io_map = pcc_set_io_map, |
693 | .set_mem_map = pcc_set_mem_map, | 673 | .set_mem_map = pcc_set_mem_map, |
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 6d9f71cfcb34..0e07d9535116 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -9,6 +9,9 @@ | |||
9 | * <oliver.kurth@cyclades.de> | 9 | * <oliver.kurth@cyclades.de> |
10 | * Further fixes, v2.6 kernel port | 10 | * Further fixes, v2.6 kernel port |
11 | * <marcelo.tosatti@cyclades.com> | 11 | * <marcelo.tosatti@cyclades.com> |
12 | * | ||
13 | * Some fixes, additions (C) 2005 Montavista Software, Inc. | ||
14 | * <vbordug@ru.mvista.com> | ||
12 | * | 15 | * |
13 | * "The ExCA standard specifies that socket controllers should provide | 16 | * "The ExCA standard specifies that socket controllers should provide |
14 | * two IO and five memory windows per socket, which can be independently | 17 | * two IO and five memory windows per socket, which can be independently |
@@ -97,6 +100,11 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
97 | #endif | 100 | #endif |
98 | #endif | 101 | #endif |
99 | 102 | ||
103 | #if defined(CONFIG_MPC885ADS) | ||
104 | #define CONFIG_PCMCIA_SLOT_A | ||
105 | #define PCMCIA_GLITCHY_CD | ||
106 | #endif | ||
107 | |||
100 | /* Cyclades ACS uses both slots */ | 108 | /* Cyclades ACS uses both slots */ |
101 | #ifdef CONFIG_PRxK | 109 | #ifdef CONFIG_PRxK |
102 | #define CONFIG_PCMCIA_SLOT_A | 110 | #define CONFIG_PCMCIA_SLOT_A |
@@ -374,10 +382,10 @@ static int voltage_set(int slot, int vcc, int vpp) | |||
374 | } | 382 | } |
375 | 383 | ||
376 | /* first, turn off all power */ | 384 | /* first, turn off all power */ |
377 | out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); | 385 | out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); |
378 | 386 | ||
379 | /* enable new powersettings */ | 387 | /* enable new powersettings */ |
380 | out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg); | 388 | out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg); |
381 | 389 | ||
382 | return 0; | 390 | return 0; |
383 | } | 391 | } |
@@ -386,12 +394,89 @@ static int voltage_set(int slot, int vcc, int vpp) | |||
386 | 394 | ||
387 | static void hardware_enable(int slot) | 395 | static void hardware_enable(int slot) |
388 | { | 396 | { |
389 | out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN); | 397 | out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN); |
390 | } | 398 | } |
391 | 399 | ||
392 | static void hardware_disable(int slot) | 400 | static void hardware_disable(int slot) |
393 | { | 401 | { |
394 | out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | BCSR1_PCCEN); | 402 | out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | BCSR1_PCCEN); |
403 | } | ||
404 | |||
405 | #endif | ||
406 | |||
407 | /* MPC885ADS Boards */ | ||
408 | |||
409 | #if defined(CONFIG_MPC885ADS) | ||
410 | |||
411 | #define PCMCIA_BOARD_MSG "MPC885ADS" | ||
412 | |||
413 | static int voltage_set(int slot, int vcc, int vpp) | ||
414 | { | ||
415 | u32 reg = 0; | ||
416 | unsigned *bcsr_io; | ||
417 | |||
418 | bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); | ||
419 | |||
420 | switch(vcc) { | ||
421 | case 0: | ||
422 | break; | ||
423 | case 33: | ||
424 | reg |= BCSR1_PCCVCC0; | ||
425 | break; | ||
426 | case 50: | ||
427 | reg |= BCSR1_PCCVCC1; | ||
428 | break; | ||
429 | default: | ||
430 | return 1; | ||
431 | } | ||
432 | |||
433 | switch(vpp) { | ||
434 | case 0: | ||
435 | break; | ||
436 | case 33: | ||
437 | case 50: | ||
438 | if(vcc == vpp) | ||
439 | reg |= BCSR1_PCCVPP1; | ||
440 | else | ||
441 | return 1; | ||
442 | break; | ||
443 | case 120: | ||
444 | if ((vcc == 33) || (vcc == 50)) | ||
445 | reg |= BCSR1_PCCVPP0; | ||
446 | else | ||
447 | return 1; | ||
448 | default: | ||
449 | return 1; | ||
450 | } | ||
451 | |||
452 | /* first, turn off all power */ | ||
453 | out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); | ||
454 | |||
455 | /* enable new powersettings */ | ||
456 | out_be32(bcsr_io, in_be32(bcsr_io) | reg); | ||
457 | |||
458 | iounmap(bcsr_io); | ||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V | ||
463 | |||
464 | static void hardware_enable(int slot) | ||
465 | { | ||
466 | unsigned *bcsr_io; | ||
467 | |||
468 | bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); | ||
469 | out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN); | ||
470 | iounmap(bcsr_io); | ||
471 | } | ||
472 | |||
473 | static void hardware_disable(int slot) | ||
474 | { | ||
475 | unsigned *bcsr_io; | ||
476 | |||
477 | bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); | ||
478 | out_be32(bcsr_io, in_be32(bcsr_io) | BCSR1_PCCEN); | ||
479 | iounmap(bcsr_io); | ||
395 | } | 480 | } |
396 | 481 | ||
397 | #endif | 482 | #endif |
@@ -440,10 +525,10 @@ static int voltage_set(int slot, int vcc, int vpp) | |||
440 | } | 525 | } |
441 | 526 | ||
442 | /* first, turn off all power */ | 527 | /* first, turn off all power */ |
443 | out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK)); | 528 | out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK)); |
444 | 529 | ||
445 | /* enable new powersettings */ | 530 | /* enable new powersettings */ |
446 | out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg); | 531 | out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg); |
447 | 532 | ||
448 | return 0; | 533 | return 0; |
449 | } | 534 | } |
@@ -823,17 +908,6 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value) | |||
823 | return 0; | 908 | return 0; |
824 | } | 909 | } |
825 | 910 | ||
826 | static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
827 | { | ||
828 | int lsock = container_of(sock, struct socket_info, socket)->slot; | ||
829 | *state = socket[lsock].state; /* copy the whole structure */ | ||
830 | |||
831 | dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " | ||
832 | "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags, | ||
833 | state->Vcc, state->Vpp, state->io_irq, state->csc_mask); | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | 911 | static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state) |
838 | { | 912 | { |
839 | int lsock = container_of(sock, struct socket_info, socket)->slot; | 913 | int lsock = container_of(sock, struct socket_info, socket)->slot; |
@@ -1023,8 +1097,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) | |||
1023 | if(io->flags & MAP_WRPROT) | 1097 | if(io->flags & MAP_WRPROT) |
1024 | reg |= M8XX_PCMCIA_POR_WRPROT; | 1098 | reg |= M8XX_PCMCIA_POR_WRPROT; |
1025 | 1099 | ||
1026 | /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/ | 1100 | if(io->flags & (MAP_16BIT | MAP_AUTOSZ)) |
1027 | if(io->flags & MAP_16BIT) | ||
1028 | reg |= M8XX_PCMCIA_POR_16BIT; | 1101 | reg |= M8XX_PCMCIA_POR_16BIT; |
1029 | 1102 | ||
1030 | if(io->flags & MAP_ACTIVE) | 1103 | if(io->flags & MAP_ACTIVE) |
@@ -1169,7 +1242,6 @@ static struct pccard_operations m8xx_services = { | |||
1169 | .init = m8xx_sock_init, | 1242 | .init = m8xx_sock_init, |
1170 | .suspend = m8xx_suspend, | 1243 | .suspend = m8xx_suspend, |
1171 | .get_status = m8xx_get_status, | 1244 | .get_status = m8xx_get_status, |
1172 | .get_socket = m8xx_get_socket, | ||
1173 | .set_socket = m8xx_set_socket, | 1245 | .set_socket = m8xx_set_socket, |
1174 | .set_io_map = m8xx_set_io_map, | 1246 | .set_io_map = m8xx_set_io_map, |
1175 | .set_mem_map = m8xx_set_mem_map, | 1247 | .set_mem_map = m8xx_set_mem_map, |
@@ -1244,7 +1316,7 @@ static int __init m8xx_init(void) | |||
1244 | socket[i].socket.io_offset = 0; | 1316 | socket[i].socket.io_offset = 0; |
1245 | socket[i].socket.pci_irq = i ? 7 : 9; | 1317 | socket[i].socket.pci_irq = i ? 7 : 9; |
1246 | socket[i].socket.ops = &m8xx_services; | 1318 | socket[i].socket.ops = &m8xx_services; |
1247 | socket[i].socket.resource_ops = &pccard_nonstatic_ops; | 1319 | socket[i].socket.resource_ops = &pccard_iodyn_ops; |
1248 | socket[i].socket.cb_dev = NULL; | 1320 | socket[i].socket.cb_dev = NULL; |
1249 | socket[i].socket.dev.dev = &m8xx_device.dev; | 1321 | socket[i].socket.dev.dev = &m8xx_device.dev; |
1250 | } | 1322 | } |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 20642f0e7bfe..f2789afb22b2 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -304,75 +304,6 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value) | |||
304 | } | 304 | } |
305 | 305 | ||
306 | 306 | ||
307 | static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
308 | { | ||
309 | struct pd6729_socket *socket | ||
310 | = container_of(sock, struct pd6729_socket, socket); | ||
311 | unsigned char reg, vcc, vpp; | ||
312 | |||
313 | state->flags = 0; | ||
314 | state->Vcc = 0; | ||
315 | state->Vpp = 0; | ||
316 | state->io_irq = 0; | ||
317 | state->csc_mask = 0; | ||
318 | |||
319 | /* First the power status of the socket */ | ||
320 | reg = indirect_read(socket, I365_POWER); | ||
321 | |||
322 | if (reg & I365_PWR_AUTO) | ||
323 | state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */ | ||
324 | |||
325 | if (reg & I365_PWR_OUT) | ||
326 | state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ | ||
327 | |||
328 | vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; | ||
329 | |||
330 | if (reg & I365_VCC_5V) { | ||
331 | state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) & | ||
332 | PD67_MC1_VCC_3V) ? 33 : 50; | ||
333 | |||
334 | if (vpp == I365_VPP1_5V) { | ||
335 | if (state->Vcc == 50) | ||
336 | state->Vpp = 50; | ||
337 | else | ||
338 | state->Vpp = 33; | ||
339 | } | ||
340 | if (vpp == I365_VPP1_12V) | ||
341 | state->Vpp = 120; | ||
342 | } | ||
343 | |||
344 | /* Now the IO card, RESET flags and IO interrupt */ | ||
345 | reg = indirect_read(socket, I365_INTCTL); | ||
346 | |||
347 | if ((reg & I365_PC_RESET) == 0) | ||
348 | state->flags |= SS_RESET; | ||
349 | if (reg & I365_PC_IOCARD) | ||
350 | state->flags |= SS_IOCARD; /* This is an IO card */ | ||
351 | |||
352 | /* Set the IRQ number */ | ||
353 | state->io_irq = socket->card_irq; | ||
354 | |||
355 | /* Card status change */ | ||
356 | reg = indirect_read(socket, I365_CSCINT); | ||
357 | |||
358 | if (reg & I365_CSC_DETECT) | ||
359 | state->csc_mask |= SS_DETECT; /* Card detect is enabled */ | ||
360 | |||
361 | if (state->flags & SS_IOCARD) {/* IO Cards behave different */ | ||
362 | if (reg & I365_CSC_STSCHG) | ||
363 | state->csc_mask |= SS_STSCHG; | ||
364 | } else { | ||
365 | if (reg & I365_CSC_BVD1) | ||
366 | state->csc_mask |= SS_BATDEAD; | ||
367 | if (reg & I365_CSC_BVD2) | ||
368 | state->csc_mask |= SS_BATWARN; | ||
369 | if (reg & I365_CSC_READY) | ||
370 | state->csc_mask |= SS_READY; | ||
371 | } | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | 307 | static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) |
377 | { | 308 | { |
378 | struct pd6729_socket *socket | 309 | struct pd6729_socket *socket |
@@ -640,7 +571,6 @@ static int pd6729_init(struct pcmcia_socket *sock) | |||
640 | static struct pccard_operations pd6729_operations = { | 571 | static struct pccard_operations pd6729_operations = { |
641 | .init = pd6729_init, | 572 | .init = pd6729_init, |
642 | .get_status = pd6729_get_status, | 573 | .get_status = pd6729_get_status, |
643 | .get_socket = pd6729_get_socket, | ||
644 | .set_socket = pd6729_set_socket, | 574 | .set_socket = pd6729_set_socket, |
645 | .set_io_map = pd6729_set_io_map, | 575 | .set_io_map = pd6729_set_io_map, |
646 | .set_mem_map = pd6729_set_mem_map, | 576 | .set_mem_map = pd6729_set_mem_map, |
@@ -704,13 +634,11 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
704 | char configbyte; | 634 | char configbyte; |
705 | struct pd6729_socket *socket; | 635 | struct pd6729_socket *socket; |
706 | 636 | ||
707 | socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, | 637 | socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, |
708 | GFP_KERNEL); | 638 | GFP_KERNEL); |
709 | if (!socket) | 639 | if (!socket) |
710 | return -ENOMEM; | 640 | return -ENOMEM; |
711 | 641 | ||
712 | memset(socket, 0, sizeof(struct pd6729_socket) * MAX_SOCKETS); | ||
713 | |||
714 | if ((ret = pci_enable_device(dev))) | 642 | if ((ret = pci_enable_device(dev))) |
715 | goto err_out_free_mem; | 643 | goto err_out_free_mem; |
716 | 644 | ||
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index 5209d8c7764f..5d957dfe23d9 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c | |||
@@ -171,10 +171,9 @@ static int __init mst_pcmcia_init(void) | |||
171 | { | 171 | { |
172 | int ret; | 172 | int ret; |
173 | 173 | ||
174 | mst_pcmcia_device = kmalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL); | 174 | mst_pcmcia_device = kzalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL); |
175 | if (!mst_pcmcia_device) | 175 | if (!mst_pcmcia_device) |
176 | return -ENOMEM; | 176 | return -ENOMEM; |
177 | memset(mst_pcmcia_device, 0, sizeof(*mst_pcmcia_device)); | ||
178 | mst_pcmcia_device->name = "pxa2xx-pcmcia"; | 177 | mst_pcmcia_device->name = "pxa2xx-pcmcia"; |
179 | mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; | 178 | mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; |
180 | 179 | ||
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 56c58831e80e..b5fdeec20b15 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -264,11 +264,10 @@ static int __init sharpsl_pcmcia_init(void) | |||
264 | int ret; | 264 | int ret; |
265 | 265 | ||
266 | sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs; | 266 | sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs; |
267 | sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); | 267 | sharpsl_pcmcia_device = kzalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); |
268 | if (!sharpsl_pcmcia_device) | 268 | if (!sharpsl_pcmcia_device) |
269 | return -ENOMEM; | 269 | return -ENOMEM; |
270 | 270 | ||
271 | memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); | ||
272 | sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; | 271 | sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; |
273 | sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; | 272 | sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; |
274 | sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev; | 273 | sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev; |
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 0668384ebc8b..514609369836 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c | |||
@@ -98,10 +98,12 @@ int pcmcia_adjust_resource_info(adjust_t *adj) | |||
98 | } | 98 | } |
99 | EXPORT_SYMBOL(pcmcia_adjust_resource_info); | 99 | EXPORT_SYMBOL(pcmcia_adjust_resource_info); |
100 | 100 | ||
101 | void pcmcia_validate_mem(struct pcmcia_socket *s) | 101 | int pcmcia_validate_mem(struct pcmcia_socket *s) |
102 | { | 102 | { |
103 | if (s->resource_ops->validate_mem) | 103 | if (s->resource_ops->validate_mem) |
104 | s->resource_ops->validate_mem(s); | 104 | return s->resource_ops->validate_mem(s); |
105 | /* if there is no callback, we can assume that everything is OK */ | ||
106 | return 0; | ||
105 | } | 107 | } |
106 | EXPORT_SYMBOL(pcmcia_validate_mem); | 108 | EXPORT_SYMBOL(pcmcia_validate_mem); |
107 | 109 | ||
@@ -164,3 +166,105 @@ struct pccard_resource_ops pccard_static_ops = { | |||
164 | .exit = NULL, | 166 | .exit = NULL, |
165 | }; | 167 | }; |
166 | EXPORT_SYMBOL(pccard_static_ops); | 168 | EXPORT_SYMBOL(pccard_static_ops); |
169 | |||
170 | |||
171 | #ifdef CONFIG_PCCARD_IODYN | ||
172 | |||
173 | static struct resource * | ||
174 | make_resource(unsigned long b, unsigned long n, int flags, char *name) | ||
175 | { | ||
176 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | ||
177 | |||
178 | if (res) { | ||
179 | res->name = name; | ||
180 | res->start = b; | ||
181 | res->end = b + n - 1; | ||
182 | res->flags = flags; | ||
183 | } | ||
184 | return res; | ||
185 | } | ||
186 | |||
187 | struct pcmcia_align_data { | ||
188 | unsigned long mask; | ||
189 | unsigned long offset; | ||
190 | }; | ||
191 | |||
192 | static void pcmcia_align(void *align_data, struct resource *res, | ||
193 | unsigned long size, unsigned long align) | ||
194 | { | ||
195 | struct pcmcia_align_data *data = align_data; | ||
196 | unsigned long start; | ||
197 | |||
198 | start = (res->start & ~data->mask) + data->offset; | ||
199 | if (start < res->start) | ||
200 | start += data->mask + 1; | ||
201 | res->start = start; | ||
202 | |||
203 | #ifdef CONFIG_X86 | ||
204 | if (res->flags & IORESOURCE_IO) { | ||
205 | if (start & 0x300) { | ||
206 | start = (start + 0x3ff) & ~0x3ff; | ||
207 | res->start = start; | ||
208 | } | ||
209 | } | ||
210 | #endif | ||
211 | |||
212 | #ifdef CONFIG_M68K | ||
213 | if (res->flags & IORESOURCE_IO) { | ||
214 | if ((res->start + size - 1) >= 1024) | ||
215 | res->start = res->end; | ||
216 | } | ||
217 | #endif | ||
218 | } | ||
219 | |||
220 | |||
221 | static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, | ||
222 | unsigned long r_end, struct pcmcia_socket *s) | ||
223 | { | ||
224 | return adjust_resource(res, r_start, r_end - r_start + 1); | ||
225 | } | ||
226 | |||
227 | |||
228 | static struct resource *iodyn_find_io_region(unsigned long base, int num, | ||
229 | unsigned long align, struct pcmcia_socket *s) | ||
230 | { | ||
231 | struct resource *res = make_resource(0, num, IORESOURCE_IO, | ||
232 | s->dev.class_id); | ||
233 | struct pcmcia_align_data data; | ||
234 | unsigned long min = base; | ||
235 | int ret; | ||
236 | |||
237 | if (align == 0) | ||
238 | align = 0x10000; | ||
239 | |||
240 | data.mask = align - 1; | ||
241 | data.offset = base & data.mask; | ||
242 | |||
243 | #ifdef CONFIG_PCI | ||
244 | if (s->cb_dev) { | ||
245 | ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, | ||
246 | min, 0, pcmcia_align, &data); | ||
247 | } else | ||
248 | #endif | ||
249 | ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, | ||
250 | 1, pcmcia_align, &data); | ||
251 | |||
252 | if (ret != 0) { | ||
253 | kfree(res); | ||
254 | res = NULL; | ||
255 | } | ||
256 | return res; | ||
257 | } | ||
258 | |||
259 | struct pccard_resource_ops pccard_iodyn_ops = { | ||
260 | .validate_mem = NULL, | ||
261 | .adjust_io_region = iodyn_adjust_io_region, | ||
262 | .find_io = iodyn_find_io_region, | ||
263 | .find_mem = NULL, | ||
264 | .adjust_resource = NULL, | ||
265 | .init = static_init, | ||
266 | .exit = NULL, | ||
267 | }; | ||
268 | EXPORT_SYMBOL(pccard_iodyn_ops); | ||
269 | |||
270 | #endif /* CONFIG_PCCARD_IODYN */ | ||
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 00960a379b9c..5301ac60358f 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -75,10 +75,9 @@ static DECLARE_MUTEX(rsrc_sem); | |||
75 | static struct resource * | 75 | static struct resource * |
76 | make_resource(unsigned long b, unsigned long n, int flags, char *name) | 76 | make_resource(unsigned long b, unsigned long n, int flags, char *name) |
77 | { | 77 | { |
78 | struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL); | 78 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
79 | 79 | ||
80 | if (res) { | 80 | if (res) { |
81 | memset(res, 0, sizeof(*res)); | ||
82 | res->name = name; | 81 | res->name = name; |
83 | res->start = b; | 82 | res->start = b; |
84 | res->end = b + n - 1; | 83 | res->end = b + n - 1; |
@@ -200,12 +199,11 @@ static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num | |||
200 | base, base+num-1); | 199 | base, base+num-1); |
201 | 200 | ||
202 | /* First, what does a floating port look like? */ | 201 | /* First, what does a floating port look like? */ |
203 | b = kmalloc(256, GFP_KERNEL); | 202 | b = kzalloc(256, GFP_KERNEL); |
204 | if (!b) { | 203 | if (!b) { |
205 | printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes"); | 204 | printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes"); |
206 | return; | 205 | return; |
207 | } | 206 | } |
208 | memset(b, 0, 256); | ||
209 | for (i = base, most = 0; i < base+num; i += 8) { | 207 | for (i = base, most = 0; i < base+num; i += 8) { |
210 | res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe"); | 208 | res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe"); |
211 | if (!res) | 209 | if (!res) |
@@ -407,69 +405,79 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s) | |||
407 | 405 | ||
408 | static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s) | 406 | static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s) |
409 | { | 407 | { |
410 | struct socket_data *s_data = s->resource_data; | 408 | struct socket_data *s_data = s->resource_data; |
411 | u_long ok; | 409 | u_long ok; |
412 | if (m == &s_data->mem_db) | 410 | if (m == &s_data->mem_db) |
413 | return 0; | 411 | return 0; |
414 | ok = inv_probe(m->next, s); | 412 | ok = inv_probe(m->next, s); |
415 | if (ok) { | 413 | if (ok) { |
416 | if (m->base >= 0x100000) | 414 | if (m->base >= 0x100000) |
417 | sub_interval(&s_data->mem_db, m->base, m->num); | 415 | sub_interval(&s_data->mem_db, m->base, m->num); |
418 | return ok; | 416 | return ok; |
419 | } | 417 | } |
420 | if (m->base < 0x100000) | 418 | if (m->base < 0x100000) |
421 | return 0; | 419 | return 0; |
422 | return do_mem_probe(m->base, m->num, s); | 420 | return do_mem_probe(m->base, m->num, s); |
423 | } | 421 | } |
424 | 422 | ||
425 | static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) | 423 | static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) |
426 | { | 424 | { |
427 | struct resource_map *m, mm; | 425 | struct resource_map *m, mm; |
428 | static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; | 426 | static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; |
429 | u_long b, i, ok = 0; | 427 | unsigned long b, i, ok = 0; |
430 | struct socket_data *s_data = s->resource_data; | 428 | struct socket_data *s_data = s->resource_data; |
431 | 429 | ||
432 | /* We do up to four passes through the list */ | 430 | /* We do up to four passes through the list */ |
433 | if (probe_mask & MEM_PROBE_HIGH) { | 431 | if (probe_mask & MEM_PROBE_HIGH) { |
434 | if (inv_probe(s_data->mem_db.next, s) > 0) | 432 | if (inv_probe(s_data->mem_db.next, s) > 0) |
435 | return; | 433 | return 0; |
436 | printk(KERN_NOTICE "cs: warning: no high memory space " | 434 | printk(KERN_NOTICE "cs: warning: no high memory space " |
437 | "available!\n"); | 435 | "available!\n"); |
438 | } | 436 | return -ENODEV; |
439 | if ((probe_mask & MEM_PROBE_LOW) == 0) | ||
440 | return; | ||
441 | for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { | ||
442 | mm = *m; | ||
443 | /* Only probe < 1 MB */ | ||
444 | if (mm.base >= 0x100000) continue; | ||
445 | if ((mm.base | mm.num) & 0xffff) { | ||
446 | ok += do_mem_probe(mm.base, mm.num, s); | ||
447 | continue; | ||
448 | } | 437 | } |
449 | /* Special probe for 64K-aligned block */ | 438 | |
450 | for (i = 0; i < 4; i++) { | 439 | for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { |
451 | b = order[i] << 12; | 440 | mm = *m; |
452 | if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { | 441 | /* Only probe < 1 MB */ |
453 | if (ok >= mem_limit) | 442 | if (mm.base >= 0x100000) |
454 | sub_interval(&s_data->mem_db, b, 0x10000); | 443 | continue; |
455 | else | 444 | if ((mm.base | mm.num) & 0xffff) { |
456 | ok += do_mem_probe(b, 0x10000, s); | 445 | ok += do_mem_probe(mm.base, mm.num, s); |
457 | } | 446 | continue; |
447 | } | ||
448 | /* Special probe for 64K-aligned block */ | ||
449 | for (i = 0; i < 4; i++) { | ||
450 | b = order[i] << 12; | ||
451 | if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { | ||
452 | if (ok >= mem_limit) | ||
453 | sub_interval(&s_data->mem_db, b, 0x10000); | ||
454 | else | ||
455 | ok += do_mem_probe(b, 0x10000, s); | ||
456 | } | ||
457 | } | ||
458 | } | 458 | } |
459 | } | 459 | |
460 | if (ok > 0) | ||
461 | return 0; | ||
462 | |||
463 | return -ENODEV; | ||
460 | } | 464 | } |
461 | 465 | ||
462 | #else /* CONFIG_PCMCIA_PROBE */ | 466 | #else /* CONFIG_PCMCIA_PROBE */ |
463 | 467 | ||
464 | static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) | 468 | static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) |
465 | { | 469 | { |
466 | struct resource_map *m, mm; | 470 | struct resource_map *m, mm; |
467 | struct socket_data *s_data = s->resource_data; | 471 | struct socket_data *s_data = s->resource_data; |
472 | unsigned long ok = 0; | ||
468 | 473 | ||
469 | for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { | 474 | for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { |
470 | mm = *m; | 475 | mm = *m; |
471 | do_mem_probe(mm.base, mm.num, s); | 476 | ok += do_mem_probe(mm.base, mm.num, s); |
472 | } | 477 | } |
478 | if (ok > 0) | ||
479 | return 0; | ||
480 | return -ENODEV; | ||
473 | } | 481 | } |
474 | 482 | ||
475 | #endif /* CONFIG_PCMCIA_PROBE */ | 483 | #endif /* CONFIG_PCMCIA_PROBE */ |
@@ -478,27 +486,30 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) | |||
478 | /* | 486 | /* |
479 | * Locking note: Must be called with skt_sem held! | 487 | * Locking note: Must be called with skt_sem held! |
480 | */ | 488 | */ |
481 | static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) | 489 | static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) |
482 | { | 490 | { |
483 | struct socket_data *s_data = s->resource_data; | 491 | struct socket_data *s_data = s->resource_data; |
484 | if (probe_mem) { | 492 | unsigned int probe_mask = MEM_PROBE_LOW; |
485 | unsigned int probe_mask; | 493 | int ret = 0; |
486 | 494 | ||
487 | down(&rsrc_sem); | 495 | if (!probe_mem) |
496 | return 0; | ||
488 | 497 | ||
489 | probe_mask = MEM_PROBE_LOW; | 498 | down(&rsrc_sem); |
490 | if (s->features & SS_CAP_PAGE_REGS) | ||
491 | probe_mask = MEM_PROBE_HIGH; | ||
492 | 499 | ||
493 | if (probe_mask & ~s_data->rsrc_mem_probe) { | 500 | if (s->features & SS_CAP_PAGE_REGS) |
501 | probe_mask = MEM_PROBE_HIGH; | ||
502 | |||
503 | if (probe_mask & ~s_data->rsrc_mem_probe) { | ||
504 | if (s->state & SOCKET_PRESENT) | ||
505 | ret = validate_mem(s, probe_mask); | ||
506 | if (!ret) | ||
494 | s_data->rsrc_mem_probe |= probe_mask; | 507 | s_data->rsrc_mem_probe |= probe_mask; |
508 | } | ||
495 | 509 | ||
496 | if (s->state & SOCKET_PRESENT) | 510 | up(&rsrc_sem); |
497 | validate_mem(s, probe_mask); | ||
498 | } | ||
499 | 511 | ||
500 | up(&rsrc_sem); | 512 | return ret; |
501 | } | ||
502 | } | 513 | } |
503 | 514 | ||
504 | struct pcmcia_align_data { | 515 | struct pcmcia_align_data { |
@@ -837,10 +848,9 @@ static int nonstatic_init(struct pcmcia_socket *s) | |||
837 | { | 848 | { |
838 | struct socket_data *data; | 849 | struct socket_data *data; |
839 | 850 | ||
840 | data = kmalloc(sizeof(struct socket_data), GFP_KERNEL); | 851 | data = kzalloc(sizeof(struct socket_data), GFP_KERNEL); |
841 | if (!data) | 852 | if (!data) |
842 | return -ENOMEM; | 853 | return -ENOMEM; |
843 | memset(data, 0, sizeof(struct socket_data)); | ||
844 | 854 | ||
845 | data->mem_db.next = &data->mem_db; | 855 | data->mem_db.next = &data->mem_db; |
846 | data->io_db.next = &data->io_db; | 856 | data->io_db.next = &data->io_db; |
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 9e7ccd8a4321..ea7d9ca160b2 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c | |||
@@ -297,25 +297,6 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) | |||
297 | 297 | ||
298 | 298 | ||
299 | /* | 299 | /* |
300 | * Implements the get_socket() operation for the in-kernel PCMCIA | ||
301 | * service (formerly SS_GetSocket in Card Services). Not a very | ||
302 | * exciting routine. | ||
303 | * | ||
304 | * Returns: 0 | ||
305 | */ | ||
306 | static int | ||
307 | soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
308 | { | ||
309 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); | ||
310 | |||
311 | debug(skt, 2, "\n"); | ||
312 | |||
313 | *state = skt->cs_state; | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * Implements the set_socket() operation for the in-kernel PCMCIA | 300 | * Implements the set_socket() operation for the in-kernel PCMCIA |
320 | * service (formerly SS_SetSocket in Card Services). We more or | 301 | * service (formerly SS_SetSocket in Card Services). We more or |
321 | * less punt all of this work and let the kernel handle the details | 302 | * less punt all of this work and let the kernel handle the details |
@@ -528,7 +509,6 @@ static struct pccard_operations soc_common_pcmcia_operations = { | |||
528 | .init = soc_common_pcmcia_sock_init, | 509 | .init = soc_common_pcmcia_sock_init, |
529 | .suspend = soc_common_pcmcia_suspend, | 510 | .suspend = soc_common_pcmcia_suspend, |
530 | .get_status = soc_common_pcmcia_get_status, | 511 | .get_status = soc_common_pcmcia_get_status, |
531 | .get_socket = soc_common_pcmcia_get_socket, | ||
532 | .set_socket = soc_common_pcmcia_set_socket, | 512 | .set_socket = soc_common_pcmcia_set_socket, |
533 | .set_io_map = soc_common_pcmcia_set_io_map, | 513 | .set_io_map = soc_common_pcmcia_set_io_map, |
534 | .set_mem_map = soc_common_pcmcia_set_mem_map, | 514 | .set_mem_map = soc_common_pcmcia_set_mem_map, |
@@ -665,13 +645,12 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops | |||
665 | 645 | ||
666 | down(&soc_pcmcia_sockets_lock); | 646 | down(&soc_pcmcia_sockets_lock); |
667 | 647 | ||
668 | sinfo = kmalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); | 648 | sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); |
669 | if (!sinfo) { | 649 | if (!sinfo) { |
670 | ret = -ENOMEM; | 650 | ret = -ENOMEM; |
671 | goto out; | 651 | goto out; |
672 | } | 652 | } |
673 | 653 | ||
674 | memset(sinfo, 0, SKT_DEV_INFO_SIZE(nr)); | ||
675 | sinfo->nskt = nr; | 654 | sinfo->nskt = nr; |
676 | 655 | ||
677 | /* | 656 | /* |
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 4a3150a7854c..7a7744662d54 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c | |||
@@ -42,35 +42,28 @@ | |||
42 | 42 | ||
43 | static ssize_t pccard_show_type(struct class_device *dev, char *buf) | 43 | static ssize_t pccard_show_type(struct class_device *dev, char *buf) |
44 | { | 44 | { |
45 | int val; | ||
46 | struct pcmcia_socket *s = to_socket(dev); | 45 | struct pcmcia_socket *s = to_socket(dev); |
47 | 46 | ||
48 | if (!(s->state & SOCKET_PRESENT)) | 47 | if (!(s->state & SOCKET_PRESENT)) |
49 | return -ENODEV; | 48 | return -ENODEV; |
50 | s->ops->get_status(s, &val); | 49 | if (s->state & SOCKET_CARDBUS) |
51 | if (val & SS_CARDBUS) | ||
52 | return sprintf(buf, "32-bit\n"); | 50 | return sprintf(buf, "32-bit\n"); |
53 | if (val & SS_DETECT) | 51 | return sprintf(buf, "16-bit\n"); |
54 | return sprintf(buf, "16-bit\n"); | ||
55 | return sprintf(buf, "invalid\n"); | ||
56 | } | 52 | } |
57 | static CLASS_DEVICE_ATTR(card_type, 0400, pccard_show_type, NULL); | 53 | static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL); |
58 | 54 | ||
59 | static ssize_t pccard_show_voltage(struct class_device *dev, char *buf) | 55 | static ssize_t pccard_show_voltage(struct class_device *dev, char *buf) |
60 | { | 56 | { |
61 | int val; | ||
62 | struct pcmcia_socket *s = to_socket(dev); | 57 | struct pcmcia_socket *s = to_socket(dev); |
63 | 58 | ||
64 | if (!(s->state & SOCKET_PRESENT)) | 59 | if (!(s->state & SOCKET_PRESENT)) |
65 | return -ENODEV; | 60 | return -ENODEV; |
66 | s->ops->get_status(s, &val); | 61 | if (s->socket.Vcc) |
67 | if (val & SS_3VCARD) | 62 | return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, |
68 | return sprintf(buf, "3.3V\n"); | 63 | s->socket.Vcc % 10); |
69 | if (val & SS_XVCARD) | 64 | return sprintf(buf, "X.XV\n"); |
70 | return sprintf(buf, "X.XV\n"); | ||
71 | return sprintf(buf, "5.0V\n"); | ||
72 | } | 65 | } |
73 | static CLASS_DEVICE_ATTR(card_voltage, 0400, pccard_show_voltage, NULL); | 66 | static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL); |
74 | 67 | ||
75 | static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) | 68 | static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) |
76 | { | 69 | { |
@@ -79,7 +72,7 @@ static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) | |||
79 | return -ENODEV; | 72 | return -ENODEV; |
80 | return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10); | 73 | return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10); |
81 | } | 74 | } |
82 | static CLASS_DEVICE_ATTR(card_vpp, 0400, pccard_show_vpp, NULL); | 75 | static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL); |
83 | 76 | ||
84 | static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) | 77 | static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) |
85 | { | 78 | { |
@@ -88,7 +81,7 @@ static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) | |||
88 | return -ENODEV; | 81 | return -ENODEV; |
89 | return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10); | 82 | return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10); |
90 | } | 83 | } |
91 | static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL); | 84 | static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL); |
92 | 85 | ||
93 | 86 | ||
94 | static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count) | 87 | static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count) |
@@ -292,10 +285,9 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz | |||
292 | if (!(s->state & SOCKET_PRESENT)) | 285 | if (!(s->state & SOCKET_PRESENT)) |
293 | return -ENODEV; | 286 | return -ENODEV; |
294 | 287 | ||
295 | cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL); | 288 | cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); |
296 | if (!cis) | 289 | if (!cis) |
297 | return -ENOMEM; | 290 | return -ENOMEM; |
298 | memset(cis, 0, sizeof(cisdump_t)); | ||
299 | 291 | ||
300 | cis->Length = count + 1; | 292 | cis->Length = count + 1; |
301 | memcpy(cis->Data, buf, count); | 293 | memcpy(cis->Data, buf, count); |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index e31263864377..73bad1d5cb23 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -181,13 +181,6 @@ static void tcic_setl(u_char reg, u_int data) | |||
181 | outw(data >> 16, tcic_base+reg+2); | 181 | outw(data >> 16, tcic_base+reg+2); |
182 | } | 182 | } |
183 | 183 | ||
184 | static u_char tcic_aux_getb(u_short reg) | ||
185 | { | ||
186 | u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; | ||
187 | tcic_setb(TCIC_MODE, mode); | ||
188 | return tcic_getb(TCIC_AUX); | ||
189 | } | ||
190 | |||
191 | static void tcic_aux_setb(u_short reg, u_char data) | 184 | static void tcic_aux_setb(u_short reg, u_char data) |
192 | { | 185 | { |
193 | u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; | 186 | u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; |
@@ -641,59 +634,6 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value) | |||
641 | debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value); | 634 | debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value); |
642 | return 0; | 635 | return 0; |
643 | } /* tcic_get_status */ | 636 | } /* tcic_get_status */ |
644 | |||
645 | /*====================================================================*/ | ||
646 | |||
647 | static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
648 | { | ||
649 | u_short psock = container_of(sock, struct tcic_socket, socket)->psock; | ||
650 | u_char reg; | ||
651 | u_short scf1, scf2; | ||
652 | |||
653 | tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT) | ||
654 | | TCIC_ADDR_INDREG | TCIC_SCF1(psock)); | ||
655 | scf1 = tcic_getw(TCIC_DATA); | ||
656 | state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0; | ||
657 | state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0; | ||
658 | state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0; | ||
659 | if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA) | ||
660 | state->flags |= SS_OUTPUT_ENA; | ||
661 | state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK; | ||
662 | if (state->io_irq == 1) state->io_irq = 11; | ||
663 | |||
664 | reg = tcic_getb(TCIC_PWR); | ||
665 | state->Vcc = state->Vpp = 0; | ||
666 | if (reg & TCIC_PWR_VCC(psock)) { | ||
667 | if (reg & TCIC_PWR_VPP(psock)) | ||
668 | state->Vcc = 50; | ||
669 | else | ||
670 | state->Vcc = state->Vpp = 50; | ||
671 | } else { | ||
672 | if (reg & TCIC_PWR_VPP(psock)) { | ||
673 | state->Vcc = 50; | ||
674 | state->Vpp = 120; | ||
675 | } | ||
676 | } | ||
677 | reg = tcic_aux_getb(TCIC_AUX_ILOCK); | ||
678 | state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0; | ||
679 | |||
680 | /* Card status change interrupt mask */ | ||
681 | tcic_setw(TCIC_ADDR, TCIC_SCF2(psock)); | ||
682 | scf2 = tcic_getw(TCIC_DATA); | ||
683 | state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT; | ||
684 | if (state->flags & SS_IOCARD) { | ||
685 | state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG; | ||
686 | } else { | ||
687 | state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD; | ||
688 | state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN; | ||
689 | state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY; | ||
690 | } | ||
691 | |||
692 | debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " | ||
693 | "io_irq %d, csc_mask %#2.2x\n", psock, state->flags, | ||
694 | state->Vcc, state->Vpp, state->io_irq, state->csc_mask); | ||
695 | return 0; | ||
696 | } /* tcic_get_socket */ | ||
697 | 637 | ||
698 | /*====================================================================*/ | 638 | /*====================================================================*/ |
699 | 639 | ||
@@ -874,7 +814,6 @@ static int tcic_init(struct pcmcia_socket *s) | |||
874 | static struct pccard_operations tcic_operations = { | 814 | static struct pccard_operations tcic_operations = { |
875 | .init = tcic_init, | 815 | .init = tcic_init, |
876 | .get_status = tcic_get_status, | 816 | .get_status = tcic_get_status, |
877 | .get_socket = tcic_get_socket, | ||
878 | .set_socket = tcic_set_socket, | 817 | .set_socket = tcic_set_socket, |
879 | .set_io_map = tcic_set_io_map, | 818 | .set_io_map = tcic_set_io_map, |
880 | .set_mem_map = tcic_set_mem_map, | 819 | .set_mem_map = tcic_set_mem_map, |
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 539b5cd1a598..d5b4ff74462e 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -873,7 +873,7 @@ static int ti1250_override(struct yenta_socket *socket) | |||
873 | * Some fixup code to make everybody happy (TM). | 873 | * Some fixup code to make everybody happy (TM). |
874 | */ | 874 | */ |
875 | 875 | ||
876 | #ifdef CONFIG_CARDBUS | 876 | #ifdef CONFIG_YENTA_ENE_TUNE |
877 | /** | 877 | /** |
878 | * set/clear various test bits: | 878 | * set/clear various test bits: |
879 | * Defaults to clear the bit. | 879 | * Defaults to clear the bit. |
@@ -937,7 +937,7 @@ static int ene_override(struct yenta_socket *socket) | |||
937 | } | 937 | } |
938 | #else | 938 | #else |
939 | # define ene_override ti1250_override | 939 | # define ene_override ti1250_override |
940 | #endif | 940 | #endif /* !CONFIG_YENTA_ENE_TUNE */ |
941 | 941 | ||
942 | #endif /* _LINUX_TI113X_H */ | 942 | #endif /* _LINUX_TI113X_H */ |
943 | 943 | ||
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 38a028c725d4..24c547ef512b 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c | |||
@@ -301,75 +301,6 @@ static int pccard_get_status(struct pcmcia_socket *sock, u_int *value) | |||
301 | return 0; | 301 | return 0; |
302 | } | 302 | } |
303 | 303 | ||
304 | static inline u_char get_Vcc_value(uint8_t voltage) | ||
305 | { | ||
306 | switch (voltage) { | ||
307 | case VCC_STATUS_3V: | ||
308 | return 33; | ||
309 | case VCC_STATUS_5V: | ||
310 | return 50; | ||
311 | default: | ||
312 | break; | ||
313 | } | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static inline u_char get_Vpp_value(uint8_t power, u_char Vcc) | ||
319 | { | ||
320 | if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02) | ||
321 | return Vcc; | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
327 | { | ||
328 | unsigned int slot; | ||
329 | uint8_t power, voltage, control, cscint; | ||
330 | |||
331 | if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL) | ||
332 | return -EINVAL; | ||
333 | |||
334 | slot = sock->sock; | ||
335 | |||
336 | power = exca_read_byte(slot, I365_POWER); | ||
337 | voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT); | ||
338 | |||
339 | state->Vcc = get_Vcc_value(voltage); | ||
340 | state->Vpp = get_Vpp_value(power, state->Vcc); | ||
341 | |||
342 | state->flags = 0; | ||
343 | if (power & POWER_ENABLE) | ||
344 | state->flags |= SS_PWR_AUTO; | ||
345 | if (power & I365_PWR_OUT) | ||
346 | state->flags |= SS_OUTPUT_ENA; | ||
347 | |||
348 | control = exca_read_byte(slot, I365_INTCTL); | ||
349 | if (control & I365_PC_IOCARD) | ||
350 | state->flags |= SS_IOCARD; | ||
351 | if (!(control & I365_PC_RESET)) | ||
352 | state->flags |= SS_RESET; | ||
353 | |||
354 | cscint = exca_read_byte(slot, I365_CSCINT); | ||
355 | state->csc_mask = 0; | ||
356 | if (state->flags & SS_IOCARD) { | ||
357 | if (cscint & I365_CSC_STSCHG) | ||
358 | state->flags |= SS_STSCHG; | ||
359 | } else { | ||
360 | if (cscint & I365_CSC_BVD1) | ||
361 | state->csc_mask |= SS_BATDEAD; | ||
362 | if (cscint & I365_CSC_BVD2) | ||
363 | state->csc_mask |= SS_BATWARN; | ||
364 | } | ||
365 | if (cscint & I365_CSC_READY) | ||
366 | state->csc_mask |= SS_READY; | ||
367 | if (cscint & I365_CSC_DETECT) | ||
368 | state->csc_mask |= SS_DETECT; | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static inline uint8_t set_Vcc_value(u_char Vcc) | 304 | static inline uint8_t set_Vcc_value(u_char Vcc) |
374 | { | 305 | { |
375 | switch (Vcc) { | 306 | switch (Vcc) { |
@@ -551,7 +482,6 @@ static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map | |||
551 | static struct pccard_operations vrc4171_pccard_operations = { | 482 | static struct pccard_operations vrc4171_pccard_operations = { |
552 | .init = pccard_init, | 483 | .init = pccard_init, |
553 | .get_status = pccard_get_status, | 484 | .get_status = pccard_get_status, |
554 | .get_socket = pccard_get_socket, | ||
555 | .set_socket = pccard_set_socket, | 485 | .set_socket = pccard_set_socket, |
556 | .set_io_map = pccard_set_io_map, | 486 | .set_io_map = pccard_set_io_map, |
557 | .set_mem_map = pccard_set_mem_map, | 487 | .set_mem_map = pccard_set_mem_map, |
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index db91259dc50e..1b277d2c1c96 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c | |||
@@ -198,48 +198,6 @@ static int cardu_get_status(unsigned int sock, u_int *value) | |||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
200 | 200 | ||
201 | static inline u_char get_Vcc_value(uint8_t val) | ||
202 | { | ||
203 | switch (val & VCC_MASK) { | ||
204 | case VCC_3V: | ||
205 | return 33; | ||
206 | case VCC_5V: | ||
207 | return 50; | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static inline u_char get_Vpp_value(uint8_t val) | ||
214 | { | ||
215 | switch (val & VPP_MASK) { | ||
216 | case VPP_12V: | ||
217 | return 120; | ||
218 | case VPP_VCC: | ||
219 | return get_Vcc_value(val); | ||
220 | } | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int cardu_get_socket(unsigned int sock, socket_state_t *state) | ||
226 | { | ||
227 | vrc4173_socket_t *socket = &cardu_sockets[sock]; | ||
228 | uint8_t val; | ||
229 | |||
230 | val = exca_readb(socket, PWR_CNT); | ||
231 | state->Vcc = get_Vcc_value(val); | ||
232 | state->Vpp = get_Vpp_value(val); | ||
233 | state->flags = 0; | ||
234 | if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA; | ||
235 | |||
236 | val = exca_readb(socket, INT_GEN_CNT); | ||
237 | if (!(val & CARD_REST0)) state->flags |= SS_RESET; | ||
238 | if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD; | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static inline uint8_t set_Vcc_value(u_char Vcc) | 201 | static inline uint8_t set_Vcc_value(u_char Vcc) |
244 | { | 202 | { |
245 | switch (Vcc) { | 203 | switch (Vcc) { |
@@ -431,7 +389,6 @@ static struct pccard_operations cardu_operations = { | |||
431 | .register_callback = cardu_register_callback, | 389 | .register_callback = cardu_register_callback, |
432 | .inquire_socket = cardu_inquire_socket, | 390 | .inquire_socket = cardu_inquire_socket, |
433 | .get_status = cardu_get_status, | 391 | .get_status = cardu_get_status, |
434 | .get_socket = cardu_get_socket, | ||
435 | .set_socket = cardu_set_socket, | 392 | .set_socket = cardu_set_socket, |
436 | .get_io_map = cardu_get_io_map, | 393 | .get_io_map = cardu_get_io_map, |
437 | .set_io_map = cardu_set_io_map, | 394 | .set_io_map = cardu_set_io_map, |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index ec6ab65f0872..4145eb83b9b6 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -49,7 +49,13 @@ MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only | |||
49 | #define to_cycles(ns) ((ns)/120) | 49 | #define to_cycles(ns) ((ns)/120) |
50 | #define to_ns(cycles) ((cycles)*120) | 50 | #define to_ns(cycles) ((cycles)*120) |
51 | 51 | ||
52 | /** | ||
53 | * yenta PCI irq probing. | ||
54 | * currently only used in the TI/EnE initialization code | ||
55 | */ | ||
56 | #ifdef CONFIG_YENTA_TI | ||
52 | static int yenta_probe_cb_irq(struct yenta_socket *socket); | 57 | static int yenta_probe_cb_irq(struct yenta_socket *socket); |
58 | #endif | ||
53 | 59 | ||
54 | 60 | ||
55 | static unsigned int override_bios; | 61 | static unsigned int override_bios; |
@@ -224,95 +230,6 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value) | |||
224 | return 0; | 230 | return 0; |
225 | } | 231 | } |
226 | 232 | ||
227 | static void yenta_get_power(struct yenta_socket *socket, socket_state_t *state) | ||
228 | { | ||
229 | if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && | ||
230 | (socket->flags & YENTA_16BIT_POWER_EXCA)) { | ||
231 | u8 reg, vcc, vpp; | ||
232 | |||
233 | reg = exca_readb(socket, I365_POWER); | ||
234 | vcc = reg & I365_VCC_MASK; | ||
235 | vpp = reg & I365_VPP1_MASK; | ||
236 | state->Vcc = state->Vpp = 0; | ||
237 | |||
238 | if (socket->flags & YENTA_16BIT_POWER_DF) { | ||
239 | if (vcc == I365_VCC_3V) | ||
240 | state->Vcc = 33; | ||
241 | if (vcc == I365_VCC_5V) | ||
242 | state->Vcc = 50; | ||
243 | if (vpp == I365_VPP1_5V) | ||
244 | state->Vpp = state->Vcc; | ||
245 | if (vpp == I365_VPP1_12V) | ||
246 | state->Vpp = 120; | ||
247 | } else { | ||
248 | if (reg & I365_VCC_5V) { | ||
249 | state->Vcc = 50; | ||
250 | if (vpp == I365_VPP1_5V) | ||
251 | state->Vpp = 50; | ||
252 | if (vpp == I365_VPP1_12V) | ||
253 | state->Vpp = 120; | ||
254 | } | ||
255 | } | ||
256 | } else { | ||
257 | u32 control; | ||
258 | |||
259 | control = cb_readl(socket, CB_SOCKET_CONTROL); | ||
260 | |||
261 | switch (control & CB_SC_VCC_MASK) { | ||
262 | case CB_SC_VCC_5V: state->Vcc = 50; break; | ||
263 | case CB_SC_VCC_3V: state->Vcc = 33; break; | ||
264 | default: state->Vcc = 0; | ||
265 | } | ||
266 | |||
267 | switch (control & CB_SC_VPP_MASK) { | ||
268 | case CB_SC_VPP_12V: state->Vpp = 120; break; | ||
269 | case CB_SC_VPP_5V: state->Vpp = 50; break; | ||
270 | case CB_SC_VPP_3V: state->Vpp = 33; break; | ||
271 | default: state->Vpp = 0; | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | |||
276 | static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
277 | { | ||
278 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | ||
279 | u8 reg; | ||
280 | u32 control; | ||
281 | |||
282 | control = cb_readl(socket, CB_SOCKET_CONTROL); | ||
283 | |||
284 | yenta_get_power(socket, state); | ||
285 | state->io_irq = socket->io_irq; | ||
286 | |||
287 | if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { | ||
288 | u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL); | ||
289 | if (bridge & CB_BRIDGE_CRST) | ||
290 | state->flags |= SS_RESET; | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | /* 16-bit card state.. */ | ||
295 | reg = exca_readb(socket, I365_POWER); | ||
296 | state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; | ||
297 | state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; | ||
298 | |||
299 | reg = exca_readb(socket, I365_INTCTL); | ||
300 | state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; | ||
301 | state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0; | ||
302 | |||
303 | reg = exca_readb(socket, I365_CSCINT); | ||
304 | state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; | ||
305 | if (state->flags & SS_IOCARD) { | ||
306 | state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; | ||
307 | } else { | ||
308 | state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; | ||
309 | state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; | ||
310 | state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; | ||
311 | } | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) | 233 | static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) |
317 | { | 234 | { |
318 | /* some birdges require to use the ExCA registers to power 16bit cards */ | 235 | /* some birdges require to use the ExCA registers to power 16bit cards */ |
@@ -531,6 +448,9 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
531 | 448 | ||
532 | csc = exca_readb(socket, I365_CSC); | 449 | csc = exca_readb(socket, I365_CSC); |
533 | 450 | ||
451 | if (!(cb_event || csc)) | ||
452 | return IRQ_NONE; | ||
453 | |||
534 | events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ; | 454 | events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ; |
535 | events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0; | 455 | events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0; |
536 | if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { | 456 | if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { |
@@ -544,10 +464,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
544 | if (events) | 464 | if (events) |
545 | pcmcia_parse_events(&socket->socket, events); | 465 | pcmcia_parse_events(&socket->socket, events); |
546 | 466 | ||
547 | if (cb_event || csc) | 467 | return IRQ_HANDLED; |
548 | return IRQ_HANDLED; | ||
549 | |||
550 | return IRQ_NONE; | ||
551 | } | 468 | } |
552 | 469 | ||
553 | static void yenta_interrupt_wrapper(unsigned long data) | 470 | static void yenta_interrupt_wrapper(unsigned long data) |
@@ -828,17 +745,24 @@ static struct pccard_operations yenta_socket_operations = { | |||
828 | .init = yenta_sock_init, | 745 | .init = yenta_sock_init, |
829 | .suspend = yenta_sock_suspend, | 746 | .suspend = yenta_sock_suspend, |
830 | .get_status = yenta_get_status, | 747 | .get_status = yenta_get_status, |
831 | .get_socket = yenta_get_socket, | ||
832 | .set_socket = yenta_set_socket, | 748 | .set_socket = yenta_set_socket, |
833 | .set_io_map = yenta_set_io_map, | 749 | .set_io_map = yenta_set_io_map, |
834 | .set_mem_map = yenta_set_mem_map, | 750 | .set_mem_map = yenta_set_mem_map, |
835 | }; | 751 | }; |
836 | 752 | ||
837 | 753 | ||
754 | #ifdef CONFIG_YENTA_TI | ||
838 | #include "ti113x.h" | 755 | #include "ti113x.h" |
756 | #endif | ||
757 | #ifdef CONFIG_YENTA_RICOH | ||
839 | #include "ricoh.h" | 758 | #include "ricoh.h" |
759 | #endif | ||
760 | #ifdef CONFIG_YENTA_TOSHIBA | ||
840 | #include "topic.h" | 761 | #include "topic.h" |
762 | #endif | ||
763 | #ifdef CONFIG_YENTA_O2 | ||
841 | #include "o2micro.h" | 764 | #include "o2micro.h" |
765 | #endif | ||
842 | 766 | ||
843 | enum { | 767 | enum { |
844 | CARDBUS_TYPE_DEFAULT = -1, | 768 | CARDBUS_TYPE_DEFAULT = -1, |
@@ -858,6 +782,7 @@ enum { | |||
858 | * initialization sequences etc details. List them here.. | 782 | * initialization sequences etc details. List them here.. |
859 | */ | 783 | */ |
860 | static struct cardbus_type cardbus_type[] = { | 784 | static struct cardbus_type cardbus_type[] = { |
785 | #ifdef CONFIG_YENTA_TI | ||
861 | [CARDBUS_TYPE_TI] = { | 786 | [CARDBUS_TYPE_TI] = { |
862 | .override = ti_override, | 787 | .override = ti_override, |
863 | .save_state = ti_save_state, | 788 | .save_state = ti_save_state, |
@@ -882,27 +807,36 @@ static struct cardbus_type cardbus_type[] = { | |||
882 | .restore_state = ti_restore_state, | 807 | .restore_state = ti_restore_state, |
883 | .sock_init = ti_init, | 808 | .sock_init = ti_init, |
884 | }, | 809 | }, |
810 | #endif | ||
811 | #ifdef CONFIG_YENTA_RICOH | ||
885 | [CARDBUS_TYPE_RICOH] = { | 812 | [CARDBUS_TYPE_RICOH] = { |
886 | .override = ricoh_override, | 813 | .override = ricoh_override, |
887 | .save_state = ricoh_save_state, | 814 | .save_state = ricoh_save_state, |
888 | .restore_state = ricoh_restore_state, | 815 | .restore_state = ricoh_restore_state, |
889 | }, | 816 | }, |
817 | #endif | ||
818 | #ifdef CONFIG_YENTA_TOSHIBA | ||
890 | [CARDBUS_TYPE_TOPIC95] = { | 819 | [CARDBUS_TYPE_TOPIC95] = { |
891 | .override = topic95_override, | 820 | .override = topic95_override, |
892 | }, | 821 | }, |
893 | [CARDBUS_TYPE_TOPIC97] = { | 822 | [CARDBUS_TYPE_TOPIC97] = { |
894 | .override = topic97_override, | 823 | .override = topic97_override, |
895 | }, | 824 | }, |
825 | #endif | ||
826 | #ifdef CONFIG_YENTA_O2 | ||
896 | [CARDBUS_TYPE_O2MICRO] = { | 827 | [CARDBUS_TYPE_O2MICRO] = { |
897 | .override = o2micro_override, | 828 | .override = o2micro_override, |
898 | .restore_state = o2micro_restore_state, | 829 | .restore_state = o2micro_restore_state, |
899 | }, | 830 | }, |
831 | #endif | ||
832 | #ifdef CONFIG_YENTA_TI | ||
900 | [CARDBUS_TYPE_ENE] = { | 833 | [CARDBUS_TYPE_ENE] = { |
901 | .override = ene_override, | 834 | .override = ene_override, |
902 | .save_state = ti_save_state, | 835 | .save_state = ti_save_state, |
903 | .restore_state = ti_restore_state, | 836 | .restore_state = ti_restore_state, |
904 | .sock_init = ti_init, | 837 | .sock_init = ti_init, |
905 | }, | 838 | }, |
839 | #endif | ||
906 | }; | 840 | }; |
907 | 841 | ||
908 | 842 | ||
@@ -948,6 +882,12 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas | |||
948 | } | 882 | } |
949 | 883 | ||
950 | 884 | ||
885 | /** | ||
886 | * yenta PCI irq probing. | ||
887 | * currently only used in the TI/EnE initialization code | ||
888 | */ | ||
889 | #ifdef CONFIG_YENTA_TI | ||
890 | |||
951 | /* interrupt handler, only used during probing */ | 891 | /* interrupt handler, only used during probing */ |
952 | static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs) | 892 | static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs) |
953 | { | 893 | { |
@@ -1000,6 +940,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) | |||
1000 | return (int) socket->probe_status; | 940 | return (int) socket->probe_status; |
1001 | } | 941 | } |
1002 | 942 | ||
943 | #endif /* CONFIG_YENTA_TI */ | ||
1003 | 944 | ||
1004 | 945 | ||
1005 | /* | 946 | /* |
@@ -1078,10 +1019,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
1078 | return -ENODEV; | 1019 | return -ENODEV; |
1079 | } | 1020 | } |
1080 | 1021 | ||
1081 | socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); | 1022 | socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL); |
1082 | if (!socket) | 1023 | if (!socket) |
1083 | return -ENOMEM; | 1024 | return -ENOMEM; |
1084 | memset(socket, 0, sizeof(*socket)); | ||
1085 | 1025 | ||
1086 | /* prepare pcmcia_socket */ | 1026 | /* prepare pcmcia_socket */ |
1087 | socket->socket.ops = ¥ta_socket_operations; | 1027 | socket->socket.ops = ¥ta_socket_operations; |
@@ -1263,6 +1203,7 @@ static struct pci_device_id yenta_table [] = { | |||
1263 | * advanced overrides instead. (I can't get the | 1203 | * advanced overrides instead. (I can't get the |
1264 | * data sheets for these devices. --rmk) | 1204 | * data sheets for these devices. --rmk) |
1265 | */ | 1205 | */ |
1206 | #ifdef CONFIG_YENTA_TI | ||
1266 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI), | 1207 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI), |
1267 | 1208 | ||
1268 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X), | 1209 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X), |
@@ -1305,18 +1246,25 @@ static struct pci_device_id yenta_table [] = { | |||
1305 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE), | 1246 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE), |
1306 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE), | 1247 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE), |
1307 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE), | 1248 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE), |
1249 | #endif /* CONFIG_YENTA_TI */ | ||
1308 | 1250 | ||
1251 | #ifdef CONFIG_YENTA_RICOH | ||
1309 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), | 1252 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), |
1310 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), | 1253 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), |
1311 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH), | 1254 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH), |
1312 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), | 1255 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), |
1313 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), | 1256 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), |
1257 | #endif | ||
1314 | 1258 | ||
1259 | #ifdef CONFIG_YENTA_TOSHIBA | ||
1315 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95), | 1260 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95), |
1316 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), | 1261 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), |
1317 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), | 1262 | CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), |
1263 | #endif | ||
1318 | 1264 | ||
1265 | #ifdef CONFIG_YENTA_O2 | ||
1319 | CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO), | 1266 | CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO), |
1267 | #endif | ||
1320 | 1268 | ||
1321 | /* match any cardbus bridge */ | 1269 | /* match any cardbus bridge */ |
1322 | CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), | 1270 | CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), |