irqchip updates for 4.15, take #4
- 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 -----BEGIN PGP SIGNATURE----- iQJJBAABCAAzFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAloJ2UYVHG1hcmMuenlu Z2llckBhcm0uY29tAAoJECPQ0LrRPXpDtkcP/i2HrgT5CmoA315h5HLXfFImxZwg YG7ti3zqu1TM7HXNlfBgSltqiU5UgYOd2KjgUR+w30t1239DwxVdtoy6ZgGWXlfe xmHlXAiEDkqaAV3P/RHKkl8xRDkyWhKmfY1ym/So0J68EPytuiZiT4wJZO39u/xk Gi2fW38gywl4bEb9MA48noEnkNkr93DjJfFyiPxPYiAaWeFRoP+X5l171kTpCdSv sT5hfQvfsz7mQZVecMBwGg6QuWnlUplkzPb4lNhuk/tJTU97vf3Py8abzeiGqBMa 5NoH9PUMZs0L8kv6DgR2DEOmhmmk0+mwO7VWVT3eVtYoxSS8oW0i2OzgB9kCOy8+ LZi+M0fMSL6hiAgwlV5YrHYvsVl2rGjCNAqC+q2ggpW4XH9Kql2caki331mGqAyr qDeI0SWaABz5c9ajtsfQ78T0FE70xwIJ5TT1RmtKt2LFCpJjBacjK3vUST2ypIrF k0AJTmBwEefKNvxTrjkZtenblCVo92lT+boAv7HuI612NicVSBEsK7S+96kGlGMw KNi+cwGriJRWIbsn+VMpLFGyPgEmWQ1p/4Z/tkwSevqOl/k8KrNw6+VoyDS1PmJU gIQ0hh8wMnm2l9VGJARc0+pHKr0KYN52j+jZI5+OGNKKAZ0jGYI4t2JiemtOwmet q2KNdm6mvBYUYirj =/8DQ -----END PGP SIGNATURE----- Merge tag 'irqchip-4.15-4' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
Коммит
41cc30412d
|
@ -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
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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);
|
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)
|
||||||
.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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
|
|
|
@ -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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
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)
|
||||||
__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);
|
||||||
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)
|
||||||
* 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)) ||
|
||||||
|
|
Загрузка…
Ссылка в новой задаче