~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#include <linux/netdevice.h>
18
18
#include <bcmdefs.h>
19
19
#include <bcmdevs.h>
20
 
#include <bcmendian.h>
21
 
#include <osl.h>
22
20
#include <bcmutils.h>
23
21
#include <sdio.h>               /* SDIO Device and Protocol Specs */
24
22
#include <sdioh.h>              /* SDIO Host Controller Specification */
28
26
#include <linux/mmc/core.h>
29
27
#include <linux/mmc/sdio_func.h>
30
28
#include <linux/mmc/sdio_ids.h>
 
29
#include <linux/suspend.h>
31
30
 
32
31
#include <dngl_stats.h>
33
32
#include <dhd.h>
34
33
 
35
 
#if defined(CONFIG_PM_SLEEP)
36
 
#include <linux/suspend.h>
37
 
extern volatile bool dhd_mmc_suspend;
38
 
#endif
39
34
#include "bcmsdh_sdmmc.h"
40
35
 
41
36
extern int sdio_function_init(void);
70
65
int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr,
71
66
                             int regsize, u32 *data);
72
67
 
 
68
void sdioh_sdio_set_host_pm_flags(int flag)
 
69
{
 
70
        if (sdio_set_host_pm_flags(gInstance->func[1], flag))
 
71
                printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\
 
72
                         __func__, (unsigned int)flag);
 
73
}
 
74
 
73
75
static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
74
76
{
75
77
        int err_ret;
112
114
/*
113
115
 *      Public entry points & extern's
114
116
 */
115
 
extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *bar0, uint irq)
 
117
sdioh_info_t *sdioh_attach(void *bar0, uint irq)
116
118
{
117
119
        sdioh_info_t *sd;
118
120
        int err_ret;
129
131
                sd_err(("sdioh_attach: out of memory\n"));
130
132
                return NULL;
131
133
        }
132
 
        sd->osh = osh;
133
134
        if (sdioh_sdmmc_osinit(sd) != 0) {
134
135
                sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__));
135
136
                kfree(sd);
175
176
        return sd;
176
177
}
177
178
 
178
 
extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *sd)
 
179
extern SDIOH_API_RC sdioh_detach(sdioh_info_t *sd)
179
180
{
180
181
        sd_trace(("%s\n", __func__));
181
182
 
267
268
}
268
269
#endif                          /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
269
270
 
270
 
/* Configure callback to client when we recieve client interrupt */
 
