kernel: bump 4.9 to 4.9.146
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.9 / 811-irqchip-support-layerscape.patch
1 From dab02a7cc54494740e849cd51b554d100eb5541d Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Thu, 5 Jul 2018 17:36:09 +0800
4 Subject: [PATCH 23/32] irqchip: support layerscape
5
6 This is an integrated patch for layerscape gic support.
7
8 Signed-off-by: Eric Auger <eric.auger@redhat.com>
9 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
10 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
11 ---
12 drivers/irqchip/Makefile | 1 +
13 drivers/irqchip/irq-gic-v3-its.c | 1 +
14 include/linux/irqchip/arm-gic-v3.h | 3 +++
15 include/linux/irqdomain.h | 36 +++++++++++++++++++++++++++
16 kernel/irq/irqdomain.c | 39 ++++++++++++++++++++++++++++++
17 kernel/irq/msi.c | 4 +--
18 6 files changed, 82 insertions(+), 2 deletions(-)
19
20 --- a/drivers/irqchip/Makefile
21 +++ b/drivers/irqchip/Makefile
22 @@ -75,3 +75,4 @@ obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scf
23 obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
24 obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o
25 obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o
26 +obj-$(CONFIG_QUICC_ENGINE) += irq-qeic.o
27 --- a/drivers/irqchip/irq-gic-v3-its.c
28 +++ b/drivers/irqchip/irq-gic-v3-its.c
29 @@ -1658,6 +1658,7 @@ static int its_init_domain(struct fwnode
30
31 inner_domain->parent = its_parent;
32 inner_domain->bus_token = DOMAIN_BUS_NEXUS;
33 + inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
34 info->ops = &its_msi_domain_ops;
35 info->data = its;
36 inner_domain->host_data = info;
37 --- a/include/linux/irqchip/arm-gic-v3.h
38 +++ b/include/linux/irqchip/arm-gic-v3.h
39 @@ -133,6 +133,9 @@
40 #define GIC_BASER_SHAREABILITY(reg, type) \
41 (GIC_BASER_##type << reg##_SHAREABILITY_SHIFT)
42
43 +/* encode a size field of width @w containing @n - 1 units */
44 +#define GIC_ENCODE_SZ(n, w) (((unsigned long)(n) - 1) & GENMASK_ULL(((w) - 1), 0))
45 +
46 #define GICR_PROPBASER_SHAREABILITY_SHIFT (10)
47 #define GICR_PROPBASER_INNER_CACHEABILITY_SHIFT (7)
48 #define GICR_PROPBASER_OUTER_CACHEABILITY_SHIFT (56)
49 --- a/include/linux/irqdomain.h
50 +++ b/include/linux/irqdomain.h
51 @@ -187,6 +187,12 @@ enum {
52 /* Irq domain is an IPI domain with single virq */
53 IRQ_DOMAIN_FLAG_IPI_SINGLE = (1 << 3),
54
55 + /* Irq domain implements MSIs */
56 + IRQ_DOMAIN_FLAG_MSI = (1 << 4),
57 +
58 + /* Irq domain implements MSI remapping */
59 + IRQ_DOMAIN_FLAG_MSI_REMAP = (1 << 5),
60 +
61 /*
62 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
63 * for implementation specific purposes and ignored by the
64 @@ -220,6 +226,7 @@ struct irq_domain *irq_domain_add_legacy
65 void *host_data);
66 extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
67 enum irq_domain_bus_token bus_token);
68 +extern bool irq_domain_check_msi_remap(void);
69 extern void irq_set_default_host(struct irq_domain *host);
70 extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
71 irq_hw_number_t hwirq, int node,
72 @@ -453,6 +460,19 @@ static inline bool irq_domain_is_ipi_sin
73 {
74 return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
75 }
76 +
77 +static inline bool irq_domain_is_msi(struct irq_domain *domain)
78 +{
79 + return domain->flags & IRQ_DOMAIN_FLAG_MSI;
80 +}
81 +
82 +static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
83 +{
84 + return domain->flags & IRQ_DOMAIN_FLAG_MSI_REMAP;
85 +}
86 +
87 +extern bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain);
88 +
89 #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
90 static inline void irq_domain_activate_irq(struct irq_data *data) { }
91 static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
92 @@ -484,6 +504,22 @@ static inline bool irq_domain_is_ipi_sin
93 {
94 return false;
95 }
96 +
97 +static inline bool irq_domain_is_msi(struct irq_domain *domain)
98 +{
99 + return false;
100 +}
101 +
102 +static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
103 +{
104 + return false;
105 +}
106 +
107 +static inline bool
108 +irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
109 +{
110 + return false;
111 +}
112 #endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
113
114 #else /* CONFIG_IRQ_DOMAIN */
115 --- a/kernel/irq/irqdomain.c
116 +++ b/kernel/irq/irqdomain.c
117 @@ -319,6 +319,31 @@ struct irq_domain *irq_find_matching_fws
118 EXPORT_SYMBOL_GPL(irq_find_matching_fwspec);
119
120 /**
121 + * irq_domain_check_msi_remap - Check whether all MSI irq domains implement
122 + * IRQ remapping
123 + *
124 + * Return: false if any MSI irq domain does not support IRQ remapping,
125 + * true otherwise (including if there is no MSI irq domain)
126 + */
127 +bool irq_domain_check_msi_remap(void)
128 +{
129 + struct irq_domain *h;
130 + bool ret = true;
131 +
132 + mutex_lock(&irq_domain_mutex);
133 + list_for_each_entry(h, &irq_domain_list, link) {
134 + if (irq_domain_is_msi(h) &&
135 + !irq_domain_hierarchical_is_msi_remap(h)) {
136 + ret = false;
137 + break;
138 + }
139 + }
140 + mutex_unlock(&irq_domain_mutex);
141 + return ret;
142 +}
143 +EXPORT_SYMBOL_GPL(irq_domain_check_msi_remap);
144 +
145 +/**
146 * irq_set_default_host() - Set a "default" irq domain
147 * @domain: default domain pointer
148 *
149 @@ -1420,6 +1445,20 @@ static void irq_domain_check_hierarchy(s
150 if (domain->ops->alloc)
151 domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY;
152 }
153 +
154 +/**
155 + * irq_domain_hierarchical_is_msi_remap - Check if the domain or any
156 + * parent has MSI remapping support
157 + * @domain: domain pointer
158 + */
159 +bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
160 +{
161 + for (; domain; domain = domain->parent) {
162 + if (irq_domain_is_msi_remap(domain))
163 + return true;
164 + }
165 + return false;
166 +}
167 #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
168 /**
169 * irq_domain_get_irq_data - Get irq_data associated with @virq and @domain
170 --- a/kernel/irq/msi.c
171 +++ b/kernel/irq/msi.c
172 @@ -272,8 +272,8 @@ struct irq_domain *msi_create_irq_domain
173 if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
174 msi_domain_update_chip_ops(info);
175
176 - return irq_domain_create_hierarchy(parent, 0, 0, fwnode,
177 - &msi_domain_ops, info);
178 + return irq_domain_create_hierarchy(parent, IRQ_DOMAIN_FLAG_MSI, 0,
179 + fwnode, &msi_domain_ops, info);
180 }
181
182 int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,