Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[pandora-kernel.git] / drivers / pcmcia / soc_common.c
1 /*======================================================================
2
3     Common support code for the PCMCIA control functionality of
4     integrated SOCs like the SA-11x0 and PXA2xx microprocessors.
5
6     The contents of this file are subject to the Mozilla Public
7     License Version 1.1 (the "License"); you may not use this file
8     except in compliance with the License. You may obtain a copy of
9     the License at http://www.mozilla.org/MPL/
10
11     Software distributed under the License is distributed on an "AS
12     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13     implied. See the License for the specific language governing
14     rights and limitations under the License.
15
16     The initial developer of the original code is John G. Dorsey
17     <john+@cs.cmu.edu>.  Portions created by John G. Dorsey are
18     Copyright (C) 1999 John G. Dorsey.  All Rights Reserved.
19
20     Alternatively, the contents of this file may be used under the
21     terms of the GNU Public License version 2 (the "GPL"), in which
22     case the provisions of the GPL are applicable instead of the
23     above.  If you wish to allow the use of your version of this file
24     only under the terms of the GPL and not to allow others to use
25     your version of this file under the MPL, indicate your decision
26     by deleting the provisions above and replace them with the notice
27     and other provisions required by the GPL.  If you do not delete
28     the provisions above, a recipient may use your version of this
29     file under either the MPL or the GPL.
30
31 ======================================================================*/
32
33
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/init.h>
37 #include <linux/kernel.h>
38 #include <linux/timer.h>
39 #include <linux/mm.h>
40 #include <linux/mutex.h>
41 #include <linux/interrupt.h>
42 #include <linux/irq.h>
43 #include <linux/spinlock.h>
44 #include <linux/cpufreq.h>
45
46 #include <mach/hardware.h>
47 #include <asm/io.h>
48 #include <asm/system.h>
49
50 #include "soc_common.h"
51
52 #ifdef CONFIG_PCMCIA_DEBUG
53
54 static int pc_debug;
55 module_param(pc_debug, int, 0644);
56
57 void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
58                       int lvl, const char *fmt, ...)
59 {
60         struct va_format vaf;
61         va_list args;
62         if (pc_debug > lvl) {
63                 va_start(args, fmt);
64
65                 vaf.fmt = fmt;
66                 vaf.va = &args;
67
68                 printk(KERN_DEBUG "skt%u: %s: %pV", skt->nr, func, &vaf);
69
70                 va_end(args);
71         }
72 }
73
74 #endif
75
76 #define to_soc_pcmcia_socket(x) container_of(x, struct soc_pcmcia_socket, socket)
77
78 static unsigned short
79 calc_speed(unsigned short *spds, int num, unsigned short dflt)
80 {
81         unsigned short speed = 0;
82         int i;
83
84         for (i = 0; i < num; i++)
85                 if (speed < spds[i])
86                         speed = spds[i];
87         if (speed == 0)
88                 speed = dflt;
89
90         return speed;
91 }
92
93 void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, struct soc_pcmcia_timing *timing)
94 {
95         timing->io = calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
96         timing->mem = calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
97         timing->attr = calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
98 }
99 EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
100
101 static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
102 {
103         struct pcmcia_state state;
104         unsigned int stat;
105
106         memset(&state, 0, sizeof(struct pcmcia_state));
107
108         skt->ops->socket_state(skt, &state);
109
110         stat = state.detect  ? SS_DETECT : 0;
111         stat |= state.ready  ? SS_READY  : 0;
112         stat |= state.wrprot ? SS_WRPROT : 0;
113         stat |= state.vs_3v  ? SS_3VCARD : 0;
114         stat |= state.vs_Xv  ? SS_XVCARD : 0;
115
116         /* The power status of individual sockets is not available
117          * explicitly from the hardware, so we just remember the state
118          * and regurgitate it upon request:
119          */
120         stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
121
122         if (skt->cs_state.flags & SS_IOCARD)
123                 stat |= state.bvd1 ? SS_STSCHG : 0;
124         else {
125                 if (state.bvd1 == 0)
126                         stat |= SS_BATDEAD;
127                 else if (state.bvd2 == 0)
128                         stat |= SS_BATWARN;
129         }
130         return stat;
131 }
132
133 /*
134  * soc_common_pcmcia_config_skt
135  * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
136  *
137  * Convert PCMCIA socket state to our socket configure structure.
138  */
139 static int
140 soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *state)
141 {
142         int ret;
143
144         ret = skt->ops->configure_socket(skt, state);
145         if (ret == 0) {
146                 /*
147                  * This really needs a better solution.  The IRQ
148                  * may or may not be claimed by the driver.
149                  */
150                 if (skt->irq_state != 1 && state->io_irq) {
151                         skt->irq_state = 1;
152                         set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
153                 } else if (skt->irq_state == 1 && state->io_irq == 0) {
154                         skt->irq_state = 0;
155                         set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
156                 }
157
158                 skt->cs_state = *state;
159         }
160
161         if (ret < 0)
162                 printk(KERN_ERR "soc_common_pcmcia: unable to configure "
163                        "socket %d\n", skt->nr);
164
165         return ret;
166 }
167
168 /* soc_common_pcmcia_sock_init()
169  * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
170  *
171  * (Re-)Initialise the socket, turning on status interrupts
172  * and PCMCIA bus.  This must wait for power to stabilise
173  * so that the card status signals report correctly.
174  *
175  * Returns: 0
176  */
177 static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
178 {
179         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
180
181         debug(skt, 2, "initializing socket\n");
182
183         skt->ops->socket_init(skt);
184         return 0;
185 }
186
187
188 /*
189  * soc_common_pcmcia_suspend()
190  * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
191  *
192  * Remove power on the socket, disable IRQs from the card.
193  * Turn off status interrupts, and disable the PCMCIA bus.
194  *
195  * Returns: 0
196  */
197 static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
198 {
199         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
200
201         debug(skt, 2, "suspending socket\n");
202
203         skt->ops->socket_suspend(skt);
204
205         return 0;
206 }
207
208 static DEFINE_SPINLOCK(status_lock);
209
210 static void soc_common_check_status(struct soc_pcmcia_socket *skt)
211 {
212         unsigned int events;
213
214         debug(skt, 4, "entering PCMCIA monitoring thread\n");
215
216         do {
217                 unsigned int status;
218                 unsigned long flags;
219
220                 status = soc_common_pcmcia_skt_state(skt);
221
222                 spin_lock_irqsave(&status_lock, flags);
223                 events = (status ^ skt->status) & skt->cs_state.csc_mask;
224                 skt->status = status;
225                 spin_unlock_irqrestore(&status_lock, flags);
226
227                 debug(skt, 4, "events: %s%s%s%s%s%s\n",
228                         events == 0         ? "<NONE>"   : "",
229                         events & SS_DETECT  ? "DETECT "  : "",
230                         events & SS_READY   ? "READY "   : "",
231                         events & SS_BATDEAD ? "BATDEAD " : "",
232                         events & SS_BATWARN ? "BATWARN " : "",
233                         events & SS_STSCHG  ? "STSCHG "  : "");
234
235                 if (events)
236                         pcmcia_parse_events(&skt->socket, events);
237         } while (events);
238 }
239
240 /* Let's poll for events in addition to IRQs since IRQ only is unreliable... */
241 static void soc_common_pcmcia_poll_event(unsigned long dummy)
242 {
243         struct soc_pcmcia_socket *skt = (struct soc_pcmcia_socket *)dummy;
244         debug(skt, 4, "polling for events\n");
245
246         mod_timer(&skt->poll_timer, jiffies + SOC_PCMCIA_POLL_PERIOD);
247
248         soc_common_check_status(skt);
249 }
250
251
252 /*
253  * Service routine for socket driver interrupts (requested by the
254  * low-level PCMCIA init() operation via soc_common_pcmcia_thread()).
255  * The actual interrupt-servicing work is performed by
256  * soc_common_pcmcia_thread(), largely because the Card Services event-
257  * handling code performs scheduling operations which cannot be
258  * executed from within an interrupt context.
259  */
260 static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev)
261 {
262         struct soc_pcmcia_socket *skt = dev;
263
264         debug(skt, 3, "servicing IRQ %d\n", irq);
265
266         soc_common_check_status(skt);
267
268         return IRQ_HANDLED;
269 }
270
271
272 /*
273  *  Implements the get_status() operation for the in-kernel PCMCIA
274  * service (formerly SS_GetStatus in Card Services). Essentially just
275  * fills in bits in `status' according to internal driver state or
276  * the value of the voltage detect chipselect register.
277  *
278  * As a debugging note, during card startup, the PCMCIA core issues
279  * three set_socket() commands in a row the first with RESET deasserted,
280  * the second with RESET asserted, and the last with RESET deasserted
281  * again. Following the third set_socket(), a get_status() command will
282  * be issued. The kernel is looking for the SS_READY flag (see
283  * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
284  *
285  * Returns: 0
286  */
287 static int
288 soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
289 {
290         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
291
292         skt->status = soc_common_pcmcia_skt_state(skt);
293         *status = skt->status;
294
295         return 0;
296 }
297
298
299 /*
300  * Implements the set_socket() operation for the in-kernel PCMCIA
301  * service (formerly SS_SetSocket in Card Services). We more or
302  * less punt all of this work and let the kernel handle the details
303  * of power configuration, reset, &c. We also record the value of
304  * `state' in order to regurgitate it to the PCMCIA core later.
305  */
306 static int
307 soc_common_pcmcia_set_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, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n",
312                         (state->csc_mask==0)?"<NONE> ":"",
313                         (state->csc_mask&SS_DETECT)?"DETECT ":"",
314                         (state->csc_mask&SS_READY)?"READY ":"",
315                         (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
316                         (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
317                         (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
318                         (state->flags==0)?"<NONE> ":"",
319                         (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
320                         (state->flags&SS_IOCARD)?"IOCARD ":"",
321                         (state->flags&SS_RESET)?"RESET ":"",
322                         (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
323                         (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
324                         state->Vcc, state->Vpp, state->io_irq);
325
326         return soc_common_pcmcia_config_skt(skt, state);
327 }
328
329
330 /*
331  * Implements the set_io_map() operation for the in-kernel PCMCIA
332  * service (formerly SS_SetIOMap in Card Services). We configure
333  * the map speed as requested, but override the address ranges
334  * supplied by Card Services.
335  *
336  * Returns: 0 on success, -1 on error
337  */
338 static int
339 soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
340 {
341         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
342         unsigned short speed = map->speed;
343
344         debug(skt, 2, "map %u  speed %u start 0x%08llx stop 0x%08llx\n",
345                 map->map, map->speed, (unsigned long long)map->start,
346                 (unsigned long long)map->stop);
347         debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
348                 (map->flags==0)?"<NONE>":"",
349                 (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
350                 (map->flags&MAP_16BIT)?"16BIT ":"",
351                 (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
352                 (map->flags&MAP_0WS)?"0WS ":"",
353                 (map->flags&MAP_WRPROT)?"WRPROT ":"",
354                 (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
355                 (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
356
357         if (map->map >= MAX_IO_WIN) {
358                 printk(KERN_ERR "%s(): map (%d) out of range\n", __func__,
359                        map->map);
360                 return -1;
361         }
362
363         if (map->flags & MAP_ACTIVE) {
364                 if (speed == 0)
365                         speed = SOC_PCMCIA_IO_ACCESS;
366         } else {
367                 speed = 0;
368         }
369
370         skt->spd_io[map->map] = speed;
371         skt->ops->set_timing(skt);
372
373         if (map->stop == 1)
374                 map->stop = PAGE_SIZE-1;
375
376         map->stop -= map->start;
377         map->stop += skt->socket.io_offset;
378         map->start = skt->socket.io_offset;
379
380         return 0;
381 }
382
383
384 /*
385  * Implements the set_mem_map() operation for the in-kernel PCMCIA
386  * service (formerly SS_SetMemMap in Card Services). We configure
387  * the map speed as requested, but override the address ranges
388  * supplied by Card Services.
389  *
390  * Returns: 0 on success, -ERRNO on error
391  */
392 static int
393 soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
394 {
395         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
396         struct resource *res;
397         unsigned short speed = map->speed;
398
399         debug(skt, 2, "map %u speed %u card_start %08x\n",
400                 map->map, map->speed, map->card_start);
401         debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
402                 (map->flags==0)?"<NONE>":"",
403                 (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
404                 (map->flags&MAP_16BIT)?"16BIT ":"",
405                 (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
406                 (map->flags&MAP_0WS)?"0WS ":"",
407                 (map->flags&MAP_WRPROT)?"WRPROT ":"",
408                 (map->flags&MAP_ATTRIB)?"ATTRIB ":"",
409                 (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
410
411         if (map->map >= MAX_WIN)
412                 return -EINVAL;
413
414         if (map->flags & MAP_ACTIVE) {
415                 if (speed == 0)
416                         speed = 300;
417         } else {
418                 speed = 0;
419         }
420
421         if (map->flags & MAP_ATTRIB) {
422                 res = &skt->res_attr;
423                 skt->spd_attr[map->map] = speed;
424                 skt->spd_mem[map->map] = 0;
425         } else {
426                 res = &skt->res_mem;
427                 skt->spd_attr[map->map] = 0;
428                 skt->spd_mem[map->map] = speed;
429         }
430
431         skt->ops->set_timing(skt);
432
433         map->static_start = res->start + map->card_start;
434
435         return 0;
436 }
437
438 struct bittbl {
439         unsigned int mask;
440         const char *name;
441 };
442
443 static struct bittbl status_bits[] = {
444         { SS_WRPROT,            "SS_WRPROT"     },
445         { SS_BATDEAD,           "SS_BATDEAD"    },
446         { SS_BATWARN,           "SS_BATWARN"    },
447         { SS_READY,             "SS_READY"      },
448         { SS_DETECT,            "SS_DETECT"     },
449         { SS_POWERON,           "SS_POWERON"    },
450         { SS_STSCHG,            "SS_STSCHG"     },
451         { SS_3VCARD,            "SS_3VCARD"     },
452         { SS_XVCARD,            "SS_XVCARD"     },
453 };
454
455 static struct bittbl conf_bits[] = {
456         { SS_PWR_AUTO,          "SS_PWR_AUTO"   },
457         { SS_IOCARD,            "SS_IOCARD"     },
458         { SS_RESET,             "SS_RESET"      },
459         { SS_DMA_MODE,          "SS_DMA_MODE"   },
460         { SS_SPKR_ENA,          "SS_SPKR_ENA"   },
461         { SS_OUTPUT_ENA,        "SS_OUTPUT_ENA" },
462 };
463
464 static void
465 dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, int sz)
466 {
467         char *b = *p;
468         int i;
469
470         b += sprintf(b, "%-9s:", prefix);
471         for (i = 0; i < sz; i++)
472                 if (val & bits[i].mask)
473                         b += sprintf(b, " %s", bits[i].name);
474         *b++ = '\n';
475         *p = b;
476 }
477
478 /*
479  * Implements the /sys/class/pcmcia_socket/??/status file.
480  *
481  * Returns: the number of characters added to the buffer
482  */
483 static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
484 {
485         struct soc_pcmcia_socket *skt =
486                 container_of(dev, struct soc_pcmcia_socket, socket.dev);
487         char *p = buf;
488
489         p+=sprintf(p, "slot     : %d\n", skt->nr);
490
491         dump_bits(&p, "status", skt->status,
492                   status_bits, ARRAY_SIZE(status_bits));
493         dump_bits(&p, "csc_mask", skt->cs_state.csc_mask,
494                   status_bits, ARRAY_SIZE(status_bits));
495         dump_bits(&p, "cs_flags", skt->cs_state.flags,
496                   conf_bits, ARRAY_SIZE(conf_bits));
497
498         p+=sprintf(p, "Vcc      : %d\n", skt->cs_state.Vcc);
499         p+=sprintf(p, "Vpp      : %d\n", skt->cs_state.Vpp);
500         p+=sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq,
501                 skt->socket.pci_irq);
502         if (skt->ops->show_timing)
503                 p+=skt->ops->show_timing(skt, p);
504
505         return p-buf;
506 }
507 static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
508
509
510 static struct pccard_operations soc_common_pcmcia_operations = {
511         .init                   = soc_common_pcmcia_sock_init,
512         .suspend                = soc_common_pcmcia_suspend,
513         .get_status             = soc_common_pcmcia_get_status,
514         .set_socket             = soc_common_pcmcia_set_socket,
515         .set_io_map             = soc_common_pcmcia_set_io_map,
516         .set_mem_map            = soc_common_pcmcia_set_mem_map,
517 };
518
519
520 int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
521                             struct pcmcia_irqs *irqs, int nr)
522 {
523         int i, res = 0;
524
525         for (i = 0; i < nr; i++) {
526                 if (irqs[i].sock != skt->nr)
527                         continue;
528                 res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
529                                   IRQF_DISABLED, irqs[i].str, skt);
530                 if (res)
531                         break;
532                 set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
533         }
534
535         if (res) {
536                 printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n",
537                         irqs[i].irq, res);
538
539                 while (i--)
540                         if (irqs[i].sock == skt->nr)
541                                 free_irq(irqs[i].irq, skt);
542         }
543         return res;
544 }
545 EXPORT_SYMBOL(soc_pcmcia_request_irqs);
546
547 void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt,
548                           struct pcmcia_irqs *irqs, int nr)
549 {
550         int i;
551
552         for (i = 0; i < nr; i++)
553                 if (irqs[i].sock == skt->nr)
554                         free_irq(irqs[i].irq, skt);
555 }
556 EXPORT_SYMBOL(soc_pcmcia_free_irqs);
557
558 void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
559                              struct pcmcia_irqs *irqs, int nr)
560 {
561         int i;
562
563         for (i = 0; i < nr; i++)
564                 if (irqs[i].sock == skt->nr)
565                         set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
566 }
567 EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
568
569 void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
570                             struct pcmcia_irqs *irqs, int nr)
571 {
572         int i;
573
574         for (i = 0; i < nr; i++)
575                 if (irqs[i].sock == skt->nr) {
576                         set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
577                         set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
578                 }
579 }
580 EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
581
582
583 static LIST_HEAD(soc_pcmcia_sockets);
584 static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
585
586 #ifdef CONFIG_CPU_FREQ
587 static int
588 soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
589 {
590         struct soc_pcmcia_socket *skt;
591         struct cpufreq_freqs *freqs = data;
592         int ret = 0;
593
594         mutex_lock(&soc_pcmcia_sockets_lock);
595         list_for_each_entry(skt, &soc_pcmcia_sockets, node)
596                 if ( skt->ops->frequency_change )
597                         ret += skt->ops->frequency_change(skt, val, freqs);
598         mutex_unlock(&soc_pcmcia_sockets_lock);
599
600         return ret;
601 }
602
603 static struct notifier_block soc_pcmcia_notifier_block = {
604         .notifier_call  = soc_pcmcia_notifier
605 };
606
607 static int soc_pcmcia_cpufreq_register(void)
608 {
609         int ret;
610
611         ret = cpufreq_register_notifier(&soc_pcmcia_notifier_block,
612                                         CPUFREQ_TRANSITION_NOTIFIER);
613         if (ret < 0)
614                 printk(KERN_ERR "Unable to register CPU frequency change "
615                                 "notifier for PCMCIA (%d)\n", ret);
616         return ret;
617 }
618 fs_initcall(soc_pcmcia_cpufreq_register);
619
620 static void soc_pcmcia_cpufreq_unregister(void)
621 {
622         cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
623 }
624 module_exit(soc_pcmcia_cpufreq_unregister);
625
626 #endif
627
628 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
629 {
630         mutex_lock(&soc_pcmcia_sockets_lock);
631         del_timer_sync(&skt->poll_timer);
632
633         pcmcia_unregister_socket(&skt->socket);
634
635         skt->ops->hw_shutdown(skt);
636
637         soc_common_pcmcia_config_skt(skt, &dead_socket);
638
639         list_del(&skt->node);
640         mutex_unlock(&soc_pcmcia_sockets_lock);
641
642         iounmap(skt->virt_io);
643         skt->virt_io = NULL;
644         release_resource(&skt->res_attr);
645         release_resource(&skt->res_mem);
646         release_resource(&skt->res_io);
647         release_resource(&skt->res_skt);
648 }
649 EXPORT_SYMBOL(soc_pcmcia_remove_one);
650
651 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
652 {
653         int ret;
654
655         init_timer(&skt->poll_timer);
656         skt->poll_timer.function = soc_common_pcmcia_poll_event;
657         skt->poll_timer.data = (unsigned long)skt;
658         skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
659
660         ret = request_resource(&iomem_resource, &skt->res_skt);
661         if (ret)
662                 goto out_err_1;
663
664         ret = request_resource(&skt->res_skt, &skt->res_io);
665         if (ret)
666                 goto out_err_2;
667
668         ret = request_resource(&skt->res_skt, &skt->res_mem);
669         if (ret)
670                 goto out_err_3;
671
672         ret = request_resource(&skt->res_skt, &skt->res_attr);
673         if (ret)
674                 goto out_err_4;
675
676         skt->virt_io = ioremap(skt->res_io.start, 0x10000);
677         if (skt->virt_io == NULL) {
678                 ret = -ENOMEM;
679                 goto out_err_5;
680         }
681
682         mutex_lock(&soc_pcmcia_sockets_lock);
683
684         list_add(&skt->node, &soc_pcmcia_sockets);
685
686         /*
687          * We initialize default socket timing here, because
688          * we are not guaranteed to see a SetIOMap operation at
689          * runtime.
690          */
691         skt->ops->set_timing(skt);
692
693         ret = skt->ops->hw_init(skt);
694         if (ret)
695                 goto out_err_6;
696
697         skt->socket.ops = &soc_common_pcmcia_operations;
698         skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
699         skt->socket.resource_ops = &pccard_static_ops;
700         skt->socket.irq_mask = 0;
701         skt->socket.map_size = PAGE_SIZE;
702         skt->socket.io_offset = (unsigned long)skt->virt_io;
703
704         skt->status = soc_common_pcmcia_skt_state(skt);
705
706         ret = pcmcia_register_socket(&skt->socket);
707         if (ret)
708                 goto out_err_7;
709
710         add_timer(&skt->poll_timer);
711
712         mutex_unlock(&soc_pcmcia_sockets_lock);
713
714         ret = device_create_file(&skt->socket.dev, &dev_attr_status);
715         if (ret)
716                 goto out_err_8;
717
718         return ret;
719
720  out_err_8:
721         mutex_lock(&soc_pcmcia_sockets_lock);
722         del_timer_sync(&skt->poll_timer);
723         pcmcia_unregister_socket(&skt->socket);
724
725  out_err_7:
726         skt->ops->hw_shutdown(skt);
727  out_err_6:
728         list_del(&skt->node);
729         mutex_unlock(&soc_pcmcia_sockets_lock);
730         iounmap(skt->virt_io);
731  out_err_5:
732         release_resource(&skt->res_attr);
733  out_err_4:
734         release_resource(&skt->res_mem);
735  out_err_3:
736         release_resource(&skt->res_io);
737  out_err_2:
738         release_resource(&skt->res_skt);
739  out_err_1:
740
741         return ret;
742 }
743 EXPORT_SYMBOL(soc_pcmcia_add_one);
744
745 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
746 MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support");
747 MODULE_LICENSE("Dual MPL/GPL");