271
/* Configure callback to client when we receive client interrupt */
271
272
extern SDIOH_API_RC
272
273
sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
273
274
{
419
420
 
420
421
        vi = bcm_iovar_lookup(sdioh_iovars, name);
421
422
        if (vi == NULL) {
422
 
                bcmerror = BCME_UNSUPPORTED;
 
423
                bcmerror = -ENOTSUPP;
423
424
                goto exit;
424
425
        }
425
426
 
441
442
                val_size = sizeof(int);
442
443
 
443
444
        if (plen >= (int)sizeof(int_val))
444
 
                bcopy(params, &int_val, sizeof(int_val));
 
445
                memcpy(&int_val, params, sizeof(int_val));
445
446
 
446
447
        bool_val = (int_val != 0) ? true : false;
447
448
 
449
450
        switch (actionid) {
450
451
        case IOV_GVAL(IOV_MSGLEVEL):
451
452
                int_val = (s32) sd_msglevel;
452
 
                bcopy(&int_val, arg, val_size);
 
453
                memcpy(arg, &int_val, val_size);
453
454
                break;
454
455
 
455
456
        case IOV_SVAL(IOV_MSGLEVEL):
458
459
 
459
460
        case IOV_GVAL(IOV_BLOCKMODE):
460
461
                int_val = (s32) si->sd_blockmode;
461
 
                bcopy(&int_val, arg, val_size);
 
462
                memcpy(arg, &int_val, val_size);
462
463
                break;
463
464
 
464
465
        case IOV_SVAL(IOV_BLOCKMODE):
468
469
 
469
470
        case IOV_GVAL(IOV_BLOCKSIZE):
470
471
                if ((u32) int_val > si->num_funcs) {
471
 
                        bcmerror = BCME_BADARG;
 
472
                        bcmerror = -EINVAL;
472
473
                        break;
473
474
                }
474
475
                int_val = (s32) si->client_block_size[int_val];
475
 
                bcopy(&int_val, arg, val_size);
 
476
                memcpy(arg, &int_val, val_size);
476
477
                break;
477
478
 
478
479
        case IOV_SVAL(IOV_BLOCKSIZE):
482
483
                        uint maxsize;
483
484
 
484
485
                        if (func > si->num_funcs) {
485
 
                                bcmerror = BCME_BADARG;
 
486
                                bcmerror = -EINVAL;
486
487
                                break;
487
488
                        }
488
489
 
500
501
                                maxsize = 0;
501
502
                        }
502
503
                        if (blksize > maxsize) {
503
 
                                bcmerror = BCME_BADARG;
 
504
                                bcmerror = -EINVAL;
504
505
                                break;
505
506
                        }
506
507
                        if (!blksize)
514
515
 
515
516
        case IOV_GVAL(IOV_RXCHAIN):
516
517
                int_val = false;
517
 
                bcopy(&int_val, arg, val_size);
 
518
                memcpy(arg, &int_val, val_size);
518
519
                break;
519
520
 
520
521
        case IOV_GVAL(IOV_DMA):
521
522
                int_val = (s32) si->sd_use_dma;
522
 
                bcopy(&int_val, arg, val_size);
 
523
                memcpy(arg, &int_val, val_size);
523
524
                break;
524
525
 
525
526
        case IOV_SVAL(IOV_DMA):
528
529
 
529
530
        case IOV_GVAL(IOV_USEINTS):
530
531
                int_val = (s32) si->use_client_ints;
531
 
                bcopy(&int_val, arg, val_size);
 
532
                memcpy(arg, &int_val, val_size);
532
533
                break;
533
534
 
534
535
        case IOV_SVAL(IOV_USEINTS):
542
543
 
543
544
        case IOV_GVAL(IOV_DIVISOR):
544
545
                int_val = (u32) sd_divisor;
545
 
                bcopy(&int_val, arg, val_size);
 
546
                memcpy(arg, &int_val, val_size);
546
547
                break;
547
548
 
548
549
        case IOV_SVAL(IOV_DIVISOR):
551
552
 
552
553
        case IOV_GVAL(IOV_POWER):
553
554
                int_val = (u32) sd_power;
554
 
                bcopy(&int_val, arg, val_size);
 
555
                memcpy(arg, &int_val, val_size);
555
556
                break;
556
557
 
557
558
        case IOV_SVAL(IOV_POWER):
560
561
 
561
562
        case IOV_GVAL(IOV_CLOCK):
562
563
                int_val = (u32) sd_clock;
563
 
                bcopy(&int_val, arg, val_size);
 
564
                memcpy(arg, &int_val, val_size);
564
565
                break;
565
566
 
566
567
        case IOV_SVAL(IOV_CLOCK):
569
570
 
570
571
        case IOV_GVAL(IOV_SDMODE):
571
572
                int_val = (u32) sd_sdmode;
572
 
                bcopy(&int_val, arg, val_size);
 
573
                memcpy(arg, &int_val, val_size);
573
574
                break;
574
575
 
575
576
        case IOV_SVAL(IOV_SDMODE):
578
579
 
579
580
        case IOV_GVAL(IOV_HISPEED):
580
581
                int_val = (u32) sd_hiok;
581
 
                bcopy(&int_val, arg, val_size);
 
582
                memcpy(arg, &int_val, val_size);
582
583
                break;
583
584
 
584
585
        case IOV_SVAL(IOV_HISPEED):
587
588
 
588
589
        case IOV_GVAL(IOV_NUMINTS):
589
590
                int_val = (s32) si->intrcount;
590
 
                bcopy(&int_val, arg, val_size);
 
591
                memcpy(arg, &int_val, val_size);
591
592
                break;
592
593
 
593
594
        case IOV_GVAL(IOV_NUMLOCALINTS):
594
595
                int_val = (s32) 0;
595
 
                bcopy(&int_val, arg, val_size);
 
596
                memcpy(arg, &int_val, val_size);
596
597
                break;
597
598
 
598
599
        case IOV_GVAL(IOV_HOSTREG):
603
604
                            || sd_ptr->offset > SD_MaxCurCap) {
604
605
                                sd_err(("%s: bad offset 0x%x\n", __func__,
605
606
                                        sd_ptr->offset));
606
 
                                bcmerror = BCME_BADARG;
 
607
                                bcmerror = -EINVAL;
607
608
                                break;
608
609
                        }
609
610
 
621
622
                                int_val = 32;   /* sdioh_sdmmc_rreg(si,
622
623
                                                 sd_ptr->offset); */
623
624
 
624
 
                        bcopy(&int_val, arg, sizeof(int_val));
 
625
                        memcpy(arg, &int_val, sizeof(int_val));
625
626
                        break;
626
627
                }
627
628
 
633
634
                            || sd_ptr->offset > SD_MaxCurCap) {
634
635
                                sd_err(("%s: bad offset 0x%x\n", __func__,
635
636
                                        sd_ptr->offset));
636
 
                                bcmerror = BCME_BADARG;
 
637
                                bcmerror = -EINVAL;
637
638
                                break;
638
639
                        }
639
640
 
652
653
 
653
654
                        if (sdioh_cfg_read
654
655
                            (si, sd_ptr->func, sd_ptr->offset, &data)) {
655
 
                                bcmerror = BCME_SDIO_ERROR;
 
656
                                bcmerror = -EIO;
656
657
                                break;
657
658
                        }
658
659
 
659
660
                        int_val = (int)data;
660
 
                        bcopy(&int_val, arg, sizeof(int_val));
 
661
                        memcpy(arg, &int_val, sizeof(int_val));
661
662
                        break;
662
663
                }
663
664
 
