0001
0002
0003
0004
0005
0006
0007 #include <linux/irq.h>
0008 #include <linux/irqchip.h>
0009 #include <linux/of.h>
0010 #include <linux/of_irq.h>
0011 #include <linux/of_address.h>
0012
0013
0014
0015 struct or1k_pic_dev {
0016 struct irq_chip chip;
0017 irq_flow_handler_t handle;
0018 unsigned long flags;
0019 };
0020
0021
0022
0023
0024
0025
0026 static void or1k_pic_mask(struct irq_data *data)
0027 {
0028 mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
0029 }
0030
0031 static void or1k_pic_unmask(struct irq_data *data)
0032 {
0033 mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->hwirq));
0034 }
0035
0036 static void or1k_pic_ack(struct irq_data *data)
0037 {
0038 mtspr(SPR_PICSR, (1UL << data->hwirq));
0039 }
0040
0041 static void or1k_pic_mask_ack(struct irq_data *data)
0042 {
0043 mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
0044 mtspr(SPR_PICSR, (1UL << data->hwirq));
0045 }
0046
0047
0048
0049
0050
0051
0052
0053 static void or1k_pic_or1200_ack(struct irq_data *data)
0054 {
0055 mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
0056 }
0057
0058 static void or1k_pic_or1200_mask_ack(struct irq_data *data)
0059 {
0060 mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
0061 mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
0062 }
0063
0064 static struct or1k_pic_dev or1k_pic_level = {
0065 .chip = {
0066 .name = "or1k-PIC-level",
0067 .irq_unmask = or1k_pic_unmask,
0068 .irq_mask = or1k_pic_mask,
0069 },
0070 .handle = handle_level_irq,
0071 .flags = IRQ_LEVEL | IRQ_NOPROBE,
0072 };
0073
0074 static struct or1k_pic_dev or1k_pic_edge = {
0075 .chip = {
0076 .name = "or1k-PIC-edge",
0077 .irq_unmask = or1k_pic_unmask,
0078 .irq_mask = or1k_pic_mask,
0079 .irq_ack = or1k_pic_ack,
0080 .irq_mask_ack = or1k_pic_mask_ack,
0081 },
0082 .handle = handle_edge_irq,
0083 .flags = IRQ_LEVEL | IRQ_NOPROBE,
0084 };
0085
0086 static struct or1k_pic_dev or1k_pic_or1200 = {
0087 .chip = {
0088 .name = "or1200-PIC",
0089 .irq_unmask = or1k_pic_unmask,
0090 .irq_mask = or1k_pic_mask,
0091 .irq_ack = or1k_pic_or1200_ack,
0092 .irq_mask_ack = or1k_pic_or1200_mask_ack,
0093 },
0094 .handle = handle_level_irq,
0095 .flags = IRQ_LEVEL | IRQ_NOPROBE,
0096 };
0097
0098 static struct irq_domain *root_domain;
0099
0100 static inline int pic_get_irq(int first)
0101 {
0102 int hwirq;
0103
0104 hwirq = ffs(mfspr(SPR_PICSR) >> first);
0105 if (!hwirq)
0106 return NO_IRQ;
0107 else
0108 hwirq = hwirq + first - 1;
0109
0110 return hwirq;
0111 }
0112
0113 static void or1k_pic_handle_irq(struct pt_regs *regs)
0114 {
0115 int irq = -1;
0116
0117 while ((irq = pic_get_irq(irq + 1)) != NO_IRQ)
0118 generic_handle_domain_irq(root_domain, irq);
0119 }
0120
0121 static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
0122 {
0123 struct or1k_pic_dev *pic = d->host_data;
0124
0125 irq_set_chip_and_handler(irq, &pic->chip, pic->handle);
0126 irq_set_status_flags(irq, pic->flags);
0127
0128 return 0;
0129 }
0130
0131 static const struct irq_domain_ops or1k_irq_domain_ops = {
0132 .xlate = irq_domain_xlate_onecell,
0133 .map = or1k_map,
0134 };
0135
0136
0137
0138
0139
0140
0141 static int __init or1k_pic_init(struct device_node *node,
0142 struct or1k_pic_dev *pic)
0143 {
0144
0145 mtspr(SPR_PICMR, (0UL));
0146
0147 root_domain = irq_domain_add_linear(node, 32, &or1k_irq_domain_ops,
0148 pic);
0149
0150 set_handle_irq(or1k_pic_handle_irq);
0151
0152 return 0;
0153 }
0154
0155 static int __init or1k_pic_or1200_init(struct device_node *node,
0156 struct device_node *parent)
0157 {
0158 return or1k_pic_init(node, &or1k_pic_or1200);
0159 }
0160 IRQCHIP_DECLARE(or1k_pic_or1200, "opencores,or1200-pic", or1k_pic_or1200_init);
0161 IRQCHIP_DECLARE(or1k_pic, "opencores,or1k-pic", or1k_pic_or1200_init);
0162
0163 static int __init or1k_pic_level_init(struct device_node *node,
0164 struct device_node *parent)
0165 {
0166 return or1k_pic_init(node, &or1k_pic_level);
0167 }
0168 IRQCHIP_DECLARE(or1k_pic_level, "opencores,or1k-pic-level",
0169 or1k_pic_level_init);
0170
0171 static int __init or1k_pic_edge_init(struct device_node *node,
0172 struct device_node *parent)
0173 {
0174 return or1k_pic_init(node, &or1k_pic_edge);
0175 }
0176 IRQCHIP_DECLARE(or1k_pic_edge, "opencores,or1k-pic-edge", or1k_pic_edge_init);