linux/arch/arm/mach-clps7500/core.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-clps7500/core.c
   3 *
   4 *  Copyright (C) 1998 Russell King
   5 *  Copyright (C) 1999 Nexus Electronics Ltd
   6 *
   7 * Extra MM routines for CL7500 architecture
   8 */
   9#include <linux/kernel.h>
  10#include <linux/types.h>
  11#include <linux/interrupt.h>
  12#include <linux/list.h>
  13#include <linux/sched.h>
  14#include <linux/init.h>
  15#include <linux/serial_8250.h>
  16
  17#include <asm/mach/arch.h>
  18#include <asm/mach/map.h>
  19#include <asm/mach/irq.h>
  20#include <asm/mach/time.h>
  21
  22#include <asm/hardware.h>
  23#include <asm/hardware/iomd.h>
  24#include <asm/io.h>
  25#include <asm/irq.h>
  26#include <asm/mach-types.h>
  27
  28static void cl7500_ack_irq_a(unsigned int irq)
  29{
  30        unsigned int val, mask;
  31
  32        mask = 1 << irq;
  33        val = iomd_readb(IOMD_IRQMASKA);
  34        iomd_writeb(val & ~mask, IOMD_IRQMASKA);
  35        iomd_writeb(mask, IOMD_IRQCLRA);
  36}
  37
  38static void cl7500_mask_irq_a(unsigned int irq)
  39{
  40        unsigned int val, mask;
  41
  42        mask = 1 << irq;
  43        val = iomd_readb(IOMD_IRQMASKA);
  44        iomd_writeb(val & ~mask, IOMD_IRQMASKA);
  45}
  46
  47static void cl7500_unmask_irq_a(unsigned int irq)
  48{
  49        unsigned int val, mask;
  50
  51        mask = 1 << irq;
  52        val = iomd_readb(IOMD_IRQMASKA);
  53        iomd_writeb(val | mask, IOMD_IRQMASKA);
  54}
  55
  56static struct irqchip clps7500_a_chip = {
  57        .ack    = cl7500_ack_irq_a,
  58        .mask   = cl7500_mask_irq_a,
  59        .unmask = cl7500_unmask_irq_a,
  60};
  61
  62static void cl7500_mask_irq_b(unsigned int irq)
  63{
  64        unsigned int val, mask;
  65
  66        mask = 1 << (irq & 7);
  67        val = iomd_readb(IOMD_IRQMASKB);
  68        iomd_writeb(val & ~mask, IOMD_IRQMASKB);
  69}
  70
  71static void cl7500_unmask_irq_b(unsigned int irq)
  72{
  73        unsigned int val, mask;
  74
  75        mask = 1 << (irq & 7);
  76        val = iomd_readb(IOMD_IRQMASKB);
  77        iomd_writeb(val | mask, IOMD_IRQMASKB);
  78}
  79
  80static struct irqchip clps7500_b_chip = {
  81        .ack    = cl7500_mask_irq_b,
  82        .mask   = cl7500_mask_irq_b,
  83        .unmask = cl7500_unmask_irq_b,
  84};
  85
  86static void cl7500_mask_irq_c(unsigned int irq)
  87{
  88        unsigned int val, mask;
  89
  90        mask = 1 << (irq & 7);
  91        val = iomd_readb(IOMD_IRQMASKC);
  92        iomd_writeb(val & ~mask, IOMD_IRQMASKC);
  93}
  94
  95static void cl7500_unmask_irq_c(unsigned int irq)
  96{
  97        unsigned int val, mask;
  98
  99        mask = 1 << (irq & 7);
 100        val = iomd_readb(IOMD_IRQMASKC);
 101        iomd_writeb(val | mask, IOMD_IRQMASKC);
 102}
 103
 104static struct irqchip clps7500_c_chip = {
 105        .ack    = cl7500_mask_irq_c,
 106        .mask   = cl7500_mask_irq_c,
 107        .unmask = cl7500_unmask_irq_c,
 108};
 109
 110static void cl7500_mask_irq_d(unsigned int irq)
 111{
 112        unsigned int val, mask;
 113
 114        mask = 1 << (irq & 7);
 115        val = iomd_readb(IOMD_IRQMASKD);
 116        iomd_writeb(val & ~mask, IOMD_IRQMASKD);
 117}
 118
 119static void cl7500_unmask_irq_d(unsigned int irq)
 120{
 121        unsigned int val, mask;
 122
 123        mask = 1 << (irq & 7);
 124        val = iomd_readb(IOMD_IRQMASKD);
 125        iomd_writeb(val | mask, IOMD_IRQMASKD);
 126}
 127
 128static struct irqchip clps7500_d_chip = {
 129        .ack    = cl7500_mask_irq_d,
 130        .mask   = cl7500_mask_irq_d,
 131        .unmask = cl7500_unmask_irq_d,
 132};
 133
 134static void cl7500_mask_irq_dma(unsigned int irq)
 135{
 136        unsigned int val, mask;
 137
 138        mask = 1 << (irq & 7);
 139        val = iomd_readb(IOMD_DMAMASK);
 140        iomd_writeb(val & ~mask, IOMD_DMAMASK);
 141}
 142
 143static void cl7500_unmask_irq_dma(unsigned int irq)
 144{
 145        unsigned int val, mask;
 146
 147        mask = 1 << (irq & 7);
 148        val = iomd_readb(IOMD_DMAMASK);
 149        iomd_writeb(val | mask, IOMD_DMAMASK);
 150}
 151
 152static struct irqchip clps7500_dma_chip = {
 153        .ack    = cl7500_mask_irq_dma,
 154        .mask   = cl7500_mask_irq_dma,
 155        .unmask = cl7500_unmask_irq_dma,
 156};
 157
 158static void cl7500_mask_irq_fiq(unsigned int irq)
 159{
 160        unsigned int val, mask;
 161
 162        mask = 1 << (irq & 7);
 163        val = iomd_readb(IOMD_FIQMASK);
 164        iomd_writeb(val & ~mask, IOMD_FIQMASK);
 165}
 166
 167static void cl7500_unmask_irq_fiq(unsigned int irq)
 168{
 169        unsigned int val, mask;
 170
 171        mask = 1 << (irq & 7);
 172        val = iomd_readb(IOMD_FIQMASK);
 173        iomd_writeb(val | mask, IOMD_FIQMASK);
 174}
 175
 176static struct irqchip clps7500_fiq_chip = {
 177        .ack    = cl7500_mask_irq_fiq,
 178        .mask   = cl7500_mask_irq_fiq,
 179        .unmask = cl7500_unmask_irq_fiq,
 180};
 181
 182static void cl7500_no_action(unsigned int irq)
 183{
 184}
 185
 186static struct irqchip clps7500_no_chip = {
 187        .ack    = cl7500_no_action,
 188        .mask   = cl7500_no_action,
 189        .unmask = cl7500_no_action,
 190};
 191
 192static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL };
 193
 194static void __init clps7500_init_irq(void)
 195{
 196        unsigned int irq, flags;
 197
 198        iomd_writeb(0, IOMD_IRQMASKA);
 199        iomd_writeb(0, IOMD_IRQMASKB);
 200        iomd_writeb(0, IOMD_FIQMASK);
 201        iomd_writeb(0, IOMD_DMAMASK);
 202
 203        for (irq = 0; irq < NR_IRQS; irq++) {
 204                flags = IRQF_VALID;
 205
 206                if (irq <= 6 || (irq >= 9 && irq <= 15) ||
 207                    (irq >= 48 && irq <= 55))
 208                        flags |= IRQF_PROBE;
 209
 210                switch (irq) {
 211                case 0 ... 7:
 212                        set_irq_chip(irq, &clps7500_a_chip);
 213                        set_irq_handler(irq, do_level_IRQ);
 214                        set_irq_flags(irq, flags);
 215                        break;
 216
 217                case 8 ... 15:
 218                        set_irq_chip(irq, &clps7500_b_chip);
 219                        set_irq_handler(irq, do_level_IRQ);
 220                        set_irq_flags(irq, flags);
 221                        break;
 222
 223                case 16 ... 22:
 224                        set_irq_chip(irq, &clps7500_dma_chip);
 225                        set_irq_handler(irq, do_level_IRQ);
 226                        set_irq_flags(irq, flags);
 227                        break;
 228
 229                case 24 ... 31:
 230                        set_irq_chip(irq, &clps7500_c_chip);
 231                        set_irq_handler(irq, do_level_IRQ);
 232                        set_irq_flags(irq, flags);
 233                        break;
 234
 235                case 40 ... 47:
 236                        set_irq_chip(irq, &clps7500_d_chip);
 237                        set_irq_handler(irq, do_level_IRQ);
 238                        set_irq_flags(irq, flags);
 239                        break;
 240
 241                case 48 ... 55:
 242                        set_irq_chip(irq, &clps7500_no_chip);
 243                        set_irq_handler(irq, do_level_IRQ);
 244                        set_irq_flags(irq, flags);
 245                        break;
 246
 247                case 64 ... 72:
 248                        set_irq_chip(irq, &clps7500_fiq_chip);
 249                        set_irq_handler(irq, do_level_IRQ);
 250                        set_irq_flags(irq, flags);
 251                        break;
 252                }
 253        }
 254
 255        setup_irq(IRQ_ISA, &irq_isa);
 256}
 257
 258static struct map_desc cl7500_io_desc[] __initdata = {
 259        { IO_BASE,      IO_START,       IO_SIZE,    MT_DEVICE },        /* IO space     */
 260        { ISA_BASE,     ISA_START,      ISA_SIZE,   MT_DEVICE },        /* ISA space    */
 261        { FLASH_BASE,   FLASH_START,    FLASH_SIZE, MT_DEVICE },        /* Flash        */
 262        { LED_BASE,     LED_START,      LED_SIZE,   MT_DEVICE }         /* LED          */
 263};
 264
 265static void __init clps7500_map_io(void)
 266{
 267        iotable_init(cl7500_io_desc, ARRAY_SIZE(cl7500_io_desc));
 268}
 269
 270extern void ioctime_init(void);
 271extern unsigned long ioc_timer_gettimeoffset(void);
 272
 273static irqreturn_t
 274clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 275{
 276        write_seqlock(&xtime_lock);
 277
 278        timer_tick(regs);
 279
 280        /* Why not using do_leds interface?? */
 281        {
 282                /* Twinkle the lights. */
 283                static int count, state = 0xff00;
 284                if (count-- == 0) {
 285                        state ^= 0x100;
 286                        count = 25;
 287                        *((volatile unsigned int *)LED_ADDRESS) = state;
 288                }
 289        }
 290
 291        write_sequnlock(&xtime_lock);
 292
 293        return IRQ_HANDLED;
 294}
 295
 296static struct irqaction clps7500_timer_irq = {
 297        .name           = "CLPS7500 Timer Tick",
 298        .flags          = SA_INTERRUPT,
 299        .handler        = clps7500_timer_interrupt
 300};
 301
 302/*
 303 * Set up timer interrupt.
 304 */
 305static void __init clps7500_timer_init(void)
 306{
 307        ioctime_init();
 308
 309        setup_irq(IRQ_TIMER, &clps7500_timer_irq);
 310}
 311
 312static struct clps7500_timer = {
 313        .init           = clps7500_timer_init,
 314        .offset         = ioc_timer_gettimeoffset,
 315};
 316
 317static struct plat_serial8250_port serial_platform_data[] = {
 318        {
 319                .mapbase        = 0x03010fe0,
 320                .irq            = 10,
 321                .uartclk        = 1843200,
 322                .regshift       = 2,
 323                .iotype         = UPIO_MEM,
 324                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST,
 325        },
 326        {
 327                .mapbase        = 0x03010be0,
 328                .irq            = 0,
 329                .uartclk        = 1843200,
 330                .regshift       = 2,
 331                .iotype         = UPIO_MEM,
 332                .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST,
 333        },
 334        {
 335                .iobase         = ISASLOT_IO + 0x2e8,
 336                .irq            = 41,
 337                .uartclk        = 1843200,
 338                .regshift       = 0,
 339                .iotype         = UPIO_PORT,
 340                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 341        },
 342        {
 343                .iobase         = ISASLOT_IO + 0x3e8,
 344                .irq            = 40,
 345                .uartclk        = 1843200,
 346                .regshift       = 0,
 347                .iotype         = UPIO_PORT,
 348                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 349        },
 350        { },
 351};
 352
 353static struct platform_device serial_device = {
 354        .name                   = "serial8250",
 355        .id                     = 0,
 356        .dev                    = {
 357                .platform_data  = serial_platform_data,
 358        },
 359};
 360
 361static int __init clps7500_init(void)
 362{
 363        return platform_register_device(&serial_device);
 364}
 365
 366MACHINE_START(CLPS7500, "CL-PS7500")
 367        MAINTAINER("Philip Blundell")
 368        BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
 369        MAPIO(clps7500_map_io)
 370        INITIRQ(clps7500_init_irq)
 371        .timer          = &clps7500_timer,
 372MACHINE_END
 373
 374
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.