linux/arch/arm/plat-s3c24xx/dma.c
<<
>>
Prefs
   1/* linux/arch/arm/plat-s3c24xx/dma.c
   2 *
   3 * Copyright (c) 2003-2005,2006 Simtec Electronics
   4 *      Ben Dooks <ben@simtec.co.uk>
   5 *
   6 * S3C2410 DMA core
   7 *
   8 * http://armlinux.simtec.co.uk/
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13*/
  14
  15
  16#ifdef CONFIG_S3C2410_DMA_DEBUG
  17#define DEBUG
  18#endif
  19
  20#include <linux/module.h>
  21#include <linux/init.h>
  22#include <linux/sched.h>
  23#include <linux/spinlock.h>
  24#include <linux/interrupt.h>
  25#include <linux/sysdev.h>
  26#include <linux/slab.h>
  27#include <linux/errno.h>
  28#include <linux/io.h>
  29
  30#include <asm/system.h>
  31#include <asm/irq.h>
  32#include <mach/hardware.h>
  33#include <mach/dma.h>
  34#include <mach/map.h>
  35
  36#include <plat/dma-plat.h>
  37#include <plat/regs-dma.h>
  38
  39/* io map for dma */
  40static void __iomem *dma_base;
  41static struct kmem_cache *dma_kmem;
  42
  43static int dma_channels;
  44
  45static struct s3c24xx_dma_selection dma_sel;
  46
  47
  48/* debugging functions */
  49
  50#define BUF_MAGIC (0xcafebabe)
  51
  52#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
  53
  54#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
  55
  56#if 1
  57#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
  58#else
  59static inline void
  60dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
  61{
  62        pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
  63        writel(val, dma_regaddr(chan, reg));
  64}
  65#endif
  66
  67#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
  68
  69/* captured register state for debug */
  70
  71struct s3c2410_dma_regstate {
  72        unsigned long         dcsrc;
  73        unsigned long         disrc;
  74        unsigned long         dstat;
  75        unsigned long         dcon;
  76        unsigned long         dmsktrig;
  77};
  78
  79#ifdef CONFIG_S3C2410_DMA_DEBUG
  80
  81/* dmadbg_showregs
  82 *
  83 * simple debug routine to print the current state of the dma registers
  84*/
  85
  86static void
  87dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
  88{
  89        regs->dcsrc    = dma_rdreg(chan, S3C2410_DMA_DCSRC);
  90        regs->disrc    = dma_rdreg(chan, S3C2410_DMA_DISRC);
  91        regs->dstat    = dma_rdreg(chan, S3C2410_DMA_DSTAT);
  92        regs->dcon     = dma_rdreg(chan, S3C2410_DMA_DCON);
  93        regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
  94}
  95
  96static void
  97dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
  98                 struct s3c2410_dma_regstate *regs)
  99{
 100        printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
 101               chan->number, fname, line,
 102               regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
 103               regs->dcon);
 104}
 105
 106static void
 107dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
 108{
 109        struct s3c2410_dma_regstate state;
 110
 111        dmadbg_capture(chan, &state);
 112
 113        printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
 114               chan->number, fname, line, chan->load_state,
 115               chan->curr, chan->next, chan->end);
 116
 117        dmadbg_dumpregs(fname, line, chan, &state);
 118}
 119
 120static void
 121dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
 122{
 123        struct s3c2410_dma_regstate state;
 124
 125        dmadbg_capture(chan, &state);
 126        dmadbg_dumpregs(fname, line, chan, &state);
 127}
 128
 129#define dbg_showregs(chan) dmadbg_showregs(__func__, __LINE__, (chan))
 130#define dbg_showchan(chan) dmadbg_showchan(__func__, __LINE__, (chan))
 131#else
 132#define dbg_showregs(chan) do { } while(0)
 133#define dbg_showchan(chan) do { } while(0)
 134#endif /* CONFIG_S3C2410_DMA_DEBUG */
 135
 136/* s3c2410_dma_stats_timeout
 137 *
 138 * Update DMA stats from timeout info
 139*/
 140
 141static void
 142s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
 143{
 144        if (stats == NULL)
 145                return;
 146
 147        if (val > stats->timeout_longest)
 148                stats->timeout_longest = val;
 149        if (val < stats->timeout_shortest)
 150                stats->timeout_shortest = val;
 151
 152        stats->timeout_avg += val;
 153}
 154
 155/* s3c2410_dma_waitforload
 156 *
 157 * wait for the DMA engine to load a buffer, and update the state accordingly
 158*/
 159
 160static int
 161s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
 162{
 163        int timeout = chan->load_timeout;
 164        int took;
 165
 166        if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
 167                printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
 168                return 0;
 169        }
 170
 171        if (chan->stats != NULL)
 172                chan->stats->loads++;
 173
 174        while (--timeout > 0) {
 175                if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
 176                        took = chan->load_timeout - timeout;
 177
 178                        s3c2410_dma_stats_timeout(chan->stats, took);
 179
 180                        switch (chan->load_state) {
 181                        case S3C2410_DMALOAD_1LOADED:
 182                                chan->load_state = S3C2410_DMALOAD_1RUNNING;
 183                                break;
 184
 185                        default:
 186                                printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
 187                        }
 188
 189                        return 1;
 190                }
 191        }
 192
 193        if (chan->stats != NULL) {
 194                chan->stats->timeout_failed++;
 195        }
 196
 197        return 0;
 198}
 199
 200/* s3c2410_dma_loadbuffer
 201 *
 202 * load a buffer, and update the channel state
 203*/
 204
 205static inline int
 206s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
 207                       struct s3c2410_dma_buf *buf)
 208{
 209        unsigned long reload;
 210
 211        if (buf == NULL) {
 212                dmawarn("buffer is NULL\n");
 213                return -EINVAL;
 214        }
 215
 216        pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
 217                 buf, (unsigned long)buf->data, buf->size);
 218
 219        /* check the state of the channel before we do anything */
 220
 221        if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
 222                dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
 223        }
 224
 225        if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
 226                dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
 227        }
 228
 229        /* it would seem sensible if we are the last buffer to not bother
 230         * with the auto-reload bit, so that the DMA engine will not try
 231         * and load another transfer after this one has finished...
 232         */
 233        if (chan->load_state == S3C2410_DMALOAD_NONE) {
 234                pr_debug("load_state is none, checking for noreload (next=%p)\n",
 235                         buf->next);
 236                reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
 237        } else {
 238                //pr_debug("load_state is %d => autoreload\n", chan->load_state);
 239                reload = S3C2410_DCON_AUTORELOAD;
 240        }
 241
 242        if ((buf->data & 0xf0000000) != 0x30000000) {
 243                dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
 244        }
 245
 246        writel(buf->data, chan->addr_reg);
 247
 248        dma_wrreg(chan, S3C2410_DMA_DCON,
 249                  chan->dcon | reload | (buf->size/chan->xfer_unit));
 250
 251        chan->next = buf->next;
 252
 253        /* update the state of the channel */
 254
 255        switch (chan->load_state) {
 256        case S3C2410_DMALOAD_NONE:
 257                chan->load_state = S3C2410_DMALOAD_1LOADED;
 258                break;
 259
 260        case S3C2410_DMALOAD_1RUNNING:
 261                chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
 262                break;
 263
 264        default:
 265                dmawarn("dmaload: unknown state %d in loadbuffer\n",
 266                        chan->load_state);
 267                break;
 268        }
 269
 270        return 0;
 271}
 272
 273/* s3c2410_dma_call_op
 274 *
 275 * small routine to call the op routine with the given op if it has been
 276 * registered
 277*/
 278
 279static void
 280s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
 281{
 282        if (chan->op_fn != NULL) {
 283                (chan->op_fn)(chan, op);
 284        }
 285}
 286
 287/* s3c2410_dma_buffdone
 288 *
 289 * small wrapper to check if callback routine needs to be called, and
 290 * if so, call it
 291*/
 292
 293static inline void
 294s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
 295                     enum s3c2410_dma_buffresult result)
 296{
 297#if 0
 298        pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
 299                 chan->callback_fn, buf, buf->id, buf->size, result);
 300#endif
 301
 302        if (chan->callback_fn != NULL) {
 303                (chan->callback_fn)(chan, buf->id, buf->size, result);
 304        }
 305}
 306
 307/* s3c2410_dma_start
 308 *
 309 * start a dma channel going
 310*/
 311
 312static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
 313{
 314        unsigned long tmp;
 315        unsigned long flags;
 316
 317        pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
 318
 319        local_irq_save(flags);
 320
 321        if (chan->state == S3C2410_DMA_RUNNING) {
 322                pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
 323                local_irq_restore(flags);
 324                return 0;
 325        }
 326
 327        chan->state = S3C2410_DMA_RUNNING;
 328
 329        /* check wether there is anything to load, and if not, see
 330         * if we can find anything to load
 331         */
 332
 333        if (chan->load_state == S3C2410_DMALOAD_NONE) {
 334                if (chan->next == NULL) {
 335                        printk(KERN_ERR "dma%d: channel has nothing loaded\n",
 336                               chan->number);
 337                        chan->state = S3C2410_DMA_IDLE;
 338                        local_irq_restore(flags);
 339                        return -EINVAL;
 340                }
 341
 342                s3c2410_dma_loadbuffer(chan, chan->next);
 343        }
 344
 345        dbg_showchan(chan);
 346
 347        /* enable the channel */
 348
 349        if (!chan->irq_enabled) {
 350                enable_irq(chan->irq);
 351                chan->irq_enabled = 1;
 352        }
 353
 354        /* start the channel going */
 355
 356        tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
 357        tmp &= ~S3C2410_DMASKTRIG_STOP;
 358        tmp |= S3C2410_DMASKTRIG_ON;
 359        dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
 360
 361        pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
 362
 363#if 0
 364        /* the dma buffer loads should take care of clearing the AUTO
 365         * reloading feature */
 366        tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
 367        tmp &= ~S3C2410_DCON_NORELOAD;
 368        dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
 369#endif
 370
 371        s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
 372
 373        dbg_showchan(chan);
 374
 375        /* if we've only loaded one buffer onto the channel, then chec
 376         * to see if we have another, and if so, try and load it so when
 377         * the first buffer is finished, the new one will be loaded onto
 378         * the channel */
 379
 380        if (chan->next != NULL) {
 381                if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
 382
 383                        if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
 384                                pr_debug("%s: buff not yet loaded, no more todo\n",
 385                                         __func__);
 386                        } else {
 387                                chan->load_state = S3C2410_DMALOAD_1RUNNING;
 388                                s3c2410_dma_loadbuffer(chan, chan->next);
 389                        }
 390
 391                } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
 392                        s3c2410_dma_loadbuffer(chan, chan->next);
 393                }
 394        }
 395
 396
 397        local_irq_restore(flags);
 398
 399        return 0;
 400}
 401
 402/* s3c2410_dma_canload
 403 *
 404 * work out if we can queue another buffer into the DMA engine
 405*/
 406
 407static int
 408s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
 409{
 410        if (chan->load_state == S3C2410_DMALOAD_NONE ||
 411            chan->load_state == S3C2410_DMALOAD_1RUNNING)
 412                return 1;
 413
 414        return 0;
 415}
 416
 417/* s3c2410_dma_enqueue
 418 *
 419 * queue an given buffer for dma transfer.
 420 *
 421 * id         the device driver's id information for this buffer
 422 * data       the physical address of the buffer data
 423 * size       the size of the buffer in bytes
 424 *
 425 * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
 426 * is checked, and if set, the channel is started. If this flag isn't set,
 427 * then an error will be returned.
 428 *
 429 * It is possible to queue more than one DMA buffer onto a channel at
 430 * once, and the code will deal with the re-loading of the next buffer
 431 * when necessary.
 432*/
 433
 434int s3c2410_dma_enqueue(unsigned int channel, void *id,
 435                        dma_addr_t data, int size)
 436{
 437        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
 438        struct s3c2410_dma_buf *buf;
 439        unsigned long flags;
 440
 441        if (chan == NULL)
 442                return -EINVAL;
 443
 444        pr_debug("%s: id=%p, data=%08x, size=%d\n",
 445                 __func__, id, (unsigned int)data, size);
 446
 447        buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
 448        if (buf == NULL) {
 449                pr_debug("%s: out of memory (%ld alloc)\n",
 450                         __func__, (long)sizeof(*buf));
 451                return -ENOMEM;
 452        }
 453
 454        //pr_debug("%s: new buffer %p\n", __func__, buf);
 455        //dbg_showchan(chan);
 456
 457        buf->next  = NULL;
 458        buf->data  = buf->ptr = data;
 459        buf->size  = size;
 460        buf->id    = id;
 461        buf->magic = BUF_MAGIC;
 462
 463        local_irq_save(flags);
 464
 465        if (chan->curr == NULL) {
 466                /* we've got nothing loaded... */
 467                pr_debug("%s: buffer %p queued onto empty channel\n",
 468                         __func__, buf);
 469
 470                chan->curr = buf;
 471                chan->end  = buf;
 472                chan->next = NULL;
 473        } else {
 474                pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
 475                         chan->number, __func__, buf);
 476
 477                if (chan->end == NULL)
 478                        pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
 479                                 chan->number, __func__, chan);
 480
 481                chan->end->next = buf;
 482                chan->end = buf;
 483        }
 484
 485        /* if necessary, update the next buffer field */
 486        if (chan->next == NULL)
 487                chan->next = buf;
 488
 489        /* check to see if we can load a buffer */
 490        if (chan->state == S3C2410_DMA_RUNNING) {
 491                if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
 492                        if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
 493                                printk(KERN_ERR "dma%d: loadbuffer:"
 494                                       "timeout loading buffer\n",
 495                                       chan->number);
 496                                dbg_showchan(chan);
 497                                local_irq_restore(flags);
 498                                return -EINVAL;
 499                        }
 500                }
 501
 502                while (s3c2410_dma_canload(chan) && chan->next != NULL) {
 503                        s3c2410_dma_loadbuffer(chan, chan->next);
 504                }
 505        } else if (chan->state == S3C2410_DMA_IDLE) {
 506                if (chan->flags & S3C2410_DMAF_AUTOSTART) {
 507                        s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
 508                                         S3C2410_DMAOP_START);
 509                }
 510        }
 511
 512        local_irq_restore(flags);
 513        return 0;
 514}
 515
 516EXPORT_SYMBOL(s3c2410_dma_enqueue);
 517
 518static inline void
 519s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
 520{
 521        int magicok = (buf->magic == BUF_MAGIC);
 522
 523        buf->magic = -1;
 524
 525        if (magicok) {
 526                kmem_cache_free(dma_kmem, buf);
 527        } else {
 528                printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
 529        }
 530}
 531
 532/* s3c2410_dma_lastxfer
 533 *
 534 * called when the system is out of buffers, to ensure that the channel
 535 * is prepared for shutdown.
 536*/
 537
 538static inline void
 539s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
 540{
 541#if 0
 542        pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
 543                 chan->number, chan->load_state);
 544#endif
 545
 546        switch (chan->load_state) {
 547        case S3C2410_DMALOAD_NONE:
 548                break;
 549
 550        case S3C2410_DMALOAD_1LOADED:
 551                if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
 552                                /* flag error? */
 553                        printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
 554                               chan->number, __func__);
 555                        return;
 556                }
 557                break;
 558
 559        case S3C2410_DMALOAD_1LOADED_1RUNNING:
 560                /* I belive in this case we do not have anything to do
 561                 * until the next buffer comes along, and we turn off the
 562                 * reload */
 563                return;
 564
 565        default:
 566                pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
 567                         chan->number, chan->load_state);
 568                return;
 569
 570        }
 571
 572        /* hopefully this'll shut the damned thing up after the transfer... */
 573        dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
 574}
 575
 576
 577#define dmadbg2(x...)
 578
 579static irqreturn_t
 580s3c2410_dma_irq(int irq, void *devpw)
 581{
 582        struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
 583        struct s3c2410_dma_buf  *buf;
 584
 585        buf = chan->curr;
 586
 587        dbg_showchan(chan);
 588
 589        /* modify the channel state */
 590
 591        switch (chan->load_state) {
 592        case S3C2410_DMALOAD_1RUNNING:
 593                /* TODO - if we are running only one buffer, we probably
 594                 * want to reload here, and then worry about the buffer
 595                 * callback */
 596
 597                chan->load_state = S3C2410_DMALOAD_NONE;
 598                break;
 599
 600        case S3C2410_DMALOAD_1LOADED:
 601                /* iirc, we should go back to NONE loaded here, we
 602                 * had a buffer, and it was never verified as being
 603                 * loaded.
 604                 */
 605
 606                chan->load_state = S3C2410_DMALOAD_NONE;
 607                break;
 608
 609        case S3C2410_DMALOAD_1LOADED_1RUNNING:
 610                /* we'll worry about checking to see if another buffer is
 611                 * ready after we've called back the owner. This should
 612                 * ensure we do not wait around too long for the DMA
 613                 * engine to start the next transfer
 614                 */
 615
 616                chan->load_state = S3C2410_DMALOAD_1LOADED;
 617                break;
 618
 619        case S3C2410_DMALOAD_NONE:
 620                printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
 621                       chan->number);
 622                break;
 623
 624        default:
 625                printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
 626                       chan->number, chan->load_state);
 627                break;
 628        }
 629
 630        if (buf != NULL) {
 631                /* update the chain to make sure that if we load any more
 632                 * buffers when we call the callback function, things should
 633                 * work properly */
 634
 635                chan->curr = buf->next;
 636                buf->next  = NULL;
 637
 638                if (buf->magic != BUF_MAGIC) {
 639                        printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
 640                               chan->number, __func__, buf);
 641                        return IRQ_HANDLED;
 642                }
 643
 644                s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
 645
 646                /* free resouces */
 647                s3c2410_dma_freebuf(buf);
 648        } else {
 649        }
 650
 651        /* only reload if the channel is still running... our buffer done
 652         * routine may have altered the state by requesting the dma channel
 653         * to stop or shutdown... */
 654
 655        /* todo: check that when the channel is shut-down from inside this
 656         * function, we cope with unsetting reload, etc */
 657
 658        if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
 659                unsigned long flags;
 660
 661                switch (chan->load_state) {
 662                case S3C2410_DMALOAD_1RUNNING:
 663                        /* don't need to do anything for this state */
 664                        break;
 665
 666                case S3C2410_DMALOAD_NONE:
 667                        /* can load buffer immediately */
 668                        break;
 669
 670                case S3C2410_DMALOAD_1LOADED:
 671                        if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
 672                                /* flag error? */
 673                                printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
 674                                       chan->number, __func__);
 675                                return IRQ_HANDLED;
 676                        }
 677
 678                        break;
 679
 680                case S3C2410_DMALOAD_1LOADED_1RUNNING:
 681                        goto no_load;
 682
 683                default:
 684                        printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
 685                               chan->number, chan->load_state);
 686                        return IRQ_HANDLED;
 687                }
 688
 689                local_irq_save(flags);
 690                s3c2410_dma_loadbuffer(chan, chan->next);
 691                local_irq_restore(flags);
 692        } else {
 693                s3c2410_dma_lastxfer(chan);
 694
 695                /* see if we can stop this channel.. */
 696                if (chan->load_state == S3C2410_DMALOAD_NONE) {
 697                        pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
 698                                 chan->number, jiffies);
 699                        s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
 700                                         S3C2410_DMAOP_STOP);
 701                }
 702        }
 703
 704 no_load:
 705        return IRQ_HANDLED;
 706}
 707
 708static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
 709
 710/* s3c2410_request_dma
 711 *
 712 * get control of an dma channel
 713*/
 714
 715int s3c2410_dma_request(unsigned int channel,
 716                        struct s3c2410_dma_client *client,
 717                        void *dev)
 718{
 719        struct s3c2410_dma_chan *chan;
 720        unsigned long flags;
 721        int err;
 722
 723        pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
 724                 channel, client->name, dev);
 725
 726        local_irq_save(flags);
 727
 728        chan = s3c2410_dma_map_channel(channel);
 729        if (chan == NULL) {
 730                local_irq_restore(flags);
 731                return -EBUSY;
 732        }
 733
 734        dbg_showchan(chan);
 735
 736        chan->client = client;
 737        chan->in_use = 1;
 738
 739        if (!chan->irq_claimed) {
 740                pr_debug("dma%d: %s : requesting irq %d\n",
 741                         channel, __func__, chan->irq);
 742
 743                chan->irq_claimed = 1;
 744                local_irq_restore(flags);
 745
 746                err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
 747                                  client->name, (void *)chan);
 748
 749                local_irq_save(flags);
 750
 751                if (err) {
 752                        chan->in_use = 0;
 753                        chan->irq_claimed = 0;
 754                        local_irq_restore(flags);
 755
 756                        printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
 757                               client->name, chan->irq, chan->number);
 758                        return err;
 759                }
 760
 761                chan->irq_enabled = 1;
 762        }
 763
 764        local_irq_restore(flags);
 765
 766        /* need to setup */
 767
 768        pr_debug("%s: channel initialised, %p\n", __func__, chan);
 769
 770        return chan->number | DMACH_LOW_LEVEL;
 771}
 772
 773EXPORT_SYMBOL(s3c2410_dma_request);
 774
 775/* s3c2410_dma_free
 776 *
 777 * release the given channel back to the system, will stop and flush
 778 * any outstanding transfers, and ensure the channel is ready for the
 779 * next claimant.
 780 *
 781 * Note, although a warning is currently printed if the freeing client
 782 * info is not the same as the registrant's client info, the free is still
 783 * allowed to go through.
 784*/
 785
 786int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
 787{
 788        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
 789        unsigned long flags;
 790
 791        if (chan == NULL)
 792                return -EINVAL;
 793
 794        local_irq_save(flags);
 795
 796        if (chan->client != client) {
 797                printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
 798                       channel, chan->client, client);
 799        }
 800
 801        /* sort out stopping and freeing the channel */
 802
 803        if (chan->state != S3C2410_DMA_IDLE) {
 804                pr_debug("%s: need to stop dma channel %p\n",
 805                       __func__, chan);
 806
 807                /* possibly flush the channel */
 808                s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
 809        }
 810
 811        chan->client = NULL;
 812        chan->in_use = 0;
 813
 814        if (chan->irq_claimed)
 815                free_irq(chan->irq, (void *)chan);
 816
 817        chan->irq_claimed = 0;
 818
 819        if (!(channel & DMACH_LOW_LEVEL))
 820                s3c_dma_chan_map[channel] = NULL;
 821
 822        local_irq_restore(flags);
 823
 824        return 0;
 825}
 826
 827EXPORT_SYMBOL(s3c2410_dma_free);
 828
 829static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
 830{
 831        unsigned long flags;
 832        unsigned long tmp;
 833
 834        pr_debug("%s:\n", __func__);
 835
 836        dbg_showchan(chan);
 837
 838        local_irq_save(flags);
 839
 840        s3c2410_dma_call_op(chan,  S3C2410_DMAOP_STOP);
 841
 842        tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
 843        tmp |= S3C2410_DMASKTRIG_STOP;
 844        //tmp &= ~S3C2410_DMASKTRIG_ON;
 845        dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
 846
 847#if 0
 848        /* should also clear interrupts, according to WinCE BSP */
 849        tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
 850        tmp |= S3C2410_DCON_NORELOAD;
 851        dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
 852#endif
 853
 854        /* should stop do this, or should we wait for flush? */
 855        chan->state      = S3C2410_DMA_IDLE;
 856        chan->load_state = S3C2410_DMALOAD_NONE;
 857
 858        local_irq_restore(flags);
 859
 860        return 0;
 861}
 862
 863static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
 864{
 865        unsigned long tmp;
 866        unsigned int timeout = 0x10000;
 867
 868        while (timeout-- > 0) {
 869                tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
 870
 871                if (!(tmp & S3C2410_DMASKTRIG_ON))
 872                        return;
 873        }
 874
 875        pr_debug("dma%d: failed to stop?\n", chan->number);
 876}
 877
 878
 879/* s3c2410_dma_flush
 880 *
 881 * stop the channel, and remove all current and pending transfers
 882*/
 883
 884static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
 885{
 886        struct s3c2410_dma_buf *buf, *next;
 887        unsigned long flags;
 888
 889        pr_debug("%s: chan %p (%d)\n", __func__, chan, chan->number);
 890
 891        dbg_showchan(chan);
 892
 893        local_irq_save(flags);
 894
 895        if (chan->state != S3C2410_DMA_IDLE) {
 896                pr_debug("%s: stopping channel...\n", __func__ );
 897                s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
 898        }
 899
 900        buf = chan->curr;
 901        if (buf == NULL)
 902                buf = chan->next;
 903
 904        chan->curr = chan->next = chan->end = NULL;
 905
 906        if (buf != NULL) {
 907                for ( ; buf != NULL; buf = next) {
 908                        next = buf->next;
 909
 910                        pr_debug("%s: free buffer %p, next %p\n",
 911                               __func__, buf, buf->next);
 912
 913                        s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
 914                        s3c2410_dma_freebuf(buf);
 915                }
 916        }
 917
 918        dbg_showregs(chan);
 919
 920        s3c2410_dma_waitforstop(chan);
 921
 922#if 0
 923        /* should also clear interrupts, according to WinCE BSP */
 924        {
 925                unsigned long tmp;
 926
 927                tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
 928                tmp |= S3C2410_DCON_NORELOAD;
 929                dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
 930        }
 931#endif
 932
 933        dbg_showregs(chan);
 934
 935        local_irq_restore(flags);
 936
 937        return 0;
 938}
 939
 940static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
 941{
 942        unsigned long flags;
 943
 944        local_irq_save(flags);
 945
 946        dbg_showchan(chan);
 947
 948        /* if we've only loaded one buffer onto the channel, then chec
 949         * to see if we have another, and if so, try and load it so when
 950         * the first buffer is finished, the new one will be loaded onto
 951         * the channel */
 952
 953        if (chan->next != NULL) {
 954                if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
 955
 956                        if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
 957                                pr_debug("%s: buff not yet loaded, no more todo\n",
 958                                         __func__);
 959                        } else {
 960                                chan->load_state = S3C2410_DMALOAD_1RUNNING;
 961                                s3c2410_dma_loadbuffer(chan, chan->next);
 962                        }
 963
 964                } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
 965                        s3c2410_dma_loadbuffer(chan, chan->next);
 966                }
 967        }
 968
 969
 970        local_irq_restore(flags);
 971
 972        return 0;
 973
 974}
 975
 976int
 977s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
 978{
 979        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
 980
 981        if (chan == NULL)
 982                return -EINVAL;
 983
 984        switch (op) {
 985        case S3C2410_DMAOP_START:
 986                return s3c2410_dma_start(chan);
 987
 988        case S3C2410_DMAOP_STOP:
 989                return s3c2410_dma_dostop(chan);
 990
 991        case S3C2410_DMAOP_PAUSE:
 992        case S3C2410_DMAOP_RESUME:
 993                return -ENOENT;
 994
 995        case S3C2410_DMAOP_FLUSH:
 996                return s3c2410_dma_flush(chan);
 997
 998        case S3C2410_DMAOP_STARTED:
 999                return s3c2410_dma_started(chan);
1000
1001        case S3C2410_DMAOP_TIMEOUT:
1002                return 0;
1003
1004        }
1005
1006        return -ENOENT;      /* unknown, don't bother */
1007}
1008
1009EXPORT_SYMBOL(s3c2410_dma_ctrl);
1010
1011/* DMA configuration for each channel
1012 *
1013 * DISRCC -> source of the DMA (AHB,APB)
1014 * DISRC  -> source address of the DMA
1015 * DIDSTC -> destination of the DMA (AHB,APD)
1016 * DIDST  -> destination address of the DMA
1017*/
1018
1019/* s3c2410_dma_config
1020 *
1021 * xfersize:     size of unit in bytes (1,2,4)
1022*/
1023
1024int s3c2410_dma_config(unsigned int channel,
1025                       int xferunit)
1026{
1027        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
1028        unsigned int dcon;
1029
1030        pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
1031                 __func__, channel, xferunit, dcon);
1032
1033        if (chan == NULL)
1034                return -EINVAL;
1035
1036        pr_debug("%s: Initial dcon is %08x\n", __func__, dcon);
1037
1038        dcon = chan->dcon & dma_sel.dcon_mask;
1039
1040        pr_debug("%s: New dcon is %08x\n", __func__, dcon);
1041
1042        switch (chan->req_ch) {
1043        case DMACH_I2S_IN:
1044        case DMACH_I2S_OUT:
1045        case DMACH_PCM_IN:
1046        case DMACH_PCM_OUT:
1047        case DMACH_MIC_IN:
1048        default:
1049                dcon |= S3C2410_DCON_HANDSHAKE;
1050                dcon |= S3C2410_DCON_SYNC_PCLK;
1051                break;
1052
1053        case DMACH_SDI:
1054                /* note, ensure if need HANDSHAKE or not */
1055                dcon |= S3C2410_DCON_SYNC_PCLK;
1056                break;
1057
1058        case DMACH_XD0:
1059        case DMACH_XD1:
1060                dcon |= S3C2410_DCON_HANDSHAKE;
1061                dcon |= S3C2410_DCON_SYNC_HCLK;
1062                break;
1063        }
1064
1065        switch (xferunit) {
1066        case 1:
1067                dcon |= S3C2410_DCON_BYTE;
1068                break;
1069
1070        case 2:
1071                dcon |= S3C2410_DCON_HALFWORD;
1072                break;
1073
1074        case 4:
1075                dcon |= S3C2410_DCON_WORD;
1076                break;
1077
1078        default:
1079                pr_debug("%s: bad transfer size %d\n", __func__, xferunit);
1080                return -EINVAL;
1081        }
1082
1083        dcon |= S3C2410_DCON_HWTRIG;
1084        dcon |= S3C2410_DCON_INTREQ;
1085
1086        pr_debug("%s: dcon now %08x\n", __func__, dcon);
1087
1088        chan->dcon = dcon;
1089        chan->xfer_unit = xferunit;
1090
1091        return 0;
1092}
1093
1094EXPORT_SYMBOL(s3c2410_dma_config);
1095
1096
1097/* s3c2410_dma_devconfig
1098 *
1099 * configure the dma source/destination hardware type and address
1100 *
1101 * source:    S3C2410_DMASRC_HW: source is hardware
1102 *            S3C2410_DMASRC_MEM: source is memory
1103 *
1104 * devaddr:   physical address of the source
1105*/
1106
1107int s3c2410_dma_devconfig(int channel,
1108                          enum s3c2410_dmasrc source,
1109                          unsigned long devaddr)
1110{
1111        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
1112        unsigned int hwcfg;
1113
1114        if (chan == NULL)
1115                return -EINVAL;
1116
1117        pr_debug("%s: source=%d, devaddr=%08lx\n",
1118                 __func__, (int)source, devaddr);
1119
1120        chan->source = source;
1121        chan->dev_addr = devaddr;
1122
1123        switch (chan->req_ch) {
1124        case DMACH_XD0:
1125        case DMACH_XD1:
1126                hwcfg = 0; /* AHB */
1127                break;
1128
1129        default:
1130                hwcfg = S3C2410_DISRCC_APB;
1131        }
1132
1133        /* always assume our peripheral desintation is a fixed
1134         * address in memory. */
1135         hwcfg |= S3C2410_DISRCC_INC;
1136
1137        switch (source) {
1138        case S3C2410_DMASRC_HW:
1139                /* source is hardware */
1140                pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
1141                         __func__, devaddr, hwcfg);
1142                dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
1143                dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
1144                dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
1145
1146                chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
1147                break;
1148
1149        case S3C2410_DMASRC_MEM:
1150                /* source is memory */
1151                pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
1152                         __func__, devaddr, hwcfg);
1153                dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
1154                dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
1155                dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
1156
1157                chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
1158                break;
1159
1160        default:
1161                printk(KERN_ERR "dma%d: invalid source type (%d)\n",
1162                       channel, source);
1163
1164                return -EINVAL;
1165        }
1166
1167        if (dma_sel.direction != NULL)
1168                (dma_sel.direction)(chan, chan->map, source);
1169
1170        return 0;
1171}
1172
1173EXPORT_SYMBOL(s3c2410_dma_devconfig);
1174
1175/* s3c2410_dma_getposition
1176 *
1177 * returns the current transfer points for the dma source and destination
1178*/
1179
1180int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst)
1181{
1182        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
1183
1184        if (chan == NULL)
1185                return -EINVAL;
1186
1187        if (src != NULL)
1188                *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
1189
1190        if (dst != NULL)
1191                *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
1192
1193        return 0;
1194}
1195
1196EXPORT_SYMBOL(s3c2410_dma_getposition);
1197
1198static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
1199{
1200        return container_of(dev, struct s3c2410_dma_chan, dev);
1201}
1202
1203/* system device class */
1204
1205#ifdef CONFIG_PM
1206
1207static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
1208{
1209        struct s3c2410_dma_chan *cp = to_dma_chan(dev);
1210
1211        printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
1212
1213        if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
1214                /* the dma channel is still working, which is probably
1215                 * a bad thing to do over suspend/resume. We stop the
1216                 * channel and assume that the client is either going to
1217                 * retry after resume, or that it is broken.
1218                 */
1219
1220                printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
1221                       cp->number);
1222
1223                s3c2410_dma_dostop(cp);
1224        }
1225
1226        return 0;
1227}
1228
1229static int s3c2410_dma_resume(struct sys_device *dev)
1230{
1231        struct s3c2410_dma_chan *cp = to_dma_chan(dev);
1232        unsigned int no = cp->number | DMACH_LOW_LEVEL;
1233
1234        /* restore channel's hardware configuration */
1235
1236        if (!cp->in_use)
1237                return 0;
1238
1239        printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
1240
1241        s3c2410_dma_config(no, cp->xfer_unit);
1242        s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);
1243
1244        /* re-select the dma source for this channel */
1245
1246        if (cp->map != NULL)
1247                dma_sel.select(cp, cp->map);
1248
1249        return 0;
1250}
1251
1252#else
1253#define s3c2410_dma_suspend NULL
1254#define s3c2410_dma_resume  NULL
1255#endif /* CONFIG_PM */
1256
1257struct sysdev_class dma_sysclass = {
1258        .name           = "s3c24xx-dma",
1259        .suspend        = s3c2410_dma_suspend,
1260        .resume         = s3c2410_dma_resume,
1261};
1262
1263/* kmem cache implementation */
1264
1265static void s3c2410_dma_cache_ctor(void *p)
1266{
1267        memset(p, 0, sizeof(struct s3c2410_dma_buf));
1268}
1269
1270/* initialisation code */
1271
1272static int __init s3c24xx_dma_sysclass_init(void)
1273{
1274        int ret = sysdev_class_register(&dma_sysclass);
1275
1276        if (ret != 0)
1277                printk(KERN_ERR "dma sysclass registration failed\n");
1278
1279        return ret;
1280}
1281
1282core_initcall(s3c24xx_dma_sysclass_init);
1283
1284static int __init s3c24xx_dma_sysdev_register(void)
1285{
1286        struct s3c2410_dma_chan *cp = s3c2410_chans;
1287        int channel, ret;
1288
1289        for (channel = 0; channel < dma_channels; cp++, channel++) {
1290                cp->dev.cls = &dma_sysclass;
1291                cp->dev.id  = channel;
1292                ret = sysdev_register(&cp->dev);
1293
1294                if (ret) {
1295                        printk(KERN_ERR "error registering dev for dma %d\n",
1296                               channel);
1297                        return ret;
1298                }
1299        }
1300
1301        return 0;
1302}
1303
1304late_initcall(s3c24xx_dma_sysdev_register);
1305
1306int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
1307                            unsigned int stride)
1308{
1309        struct s3c2410_dma_chan *cp;
1310        int channel;
1311        int ret;
1312
1313        printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
1314
1315        dma_channels = channels;
1316
1317        dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
1318        if (dma_base == NULL) {
1319                printk(KERN_ERR "dma failed to remap register block\n");
1320                return -ENOMEM;
1321        }
1322
1323        dma_kmem = kmem_cache_create("dma_desc",
1324                                     sizeof(struct s3c2410_dma_buf), 0,
1325                                     SLAB_HWCACHE_ALIGN,
1326                                     s3c2410_dma_cache_ctor);
1327
1328        if (dma_kmem == NULL) {
1329                printk(KERN_ERR "dma failed to make kmem cache\n");
1330                ret = -ENOMEM;
1331                goto err;
1332        }
1333
1334        for (channel = 0; channel < channels;  channel++) {
1335                cp = &s3c2410_chans[channel];
1336
1337                memset(cp, 0, sizeof(struct s3c2410_dma_chan));
1338
1339                /* dma channel irqs are in order.. */
1340                cp->number = channel;
1341                cp->irq    = channel + irq;
1342                cp->regs   = dma_base + (channel * stride);
1343
1344                /* point current stats somewhere */
1345                cp->stats  = &cp->stats_store;
1346                cp->stats_store.timeout_shortest = LONG_MAX;
1347
1348                /* basic channel configuration */
1349
1350                cp->load_timeout = 1<<18;
1351
1352                printk("DMA channel %d at %p, irq %d\n",
1353                       cp->number, cp->regs, cp->irq);
1354        }
1355
1356        return 0;
1357
1358 err:
1359        kmem_cache_destroy(dma_kmem);
1360        iounmap(dma_base);
1361        dma_base = NULL;
1362        return ret;
1363}
1364
1365int __init s3c2410_dma_init(void)
1366{
1367        return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
1368}
1369
1370static inline int is_channel_valid(unsigned int channel)
1371{
1372        return (channel & DMA_CH_VALID);
1373}
1374
1375static struct s3c24xx_dma_order *dma_order;
1376
1377
1378/* s3c2410_dma_map_channel()
1379 *
1380 * turn the virtual channel number into a real, and un-used hardware
1381 * channel.
1382 *
1383 * first, try the dma ordering given to us by either the relevant
1384 * dma code, or the board. Then just find the first usable free
1385 * channel
1386*/
1387
1388static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
1389{
1390        struct s3c24xx_dma_order_ch *ord = NULL;
1391        struct s3c24xx_dma_map *ch_map;
1392        struct s3c2410_dma_chan *dmach;
1393        int ch;
1394
1395        if (dma_sel.map == NULL || channel > dma_sel.map_size)
1396                return NULL;
1397
1398        ch_map = dma_sel.map + channel;
1399
1400        /* first, try the board mapping */
1401
1402        if (dma_order) {
1403                ord = &dma_order->channels[channel];
1404
1405                for (ch = 0; ch < dma_channels; ch++) {
1406                        if (!is_channel_valid(ord->list[ch]))
1407                                continue;
1408
1409                        if (s3c2410_chans[ord->list[ch]].in_use == 0) {
1410                                ch = ord->list[ch] & ~DMA_CH_VALID;
1411                                goto found;
1412                        }
1413                }
1414
1415                if (ord->flags & DMA_CH_NEVER)
1416                        return NULL;
1417        }
1418
1419        /* second, search the channel map for first free */
1420
1421        for (ch = 0; ch < dma_channels; ch++) {
1422                if (!is_channel_valid(ch_map->channels[ch]))
1423                        continue;
1424
1425                if (s3c2410_chans[ch].in_use == 0) {
1426                        printk("mapped channel %d to %d\n", channel, ch);
1427                        break;
1428                }
1429        }
1430
1431        if (ch >= dma_channels)
1432                return NULL;
1433
1434        /* update our channel mapping */
1435
1436 found:
1437        dmach = &s3c2410_chans[ch];
1438        dmach->map = ch_map;
1439        dmach->req_ch = channel;
1440        s3c_dma_chan_map[channel] = dmach;
1441
1442        /* select the channel */
1443
1444        (dma_sel.select)(dmach, ch_map);
1445
1446        return dmach;
1447}
1448
1449static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
1450{
1451        return 0;
1452}
1453
1454int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
1455{
1456        struct s3c24xx_dma_map *nmap;
1457        size_t map_sz = sizeof(*nmap) * sel->map_size;
1458        int ptr;
1459
1460        nmap = kmalloc(map_sz, GFP_KERNEL);
1461        if (nmap == NULL)
1462                return -ENOMEM;
1463
1464        memcpy(nmap, sel->map, map_sz);
1465        memcpy(&dma_sel, sel, sizeof(*sel));
1466
1467        dma_sel.map = nmap;
1468
1469        for (ptr = 0; ptr < sel->map_size; ptr++)
1470                s3c24xx_dma_check_entry(nmap+ptr, ptr);
1471
1472        return 0;
1473}
1474
1475int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
1476{
1477        struct s3c24xx_dma_order *nord = dma_order;
1478
1479        if (nord == NULL)
1480                nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
1481
1482        if (nord == NULL) {
1483                printk(KERN_ERR "no memory to store dma channel order\n");
1484                return -ENOMEM;
1485        }
1486
1487        dma_order = nord;
1488        memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
1489        return 0;
1490}
1491