linux/arch/cris/arch-v10/kernel/dma.c
<<
>>
Prefs
   1/* Wrapper for DMA channel allocator that updates DMA client muxing.
   2 * Copyright 2004-2007, Axis Communications AB
   3 */
   4
   5#include <linux/kernel.h>
   6#include <linux/module.h>
   7#include <linux/errno.h>
   8
   9#include <asm/dma.h>
  10#include <arch/svinto.h>
  11
  12/* Macro to access ETRAX 100 registers */
  13#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
  14                                          IO_STATE_(reg##_, field##_, _##val)
  15
  16
  17static char used_dma_channels[MAX_DMA_CHANNELS];
  18static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
  19
  20int cris_request_dma(unsigned int dmanr, const char * device_id,
  21                     unsigned options, enum dma_owner owner)
  22{
  23        unsigned long flags;
  24        unsigned long int gens;
  25        int fail = -EINVAL;
  26
  27        if (dmanr >= MAX_DMA_CHANNELS) {
  28                printk(KERN_CRIT "cris_request_dma: invalid DMA channel %u\n", dmanr);
  29                return -EINVAL;
  30        }
  31
  32        local_irq_save(flags);
  33        if (used_dma_channels[dmanr]) {
  34                local_irq_restore(flags);
  35                if (options & DMA_VERBOSE_ON_ERROR) {
  36                        printk(KERN_CRIT "Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]);
  37                }
  38                if (options & DMA_PANIC_ON_ERROR) {
  39                        panic("request_dma error!");
  40                }
  41                return -EBUSY;
  42        }
  43
  44        gens = genconfig_shadow;
  45
  46        switch(owner)
  47        {
  48        case dma_eth:
  49                if ((dmanr != NETWORK_TX_DMA_NBR) &&
  50                    (dmanr != NETWORK_RX_DMA_NBR)) {
  51                        printk(KERN_CRIT "Invalid DMA channel for eth\n");
  52                        goto bail;
  53                }
  54                break;
  55        case dma_ser0:
  56                if (dmanr == SER0_TX_DMA_NBR) {
  57                        SETS(gens, R_GEN_CONFIG, dma6, serial0);
  58                } else if (dmanr == SER0_RX_DMA_NBR) {
  59                        SETS(gens, R_GEN_CONFIG, dma7, serial0);
  60                } else {
  61                        printk(KERN_CRIT "Invalid DMA channel for ser0\n");
  62                        goto bail;
  63                }
  64                break;
  65        case dma_ser1:
  66                if (dmanr == SER1_TX_DMA_NBR) {
  67                        SETS(gens, R_GEN_CONFIG, dma8, serial1);
  68                } else if (dmanr == SER1_RX_DMA_NBR) {
  69                        SETS(gens, R_GEN_CONFIG, dma9, serial1);
  70                } else {
  71                        printk(KERN_CRIT "Invalid DMA channel for ser1\n");
  72                        goto bail;
  73                }
  74                break;
  75        case dma_ser2:
  76                if (dmanr == SER2_TX_DMA_NBR) {
  77                        SETS(gens, R_GEN_CONFIG, dma2, serial2);
  78                } else if (dmanr == SER2_RX_DMA_NBR) {
  79                        SETS(gens, R_GEN_CONFIG, dma3, serial2);
  80                } else {
  81                        printk(KERN_CRIT "Invalid DMA channel for ser2\n");
  82                        goto bail;
  83                }
  84                break;
  85        case dma_ser3:
  86                if (dmanr == SER3_TX_DMA_NBR) {
  87                        SETS(gens, R_GEN_CONFIG, dma4, serial3);
  88                } else if (dmanr == SER3_RX_DMA_NBR) {
  89                        SETS(gens, R_GEN_CONFIG, dma5, serial3);
  90                } else {
  91                        printk(KERN_CRIT "Invalid DMA channel for ser3\n");
  92                        goto bail;
  93                }
  94                break;
  95        case dma_ata:
  96                if (dmanr == ATA_TX_DMA_NBR) {
  97                        SETS(gens, R_GEN_CONFIG, dma2, ata);
  98                } else if (dmanr == ATA_RX_DMA_NBR) {
  99                        SETS(gens, R_GEN_CONFIG, dma3, ata);
 100                } else {
 101                        printk(KERN_CRIT "Invalid DMA channel for ata\n");
 102                        goto bail;
 103                }
 104                break;
 105        case dma_ext0:
 106                if (dmanr == EXTDMA0_TX_DMA_NBR) {
 107                        SETS(gens, R_GEN_CONFIG, dma4, extdma0);
 108                } else if (dmanr == EXTDMA0_RX_DMA_NBR) {
 109                        SETS(gens, R_GEN_CONFIG, dma5, extdma0);
 110                } else {
 111                        printk(KERN_CRIT "Invalid DMA channel for ext0\n");
 112                        goto bail;
 113                }
 114                break;
 115        case dma_ext1:
 116                if (dmanr == EXTDMA1_TX_DMA_NBR) {
 117                        SETS(gens, R_GEN_CONFIG, dma6, extdma1);
 118                } else if (dmanr == EXTDMA1_RX_DMA_NBR) {
 119                        SETS(gens, R_GEN_CONFIG, dma7, extdma1);
 120                } else {
 121                        printk(KERN_CRIT "Invalid DMA channel for ext1\n");
 122                        goto bail;
 123                }
 124                break;
 125        case dma_int6:
 126                if (dmanr == MEM2MEM_RX_DMA_NBR) {
 127                        SETS(gens, R_GEN_CONFIG, dma7, intdma6);
 128                } else {
 129                        printk(KERN_CRIT "Invalid DMA channel for int6\n");
 130                        goto bail;
 131                }
 132                break;
 133        case dma_int7:
 134                if (dmanr == MEM2MEM_TX_DMA_NBR) {
 135                        SETS(gens, R_GEN_CONFIG, dma6, intdma7);
 136                } else {
 137                        printk(KERN_CRIT "Invalid DMA channel for int7\n");
 138                        goto bail;
 139                }
 140                break;
 141        case dma_usb:
 142                if (dmanr == USB_TX_DMA_NBR) {
 143                        SETS(gens, R_GEN_CONFIG, dma8, usb);
 144                } else if (dmanr == USB_RX_DMA_NBR) {
 145                        SETS(gens, R_GEN_CONFIG, dma9, usb);
 146                } else {
 147                        printk(KERN_CRIT "Invalid DMA channel for usb\n");
 148                        goto bail;
 149                }
 150                break;
 151        case dma_scsi0:
 152                if (dmanr == SCSI0_TX_DMA_NBR) {
 153                        SETS(gens, R_GEN_CONFIG, dma2, scsi0);
 154                } else if (dmanr == SCSI0_RX_DMA_NBR) {
 155                        SETS(gens, R_GEN_CONFIG, dma3, scsi0);
 156                } else {
 157                        printk(KERN_CRIT "Invalid DMA channel for scsi0\n");
 158                        goto bail;
 159                }
 160                break;
 161        case dma_scsi1:
 162                if (dmanr == SCSI1_TX_DMA_NBR) {
 163                        SETS(gens, R_GEN_CONFIG, dma4, scsi1);
 164                } else if (dmanr == SCSI1_RX_DMA_NBR) {
 165                        SETS(gens, R_GEN_CONFIG, dma5, scsi1);
 166                } else {
 167                        printk(KERN_CRIT "Invalid DMA channel for scsi1\n");
 168                        goto bail;
 169                }
 170                break;
 171        case dma_par0:
 172                if (dmanr == PAR0_TX_DMA_NBR) {
 173                        SETS(gens, R_GEN_CONFIG, dma2, par0);
 174                } else if (dmanr == PAR0_RX_DMA_NBR) {
 175                        SETS(gens, R_GEN_CONFIG, dma3, par0);
 176                } else {
 177                        printk(KERN_CRIT "Invalid DMA channel for par0\n");
 178                        goto bail;
 179                }
 180                break;
 181        case dma_par1:
 182                if (dmanr == PAR1_TX_DMA_NBR) {
 183                        SETS(gens, R_GEN_CONFIG, dma4, par1);
 184                } else if (dmanr == PAR1_RX_DMA_NBR) {
 185                        SETS(gens, R_GEN_CONFIG, dma5, par1);
 186                } else {
 187                        printk(KERN_CRIT "Invalid DMA channel for par1\n");
 188                        goto bail;
 189                }
 190                break;
 191        default:
 192                printk(KERN_CRIT "Invalid DMA owner.\n");
 193                goto bail;
 194        }
 195
 196        used_dma_channels[dmanr] = 1;
 197        used_dma_channels_users[dmanr] = device_id;
 198
 199        {
 200                volatile int i;
 201                genconfig_shadow = gens;
 202                *R_GEN_CONFIG = genconfig_shadow;
 203                /* Wait 12 cycles before doing any DMA command */
 204                for(i = 6; i > 0; i--)
 205                        nop();
 206        }
 207        fail = 0;
 208 bail:
 209        local_irq_restore(flags);
 210        return fail;
 211}
 212
 213void cris_free_dma(unsigned int dmanr, const char * device_id)
 214{
 215        unsigned long flags;
 216        if (dmanr >= MAX_DMA_CHANNELS) {
 217                printk(KERN_CRIT "cris_free_dma: invalid DMA channel %u\n", dmanr);
 218                return;
 219        }
 220
 221        local_irq_save(flags);
 222        if (!used_dma_channels[dmanr]) {
 223                printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated\n", dmanr);
 224        } else if (device_id != used_dma_channels_users[dmanr]) {
 225                printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated by device\n", dmanr);
 226        } else {
 227                switch(dmanr)
 228                {
 229                case 0:
 230                        *R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, reset);
 231                        while (IO_EXTRACT(R_DMA_CH0_CMD, cmd, *R_DMA_CH0_CMD) ==
 232                               IO_STATE_VALUE(R_DMA_CH0_CMD, cmd, reset));
 233                        break;
 234                case 1:
 235                        *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, reset);
 236                        while (IO_EXTRACT(R_DMA_CH1_CMD, cmd, *R_DMA_CH1_CMD) ==
 237                               IO_STATE_VALUE(R_DMA_CH1_CMD, cmd, reset));
 238                        break;
 239                case 2:
 240                        *R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, reset);
 241                        while (IO_EXTRACT(R_DMA_CH2_CMD, cmd, *R_DMA_CH2_CMD) ==
 242                               IO_STATE_VALUE(R_DMA_CH2_CMD, cmd, reset));
 243                        break;
 244                case 3:
 245                        *R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, reset);
 246                        while (IO_EXTRACT(R_DMA_CH3_CMD, cmd, *R_DMA_CH3_CMD) ==
 247                               IO_STATE_VALUE(R_DMA_CH3_CMD, cmd, reset));
 248                        break;
 249                case 4:
 250                        *R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, reset);
 251                        while (IO_EXTRACT(R_DMA_CH4_CMD, cmd, *R_DMA_CH4_CMD) ==
 252                               IO_STATE_VALUE(R_DMA_CH4_CMD, cmd, reset));
 253                        break;
 254                case 5:
 255                        *R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, reset);
 256                        while (IO_EXTRACT(R_DMA_CH5_CMD, cmd, *R_DMA_CH5_CMD) ==
 257                               IO_STATE_VALUE(R_DMA_CH5_CMD, cmd, reset));
 258                        break;
 259                case 6:
 260                        *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 261                        while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *R_DMA_CH6_CMD) ==
 262                               IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
 263                        break;
 264                case 7:
 265                        *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, reset);
 266                        while (IO_EXTRACT(R_DMA_CH7_CMD, cmd, *R_DMA_CH7_CMD) ==
 267                               IO_STATE_VALUE(R_DMA_CH7_CMD, cmd, reset));
 268                        break;
 269                case 8:
 270                        *R_DMA_CH8_CMD = IO_STATE(R_DMA_CH8_CMD, cmd, reset);
 271                        while (IO_EXTRACT(R_DMA_CH8_CMD, cmd, *R_DMA_CH8_CMD) ==
 272                               IO_STATE_VALUE(R_DMA_CH8_CMD, cmd, reset));
 273                        break;
 274                case 9:
 275                        *R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, reset);
 276                        while (IO_EXTRACT(R_DMA_CH9_CMD, cmd, *R_DMA_CH9_CMD) ==
 277                               IO_STATE_VALUE(R_DMA_CH9_CMD, cmd, reset));
 278                        break;
 279                }
 280                used_dma_channels[dmanr] = 0;
 281        }
 282        local_irq_restore(flags);
 283}
 284
 285EXPORT_SYMBOL(cris_request_dma);
 286EXPORT_SYMBOL(cris_free_dma);
 287