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#include <linux/io.h>
  22
  23#include <asm/page.h>
  24#include <asm/pgtable.h>
  25#include <asm/dma.h>
  26#include <mach/hardware.h>
  27#include <asm/irq.h>
  28#include <asm/mach/irq.h>
  29#include <asm/mach/map.h>
  30#include <mach/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 irq_desc *desc)
 105{
 106        IRQDBG("%s irq: %d\n", __func__, irq);
 107        while (mask) {
 108                if (mask & 1) {
 109                        IRQDBG("handling irq %d\n", irq);
 110                        generic_handle_irq(irq);
 111                }
 112                irq++;
 113                mask >>= 1;
 114        }
 115}
 116
 117static void
 118h720x_gpioa_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 119{
 120        unsigned int mask, irq;
 121
 122        mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT);
 123        irq = IRQ_CHAINED_GPIOA(0);
 124        IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
 125        h720x_gpio_handler(mask, irq, desc);
 126}
 127
 128static void
 129h720x_gpiob_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 130{
 131        unsigned int mask, irq;
 132        mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT);
 133        irq = IRQ_CHAINED_GPIOB(0);
 134        IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
 135        h720x_gpio_handler(mask, irq, desc);
 136}
 137
 138static void
 139h720x_gpioc_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 140{
 141        unsigned int mask, irq;
 142
 143        mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT);
 144        irq = IRQ_CHAINED_GPIOC(0);
 145        IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
 146        h720x_gpio_handler(mask, irq, desc);
 147}
 148
 149static void
 150h720x_gpiod_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 151{
 152        unsigned int mask, irq;
 153
 154        mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT);
 155        irq = IRQ_CHAINED_GPIOD(0);
 156        IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
 157        h720x_gpio_handler(mask, irq, desc);
 158}
 159
 160#ifdef CONFIG_CPU_H7202
 161static void
 162h720x_gpioe_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
 163{
 164        unsigned int mask, irq;
 165
 166        mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT);
 167        irq = IRQ_CHAINED_GPIOE(0);
 168        IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
 169        h720x_gpio_handler(mask, irq, desc);
 170}
 171#endif
 172
 173static struct irq_chip h720x_global_chip = {
 174        .ack = mask_global_irq,
 175        .mask = mask_global_irq,
 176        .unmask = unmask_global_irq,
 177};
 178
 179static struct irq_chip h720x_gpio_chip = {
 180        .ack = ack_gpio_irq,
 181        .mask = mask_gpio_irq,
 182        .unmask = unmask_gpio_irq,
 183};
 184
 185/*
 186 * Initialize IRQ's, mask all, enable multiplexed irq's
 187 */
 188void __init h720x_init_irq (void)
 189{
 190        int     irq;
 191
 192        /* Mask global irq's */
 193        CPU_REG (IRQC_VIRT, IRQC_IER) = 0x0;
 194
 195        /* Mask all multiplexed irq's */
 196        CPU_REG (GPIO_A_VIRT, GPIO_MASK) = 0x0;
 197        CPU_REG (GPIO_B_VIRT, GPIO_MASK) = 0x0;
 198        CPU_REG (GPIO_C_VIRT, GPIO_MASK) = 0x0;
 199        CPU_REG (GPIO_D_VIRT, GPIO_MASK) = 0x0;
 200
 201        /* Initialize global IRQ's, fast path */
 202        for (irq = 0; irq < NR_GLBL_IRQS; irq++) {
 203                set_irq_chip(irq, &h720x_global_chip);
 204                set_irq_handler(irq, handle_level_irq);
 205                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 206        }
 207
 208        /* Initialize multiplexed IRQ's, slow path */
 209        for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) {
 210                set_irq_chip(irq, &h720x_gpio_chip);
 211                set_irq_handler(irq, handle_edge_irq);
 212                set_irq_flags(irq, IRQF_VALID );
 213        }
 214        set_irq_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler);
 215        set_irq_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler);
 216        set_irq_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler);
 217        set_irq_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler);
 218
 219#ifdef CONFIG_CPU_H7202
 220        for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) {
 221                set_irq_chip(irq, &h720x_gpio_chip);
 222                set_irq_handler(irq, handle_edge_irq);
 223                set_irq_flags(irq, IRQF_VALID );
 224        }
 225        set_irq_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler);
 226#endif
 227
 228        /* Enable multiplexed irq's */
 229        CPU_REG (IRQC_VIRT, IRQC_IER) = IRQ_ENA_MUX;
 230}
 231
 232static struct map_desc h720x_io_desc[] __initdata = {
 233        {
 234                .virtual        = IO_VIRT,
 235                .pfn            = __phys_to_pfn(IO_PHYS),
 236                .length         = IO_SIZE,
 237                .type           = MT_DEVICE
 238        },
 239};
 240
 241/* Initialize io tables */
 242void __init h720x_map_io(void)
 243{
 244        iotable_init(h720x_io_desc,ARRAY_SIZE(h720x_io_desc));
 245}
 246
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.