1// SPDX-License-Identifier: GPL-2.0 2/* 3 * H8/300H interrupt controller driver 4 * 5 * Copyright 2015 Yoshinori Sato <ysato@users.sourceforge.jp> 6 */ 7 8#include <linux/init.h> 9#include <linux/irq.h> 10#include <linux/irqchip.h> 11#include <linux/of_address.h> 12#include <linux/of_irq.h> 13#include <asm/io.h> 14 15static const char ipr_bit[] = { 16 7, 6, 5, 5, 17 4, 4, 4, 4, 3, 3, 3, 3, 18 2, 2, 2, 2, 1, 1, 1, 1, 19 0, 0, 0, 0, 15, 15, 15, 15, 20 14, 14, 14, 14, 13, 13, 13, 13, 21 -1, -1, -1, -1, 11, 11, 11, 11, 22 10, 10, 10, 10, 9, 9, 9, 9, 23}; 24 25static void __iomem *intc_baseaddr; 26 27#define IPR (intc_baseaddr + 6) 28 29static void h8300h_disable_irq(struct irq_data *data) 30{ 31 int bit; 32 int irq = data->irq - 12; 33 34 bit = ipr_bit[irq]; 35 if (bit >= 0) { 36 if (bit < 8) 37 ctrl_bclr(bit & 7, IPR); 38 else 39 ctrl_bclr(bit & 7, (IPR+1)); 40 } 41} 42 43static void h8300h_enable_irq(struct irq_data *data) 44{ 45 int bit; 46 int irq = data->irq - 12; 47 48 bit = ipr_bit[irq]; 49 if (bit >= 0) { 50 if (bit < 8) 51 ctrl_bset(bit & 7, IPR); 52 else 53 ctrl_bset(bit & 7, (IPR+1)); 54 } 55} 56 57struct irq_chip h8300h_irq_chip = { 58 .name = "H8/300H-INTC", 59 .irq_enable = h8300h_enable_irq, 60 .irq_disable = h8300h_disable_irq, 61}; 62 63static int irq_map(struct irq_domain *h, unsigned int virq, 64 irq_hw_number_t hw_irq_num) 65{ 66 irq_set_chip_and_handler(virq, &h8300h_irq_chip, handle_simple_irq); 67 68 return 0; 69} 70 71static const struct irq_domain_ops irq_ops = { 72 .map = irq_map, 73 .xlate = irq_domain_xlate_onecell, 74}; 75 76static int __init h8300h_intc_of_init(struct device_node *intc, 77 struct device_node *parent) 78{ 79 struct irq_domain *domain; 80 81 intc_baseaddr = of_iomap(intc, 0); 82 BUG_ON(!intc_baseaddr); 83 84 /* All interrupt priority low */ 85 writeb(0x00, IPR + 0); 86 writeb(0x00, IPR + 1); 87 88 domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, NULL); 89 BUG_ON(!domain); 90 irq_set_default_host(domain); 91 return 0; 92} 93 94IRQCHIP_DECLARE(h8300h_intc, "renesas,h8300h-intc", h8300h_intc_of_init); 95