提交 dec0029a 编写于 作者: L Linus Torvalds

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
...@@ -41,8 +41,15 @@ config ARM_GIC_V3 ...@@ -41,8 +41,15 @@ config ARM_GIC_V3
config ARM_GIC_V3_ITS config ARM_GIC_V3_ITS
bool bool
select GENERIC_MSI_IRQ_DOMAIN
default ARM_GIC_V3
config ARM_GIC_V3_ITS_PCI
bool
depends on ARM_GIC_V3_ITS
depends on PCI depends on PCI
depends on PCI_MSI depends on PCI_MSI
default ARM_GIC_V3_ITS
config ARM_NVIC config ARM_NVIC
bool bool
......
...@@ -30,7 +30,8 @@ obj-$(CONFIG_ARM_GIC_PM) += irq-gic-pm.o ...@@ -30,7 +30,8 @@ obj-$(CONFIG_ARM_GIC_PM) += irq-gic-pm.o
obj-$(CONFIG_ARCH_REALVIEW) += irq-gic-realview.o obj-$(CONFIG_ARCH_REALVIEW) += irq-gic-realview.o
obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o
obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o
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 obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o
obj-$(CONFIG_ARM_GIC_V3_ITS_PCI) += irq-gic-v3-its-pci-msi.o
obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o
obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o
obj-$(CONFIG_ARM_NVIC) += irq-nvic.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
......
...@@ -1103,18 +1103,18 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) ...@@ -1103,18 +1103,18 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
int nr_parts; int nr_parts;
struct partition_affinity *parts; struct partition_affinity *parts;
parts_node = of_find_node_by_name(gic_node, "ppi-partitions"); parts_node = of_get_child_by_name(gic_node, "ppi-partitions");
if (!parts_node) if (!parts_node)
return; return;
nr_parts = of_get_child_count(parts_node); nr_parts = of_get_child_count(parts_node);
if (!nr_parts) if (!nr_parts)
return; goto out_put_node;
parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL); parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL);
if (WARN_ON(!parts)) if (WARN_ON(!parts))
return; goto out_put_node;
for_each_child_of_node(parts_node, child_part) { for_each_child_of_node(parts_node, child_part) {
struct partition_affinity *part; struct partition_affinity *part;
...@@ -1181,6 +1181,9 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) ...@@ -1181,6 +1181,9 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
gic_data.ppi_descs[i] = desc; gic_data.ppi_descs[i] = desc;
} }
out_put_node:
of_node_put(parts_node);
} }
static void __init gic_of_setup_kvm_info(struct device_node *node) 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,7 +1526,7 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
err = gic_validate_dist_version(acpi_data.dist_base); err = gic_validate_dist_version(acpi_data.dist_base);
if (err) { if (err) {
pr_err("No distributor detected at @%p, giving up", pr_err("No distributor detected at @%p, giving up\n",
acpi_data.dist_base); acpi_data.dist_base);
goto out_dist_unmap; goto out_dist_unmap;
} }
......
...@@ -177,6 +177,7 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map) ...@@ -177,6 +177,7 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map)
.map = map, .map = map,
}, },
}; };
int ret;
/* /*
* The host will never see that interrupt firing again, so it * 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,7 +185,11 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map)
*/ */
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
return irq_set_vcpu_affinity(irq, &info); ret = irq_set_vcpu_affinity(irq, &info);
if (ret)
irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY);
return ret;
} }
int its_get_vlpi(int irq, struct its_vlpi_map *map) int its_get_vlpi(int irq, struct its_vlpi_map *map)
......
...@@ -325,7 +325,7 @@ static int pdc_intc_probe(struct platform_device *pdev) ...@@ -325,7 +325,7 @@ static int pdc_intc_probe(struct platform_device *pdev)
/* Ioremap the registers */ /* Ioremap the registers */
priv->pdc_base = devm_ioremap(&pdev->dev, res_regs->start, priv->pdc_base = devm_ioremap(&pdev->dev, res_regs->start,
res_regs->end - res_regs->start); resource_size(res_regs));
if (!priv->pdc_base) if (!priv->pdc_base)
return -EIO; return -EIO;
......
...@@ -156,7 +156,7 @@ static int s3c_irq_type(struct irq_data *data, unsigned int type) ...@@ -156,7 +156,7 @@ static int s3c_irq_type(struct irq_data *data, unsigned int type)
irq_set_handler(data->irq, handle_level_irq); irq_set_handler(data->irq, handle_level_irq);
break; break;
default: default:
pr_err("No such irq type %d", type); pr_err("No such irq type %d\n", type);
return -EINVAL; return -EINVAL;
} }
...@@ -204,7 +204,7 @@ static int s3c_irqext_type_set(void __iomem *gpcon_reg, ...@@ -204,7 +204,7 @@ static int s3c_irqext_type_set(void __iomem *gpcon_reg,
break; break;
default: default:
pr_err("No such irq type %d", type); pr_err("No such irq type %d\n", type);
return -EINVAL; return -EINVAL;
} }
......
...@@ -196,8 +196,8 @@ static int __init exiu_init(struct device_node *node, ...@@ -196,8 +196,8 @@ static int __init exiu_init(struct device_node *node,
} }
data->base = of_iomap(node, 0); data->base = of_iomap(node, 0);
if (IS_ERR(data->base)) { if (!data->base) {
err = PTR_ERR(data->base); err = -ENODEV;
goto out_free; goto out_free;
} }
......
...@@ -238,7 +238,7 @@ static int __init combiner_probe(struct platform_device *pdev) ...@@ -238,7 +238,7 @@ static int __init combiner_probe(struct platform_device *pdev)
{ {
struct combiner *combiner; struct combiner *combiner;
size_t alloc_sz; size_t alloc_sz;
u32 nregs; int nregs;
int err; int err;
nregs = count_registers(pdev); nregs = count_registers(pdev);
......
...@@ -211,6 +211,7 @@ struct irq_data { ...@@ -211,6 +211,7 @@ struct irq_data {
* IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity * IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity
* mask. Applies only to affinity managed irqs. * mask. Applies only to affinity managed irqs.
* IRQD_SINGLE_TARGET - IRQ allows only a single affinity target * IRQD_SINGLE_TARGET - IRQ allows only a single affinity target
* IRQD_DEFAULT_TRIGGER_SET - Expected trigger already been set
*/ */
enum { enum {
IRQD_TRIGGER_MASK = 0xf, IRQD_TRIGGER_MASK = 0xf,
...@@ -231,6 +232,7 @@ enum { ...@@ -231,6 +232,7 @@ enum {
IRQD_IRQ_STARTED = (1 << 22), IRQD_IRQ_STARTED = (1 << 22),
IRQD_MANAGED_SHUTDOWN = (1 << 23), IRQD_MANAGED_SHUTDOWN = (1 << 23),
IRQD_SINGLE_TARGET = (1 << 24), IRQD_SINGLE_TARGET = (1 << 24),
IRQD_DEFAULT_TRIGGER_SET = (1 << 25),
}; };
#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) #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,18 +262,25 @@ static inline void irqd_mark_affinity_was_set(struct irq_data *d)
__irqd_to_state(d) |= IRQD_AFFINITY_SET; __irqd_to_state(d) |= IRQD_AFFINITY_SET;
} }
static inline bool irqd_trigger_type_was_set(struct irq_data *d)
{
return __irqd_to_state(d) & IRQD_DEFAULT_TRIGGER_SET;
}
static inline u32 irqd_get_trigger_type(struct irq_data *d) static inline u32 irqd_get_trigger_type(struct irq_data *d)
{ {
return __irqd_to_state(d) & IRQD_TRIGGER_MASK; return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
} }
/* /*
* Must only be called inside irq_chip.irq_set_type() functions. * Must only be called inside irq_chip.irq_set_type() functions or
* from the DT/ACPI setup code.
*/ */
static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
{ {
__irqd_to_state(d) &= ~IRQD_TRIGGER_MASK; __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
__irqd_to_state(d) |= type & IRQD_TRIGGER_MASK; __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
__irqd_to_state(d) |= IRQD_DEFAULT_TRIGGER_SET;
} }
static inline bool irqd_is_level_type(struct irq_data *d) static inline bool irqd_is_level_type(struct irq_data *d)
......
...@@ -109,6 +109,7 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map); ...@@ -109,6 +109,7 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map);
int its_unmap_vlpi(int irq); int its_unmap_vlpi(int irq);
int its_prop_update_vlpi(int irq, u8 config, bool inv); int its_prop_update_vlpi(int irq, u8 config, bool inv);
struct irq_domain_ops;
int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *ops); int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *ops);
#endif #endif
...@@ -1246,7 +1246,18 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) ...@@ -1246,7 +1246,18 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
* set the trigger type must match. Also all must * set the trigger type must match. Also all must
* agree on ONESHOT. * agree on ONESHOT.
*/ */
unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data); unsigned int oldtype;
/*
* If nobody did set the configuration before, inherit
* the one provided by the requester.
*/
if (irqd_trigger_type_was_set(&desc->irq_data)) {
oldtype = irqd_get_trigger_type(&desc->irq_data);
} else {
oldtype = new->flags & IRQF_TRIGGER_MASK;
irqd_set_trigger_type(&desc->irq_data, oldtype);
}
if (!((old->flags & new->flags) & IRQF_SHARED) || if (!((old->flags & new->flags) & IRQF_SHARED) ||
(oldtype != (new->flags & IRQF_TRIGGER_MASK)) || (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
......
...@@ -384,7 +384,7 @@ unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown) ...@@ -384,7 +384,7 @@ unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown)
{ {
struct cpumap *cm = this_cpu_ptr(m->maps); struct cpumap *cm = this_cpu_ptr(m->maps);
return m->global_available - cpudown ? cm->available : 0; return (m->global_available - cpudown) ? cm->available : 0;
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册