linux/arch/arm/mach-sa1100/irq.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-sa1100/irq.c
   3 *
   4 * Copyright (C) 1999-2001 Nicolas Pitre
   5 *
   6 * Generic IRQ handling for the SA11x0, GPIO 11-27 IRQ demultiplexing.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12#include <linux/init.h>
  13#include <linux/module.h>
  14#include <linux/ioport.h>
  15#include <linux/ptrace.h>
  16#include <linux/sysdev.h>
  17
  18#include <asm/hardware.h>
  19#include <asm/irq.h>
  20#include <asm/mach/irq.h>
  21
  22#include "generic.h"
  23
  24
  25/*
  26 * SA1100 GPIO edge detection for IRQs:
  27 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
  28 * Use this instead of directly setting GRER/GFER.
  29 */
  30static int GPIO_IRQ_rising_edge;
  31static int GPIO_IRQ_falling_edge;
  32static int GPIO_IRQ_mask = (1 << 11) - 1;
  33
  34/*
  35 * To get the GPIO number from an IRQ number
  36 */
  37#define GPIO_11_27_IRQ(i)       ((i) - 21)
  38#define GPIO11_27_MASK(irq)     (1 << GPIO_11_27_IRQ(irq))
  39
  40static int sa1100_gpio_type(unsigned int irq, unsigned int type)
  41{
  42        unsigned int mask;
  43
  44        if (irq <= 10)
  45                mask = 1 << irq;
  46        else
  47                mask = GPIO11_27_MASK(irq);
  48
  49        if (type == IRQT_PROBE) {
  50                if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
  51                        return 0;
  52                type = __IRQT_RISEDGE | __IRQT_FALEDGE;
  53        }
  54
  55        if (type & __IRQT_RISEDGE) {
  56                GPIO_IRQ_rising_edge |= mask;
  57        } else
  58                GPIO_IRQ_rising_edge &= ~mask;
  59        if (type & __IRQT_FALEDGE) {
  60                GPIO_IRQ_falling_edge |= mask;
  61        } else
  62                GPIO_IRQ_falling_edge &= ~mask;
  63
  64        GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
  65        GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
  66
  67        return 0;
  68}
  69
  70/*
  71 * GPIO IRQs must be acknowledged.  This is for IRQs from 0 to 10.
  72 */
  73static void sa1100_low_gpio_ack(unsigned int irq)
  74{
  75        GEDR = (1 << irq);
  76}
  77
  78static void sa1100_low_gpio_mask(unsigned int irq)
  79{
  80        ICMR &= ~(1 << irq);
  81}
  82
  83static void sa1100_low_gpio_unmask(unsigned int irq)
  84{
  85        ICMR |= 1 << irq;
  86}
  87
  88static int sa1100_low_gpio_wake(unsigned int irq, unsigned int on)
  89{
  90        if (on)
  91                PWER |= 1 << irq;
  92        else
  93                PWER &= ~(1 << irq);
  94        return 0;
  95}
  96
  97static struct irqchip sa1100_low_gpio_chip = {
  98        .ack            = sa1100_low_gpio_ack,
  99        .mask           = sa1100_low_gpio_mask,
 100        .unmask         = sa1100_low_gpio_unmask,
 101        .type           = sa1100_gpio_type,
 102        .wake           = sa1100_low_gpio_wake,
 103};
 104
 105/*
 106 * IRQ11 (GPIO11 through 27) handler.  We enter here with the
 107 * irq_controller_lock held, and IRQs disabled.  Decode the IRQ
 108 * and call the handler.
 109 */
 110static void
 111sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,
 112                         struct pt_regs *regs)
 113{
 114        unsigned int mask;
 115
 116        mask = GEDR & 0xfffff800;
 117        do {
 118                /*
 119                 * clear down all currently active IRQ sources.
 120                 * We will be processing them all.
 121                 */
 122                GEDR = mask;
 123
 124                irq = IRQ_GPIO11;
 125                desc = irq_desc + irq;
 126                mask >>= 11;
 127                do {
 128                        if (mask & 1)
 129                                desc->handle(irq, desc, regs);
 130                        mask >>= 1;
 131                        irq++;
 132                        desc++;
 133                } while (mask);
 134
 135                mask = GEDR & 0xfffff800;
 136        } while (mask);
 137}
 138
 139/*
 140 * Like GPIO0 to 10, GPIO11-27 IRQs need to be handled specially.
 141 * In addition, the IRQs are all collected up into one bit in the
 142 * interrupt controller registers.
 143 */
 144static void sa1100_high_gpio_ack(unsigned int irq)
 145{
 146        unsigned int mask = GPIO11_27_MASK(irq);
 147
 148        GEDR = mask;
 149}
 150
 151static void sa1100_high_gpio_mask(unsigned int irq)
 152{
 153        unsigned int mask = GPIO11_27_MASK(irq);
 154
 155        GPIO_IRQ_mask &= ~mask;
 156
 157        GRER &= ~mask;
 158        GFER &= ~mask;
 159}
 160
 161static void sa1100_high_gpio_unmask(unsigned int irq)
 162{
 163        unsigned int mask = GPIO11_27_MASK(irq);
 164
 165        GPIO_IRQ_mask |= mask;
 166
 167        GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
 168        GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 169}
 170
 171static int sa1100_high_gpio_wake(unsigned int irq, unsigned int on)
 172{
 173        if (on)
 174                PWER |= GPIO11_27_MASK(irq);
 175        else
 176                PWER &= ~GPIO11_27_MASK(irq);
 177        return 0;
 178}
 179
 180static struct irqchip sa1100_high_gpio_chip = {
 181        .ack            = sa1100_high_gpio_ack,
 182        .mask           = sa1100_high_gpio_mask,
 183        .unmask         = sa1100_high_gpio_unmask,
 184        .type           = sa1100_gpio_type,
 185        .wake           = sa1100_high_gpio_wake,
 186};
 187
 188/*
 189 * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
 190 * this is for internal IRQs i.e. from 11 to 31.
 191 */
 192static void sa1100_mask_irq(unsigned int irq)
 193{
 194        ICMR &= ~(1 << irq);
 195}
 196
 197static void sa1100_unmask_irq(unsigned int irq)
 198{
 199        ICMR |= (1 << irq);
 200}
 201
 202static struct irqchip sa1100_normal_chip = {
 203        .ack            = sa1100_mask_irq,
 204        .mask           = sa1100_mask_irq,
 205        .unmask         = sa1100_unmask_irq,
 206};
 207
 208static struct resource irq_resource = {
 209        .name   = "irqs",
 210        .start  = 0x90050000,
 211        .end    = 0x9005ffff,
 212};
 213
 214static struct sa1100irq_state {
 215        unsigned int    saved;
 216        unsigned int    icmr;
 217        unsigned int    iclr;
 218        unsigned int    iccr;
 219} sa1100irq_state;
 220
 221static int sa1100irq_suspend(struct sys_device *dev, u32 state)
 222{
 223        struct sa1100irq_state *st = &sa1100irq_state;
 224
 225        st->saved = 1;
 226        st->icmr = ICMR;
 227        st->iclr = ICLR;
 228        st->iccr = ICCR;
 229
 230        /*
 231         * Disable all GPIO-based interrupts.
 232         */
 233        ICMR &= ~(IC_GPIO11_27|IC_GPIO10|IC_GPIO9|IC_GPIO8|IC_GPIO7|
 234                  IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2|
 235                  IC_GPIO1|IC_GPIO0);
 236
 237        /*
 238         * Set the appropriate edges for wakeup.
 239         */
 240        GRER = PWER & GPIO_IRQ_rising_edge;
 241        GFER = PWER & GPIO_IRQ_falling_edge;
 242        
 243        /*
 244         * Clear any pending GPIO interrupts.
 245         */
 246        GEDR = GEDR;
 247
 248        return 0;
 249}
 250
 251static int sa1100irq_resume(struct sys_device *dev)
 252{
 253        struct sa1100irq_state *st = &sa1100irq_state;
 254
 255        if (st->saved) {
 256                ICCR = st->iccr;
 257                ICLR = st->iclr;
 258
 259                GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
 260                GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 261
 262                ICMR = st->icmr;
 263        }
 264        return 0;
 265}
 266
 267static struct sysdev_class sa1100irq_sysclass = {
 268        set_kset_name("sa11x0-irq"),
 269        .suspend        = sa1100irq_suspend,
 270        .resume         = sa1100irq_resume,
 271};
 272
 273static struct sys_device sa1100irq_device = {
 274        .id             = 0,
 275        .cls            = &sa1100irq_sysclass,
 276};
 277
 278static int __init sa1100irq_init_devicefs(void)
 279{
 280        sysdev_class_register(&sa1100irq_sysclass);
 281        return sysdev_register(&sa1100irq_device);
 282}
 283
 284device_initcall(sa1100irq_init_devicefs);
 285
 286void __init sa1100_init_irq(void)
 287{
 288        unsigned int irq;
 289
 290        request_resource(&iomem_resource, &irq_resource);
 291
 292        /* disable all IRQs */
 293        ICMR = 0;
 294
 295        /* all IRQs are IRQ, not FIQ */
 296        ICLR = 0;
 297
 298        /* clear all GPIO edge detects */
 299        GFER = 0;
 300        GRER = 0;
 301        GEDR = -1;
 302
 303        /*
 304         * Whatever the doc says, this has to be set for the wait-on-irq
 305         * instruction to work... on a SA1100 rev 9 at least.
 306         */
 307        ICCR = 1;
 308
 309        for (irq = 0; irq <= 10; irq++) {
 310                set_irq_chip(irq, &sa1100_low_gpio_chip);
 311                set_irq_handler(irq, do_edge_IRQ);
 312                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 313        }
 314
 315        for (irq = 12; irq <= 31; irq++) {
 316                set_irq_chip(irq, &sa1100_normal_chip);
 317                set_irq_handler(irq, do_level_IRQ);
 318                set_irq_flags(irq, IRQF_VALID);
 319        }
 320
 321        for (irq = 32; irq <= 48; irq++) {
 322                set_irq_chip(irq, &sa1100_high_gpio_chip);
 323                set_irq_handler(irq, do_edge_IRQ);
 324                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 325        }
 326
 327        /*
 328         * Install handler for GPIO 11-27 edge detect interrupts
 329         */
 330        set_irq_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
 331        set_irq_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
 332}
 333
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.