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