668
669
 
669
670
                        if (sdioh_cfg_write
670
671
                            (si, sd_ptr->func, sd_ptr->offset, &data)) {
671
 
                                bcmerror = BCME_SDIO_ERROR;
 
672
                                bcmerror = -EIO;
672
673
                                break;
673
674
                        }
674
675
                        break;
675
676
                }
676
677
 
677
678
        default:
678
 
                bcmerror = BCME_UNSUPPORTED;
 
679
                bcmerror = -ENOTSUPP;
679
680
                break;
680
681
        }
681
682
exit:
735
736
        }
736
737
 
737
738
        /* Only the lower 17-bits are valid */
738
 
        scratch = ltoh32(scratch);
 
739
        scratch = le32_to_cpu(scratch);
739
740
        scratch &= 0x0001FFFF;
740
741
        return scratch;
741
742
}
1009
1010
 
1010
1011
/*
1011
1012
 * This function takes a buffer or packet, and fixes everything up
1012
 
 * so that in the
1013
 
 * end, a DMA-able packet is created.
 
1013
 * so that in the end, a DMA-able packet is created.
1014
1014
 *
1015
1015
 * A buffer does not have an associated packet pointer,
1016
1016
 * and may or may not be aligned.
1017
1017
 * A packet may consist of a single packet, or a packet chain.
1018
 
 * If it is a packet chain,
1019
 
 * then all the packets in the chain must be properly aligned.
1020
 
 * If the packet data is not
1021
 
 * aligned, then there may only be one packet, and in this case,
1022
 
 * it is copied to a new
 
1018
 * If it is a packet chain, then all the packets in the chain
 
1019
 * must be properly aligned.
 
1020
 *
 
1021
 * If the packet data is not aligned, then there may only be
 
1022
 * one packet, and in this case,  it is copied to a new
1023
1023
 * aligned packet.
1024
1024
 *
1025
1025
 */
1039
1039
        if (pkt == NULL) {
1040
1040
                sd_data(("%s: Creating new %s Packet, len=%d\n",
1041
1041
                         __func__, write ? "TX" : "RX", buflen_u));
1042
 
                mypkt = pkt_buf_get_skb(sd->osh, buflen_u);
 
1042
                mypkt = bcm_pkt_buf_get_skb(buflen_u);
1043
1043
                if (!mypkt) {
1044
 
                        sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
 
1044
                        sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
1045
1045
                                __func__, buflen_u));
1046
1046
                        return SDIOH_API_RC_FAIL;
1047
1047
                }
1048
1048
 
1049
1049
                /* For a write, copy the buffer data into the packet. */
1050
1050
                if (write)
1051
 
                        bcopy(buffer, mypkt->data, buflen_u);
 
1051
                        memcpy(mypkt->data, buffer, buflen_u);
1052
1052
 
1053
1053
                Status =
1054
1054
                    sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
1055
1055
 
1056
1056
                /* For a read, copy the packet data back to the buffer. */
1057
1057
                if (!write)
1058
 
                        bcopy(mypkt->data, buffer, buflen_u);
 
1058
                        memcpy(buffer, mypkt->data, buflen_u);
1059
1059
 
1060
 
                pkt_buf_free_skb(sd->osh, mypkt, write ? true : false);
 
1060
                bcm_pkt_buf_free_skb(mypkt);
1061
1061
        } else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) {
1062
1062
                /* Case 2: We have a packet, but it is unaligned. */
1063
1063
 
1066
1066
 
1067
1067
                sd_data(("%s: Creating aligned %s Packet, len=%d\n",
1068
1068
                         __func__, write ? "TX" : "RX", pkt->len));
1069
 
                mypkt = pkt_buf_get_skb(sd->osh, pkt->len);
 
1069
                mypkt = bcm_pkt_buf_get_skb(pkt->len);
1070
1070
                if (!mypkt) {
1071
 
                        sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
 
1071
                        sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
1072
1072
                                __func__, pkt->len));
1073
1073
                        return SDIOH_API_RC_FAIL;
1074
1074
                }
1075
1075
 
1076
1076
                /* For a write, copy the buffer data into the packet. */
1077
1077
                if (write)
1078
 
                        bcopy(pkt->data, mypkt->data, pkt->len);
 
1078
                        memcpy(mypkt->data, pkt->data, pkt->len);
1079
1079
 
1080
1080
                Status =
1081
1081
                    sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
1082
1082
 
1083
1083
                /* For a read, copy the packet data back to the buffer. */
1084
1084
                if (!write)
1085
 
                        bcopy(mypkt->data, pkt->data, mypkt->len);
 
1085
                        memcpy(pkt->data, mypkt->data, mypkt->len);
1086
1086
 
1087
 
                pkt_buf_free_skb(sd->osh, mypkt, write ? true : false);
 
1087
                bcm_pkt_buf_free_skb(mypkt);
1088
1088
        } else {                /* case 3: We have a packet and
1089
1089
                                 it is aligned. */
1090
1090
                sd_data(("%s: Aligned %s Packet, direct DMA\n",