Blame view

drivers/irqchip/irq-renesas-h8300h.c 1.9 KB
8a7644821   Yoshinori Sato   h8300: IRQ chip d...
1
2
3
4
5
6
7
8
9
10
11
12
  /*
   * H8/300H interrupt controller driver
   *
   * Copyright 2015 Yoshinori Sato <ysato@users.sourceforge.jp>
   */
  
  #include <linux/init.h>
  #include <linux/irq.h>
  #include <linux/irqchip.h>
  #include <linux/of_address.h>
  #include <linux/of_irq.h>
  #include <asm/io.h>
8a7644821   Yoshinori Sato   h8300: IRQ chip d...
13
14
15
16
17
18
19
20
21
  static const char ipr_bit[] = {
  	 7,  6,  5,  5,
  	 4,  4,  4,  4,  3,  3,  3,  3,
  	 2,  2,  2,  2,  1,  1,  1,  1,
  	 0,  0,  0,  0, 15, 15, 15, 15,
  	14, 14, 14, 14, 13, 13, 13, 13,
  	-1, -1, -1, -1, 11, 11, 11, 11,
  	10, 10, 10, 10,  9,  9,  9,  9,
  };
751605152   Daniel Lezcano   h8300: Rename ctl...
22
  static void __iomem *intc_baseaddr;
8a7644821   Yoshinori Sato   h8300: IRQ chip d...
23

751605152   Daniel Lezcano   h8300: Rename ctl...
24
  #define IPR (intc_baseaddr + 6)
8a7644821   Yoshinori Sato   h8300: IRQ chip d...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  
  static void h8300h_disable_irq(struct irq_data *data)
  {
  	int bit;
  	int irq = data->irq - 12;
  
  	bit = ipr_bit[irq];
  	if (bit >= 0) {
  		if (bit < 8)
  			ctrl_bclr(bit & 7, IPR);
  		else
  			ctrl_bclr(bit & 7, (IPR+1));
  	}
  }
  
  static void h8300h_enable_irq(struct irq_data *data)
  {
  	int bit;
  	int irq = data->irq - 12;
  
  	bit = ipr_bit[irq];
  	if (bit >= 0) {
  		if (bit < 8)
  			ctrl_bset(bit & 7, IPR);
  		else
  			ctrl_bset(bit & 7, (IPR+1));
  	}
  }
  
  struct irq_chip h8300h_irq_chip = {
  	.name		= "H8/300H-INTC",
  	.irq_enable	= h8300h_enable_irq,
  	.irq_disable	= h8300h_disable_irq,
  };
  
  static int irq_map(struct irq_domain *h, unsigned int virq,
  		   irq_hw_number_t hw_irq_num)
  {
         irq_set_chip_and_handler(virq, &h8300h_irq_chip, handle_simple_irq);
  
         return 0;
  }
  
  static struct irq_domain_ops irq_ops = {
         .map    = irq_map,
         .xlate  = irq_domain_xlate_onecell,
  };
  
  static int __init h8300h_intc_of_init(struct device_node *intc,
  				      struct device_node *parent)
  {
  	struct irq_domain *domain;
  
  	intc_baseaddr = of_iomap(intc, 0);
  	BUG_ON(!intc_baseaddr);
  
  	/* All interrupt priority low */
751605152   Daniel Lezcano   h8300: Rename ctl...
82
83
  	writeb(0x00, IPR + 0);
  	writeb(0x00, IPR + 1);
8a7644821   Yoshinori Sato   h8300: IRQ chip d...
84
85
86
87
88
89
90
91
  
  	domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, NULL);
  	BUG_ON(!domain);
  	irq_set_default_host(domain);
  	return 0;
  }
  
  IRQCHIP_DECLARE(h8300h_intc, "renesas,h8300h-intc", h8300h_intc_of_init);