linux/drivers/irqchip/irq-or1k-pic.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
   3 * Copyright (C) 2014 Stefan Kristansson <stefan.kristiansson@saunalahti.fi>
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License
   7 * as published by the Free Software Foundation; either version
   8 * 2 of the License, or (at your option) any later version.
   9 */
  10
  11#include <linux/irq.h>
  12#include <linux/irqchip.h>
  13#include <linux/of.h>
  14#include <linux/of_irq.h>
  15#include <linux/of_address.h>
  16
  17/* OR1K PIC implementation */
  18
  19struct or1k_pic_dev {
  20        struct irq_chip chip;
  21        irq_flow_handler_t handle;
  22        unsigned long flags;
  23};
  24
  25/*
  26 * We're a couple of cycles faster than the generic implementations with
  27 * these 'fast' versions.
  28 */
  29
  30static void or1k_pic_mask(struct irq_data *data)
  31{
  32        mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
  33}
  34
  35static void or1k_pic_unmask(struct irq_data *data)
  36{
  37        mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->hwirq));
  38}
  39
  40static void or1k_pic_ack(struct irq_data *data)
  41{
  42        mtspr(SPR_PICSR, (1UL << data->hwirq));
  43}
  44
  45static void or1k_pic_mask_ack(struct irq_data *data)
  46{
  47        mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
  48        mtspr(SPR_PICSR, (1UL << data->hwirq));
  49}
  50
  51/*
  52 * There are two oddities with the OR1200 PIC implementation:
  53 * i)  LEVEL-triggered interrupts are latched and need to be cleared
  54 * ii) the interrupt latch is cleared by writing a 0 to the bit,
  55 *     as opposed to a 1 as mandated by the spec
  56 */
  57static void or1k_pic_or1200_ack(struct irq_data *data)
  58{
  59        mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
  60}
  61
  62static void or1k_pic_or1200_mask_ack(struct irq_data *data)
  63{
  64        mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
  65        mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
  66}
  67
  68static struct or1k_pic_dev or1k_pic_level = {
  69        .chip = {
  70                .name = "or1k-PIC-level",
  71                .irq_unmask = or1k_pic_unmask,
  72                .irq_mask = or1k_pic_mask,
  73                .irq_mask_ack = or1k_pic_mask_ack,
  74        },
  75        .handle = handle_level_irq,
  76        .flags = IRQ_LEVEL | IRQ_NOPROBE,
  77};
  78
  79static struct or1k_pic_dev or1k_pic_edge = {
  80        .chip = {
  81                .name = "or1k-PIC-edge",
  82                .irq_unmask = or1k_pic_unmask,
  83                .irq_mask = or1k_pic_mask,
  84                .irq_ack = or1k_pic_ack,
  85                .irq_mask_ack = or1k_pic_mask_ack,
  86        },
  87        .handle = handle_edge_irq,
  88        .flags = IRQ_LEVEL | IRQ_NOPROBE,
  89};
  90
  91static struct or1k_pic_dev or1k_pic_or1200 = {
  92        .chip = {
  93                .name = "or1200-PIC",
  94                .irq_unmask = or1k_pic_unmask,
  95                .irq_mask = or1k_pic_mask,
  96                .irq_ack = or1k_pic_or1200_ack,
  97                .irq_mask_ack = or1k_pic_or1200_mask_ack,
  98        },
  99        .handle = handle_level_irq,
 100        .flags = IRQ_LEVEL | IRQ_NOPROBE,
 101};
 102
 103static struct irq_domain *root_domain;
 104
 105static inline int pic_get_irq(int first)
 106{
 107        int hwirq;
 108
 109        hwirq = ffs(mfspr(SPR_PICSR) >> first);
 110        if (!hwirq)
 111                return NO_IRQ;
 112        else
 113                hwirq = hwirq + first - 1;
 114
 115        return hwirq;
 116}
 117
 118static void or1k_pic_handle_irq(struct pt_regs *regs)
 119{
 120        int irq = -1;
 121
 122        while ((irq = pic_get_irq(irq + 1)) != NO_IRQ)
 123                handle_domain_irq(root_domain, irq, regs);
 124}
 125
 126static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 127{
 128        struct or1k_pic_dev *pic = d->host_data;
 129
 130        irq_set_chip_and_handler(irq, &pic->chip, pic->handle);
 131        irq_set_status_flags(irq, pic->flags);
 132
 133        return 0;
 134}
 135
 136static const struct irq_domain_ops or1k_irq_domain_ops = {
 137        .xlate = irq_domain_xlate_onecell,
 138        .map = or1k_map,
 139};
 140
 141/*
 142 * This sets up the IRQ domain for the PIC built in to the OpenRISC
 143 * 1000 CPU.  This is the "root" domain as these are the interrupts
 144 * that directly trigger an exception in the CPU.
 145 */
 146static int __init or1k_pic_init(struct device_node *node,
 147                                 struct or1k_pic_dev *pic)
 148{
 149        /* Disable all interrupts until explicitly requested */
 150        mtspr(SPR_PICMR, (0UL));
 151
 152        root_domain = irq_domain_add_linear(node, 32, &or1k_irq_domain_ops,
 153                                            pic);
 154
 155        set_handle_irq(or1k_pic_handle_irq);
 156
 157        return 0;
 158}
 159
 160static int __init or1k_pic_or1200_init(struct device_node *node,
 161                                       struct device_node *parent)
 162{
 163        return or1k_pic_init(node, &or1k_pic_or1200);
 164}
 165IRQCHIP_DECLARE(or1k_pic_or1200, "opencores,or1200-pic", or1k_pic_or1200_init);
 166IRQCHIP_DECLARE(or1k_pic, "opencores,or1k-pic", or1k_pic_or1200_init);
 167
 168static int __init or1k_pic_level_init(struct device_node *node,
 169                                      struct device_node *parent)
 170{
 171        return or1k_pic_init(node, &or1k_pic_level);
 172}
 173IRQCHIP_DECLARE(or1k_pic_level, "opencores,or1k-pic-level",
 174                or1k_pic_level_init);
 175
 176static int __init or1k_pic_edge_init(struct device_node *node,
 177                                     struct device_node *parent)
 178{
 179        return or1k_pic_init(node, &or1k_pic_edge);
 180}
 181IRQCHIP_DECLARE(or1k_pic_edge, "opencores,or1k-pic-edge", or1k_pic_edge_init);
 182