IRQ fixes
Subsystems (9)
Linus,
Please pull the latest irq-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus
# HEAD: c5b635203032462603c503ecce91a7021c1ad44a irqchip/mxs: Add missing set_handle_irq()
Mostly driver fixes, but also an irq core crash fix and a build fix.
Thanks,
Ingo
------------------>
Arnd Bergmann (1):
irqchip/s3c24xx: Mark init_eint as __maybe_unused
Marc Zyngier (3):
irqdomain: Allow domain lookup with DOMAIN_BUS_WIRED token
of: MSI: Simplify irqdomain lookup
irqchip/gic-v3-its: Recompute the number of pages on page size change
Milo Kim (1):
irqchip/atmel-aic: Fix wrong bit operation for IRQ priority
Oleksij Rempel (1):
irqchip/mxs: Add missing set_handle_irq()
Richard Weinberger (1):
irqchip: Fix dependencies for archs w/o HAS_IOMEM
Thomas Gleixner (1):
genirq: Validate action before dereferencing it in handle_irq_event_percpu()
Thomas Petazzoni (1):
base: Export platform_msi_domain_[alloc,free]_irqs
drivers/base/platform-msi.c | 2 ++ drivers/irqchip/Kconfig | 1 + drivers/irqchip/irq-atmel-aic-common.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 8 ++++++-- drivers/irqchip/irq-mxs.c | 1 + drivers/irqchip/irq-s3c24xx.c | 2 +- drivers/of/irq.c | 18 +++--------------- include/linux/irqdomain.h | 1 + kernel/irq/handle.c | 5 +++-- kernel/irq/irqdomain.c | 11 ++++++++--- 10 files changed, 27 insertions(+), 24 deletions(-)
drivers/base/platform-msi.c +2 -0
@@ -284,6 +284,7 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,return err; } +EXPORT_SYMBOL_GPL (platform_msi_domain_alloc_irqs);/** * platform_msi_domain_free_irqs - Free MSI interrupts for @dev
@@ -301,6 +302,7 @@ void platform_msi_domain_free_irqs(struct device *dev)msi_domain_free_irqs (dev->msi_domain, dev);platform_msi_free_descs (dev,0 ,MAX_DEV_MSIS ); } +EXPORT_SYMBOL_GPL (platform_msi_domain_free_irqs);/** * platform_msi_get_host_data - Query the private data associated with
drivers/irqchip/Kconfig +1 -0
@@ -154,6 +154,7 @@ config TB10X_IRQC config TS4800_IRQ tristate "TS-4800 IRQ controller" select IRQ_DOMAIN + depends on HAS_IOMEM help Support for the TS-4800 FPGA IRQ controller
drivers/irqchip/irq-atmel-aic-common.c +1 -1
@@ -86,7 +86,7 @@ int aic_common_set_priority(int priority, unsigned *val) priority > AT91_AIC_IRQ_MAX_PRIORITY)return -EINVAL ; - *val &=AT91_AIC_PRIOR ; + *val &= ~AT91_AIC_PRIOR ; *val |= priority;return 0 ;
drivers/irqchip/irq-gic-v3-its.c +6 -2
@@ -875,6 +875,7 @@ static int its_alloc_tables(const char *node_name, struct its_node *its) } alloc_size = (1 << order) *PAGE_SIZE ; +retry_alloc_baser: alloc_pages = (alloc_size / psz);if (alloc_pages >GITS_BASER_PAGES_MAX ) { alloc_pages =GITS_BASER_PAGES_MAX ;
@@ -938,13 +939,16 @@ static int its_alloc_tables(const char *node_name, struct its_node *its)* size and retry. If we reach 4K, then * something is horribly wrong... */ +free_pages ((unsigned long )base, order); + its->tables[i] =NULL ; +switch (psz) {case SZ_16K : psz =SZ_4K ; - goto retry_baser; + goto retry_alloc_baser;case SZ_64K : psz =SZ_16K ; - goto retry_baser; + goto retry_alloc_baser; } }
drivers/irqchip/irq-mxs.c +1 -0
@@ -241,6 +241,7 @@ static int __init asm9260_of_init(struct device_node *np,writel (0 , icoll_priv.intr + i);icoll_add_domain (np,ASM9260_NUM_IRQS ); +set_handle_irq (icoll_handle_irq);return 0 ; }
drivers/irqchip/irq-s3c24xx.c +1 -1
@@ -605,7 +605,7 @@ static struct s3c_irq_intc * __init s3c24xx_init_intc(struct device_node *np,return ERR_PTR (ret); } -static struct s3c_irq_data init_eint[32 ] = { +static struct s3c_irq_data __maybe_unused init_eint[32 ] = { { .type =S3C_IRQTYPE_NONE , },/* reserved */ { .type =S3C_IRQTYPE_NONE , },/* reserved */ { .type =S3C_IRQTYPE_NONE , },/* reserved */
drivers/of/irq.c +3 -15
@@ -680,18 +680,6 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)return __of_msi_map_rid (dev, &msi_np, rid_in); } -static struct irq_domain *__of_get_msi_domain (struct device_node *np, -enum irq_domain_bus_token token) -{ -struct irq_domain *d; - - d =irq_find_matching_host (np, token); -if (!d) - d =irq_find_host (np); - -return d; -} -/** * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain * @dev: device for which the mapping is to be done.
@@ -707,7 +695,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid)struct device_node *np =NULL ;__of_msi_map_rid (dev, &np, rid); -return __of_get_msi_domain (np,DOMAIN_BUS_PCI_MSI ); +return irq_find_matching_host (np,DOMAIN_BUS_PCI_MSI ); }/**
@@ -731,7 +719,7 @@ struct irq_domain *of_msi_get_domain(struct device *dev,/* Check for a single msi-parent property */ msi_np =of_parse_phandle (np,"msi-parent" ,0 );if (msi_np && !of_property_read_bool (msi_np,"#msi-cells" )) { - d =__of_get_msi_domain (msi_np, token); + d =irq_find_matching_host (msi_np, token);if (!d)of_node_put (msi_np);return d;
@@ -745,7 +733,7 @@ struct irq_domain *of_msi_get_domain(struct device *dev,while (!of_parse_phandle_with_args (np,"msi-parent" ,"#msi-cells" , index, &args)) { - d =__of_get_msi_domain (args.np, token); + d =irq_find_matching_host (args.np, token);if (d)return d;
include/linux/irqdomain.h +1 -0
@@ -70,6 +70,7 @@ struct irq_fwspec {*/ enum irq_domain_bus_token {DOMAIN_BUS_ANY =0 , +DOMAIN_BUS_WIRED ,DOMAIN_BUS_PCI_MSI ,DOMAIN_BUS_PLATFORM_MSI ,DOMAIN_BUS_NEXUS ,
kernel/irq/handle.c +3 -2
@@ -138,7 +138,8 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)unsigned int flags =0 , irq = desc->irq_data.irq;struct irqaction *action = desc->action; - do { +/* action might have become NULL since we dropped the lock */ +while (action) {irqreturn_t res;trace_irq_handler_entry (irq, action);
@@ -173,7 +174,7 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc) retval |= res; action = action->next; - }while (action); + }add_interrupt_randomness (irq, flags);
kernel/irq/irqdomain.c +8 -3
@@ -575,10 +575,15 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)unsigned int type =IRQ_TYPE_NONE ;int virq; -if (fwspec->fwnode) - domain =irq_find_matching_fwnode (fwspec->fwnode,DOMAIN_BUS_ANY ); -else +if (fwspec->fwnode) { + domain =irq_find_matching_fwnode (fwspec->fwnode, +DOMAIN_BUS_WIRED ); +if (!domain) + domain =irq_find_matching_fwnode (fwspec->fwnode, +DOMAIN_BUS_ANY ); + }else { domain = irq_default_domain; + }if (!domain) { pr_warn("no irq domain found for %s !\n",