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

Archive Download this file



interactive