linux/arch/arm/mach-s3c2410/irq.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-s3c2410/irq.c
   2 *
   3 * Copyright (c) 2003,2004 Simtec Electronics
   4 *      Ben Dooks <ben@simtec.co.uk>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 *
  20 * Changelog:
  21 *
  22 *   22-Jul-2004  Ben Dooks <ben@simtec.co.uk>
  23 *                Fixed compile warnings
  24 *
  25 *   22-Jul-2004  Roc Wu <cooloney@yahoo.com.cn>
  26 *                Fixed s3c_extirq_type
  27 *
  28 *   21-Jul-2004  Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
  29 *                Addition of ADC/TC demux
  30 *
  31 *   04-Oct-2004  Klaus Fetscher <k.fetscher@fetron.de>
  32 *                Fix for set_irq_type() on low EINT numbers
  33 *
  34 *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
  35 *                Tidy up KF's patch and sort out new release
  36 *
  37 *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
  38 *                Add support for power management controls
  39 *
  40 *   04-Nov-2004  Ben Dooks
  41 *                Fix standard IRQ wake for EINT0..4 and RTC
  42*/
  43
  44#include <linux/init.h>
  45#include <linux/module.h>
  46#include <linux/interrupt.h>
  47#include <linux/ioport.h>
  48#include <linux/ptrace.h>
  49#include <linux/sysdev.h>
  50
  51#include <asm/hardware.h>
  52#include <asm/irq.h>
  53#include <asm/io.h>
  54
  55#include <asm/mach/irq.h>
  56
  57#include <asm/arch/regs-irq.h>
  58#include <asm/arch/regs-gpio.h>
  59
  60#include "pm.h"
  61
  62#define irqdbf(x...)
  63#define irqdbf2(x...)
  64
  65#define EXTINT_OFF (IRQ_EINT4 - 4)
  66
  67/* wakeup irq control */
  68
  69#ifdef CONFIG_PM
  70
  71/* state for IRQs over sleep */
  72
  73/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
  74 *
  75 * set bit to 1 in allow bitfield to enable the wakeup settings on it
  76*/
  77
  78unsigned long s3c_irqwake_intallow      = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
  79unsigned long s3c_irqwake_intmask       = 0xffffffffL;
  80unsigned long s3c_irqwake_eintallow     = 0x0000fff0L;
  81unsigned long s3c_irqwake_eintmask      = 0xffffffffL;
  82
  83static int
  84s3c_irq_wake(unsigned int irqno, unsigned int state)
  85{
  86        unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
  87
  88        if (!(s3c_irqwake_intallow & irqbit))
  89                return -ENOENT;
  90
  91        printk(KERN_INFO "wake %s for irq %d\n",
  92               state ? "enabled" : "disabled", irqno);
  93
  94        if (!state)
  95                s3c_irqwake_intmask |= irqbit;
  96        else
  97                s3c_irqwake_intmask &= ~irqbit;
  98
  99        return 0;
 100}
 101
 102static int
 103s3c_irqext_wake(unsigned int irqno, unsigned int state)
 104{
 105        unsigned long bit = 1L << (irqno - EXTINT_OFF);
 106
 107        if (!(s3c_irqwake_eintallow & bit))
 108                return -ENOENT;
 109
 110        printk(KERN_INFO "wake %s for irq %d\n",
 111               state ? "enabled" : "disabled", irqno);
 112
 113        if (!state)
 114                s3c_irqwake_eintmask |= bit;
 115        else
 116                s3c_irqwake_eintmask &= ~bit;
 117
 118        return 0;
 119}
 120
 121#else
 122#define s3c_irqext_wake NULL
 123#define s3c_irq_wake NULL
 124#endif
 125
 126
 127static void
 128s3c_irq_mask(unsigned int irqno)
 129{
 130        unsigned long mask;
 131
 132        irqno -= IRQ_EINT0;
 133
 134        mask = __raw_readl(S3C2410_INTMSK);
 135        mask |= 1UL << irqno;
 136        __raw_writel(mask, S3C2410_INTMSK);
 137}
 138
 139static inline void
 140s3c_irq_ack(unsigned int irqno)
 141{
 142        unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
 143
 144        __raw_writel(bitval, S3C2410_SRCPND);
 145        __raw_writel(bitval, S3C2410_INTPND);
 146}
 147
 148static inline void
 149s3c_irq_maskack(unsigned int irqno)
 150{
 151        unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
 152        unsigned long mask;
 153
 154        mask = __raw_readl(S3C2410_INTMSK);
 155        __raw_writel(mask|bitval, S3C2410_INTMSK);
 156
 157        __raw_writel(bitval, S3C2410_SRCPND);
 158        __raw_writel(bitval, S3C2410_INTPND);
 159}
 160
 161
 162static void
 163s3c_irq_unmask(unsigned int irqno)
 164{
 165        unsigned long mask;
 166
 167        if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
 168                irqdbf2("s3c_irq_unmask %d\n", irqno);
 169
 170        irqno -= IRQ_EINT0;
 171
 172        mask = __raw_readl(S3C2410_INTMSK);
 173        mask &= ~(1UL << irqno);
 174        __raw_writel(mask, S3C2410_INTMSK);
 175}
 176
 177static struct irqchip s3c_irq_level_chip = {
 178        .ack       = s3c_irq_maskack,
 179        .mask      = s3c_irq_mask,
 180        .unmask    = s3c_irq_unmask,
 181        .wake      = s3c_irq_wake
 182};
 183
 184static struct irqchip s3c_irq_chip = {
 185        .ack       = s3c_irq_ack,
 186        .mask      = s3c_irq_mask,
 187        .unmask    = s3c_irq_unmask,
 188        .wake      = s3c_irq_wake
 189};
 190
 191/* S3C2410_EINTMASK
 192 * S3C2410_EINTPEND
 193 */
 194
 195static void
 196s3c_irqext_mask(unsigned int irqno)
 197{
 198        unsigned long mask;
 199
 200        irqno -= EXTINT_OFF;
 201
 202        mask = __raw_readl(S3C2410_EINTMASK);
 203        mask |= ( 1UL << irqno);
 204        __raw_writel(mask, S3C2410_EINTMASK);
 205
 206        if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) {
 207                /* check to see if all need masking */
 208
 209                if ((mask & (0xf << 4)) == (0xf << 4)) {
 210                        /* all masked, mask the parent */
 211                        s3c_irq_mask(IRQ_EINT4t7);
 212                }
 213        } else {
 214                /* todo: the same check as above for the rest of the irq regs...*/
 215
 216        }
 217}
 218
 219static void
 220s3c_irqext_ack(unsigned int irqno)
 221{
 222        unsigned long req;
 223        unsigned long bit;
 224        unsigned long mask;
 225
 226        bit = 1UL << (irqno - EXTINT_OFF);
 227
 228
 229        mask = __raw_readl(S3C2410_EINTMASK);
 230
 231        __raw_writel(bit, S3C2410_EINTPEND);
 232
 233        req = __raw_readl(S3C2410_EINTPEND);
 234        req &= ~mask;
 235
 236        /* not sure if we should be acking the parent irq... */
 237
 238        if (irqno <= IRQ_EINT7 ) {
 239                if ((req & 0xf0) == 0)
 240                        s3c_irq_ack(IRQ_EINT4t7);
 241        } else {
 242                if ((req >> 8) == 0)
 243                        s3c_irq_ack(IRQ_EINT8t23);
 244        }
 245}
 246
 247static void
 248s3c_irqext_unmask(unsigned int irqno)
 249{
 250        unsigned long mask;
 251
 252        irqno -= EXTINT_OFF;
 253
 254        mask = __raw_readl(S3C2410_EINTMASK);
 255        mask &= ~( 1UL << irqno);
 256        __raw_writel(mask, S3C2410_EINTMASK);
 257
 258        s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23);
 259}
 260
 261static int
 262s3c_irqext_type(unsigned int irq, unsigned int type)
 263{
 264        unsigned long extint_reg;
 265        unsigned long gpcon_reg;
 266        unsigned long gpcon_offset, extint_offset;
 267        unsigned long newvalue = 0, value;
 268
 269        if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
 270        {
 271                gpcon_reg = S3C2410_GPFCON;
 272                extint_reg = S3C2410_EXTINT0;
 273                gpcon_offset = (irq - IRQ_EINT0) * 2;
 274                extint_offset = (irq - IRQ_EINT0) * 4;
 275        }
 276        else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
 277        {
 278                gpcon_reg = S3C2410_GPFCON;
 279                extint_reg = S3C2410_EXTINT0;
 280                gpcon_offset = (irq - (EXTINT_OFF)) * 2;
 281                extint_offset = (irq - (EXTINT_OFF)) * 4;
 282        }
 283        else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
 284        {
 285                gpcon_reg = S3C2410_GPGCON;
 286                extint_reg = S3C2410_EXTINT1;
 287                gpcon_offset = (irq - IRQ_EINT8) * 2;
 288                extint_offset = (irq - IRQ_EINT8) * 4;
 289        }
 290        else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
 291        {
 292                gpcon_reg = S3C2410_GPGCON;
 293                extint_reg = S3C2410_EXTINT2;
 294                gpcon_offset = (irq - IRQ_EINT8) * 2;
 295                extint_offset = (irq - IRQ_EINT16) * 4;
 296        } else
 297                return -1;
 298
 299        /* Set the GPIO to external interrupt mode */
 300        value = __raw_readl(gpcon_reg);
 301        value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
 302        __raw_writel(value, gpcon_reg);
 303
 304        /* Set the external interrupt to pointed trigger type */
 305        switch (type)
 306        {
 307                case IRQT_NOEDGE:
 308                        printk(KERN_WARNING "No edge setting!\n");
 309                        break;
 310
 311                case IRQT_RISING:
 312                        newvalue = S3C2410_EXTINT_RISEEDGE;
 313                        break;
 314
 315                case IRQT_FALLING:
 316                        newvalue = S3C2410_EXTINT_FALLEDGE;
 317                        break;
 318
 319                case IRQT_BOTHEDGE:
 320                        newvalue = S3C2410_EXTINT_BOTHEDGE;
 321                        break;
 322
 323                case IRQT_LOW:
 324                        newvalue = S3C2410_EXTINT_LOWLEV;
 325                        break;
 326
 327                case IRQT_HIGH:
 328                        newvalue = S3C2410_EXTINT_HILEV;
 329                        break;
 330
 331                default:
 332                        printk(KERN_ERR "No such irq type %d", type);
 333                        return -1;
 334        }
 335
 336        value = __raw_readl(extint_reg);
 337        value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
 338        __raw_writel(value, extint_reg);
 339
 340        return 0;
 341}
 342
 343static struct irqchip s3c_irqext_chip = {
 344        .mask       = s3c_irqext_mask,
 345        .unmask     = s3c_irqext_unmask,
 346        .ack        = s3c_irqext_ack,
 347        .type       = s3c_irqext_type,
 348        .wake       = s3c_irqext_wake
 349};
 350
 351static struct irqchip s3c_irq_eint0t4 = {
 352        .ack       = s3c_irq_ack,
 353        .mask      = s3c_irq_mask,
 354        .unmask    = s3c_irq_unmask,
 355        .wake      = s3c_irq_wake,
 356        .type      = s3c_irqext_type,
 357};
 358
 359/* mask values for the parent registers for each of the interrupt types */
 360
 361#define INTMSK_UART0     (1UL << (IRQ_UART0 - IRQ_EINT0))
 362#define INTMSK_UART1     (1UL << (IRQ_UART1 - IRQ_EINT0))
 363#define INTMSK_UART2     (1UL << (IRQ_UART2 - IRQ_EINT0))
 364#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
 365#define INTMSK_LCD       (1UL << (IRQ_LCD - IRQ_EINT0))
 366
 367static inline void
 368s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
 369                int subcheck)
 370{
 371        unsigned long mask;
 372        unsigned long submask;
 373
 374        submask = __raw_readl(S3C2410_INTSUBMSK);
 375        mask = __raw_readl(S3C2410_INTMSK);
 376
 377        submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
 378
 379        /* check to see if we need to mask the parent IRQ */
 380
 381        if ((submask  & subcheck) == subcheck) {
 382                __raw_writel(mask | parentbit, S3C2410_INTMSK);
 383        }
 384
 385        /* write back masks */
 386        __raw_writel(submask, S3C2410_INTSUBMSK);
 387
 388}
 389
 390static inline void
 391s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
 392{
 393        unsigned long mask;
 394        unsigned long submask;
 395
 396        submask = __raw_readl(S3C2410_INTSUBMSK);
 397        mask = __raw_readl(S3C2410_INTMSK);
 398
 399        submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
 400        mask &= ~parentbit;
 401
 402        /* write back masks */
 403        __raw_writel(submask, S3C2410_INTSUBMSK);
 404        __raw_writel(mask, S3C2410_INTMSK);
 405}
 406
 407
 408static inline void
 409s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
 410{
 411        unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
 412
 413        s3c_irqsub_mask(irqno, parentmask, group);
 414
 415        __raw_writel(bit, S3C2410_SUBSRCPND);
 416
 417        /* only ack parent if we've got all the irqs (seems we must
 418         * ack, all and hope that the irq system retriggers ok when
 419         * the interrupt goes off again)
 420         */
 421
 422        if (1) {
 423                __raw_writel(parentmask, S3C2410_SRCPND);
 424                __raw_writel(parentmask, S3C2410_INTPND);
 425        }
 426}
 427
 428
 429/* UART0 */
 430
 431static void
 432s3c_irq_uart0_mask(unsigned int irqno)
 433{
 434        s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
 435}
 436
 437static void
 438s3c_irq_uart0_unmask(unsigned int irqno)
 439{
 440        s3c_irqsub_unmask(irqno, INTMSK_UART0);
 441}
 442
 443static void
 444s3c_irq_uart0_ack(unsigned int irqno)
 445{
 446        s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
 447}
 448
 449static struct irqchip s3c_irq_uart0 = {
 450        .mask       = s3c_irq_uart0_mask,
 451        .unmask     = s3c_irq_uart0_unmask,
 452        .ack        = s3c_irq_uart0_ack,
 453};
 454
 455/* UART1 */
 456
 457static void
 458s3c_irq_uart1_mask(unsigned int irqno)
 459{
 460        s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
 461}
 462
 463static void
 464s3c_irq_uart1_unmask(unsigned int irqno)
 465{
 466        s3c_irqsub_unmask(irqno, INTMSK_UART1);
 467}
 468
 469static void
 470s3c_irq_uart1_ack(unsigned int irqno)
 471{
 472        s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
 473}
 474
 475static struct irqchip s3c_irq_uart1 = {
 476        .mask       = s3c_irq_uart1_mask,
 477        .unmask     = s3c_irq_uart1_unmask,
 478        .ack        = s3c_irq_uart1_ack,
 479};
 480
 481/* UART2 */
 482
 483static void
 484s3c_irq_uart2_mask(unsigned int irqno)
 485{
 486        s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
 487}
 488
 489static void
 490s3c_irq_uart2_unmask(unsigned int irqno)
 491{
 492        s3c_irqsub_unmask(irqno, INTMSK_UART2);
 493}
 494
 495static void
 496s3c_irq_uart2_ack(unsigned int irqno)
 497{
 498        s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
 499}
 500
 501static struct irqchip s3c_irq_uart2 = {
 502        .mask       = s3c_irq_uart2_mask,
 503        .unmask     = s3c_irq_uart2_unmask,
 504        .ack        = s3c_irq_uart2_ack,
 505};
 506
 507/* ADC and Touchscreen */
 508
 509static void
 510s3c_irq_adc_mask(unsigned int irqno)
 511{
 512        s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
 513}
 514
 515static void
 516s3c_irq_adc_unmask(unsigned int irqno)
 517{
 518        s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
 519}
 520
 521static void
 522s3c_irq_adc_ack(unsigned int irqno)
 523{
 524        s3c_irqsub_maskack(irqno, INTMSK_ADCPARENT, 3 << 9);
 525}
 526
 527static struct irqchip s3c_irq_adc = {
 528        .mask       = s3c_irq_adc_mask,
 529        .unmask     = s3c_irq_adc_unmask,
 530        .ack        = s3c_irq_adc_ack,
 531};
 532
 533/* irq demux for adc */
 534static void s3c_irq_demux_adc(unsigned int irq,
 535                              struct irqdesc *desc,
 536                              struct pt_regs *regs)
 537{
 538        unsigned int subsrc, submsk;
 539        unsigned int offset = 9;
 540        struct irqdesc *mydesc;
 541
 542        /* read the current pending interrupts, and the mask
 543         * for what it is available */
 544
 545        subsrc = __raw_readl(S3C2410_SUBSRCPND);
 546        submsk = __raw_readl(S3C2410_INTSUBMSK);
 547
 548        subsrc &= ~submsk;
 549        subsrc >>= offset;
 550        subsrc &= 3;
 551
 552        if (subsrc != 0) {
 553                if (subsrc & 1) {
 554                        mydesc = irq_desc + IRQ_TC;
 555                        mydesc->handle( IRQ_TC, mydesc, regs);
 556                }
 557                if (subsrc & 2) {
 558                        mydesc = irq_desc + IRQ_ADC;
 559                        mydesc->handle(IRQ_ADC, mydesc, regs);
 560                }
 561        }
 562}
 563
 564static void s3c_irq_demux_uart(unsigned int start,
 565                               struct pt_regs *regs)
 566{
 567        unsigned int subsrc, submsk;
 568        unsigned int offset = start - IRQ_S3CUART_RX0;
 569        struct irqdesc *desc;
 570
 571        /* read the current pending interrupts, and the mask
 572         * for what it is available */
 573
 574        subsrc = __raw_readl(S3C2410_SUBSRCPND);
 575        submsk = __raw_readl(S3C2410_INTSUBMSK);
 576
 577        irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
 578                start, offset, subsrc, submsk);
 579
 580        subsrc &= ~submsk;
 581        subsrc >>= offset;
 582        subsrc &= 7;
 583
 584        if (subsrc != 0) {
 585                desc = irq_desc + start;
 586
 587                if (subsrc & 1)
 588                        desc->handle(start, desc, regs);
 589
 590                desc++;
 591
 592                if (subsrc & 2)
 593                        desc->handle(start+1, desc, regs);
 594
 595                desc++;
 596
 597                if (subsrc & 4)
 598                        desc->handle(start+2, desc, regs);
 599        }
 600}
 601
 602/* uart demux entry points */
 603
 604static void
 605s3c_irq_demux_uart0(unsigned int irq,
 606                    struct irqdesc *desc,
 607                    struct pt_regs *regs)
 608{
 609        irq = irq;
 610        s3c_irq_demux_uart(IRQ_S3CUART_RX0, regs);
 611}
 612
 613static void
 614s3c_irq_demux_uart1(unsigned int irq,
 615                    struct irqdesc *desc,
 616                    struct pt_regs *regs)
 617{
 618        irq = irq;
 619        s3c_irq_demux_uart(IRQ_S3CUART_RX1, regs);
 620}
 621
 622static void
 623s3c_irq_demux_uart2(unsigned int irq,
 624                    struct irqdesc *desc,
 625                    struct pt_regs *regs)
 626{
 627        irq = irq;
 628        s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
 629}
 630
 631/* s3c24xx_init_irq
 632 *
 633 * Initialise S3C2410 IRQ system
 634*/
 635
 636void __init s3c24xx_init_irq(void)
 637{
 638        unsigned long pend;
 639        unsigned long last;
 640        int irqno;
 641        int i;
 642
 643        irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
 644
 645        /* first, clear all interrupts pending... */
 646
 647        last = 0;
 648        for (i = 0; i < 4; i++) {
 649                pend = __raw_readl(S3C2410_EINTPEND);
 650
 651                if (pend == 0 || pend == last)
 652                        break;
 653
 654                __raw_writel(pend, S3C2410_EINTPEND);
 655                printk("irq: clearing pending ext status %08x\n", (int)pend);
 656                last = pend;
 657        }
 658
 659        last = 0;
 660        for (i = 0; i < 4; i++) {
 661                pend = __raw_readl(S3C2410_INTPND);
 662
 663                if (pend == 0 || pend == last)
 664                        break;
 665
 666                __raw_writel(pend, S3C2410_SRCPND);
 667                __raw_writel(pend, S3C2410_INTPND);
 668                printk("irq: clearing pending status %08x\n", (int)pend);
 669                last = pend;
 670        }
 671
 672        last = 0;
 673        for (i = 0; i < 4; i++) {
 674                pend = __raw_readl(S3C2410_SUBSRCPND);
 675
 676                if (pend == 0 || pend == last)
 677                        break;
 678
 679                printk("irq: clearing subpending status %08x\n", (int)pend);
 680                __raw_writel(pend, S3C2410_SUBSRCPND);
 681                last = pend;
 682        }
 683
 684        /* register the main interrupts */
 685
 686        irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
 687
 688        for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) {
 689                /* set all the s3c2410 internal irqs */
 690
 691                switch (irqno) {
 692                        /* deal with the special IRQs (cascaded) */
 693
 694                case IRQ_UART0:
 695                case IRQ_UART1:
 696                case IRQ_UART2:
 697                case IRQ_LCD:
 698                case IRQ_ADCPARENT:
 699                        set_irq_chip(irqno, &s3c_irq_level_chip);
 700                        set_irq_handler(irqno, do_level_IRQ);
 701                        break;
 702
 703                case IRQ_RESERVED6:
 704                case IRQ_RESERVED24:
 705                        /* no IRQ here */
 706                        break;
 707
 708                default:
 709                        //irqdbf("registering irq %d (s3c irq)\n", irqno);
 710                        set_irq_chip(irqno, &s3c_irq_chip);
 711                        set_irq_handler(irqno, do_edge_IRQ);
 712                        set_irq_flags(irqno, IRQF_VALID);
 713                }
 714        }
 715
 716        /* setup the cascade irq handlers */
 717
 718        set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
 719        set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
 720        set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
 721        set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
 722
 723
 724        /* external interrupts */
 725
 726        for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
 727                irqdbf("registering irq %d (ext int)\n", irqno);
 728                set_irq_chip(irqno, &s3c_irq_eint0t4);
 729                set_irq_handler(irqno, do_edge_IRQ);
 730                set_irq_flags(irqno, IRQF_VALID);
 731        }
 732
 733        for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
 734                irqdbf("registering irq %d (extended s3c irq)\n", irqno);
 735                set_irq_chip(irqno, &s3c_irqext_chip);
 736                set_irq_handler(irqno, do_edge_IRQ);
 737                set_irq_flags(irqno, IRQF_VALID);
 738        }
 739
 740        /* register the uart interrupts */
 741
 742        irqdbf("s3c2410: registering external interrupts\n");
 743
 744        for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
 745                irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
 746                set_irq_chip(irqno, &s3c_irq_uart0);
 747                set_irq_handler(irqno, do_level_IRQ);
 748                set_irq_flags(irqno, IRQF_VALID);
 749        }
 750
 751        for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
 752                irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
 753                set_irq_chip(irqno, &s3c_irq_uart1);
 754                set_irq_handler(irqno, do_level_IRQ);
 755                set_irq_flags(irqno, IRQF_VALID);
 756        }
 757
 758        for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
 759                irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
 760                set_irq_chip(irqno, &s3c_irq_uart2);
 761                set_irq_handler(irqno, do_level_IRQ);
 762                set_irq_flags(irqno, IRQF_VALID);
 763        }
 764
 765        for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
 766                irqdbf("registering irq %d (s3c adc irq)\n", irqno);
 767                set_irq_chip(irqno, &s3c_irq_adc);
 768                set_irq_handler(irqno, do_edge_IRQ);
 769                set_irq_flags(irqno, IRQF_VALID);
 770        }
 771
 772        irqdbf("s3c2410: registered interrupt handlers\n");
 773}
 774
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.