diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-26 17:39:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-26 17:39:20 -0500 |
commit | dec0029a59779d8279dde663ef8abe9824ee5773 (patch) | |
tree | f4958e8af2877fc5227f688727d22ce9ebf38939 | |
parent | 02fc87b117a9b9ec325089d098fce86ed11966bd (diff) | |
parent | 75f1133873d6a1276d3c19918b7c94975840f990 (diff) |
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Thomas Glexiner:
- unbreak the irq trigger type check for legacy platforms
- a handful fixes for ARM GIC v3/4 interrupt controllers
- a few trivial fixes all over the place
* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
genirq/matrix: Make - vs ?: Precedence explicit
irqchip/imgpdc: Use resource_size function on resource object
irqchip/qcom: Fix u32 comparison with value less than zero
irqchip/exiu: Fix return value check in exiu_init()
irqchip/gic-v3-its: Remove artificial dependency on PCI
irqchip/gic-v4: Add forward definition of struct irq_domain_ops
irqchip/gic-v3: pr_err() strings should end with newlines
irqchip/s3c24xx: pr_err() strings should end with newlines
irqchip/gic-v3: Fix ppi-partitions lookup
irqchip/gic-v4: Clear IRQ_DISABLE_UNLAZY again if mapping fails
genirq: Track whether the trigger type has been set
-rw-r--r-- | drivers/irqchip/Kconfig | 7 | ||||
-rw-r--r-- | drivers/irqchip/Makefile | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 11 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v4.c | 7 | ||||
-rw-r--r-- | drivers/irqchip/irq-imgpdc.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-s3c24xx.c | 4 | ||||
-rw-r--r-- | drivers/irqchip/irq-sni-exiu.c | 4 | ||||
-rw-r--r-- | drivers/irqchip/qcom-irq-combiner.c | 2 | ||||
-rw-r--r-- | include/linux/irq.h | 11 | ||||
-rw-r--r-- | include/linux/irqchip/arm-gic-v4.h | 1 | ||||
-rw-r--r-- | kernel/irq/manage.c | 13 | ||||
-rw-r--r-- | kernel/irq/matrix.c | 2 |
12 files changed, 52 insertions, 15 deletions
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 53380bd72ea4..c70476b34a53 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
@@ -41,8 +41,15 @@ config ARM_GIC_V3 | |||
41 | 41 | ||
42 | config ARM_GIC_V3_ITS | 42 | config ARM_GIC_V3_ITS |
43 | bool | 43 | bool |
44 | select GENERIC_MSI_IRQ_DOMAIN | ||
45 | default ARM_GIC_V3 | ||
46 | |||
47 | config ARM_GIC_V3_ITS_PCI | ||
48 | bool | ||
49 | depends on ARM_GIC_V3_ITS | ||
44 | depends on PCI | 50 | depends on PCI |
45 | depends on PCI_MSI | 51 | depends on PCI_MSI |
52 | default ARM_GIC_V3_ITS | ||
46 | 53 | ||
47 | config ARM_NVIC | 54 | config ARM_NVIC |
48 | bool | 55 | bool |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index dae7282bfdef..d2df34a54d38 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -30,7 +30,8 @@ obj-$(CONFIG_ARM_GIC_PM) += irq-gic-pm.o | |||
30 | obj-$(CONFIG_ARCH_REALVIEW) += irq-gic-realview.o | 30 | obj-$(CONFIG_ARCH_REALVIEW) += irq-gic-realview.o |
31 | obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o | 31 | obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o |
32 | obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o | 32 | obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o |
33 | obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o | 33 | obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o |
34 | obj-$(CONFIG_ARM_GIC_V3_ITS_PCI) += irq-gic-v3-its-pci-msi.o | ||
34 | obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o | 35 | obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o |
35 | obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o | 36 | obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o |
36 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o | 37 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 17221143f505..b56c3e23f0af 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -1103,18 +1103,18 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) | |||
1103 | int nr_parts; | 1103 | int nr_parts; |
1104 | struct partition_affinity *parts; | 1104 | struct partition_affinity *parts; |
1105 | 1105 | ||
1106 | parts_node = of_find_node_by_name(gic_node, "ppi-partitions"); | 1106 | parts_node = of_get_child_by_name(gic_node, "ppi-partitions"); |
1107 | if (!parts_node) | 1107 | if (!parts_node) |
1108 | return; | 1108 | return; |
1109 | 1109 | ||
1110 | nr_parts = of_get_child_count(parts_node); | 1110 | nr_parts = of_get_child_count(parts_node); |
1111 | 1111 | ||
1112 | if (!nr_parts) | 1112 | if (!nr_parts) |
1113 | return; | 1113 | goto out_put_node; |
1114 | 1114 | ||
1115 | parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL); | 1115 | parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL); |
1116 | if (WARN_ON(!parts)) | 1116 | if (WARN_ON(!parts)) |
1117 | return; | 1117 | goto out_put_node; |
1118 | 1118 | ||
1119 | for_each_child_of_node(parts_node, child_part) { | 1119 | for_each_child_of_node(parts_node, child_part) { |
1120 | struct partition_affinity *part; | 1120 | struct partition_affinity *part; |
@@ -1181,6 +1181,9 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) | |||
1181 | 1181 | ||
1182 | gic_data.ppi_descs[i] = desc; | 1182 | gic_data.ppi_descs[i] = desc; |
1183 | } | 1183 | } |
1184 | |||
1185 | out_put_node: | ||
1186 | of_node_put(parts_node); | ||
1184 | } | 1187 | } |
1185 | 1188 | ||
1186 | static void __init gic_of_setup_kvm_info(struct device_node *node) | 1189 | static void __init gic_of_setup_kvm_info(struct device_node *node) |
@@ -1523,7 +1526,7 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end) | |||
1523 | 1526 | ||
1524 | err = gic_validate_dist_version(acpi_data.dist_base); | 1527 | err = gic_validate_dist_version(acpi_data.dist_base); |
1525 | if (err) { | 1528 | if (err) { |
1526 | pr_err("No distributor detected at @%p, giving up", | 1529 | pr_err("No distributor detected at @%p, giving up\n", |
1527 | acpi_data.dist_base); | 1530 | acpi_data.dist_base); |
1528 | goto out_dist_unmap; | 1531 | goto out_dist_unmap; |
1529 | } | 1532 | } |
diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c index cd0bcc3b7e33..dba9d67cb9c1 100644 --- a/drivers/irqchip/irq-gic-v4.c +++ b/drivers/irqchip/irq-gic-v4.c | |||
@@ -177,6 +177,7 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map) | |||
177 | .map = map, | 177 | .map = map, |
178 | }, | 178 | }, |
179 | }; | 179 | }; |
180 | int ret; | ||
180 | 181 | ||
181 | /* | 182 | /* |
182 | * The host will never see that interrupt firing again, so it | 183 | * The host will never see that interrupt firing again, so it |
@@ -184,7 +185,11 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map) | |||
184 | */ | 185 | */ |
185 | irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); | 186 | irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); |
186 | 187 | ||
187 | return irq_set_vcpu_affinity(irq, &info); | 188 | ret = irq_set_vcpu_affinity(irq, &info); |
189 | if (ret) | ||
190 | irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY); | ||
191 | |||
192 | return ret; | ||
188 | } | 193 | } |
189 | 194 | ||
190 | int its_get_vlpi(int irq, struct its_vlpi_map *map) | 195 | int its_get_vlpi(int irq, struct its_vlpi_map *map) |
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c index 1f59998e03f8..e80263e16c4c 100644 --- a/drivers/irqchip/irq-imgpdc.c +++ b/drivers/irqchip/irq-imgpdc.c | |||
@@ -325,7 +325,7 @@ static int pdc_intc_probe(struct platform_device *pdev) | |||
325 | 325 | ||
326 | /* Ioremap the registers */ | 326 | /* Ioremap the registers */ |
327 | priv->pdc_base = devm_ioremap(&pdev->dev, res_regs->start, | 327 | priv->pdc_base = devm_ioremap(&pdev->dev, res_regs->start, |
328 | res_regs->end - res_regs->start); | 328 | resource_size(res_regs)); |
329 | if (!priv->pdc_base) | 329 | if (!priv->pdc_base) |
330 | return -EIO; | 330 | return -EIO; |
331 | 331 | ||
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c index c25ce5af091a..ec0e6a8cdb75 100644 --- a/drivers/irqchip/irq-s3c24xx.c +++ b/drivers/irqchip/irq-s3c24xx.c | |||
@@ -156,7 +156,7 @@ static int s3c_irq_type(struct irq_data *data, unsigned int type) | |||
156 | irq_set_handler(data->irq, handle_level_irq); | 156 | irq_set_handler(data->irq, handle_level_irq); |
157 | break; | 157 | break; |
158 | default: | 158 | default: |
159 | pr_err("No such irq type %d", type); | 159 | pr_err("No such irq type %d\n", type); |
160 | return -EINVAL; | 160 | return -EINVAL; |
161 | } | 161 | } |
162 | 162 | ||
@@ -204,7 +204,7 @@ static int s3c_irqext_type_set(void __iomem *gpcon_reg, | |||
204 | break; | 204 | break; |
205 | 205 | ||
206 | default: | 206 | default: |
207 | pr_err("No such irq type %d", type); | 207 | pr_err("No such irq type %d\n", type); |
208 | return -EINVAL; | 208 | return -EINVAL; |
209 | } | 209 | } |
210 | 210 | ||
diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c index 1b6e2f7c59af..1927b2f36ff6 100644 --- a/drivers/irqchip/irq-sni-exiu.c +++ b/drivers/irqchip/irq-sni-exiu.c | |||
@@ -196,8 +196,8 @@ static int __init exiu_init(struct device_node *node, | |||
196 | } | 196 | } |
197 | 197 | ||
198 | data->base = of_iomap(node, 0); | 198 | data->base = of_iomap(node, 0); |
199 | if (IS_ERR(data->base)) { | 199 | if (!data->base) { |
200 | err = PTR_ERR(data->base); | 200 | err = -ENODEV; |
201 | goto out_free; | 201 | goto out_free; |
202 | } | 202 | } |
203 | 203 | ||
diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c index 6aa3ea479214..f31265937439 100644 --- a/drivers/irqchip/qcom-irq-combiner.c +++ b/drivers/irqchip/qcom-irq-combiner.c | |||
@@ -238,7 +238,7 @@ static int __init combiner_probe(struct platform_device *pdev) | |||
238 | { | 238 | { |
239 | struct combiner *combiner; | 239 | struct combiner *combiner; |
240 | size_t alloc_sz; | 240 | size_t alloc_sz; |
241 | u32 nregs; | 241 | int nregs; |
242 | int err; | 242 | int err; |
243 | 243 | ||
244 | nregs = count_registers(pdev); | 244 | nregs = count_registers(pdev); |
diff --git a/include/linux/irq.h b/include/linux/irq.h index b01d06db9101..e140f69163b6 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -211,6 +211,7 @@ struct irq_data { | |||
211 | * IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity | 211 | * IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity |
212 | * mask. Applies only to affinity managed irqs. | 212 | * mask. Applies only to affinity managed irqs. |
213 | * IRQD_SINGLE_TARGET - IRQ allows only a single affinity target | 213 | * IRQD_SINGLE_TARGET - IRQ allows only a single affinity target |
214 | * IRQD_DEFAULT_TRIGGER_SET - Expected trigger already been set | ||
214 | */ | 215 | */ |
215 | enum { | 216 | enum { |
216 | IRQD_TRIGGER_MASK = 0xf, | 217 | IRQD_TRIGGER_MASK = 0xf, |
@@ -231,6 +232,7 @@ enum { | |||
231 | IRQD_IRQ_STARTED = (1 << 22), | 232 | IRQD_IRQ_STARTED = (1 << 22), |
232 | IRQD_MANAGED_SHUTDOWN = (1 << 23), | 233 | IRQD_MANAGED_SHUTDOWN = (1 << 23), |
233 | IRQD_SINGLE_TARGET = (1 << 24), | 234 | IRQD_SINGLE_TARGET = (1 << 24), |
235 | IRQD_DEFAULT_TRIGGER_SET = (1 << 25), | ||
234 | }; | 236 | }; |
235 | 237 | ||
236 | #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) | 238 | #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) |
@@ -260,18 +262,25 @@ static inline void irqd_mark_affinity_was_set(struct irq_data *d) | |||
260 | __irqd_to_state(d) |= IRQD_AFFINITY_SET; | 262 | __irqd_to_state(d) |= IRQD_AFFINITY_SET; |
261 | } | 263 | } |
262 | 264 | ||
265 | static inline bool irqd_trigger_type_was_set(struct irq_data *d) | ||
266 | { | ||
267 | return __irqd_to_state(d) & IRQD_DEFAULT_TRIGGER_SET; | ||
268 | } | ||
269 | |||
263 | static inline u32 irqd_get_trigger_type(struct irq_data *d) | 270 | static inline u32 irqd_get_trigger_type(struct irq_data *d) |
264 | { | 271 | { |
265 | return __irqd_to_state(d) & IRQD_TRIGGER_MASK; | 272 | return __irqd_to_state(d) & IRQD_TRIGGER_MASK; |
266 | } | 273 | } |
267 | 274 | ||
268 | /* | 275 | /* |
269 | * Must only be called inside irq_chip.irq_set_type() functions. | 276 | * Must only be called inside irq_chip.irq_set_type() functions or |
277 | * from the DT/ACPI setup code. | ||
270 | */ | 278 | */ |
271 | static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) | 279 | static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) |
272 | { | 280 | { |
273 | __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK; | 281 | __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK; |
274 | __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK; | 282 | __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK; |
283 | __irqd_to_state(d) |= IRQD_DEFAULT_TRIGGER_SET; | ||
275 | } | 284 | } |
276 | 285 | ||
277 | static inline bool irqd_is_level_type(struct irq_data *d) | 286 | static inline bool irqd_is_level_type(struct irq_data *d) |
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h index 447da8ca2156..fa683ea5c769 100644 --- a/include/linux/irqchip/arm-gic-v4.h +++ b/include/linux/irqchip/arm-gic-v4.h | |||
@@ -109,6 +109,7 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map); | |||
109 | int its_unmap_vlpi(int irq); | 109 | int its_unmap_vlpi(int irq); |
110 | int its_prop_update_vlpi(int irq, u8 config, bool inv); | 110 | int its_prop_update_vlpi(int irq, u8 config, bool inv); |
111 | 111 | ||
112 | struct irq_domain_ops; | ||
112 | int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *ops); | 113 | int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *ops); |
113 | 114 | ||
114 | #endif | 115 | #endif |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 2ff1c0c82fc9..0f922729bab9 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -1246,7 +1246,18 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1246 | * set the trigger type must match. Also all must | 1246 | * set the trigger type must match. Also all must |
1247 | * agree on ONESHOT. | 1247 | * agree on ONESHOT. |
1248 | */ | 1248 | */ |
1249 | unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data); | 1249 | unsigned int oldtype; |
1250 | |||
1251 | /* | ||
1252 | * If nobody did set the configuration before, inherit | ||
1253 | * the one provided by the requester. | ||
1254 | */ | ||
1255 | if (irqd_trigger_type_was_set(&desc->irq_data)) { | ||
1256 | oldtype = irqd_get_trigger_type(&desc->irq_data); | ||
1257 | } else { | ||
1258 | oldtype = new->flags & IRQF_TRIGGER_MASK; | ||
1259 | irqd_set_trigger_type(&desc->irq_data, oldtype); | ||
1260 | } | ||
1250 | 1261 | ||
1251 | if (!((old->flags & new->flags) & IRQF_SHARED) || | 1262 | if (!((old->flags & new->flags) & IRQF_SHARED) || |
1252 | (oldtype != (new->flags & IRQF_TRIGGER_MASK)) || | 1263 | (oldtype != (new->flags & IRQF_TRIGGER_MASK)) || |
diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index a3cbbc8191c5..7df2480005f8 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c | |||
@@ -384,7 +384,7 @@ unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown) | |||
384 | { | 384 | { |
385 | struct cpumap *cm = this_cpu_ptr(m->maps); | 385 | struct cpumap *cm = this_cpu_ptr(m->maps); |
386 | 386 | ||
387 | return m->global_available - cpudown ? cm->available : 0; | 387 | return (m->global_available - cpudown) ? cm->available : 0; |
388 | } | 388 | } |
389 | 389 | ||
390 | /** | 390 | /** |