linux/arch/arm/mach-h720x/common.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-h720x/common.c
   3 *
   4 * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
   5 *               2003 Robert Schwebel <r.schwebel@pengutronix.de>
   6 *               2004 Sascha Hauer    <s.hauer@pengutronix.de>
   7 *
   8 * common stuff for Hynix h720x processors
   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#include <linux/sched.h>
  17#include <linux/slab.h>
  18#include <linux/mman.h>
  19#include <linux/init.h>
  20#include <linux/interrupt.h>
  21
  22#include <asm/page.h>
  23#include <asm/pgtable.h>
  24#include <asm/dma.h>
  25#include <asm/io.h>
  26#include <asm/hardware.h>
  27#include <asm/irq.h>
  28#include <asm/mach/irq.h>
  29#include <asm/mach/map.h>
  30#include <asm/arch/irqs.h>
  31
  32#include <asm/mach/dma.h>
  33
  34#if 0
  35#define IRQDBG(args...) printk(args)
  36#else
  37#define IRQDBG(args...) do {} while(0)
  38#endif
  39
  40void __init arch_dma_init(dma_t *dma)
  41{
  42}
  43
  44/*
  45 * Return usecs since last timer reload
  46 * (timercount * (usecs perjiffie)) / (ticks per jiffie)
  47 */
  48unsigned long h720x_gettimeoffset(void)
  49{
  50        return (CPU_REG (TIMER_VIRT, TM0_COUNT) * tick_usec) / LATCH;
  51}
  52
  53/*
  54 * mask Global irq's
  55 */
  56static void mask_global_irq (unsigned int irq )
  57{
  58        CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << irq);
  59}
  60
  61/*
  62 * unmask Global irq's
  63 */
  64static void unmask_global_irq (unsigned int irq )
  65{
  66        CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << irq);
  67}
  68
  69
  70/*
  71 * ack GPIO irq's
  72 * Ack only for edge triggered int's valid
  73 */
  74static void inline ack_gpio_irq(u32 irq)
  75{
  76        u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
  77        u32 bit = IRQ_TO_BIT(irq);
  78        if ( (CPU_REG (reg_base, GPIO_EDGE) & bit))
  79                CPU_REG (reg_base, GPIO_CLR) = bit;
  80}
  81
  82/*
  83 * mask GPIO irq's
  84 */
  85static void inline mask_gpio_irq(u32 irq)
  86{
  87        u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
  88        u32 bit = IRQ_TO_BIT(irq);
  89        CPU_REG (reg_base, GPIO_MASK) &= ~bit;
  90}
  91
  92/*
  93 * unmask GPIO irq's
  94 */
  95static void inline unmask_gpio_irq(u32 irq)
  96{
  97        u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq));
  98        u32 bit = IRQ_TO_BIT(irq);
  99        CPU_REG (reg_base, GPIO_MASK) |= bit;
 100}
 101
 102static void
 103h720x_gpio_handler(unsigned int mask, unsigned int irq,
 104                 struct irqdesc *desc, struct pt_regs *regs)
 105{
 106        IRQDBG("%s irq: %d\n",__FUNCTION__,irq);
 107        desc = irq_desc + irq;
 108        while (mask) {
 109                if (mask & 1) {
 110                        IRQDBG("handling irq %d\n", irq);
 111                        desc->handle(irq, desc, regs);
 112                }
 113                irq++;
 114                desc++;
 115                mask >>= 1;
 116        }
 117}
 118
 119static void
 120h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
 121                        struct pt_regs *regs)
 122{
 123        unsigned int mask, irq;
 124
 125        mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT);
 126        irq = IRQ_CHAINED_GPIOA(0);
 127        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
 128        h720x_gpio_handler(mask, irq, desc, regs);
 129}
 130
 131static void
 132h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
 133                        struct pt_regs *regs)
 134{
 135        unsigned int mask, irq;
 136        mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT);
 137        irq = IRQ_CHAINED_GPIOB(0);
 138        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
 139        h720x_gpio_handler(mask, irq, desc, regs);
 140}
 141
 142static void
 143h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
 144                        struct pt_regs *regs)
 145{
 146        unsigned int mask, irq;
 147
 148        mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT);
 149        irq = IRQ_CHAINED_GPIOC(0);
 150        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
 151        h720x_gpio_handler(mask, irq, desc, regs);
 152}
 153
 154static void
 155h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
 156                        struct pt_regs *regs)
 157{
 158        unsigned int mask, irq;
 159
 160        mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT);
 161        irq = IRQ_CHAINED_GPIOD(0);
 162        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
 163        h720x_gpio_handler(mask, irq, desc, regs);
 164}
 165
 166#ifdef CONFIG_CPU_H7202
 167static void
 168h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
 169                        struct pt_regs *regs)
 170{
 171        unsigned int mask, irq;
 172
 173        mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT);
 174        irq = IRQ_CHAINED_GPIOE(0);
 175        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
 176        h720x_gpio_handler(mask, irq, desc, regs);
 177}
 178#endif
 179
 180static struct irqchip h720x_global_chip = {
 181        .ack = mask_global_irq,
 182        .mask = mask_global_irq,
 183        .unmask = unmask_global_irq,
 184};
 185
 186static struct irqchip h720x_gpio_chip = {
 187        .ack = ack_gpio_irq,
 188        .mask = mask_gpio_irq,
 189        .unmask = unmask_gpio_irq,
 190};
 191
 192/*
 193 * Initialize IRQ's, mask all, enable multiplexed irq's
 194 */
 195void __init h720x_init_irq (void)
 196{
 197        int     irq;
 198
 199        /* Mask global irq's */
 200        CPU_REG (IRQC_VIRT, IRQC_IER) = 0x0;
 201
 202        /* Mask all multiplexed irq's */
 203        CPU_REG (GPIO_A_VIRT, GPIO_MASK) = 0x0;
 204        CPU_REG (GPIO_B_VIRT, GPIO_MASK) = 0x0;
 205        CPU_REG (GPIO_C_VIRT, GPIO_MASK) = 0x0;
 206        CPU_REG (GPIO_D_VIRT, GPIO_MASK) = 0x0;
 207
 208        /* Initialize global IRQ's, fast path */
 209        for (irq = 0; irq < NR_GLBL_IRQS; irq++) {
 210                set_irq_chip(irq, &h720x_global_chip);
 211                set_irq_handler(irq, do_level_IRQ);
 212                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 213        }
 214
 215        /* Initialize multiplexed IRQ's, slow path */
 216        for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) {
 217                set_irq_chip(irq, &h720x_gpio_chip);
 218                set_irq_handler(irq, do_edge_IRQ);
 219                set_irq_flags(irq, IRQF_VALID );
 220        }
 221        set_irq_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler);
 222        set_irq_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler);
 223        set_irq_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler);
 224        set_irq_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler);
 225
 226#ifdef CONFIG_CPU_H7202
 227        for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) {
 228                set_irq_chip(irq, &h720x_gpio_chip);
 229                set_irq_handler(irq, do_edge_IRQ);
 230                set_irq_flags(irq, IRQF_VALID );
 231        }
 232        set_irq_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler);
 233#endif
 234
 235        /* Enable multiplexed irq's */
 236        CPU_REG (IRQC_VIRT, IRQC_IER) = IRQ_ENA_MUX;
 237}
 238
 239static struct map_desc h720x_io_desc[] __initdata = {
 240        { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
 241};
 242
 243/* Initialize io tables */
 244void __init h720x_map_io(void)
 245{
 246        iotable_init(h720x_io_desc,ARRAY_SIZE(h720x_io_desc));
 247}
 248
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.