root/drivers/irqchip/irq-or1k-pic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. or1k_pic_mask
  2. or1k_pic_unmask
  3. or1k_pic_ack
  4. or1k_pic_mask_ack
  5. or1k_pic_or1200_ack
  6. or1k_pic_or1200_mask_ack
  7. pic_get_irq
  8. or1k_pic_handle_irq
  9. or1k_map
  10. or1k_pic_init
  11. or1k_pic_or1200_init
  12. or1k_pic_level_init
  13. or1k_pic_edge_init

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

/* [<][>][^][v][top][bottom][index][help] */