Skip to content

Commit

Permalink
Merge tag 'irqchip-4.15-4' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/maz/arm-platforms into irq/urgent

Pull irqchip updates for 4.15, take #4 from Marc Zyngier

 - A core irq fix for legacy cases where the irq trigger is not reported
   by firmware

 - A couple of GICv3/4 fixes (Kconfig, of-node refcount, error handling)

 - Trivial pr_err fixes
  • Loading branch information
KAGA-KOKO committed Nov 14, 2017
2 parents b29c6ef + 29f4113 commit 41cc304
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 10 deletions.
7 changes: 7 additions & 0 deletions drivers/irqchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,15 @@ config ARM_GIC_V3

config ARM_GIC_V3_ITS
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_MSI
default ARM_GIC_V3_ITS

config ARM_NVIC
bool
Expand Down
3 changes: 2 additions & 1 deletion drivers/irqchip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ obj-$(CONFIG_ARM_GIC_PM) += irq-gic-pm.o
obj-$(CONFIG_ARCH_REALVIEW) += irq-gic-realview.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_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_HISILICON_IRQ_MBIGEN) += irq-mbigen.o
obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
Expand Down
11 changes: 7 additions & 4 deletions drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1103,18 +1103,18 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
int nr_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)
return;

nr_parts = of_get_child_count(parts_node);

if (!nr_parts)
return;
goto out_put_node;

parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL);
if (WARN_ON(!parts))
return;
goto out_put_node;

for_each_child_of_node(parts_node, child_part) {
struct partition_affinity *part;
Expand Down Expand Up @@ -1181,6 +1181,9 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)

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)
Expand Down Expand Up @@ -1521,7 +1524,7 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)

err = gic_validate_dist_version(acpi_data.dist_base);
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);
goto out_dist_unmap;
}
Expand Down
7 changes: 6 additions & 1 deletion drivers/irqchip/irq-gic-v4.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,19 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map)
.map = map,
},
};
int ret;

/*
* The host will never see that interrupt firing again, so it
* is vital that we don't do any lazy masking.
*/
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)
Expand Down
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-s3c24xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static int s3c_irq_type(struct irq_data *data, unsigned int type)
irq_set_handler(data->irq, handle_level_irq);
break;
default:
pr_err("No such irq type %d", type);
pr_err("No such irq type %d\n", type);
return -EINVAL;
}

Expand Down Expand Up @@ -204,7 +204,7 @@ static int s3c_irqext_type_set(void __iomem *gpcon_reg,
break;

default:
pr_err("No such irq type %d", type);
pr_err("No such irq type %d\n", type);
return -EINVAL;
}

Expand Down
11 changes: 10 additions & 1 deletion include/linux/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ struct irq_data {
* IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity
* mask. Applies only to affinity managed irqs.
* IRQD_SINGLE_TARGET - IRQ allows only a single affinity target
* IRQD_DEFAULT_TRIGGER_SET - Expected trigger already been set
*/
enum {
IRQD_TRIGGER_MASK = 0xf,
Expand All @@ -231,6 +232,7 @@ enum {
IRQD_IRQ_STARTED = (1 << 22),
IRQD_MANAGED_SHUTDOWN = (1 << 23),
IRQD_SINGLE_TARGET = (1 << 24),
IRQD_DEFAULT_TRIGGER_SET = (1 << 25),
};

#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
Expand Down Expand Up @@ -260,18 +262,25 @@ static inline void irqd_mark_affinity_was_set(struct irq_data *d)
__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)
{
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)
{
__irqd_to_state(d) &= ~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)
Expand Down
1 change: 1 addition & 0 deletions include/linux/irqchip/arm-gic-v4.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map);
int its_unmap_vlpi(int irq);
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);

#endif
13 changes: 12 additions & 1 deletion kernel/irq/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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) ||
(oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
Expand Down

0 comments on commit 41cc304

Please sign in to comment.