linux/arch/arm/mach-lpc32xx/irq.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-lpc32xx/irq.c
   3 *
   4 * Author: Kevin Wells <kevin.wells@nxp.com>
   5 *
   6 * Copyright (C) 2010 NXP Semiconductors
   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 as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/types.h>
  21#include <linux/interrupt.h>
  22#include <linux/irq.h>
  23#include <linux/err.h>
  24#include <linux/io.h>
  25#include <linux/of.h>
  26#include <linux/of_address.h>
  27#include <linux/of_irq.h>
  28#include <linux/irqdomain.h>
  29#include <linux/module.h>
  30
  31#include <mach/irqs.h>
  32#include <mach/hardware.h>
  33#include <mach/platform.h>
  34#include "common.h"
  35
  36/*
  37 * Default value representing the Activation polarity of all internal
  38 * interrupt sources
  39 */
  40#define MIC_APR_DEFAULT         0x3FF0EFE0
  41#define SIC1_APR_DEFAULT        0xFBD27186
  42#define SIC2_APR_DEFAULT        0x801810C0
  43
  44/*
  45 * Default value representing the Activation Type of all internal
  46 * interrupt sources. All are level sensitive.
  47 */
  48#define MIC_ATR_DEFAULT         0x00000000
  49#define SIC1_ATR_DEFAULT        0x00026000
  50#define SIC2_ATR_DEFAULT        0x00000000
  51
  52static struct irq_domain *lpc32xx_mic_domain;
  53static struct device_node *lpc32xx_mic_np;
  54
  55struct lpc32xx_event_group_regs {
  56        void __iomem *enab_reg;
  57        void __iomem *edge_reg;
  58        void __iomem *maskstat_reg;
  59        void __iomem *rawstat_reg;
  60};
  61
  62static const struct lpc32xx_event_group_regs lpc32xx_event_int_regs = {
  63        .enab_reg = LPC32XX_CLKPWR_INT_ER,
  64        .edge_reg = LPC32XX_CLKPWR_INT_AP,
  65        .maskstat_reg = LPC32XX_CLKPWR_INT_SR,
  66        .rawstat_reg = LPC32XX_CLKPWR_INT_RS,
  67};
  68
  69static const struct lpc32xx_event_group_regs lpc32xx_event_pin_regs = {
  70        .enab_reg = LPC32XX_CLKPWR_PIN_ER,
  71        .edge_reg = LPC32XX_CLKPWR_PIN_AP,
  72        .maskstat_reg = LPC32XX_CLKPWR_PIN_SR,
  73        .rawstat_reg = LPC32XX_CLKPWR_PIN_RS,
  74};
  75
  76struct lpc32xx_event_info {
  77        const struct lpc32xx_event_group_regs *event_group;
  78        u32 mask;
  79};
  80
  81/*
  82 * Maps an IRQ number to and event mask and register
  83 */
  84static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
  85        [IRQ_LPC32XX_GPI_08] = {
  86                .event_group = &lpc32xx_event_pin_regs,
  87                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT,
  88        },
  89        [IRQ_LPC32XX_GPI_09] = {
  90                .event_group = &lpc32xx_event_pin_regs,
  91                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT,
  92        },
  93        [IRQ_LPC32XX_GPI_19] = {
  94                .event_group = &lpc32xx_event_pin_regs,
  95                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT,
  96        },
  97        [IRQ_LPC32XX_GPI_07] = {
  98                .event_group = &lpc32xx_event_pin_regs,
  99                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT,
 100        },
 101        [IRQ_LPC32XX_GPI_00] = {
 102                .event_group = &lpc32xx_event_pin_regs,
 103                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT,
 104        },
 105        [IRQ_LPC32XX_GPI_01] = {
 106                .event_group = &lpc32xx_event_pin_regs,
 107                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT,
 108        },
 109        [IRQ_LPC32XX_GPI_02] = {
 110                .event_group = &lpc32xx_event_pin_regs,
 111                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT,
 112        },
 113        [IRQ_LPC32XX_GPI_03] = {
 114                .event_group = &lpc32xx_event_pin_regs,
 115                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT,
 116        },
 117        [IRQ_LPC32XX_GPI_04] = {
 118                .event_group = &lpc32xx_event_pin_regs,
 119                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT,
 120        },
 121        [IRQ_LPC32XX_GPI_05] = {
 122                .event_group = &lpc32xx_event_pin_regs,
 123                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT,
 124        },
 125        [IRQ_LPC32XX_GPI_06] = {
 126                .event_group = &lpc32xx_event_pin_regs,
 127                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT,
 128        },
 129        [IRQ_LPC32XX_GPI_28] = {
 130                .event_group = &lpc32xx_event_pin_regs,
 131                .mask = LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT,
 132        },
 133        [IRQ_LPC32XX_GPIO_00] = {
 134                .event_group = &lpc32xx_event_int_regs,
 135                .mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT,
 136        },
 137        [IRQ_LPC32XX_GPIO_01] = {
 138                .event_group = &lpc32xx_event_int_regs,
 139                .mask = LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT,
 140        },
 141        [IRQ_LPC32XX_GPIO_02] = {
 142                .event_group = &lpc32xx_event_int_regs,
 143                .mask = LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT,
 144        },
 145        [IRQ_LPC32XX_GPIO_03] = {
 146                .event_group = &lpc32xx_event_int_regs,
 147                .mask = LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT,
 148        },
 149        [IRQ_LPC32XX_GPIO_04] = {
 150                .event_group = &lpc32xx_event_int_regs,
 151                .mask = LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT,
 152        },
 153        [IRQ_LPC32XX_GPIO_05] = {
 154                .event_group = &lpc32xx_event_int_regs,
 155                .mask = LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT,
 156        },
 157        [IRQ_LPC32XX_KEY] = {
 158                .event_group = &lpc32xx_event_int_regs,
 159                .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT,
 160        },
 161        [IRQ_LPC32XX_ETHERNET] = {
 162                .event_group = &lpc32xx_event_int_regs,
 163                .mask = LPC32XX_CLKPWR_INTSRC_MAC_BIT,
 164        },
 165        [IRQ_LPC32XX_USB_OTG_ATX] = {
 166                .event_group = &lpc32xx_event_int_regs,
 167                .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT,
 168        },
 169        [IRQ_LPC32XX_USB_HOST] = {
 170                .event_group = &lpc32xx_event_int_regs,
 171                .mask = LPC32XX_CLKPWR_INTSRC_USB_BIT,
 172        },
 173        [IRQ_LPC32XX_RTC] = {
 174                .event_group = &lpc32xx_event_int_regs,
 175                .mask = LPC32XX_CLKPWR_INTSRC_RTC_BIT,
 176        },
 177        [IRQ_LPC32XX_MSTIMER] = {
 178                .event_group = &lpc32xx_event_int_regs,
 179                .mask = LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT,
 180        },
 181        [IRQ_LPC32XX_TS_AUX] = {
 182                .event_group = &lpc32xx_event_int_regs,
 183                .mask = LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT,
 184        },
 185        [IRQ_LPC32XX_TS_P] = {
 186                .event_group = &lpc32xx_event_int_regs,
 187                .mask = LPC32XX_CLKPWR_INTSRC_TS_P_BIT,
 188        },
 189        [IRQ_LPC32XX_TS_IRQ] = {
 190                .event_group = &lpc32xx_event_int_regs,
 191                .mask = LPC32XX_CLKPWR_INTSRC_ADC_BIT,
 192        },
 193};
 194
 195static void get_controller(unsigned int irq, unsigned int *base,
 196        unsigned int *irqbit)
 197{
 198        if (irq < 32) {
 199                *base = LPC32XX_MIC_BASE;
 200                *irqbit = 1 << irq;
 201        } else if (irq < 64) {
 202                *base = LPC32XX_SIC1_BASE;
 203                *irqbit = 1 << (irq - 32);
 204        } else {
 205                *base = LPC32XX_SIC2_BASE;
 206                *irqbit = 1 << (irq - 64);
 207        }
 208}
 209
 210static void lpc32xx_mask_irq(struct irq_data *d)
 211{
 212        unsigned int reg, ctrl, mask;
 213
 214        get_controller(d->hwirq, &ctrl, &mask);
 215
 216        reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask;
 217        __raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
 218}
 219
 220static void lpc32xx_unmask_irq(struct irq_data *d)
 221{
 222        unsigned int reg, ctrl, mask;
 223
 224        get_controller(d->hwirq, &ctrl, &mask);
 225
 226        reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask;
 227        __raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
 228}
 229
 230static void lpc32xx_ack_irq(struct irq_data *d)
 231{
 232        unsigned int ctrl, mask;
 233
 234        get_controller(d->hwirq, &ctrl, &mask);
 235
 236        __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl));
 237
 238        /* Also need to clear pending wake event */
 239        if (lpc32xx_events[d->hwirq].mask != 0)
 240                __raw_writel(lpc32xx_events[d->hwirq].mask,
 241                        lpc32xx_events[d->hwirq].event_group->rawstat_reg);
 242}
 243
 244static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level,
 245        int use_edge)
 246{
 247        unsigned int reg, ctrl, mask;
 248
 249        get_controller(irq, &ctrl, &mask);
 250
 251        /* Activation level, high or low */
 252        reg = __raw_readl(LPC32XX_INTC_POLAR(ctrl));
 253        if (use_high_level)
 254                reg |= mask;
 255        else
 256                reg &= ~mask;
 257        __raw_writel(reg, LPC32XX_INTC_POLAR(ctrl));
 258
 259        /* Activation type, edge or level */
 260        reg = __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl));
 261        if (use_edge)
 262                reg |= mask;
 263        else
 264                reg &= ~mask;
 265        __raw_writel(reg, LPC32XX_INTC_ACT_TYPE(ctrl));
 266
 267        /* Use same polarity for the wake events */
 268        if (lpc32xx_events[irq].mask != 0) {
 269                reg = __raw_readl(lpc32xx_events[irq].event_group->edge_reg);
 270
 271                if (use_high_level)
 272                        reg |= lpc32xx_events[irq].mask;
 273                else
 274                        reg &= ~lpc32xx_events[irq].mask;
 275
 276                __raw_writel(reg, lpc32xx_events[irq].event_group->edge_reg);
 277        }
 278}
 279
 280static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
 281{
 282        switch (type) {
 283        case IRQ_TYPE_EDGE_RISING:
 284                /* Rising edge sensitive */
 285                __lpc32xx_set_irq_type(d->hwirq, 1, 1);
 286                irq_set_handler_locked(d, handle_edge_irq);
 287                break;
 288
 289        case IRQ_TYPE_EDGE_FALLING:
 290                /* Falling edge sensitive */
 291                __lpc32xx_set_irq_type(d->hwirq, 0, 1);
 292                irq_set_handler_locked(d, handle_edge_irq);
 293                break;
 294
 295        case IRQ_TYPE_LEVEL_LOW:
 296                /* Low level sensitive */
 297                __lpc32xx_set_irq_type(d->hwirq, 0, 0);
 298                irq_set_handler_locked(d, handle_level_irq);
 299                break;
 300
 301        case IRQ_TYPE_LEVEL_HIGH:
 302                /* High level sensitive */
 303                __lpc32xx_set_irq_type(d->hwirq, 1, 0);
 304                irq_set_handler_locked(d, handle_level_irq);
 305                break;
 306
 307        /* Other modes are not supported */
 308        default:
 309                return -EINVAL;
 310        }
 311
 312        return 0;
 313}
 314
 315static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state)
 316{
 317        unsigned long eventreg;
 318
 319        if (lpc32xx_events[d->hwirq].mask != 0) {
 320                eventreg = __raw_readl(lpc32xx_events[d->hwirq].
 321                        event_group->enab_reg);
 322
 323                if (state)
 324                        eventreg |= lpc32xx_events[d->hwirq].mask;
 325                else {
 326                        eventreg &= ~lpc32xx_events[d->hwirq].mask;
 327
 328                        /*
 329                         * When disabling the wakeup, clear the latched
 330                         * event
 331                         */
 332                        __raw_writel(lpc32xx_events[d->hwirq].mask,
 333                                lpc32xx_events[d->hwirq].
 334                                event_group->rawstat_reg);
 335                }
 336
 337                __raw_writel(eventreg,
 338                        lpc32xx_events[d->hwirq].event_group->enab_reg);
 339
 340                return 0;
 341        }
 342
 343        /* Clear event */
 344        __raw_writel(lpc32xx_events[d->hwirq].mask,
 345                lpc32xx_events[d->hwirq].event_group->rawstat_reg);
 346
 347        return -ENODEV;
 348}
 349
 350static void __init lpc32xx_set_default_mappings(unsigned int apr,
 351        unsigned int atr, unsigned int offset)
 352{
 353        unsigned int i;
 354
 355        /* Set activation levels for each interrupt */
 356        i = 0;
 357        while (i < 32) {
 358                __lpc32xx_set_irq_type(offset + i, ((apr >> i) & 0x1),
 359                        ((atr >> i) & 0x1));
 360                i++;
 361        }
 362}
 363
 364static struct irq_chip lpc32xx_irq_chip = {
 365        .name = "MIC",
 366        .irq_ack = lpc32xx_ack_irq,
 367        .irq_mask = lpc32xx_mask_irq,
 368        .irq_unmask = lpc32xx_unmask_irq,
 369        .irq_set_type = lpc32xx_set_irq_type,
 370        .irq_set_wake = lpc32xx_irq_wake
 371};
 372
 373static void lpc32xx_sic1_handler(struct irq_desc *desc)
 374{
 375        unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE));
 376
 377        while (ints != 0) {
 378                int irqno = fls(ints) - 1;
 379
 380                ints &= ~(1 << irqno);
 381
 382                generic_handle_irq(LPC32XX_SIC1_IRQ(irqno));
 383        }
 384}
 385
 386static void lpc32xx_sic2_handler(struct irq_desc *desc)
 387{
 388        unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE));
 389
 390        while (ints != 0) {
 391                int irqno = fls(ints) - 1;
 392
 393                ints &= ~(1 << irqno);
 394
 395                generic_handle_irq(LPC32XX_SIC2_IRQ(irqno));
 396        }
 397}
 398
 399static int __init __lpc32xx_mic_of_init(struct device_node *node,
 400                                        struct device_node *parent)
 401{
 402        lpc32xx_mic_np = node;
 403
 404        return 0;
 405}
 406
 407static const struct of_device_id mic_of_match[] __initconst = {
 408        { .compatible = "nxp,lpc3220-mic", .data = __lpc32xx_mic_of_init },
 409        { }
 410};
 411
 412void __init lpc32xx_init_irq(void)
 413{
 414        unsigned int i;
 415
 416        /* Setup MIC */
 417        __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
 418        __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE));
 419        __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE));
 420
 421        /* Setup SIC1 */
 422        __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
 423        __raw_writel(SIC1_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
 424        __raw_writel(SIC1_ATR_DEFAULT,
 425                                LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
 426
 427        /* Setup SIC2 */
 428        __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
 429        __raw_writel(SIC2_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
 430        __raw_writel(SIC2_ATR_DEFAULT,
 431                                LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
 432
 433        /* Configure supported IRQ's */
 434        for (i = 0; i < NR_IRQS; i++) {
 435                irq_set_chip_and_handler(i, &lpc32xx_irq_chip,
 436                                         handle_level_irq);
 437                irq_clear_status_flags(i, IRQ_NOREQUEST);
 438        }
 439
 440        /* Set default mappings */
 441        lpc32xx_set_default_mappings(MIC_APR_DEFAULT, MIC_ATR_DEFAULT, 0);
 442        lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32);
 443        lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64);
 444
 445        /* Initially disable all wake events */
 446        __raw_writel(0, LPC32XX_CLKPWR_P01_ER);
 447        __raw_writel(0, LPC32XX_CLKPWR_INT_ER);
 448        __raw_writel(0, LPC32XX_CLKPWR_PIN_ER);
 449
 450        /*
 451         * Default wake activation polarities, all pin sources are low edge
 452         * triggered
 453         */
 454        __raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT |
 455                LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT |
 456                LPC32XX_CLKPWR_INTSRC_RTC_BIT,
 457                LPC32XX_CLKPWR_INT_AP);
 458        __raw_writel(0, LPC32XX_CLKPWR_PIN_AP);
 459
 460        /* Clear latched wake event states */
 461        __raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS),
 462                LPC32XX_CLKPWR_PIN_RS);
 463        __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS),
 464                LPC32XX_CLKPWR_INT_RS);
 465
 466        of_irq_init(mic_of_match);
 467
 468        lpc32xx_mic_domain = irq_domain_add_legacy(lpc32xx_mic_np, NR_IRQS,
 469                                                   0, 0, &irq_domain_simple_ops,
 470                                                   NULL);
 471        if (!lpc32xx_mic_domain)
 472                panic("Unable to add MIC irq domain\n");
 473
 474        /* MIC SUBIRQx interrupts will route handling to the chain handlers */
 475        irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
 476        irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
 477}
 478