forked from Minki/linux
of/irq: Move irq_of_parse_and_map() to common code
Merge common code between PowerPC and Microblaze. SPARC implements irq_of_parse_and_map(), but the implementation is different, so it does not use this code. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Michal Simek <monstr@monstr.eu> Cc: "David S. Miller" <davem@davemloft.net> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: Jeremy Kerr <jeremy.kerr@canonical.com>
This commit is contained in:
parent
b505ff5e72
commit
e387344499
@ -27,17 +27,6 @@ extern unsigned int nr_irq;
|
|||||||
struct pt_regs;
|
struct pt_regs;
|
||||||
extern void do_IRQ(struct pt_regs *regs);
|
extern void do_IRQ(struct pt_regs *regs);
|
||||||
|
|
||||||
/**
|
|
||||||
* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
|
|
||||||
* @device: Device node of the device whose interrupt is to be mapped
|
|
||||||
* @index: Index of the interrupt to map
|
|
||||||
*
|
|
||||||
* This function is a wrapper that chains of_irq_map_one() and
|
|
||||||
* irq_create_of_mapping() to make things easier to callers
|
|
||||||
*/
|
|
||||||
struct device_node;
|
|
||||||
extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
|
|
||||||
|
|
||||||
/** FIXME - not implement
|
/** FIXME - not implement
|
||||||
* irq_dispose_mapping - Unmap an interrupt
|
* irq_dispose_mapping - Unmap an interrupt
|
||||||
* @virq: linux virq number of the interrupt to unmap
|
* @virq: linux virq number of the interrupt to unmap
|
||||||
@ -62,17 +51,4 @@ struct irq_host;
|
|||||||
extern unsigned int irq_create_mapping(struct irq_host *host,
|
extern unsigned int irq_create_mapping(struct irq_host *host,
|
||||||
irq_hw_number_t hwirq);
|
irq_hw_number_t hwirq);
|
||||||
|
|
||||||
/**
|
|
||||||
* irq_create_of_mapping - Map a hardware interrupt into linux virq space
|
|
||||||
* @controller: Device node of the interrupt controller
|
|
||||||
* @inspec: Interrupt specifier from the device-tree
|
|
||||||
* @intsize: Size of the interrupt specifier from the device-tree
|
|
||||||
*
|
|
||||||
* This function is identical to irq_create_mapping except that it takes
|
|
||||||
* as input informations straight from the device-tree (typically the results
|
|
||||||
* of the of_irq_map_*() functions.
|
|
||||||
*/
|
|
||||||
extern unsigned int irq_create_of_mapping(struct device_node *controller,
|
|
||||||
u32 *intspec, unsigned int intsize);
|
|
||||||
|
|
||||||
#endif /* _ASM_MICROBLAZE_IRQ_H */
|
#endif /* _ASM_MICROBLAZE_IRQ_H */
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
#include <linux/of_fdt.h>
|
#include <linux/of_fdt.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
@ -92,18 +93,6 @@ extern const void *of_get_mac_address(struct device_node *np);
|
|||||||
* OF interrupt mapping
|
* OF interrupt mapping
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This structure is returned when an interrupt is mapped. The controller
|
|
||||||
* field needs to be put() after use
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
|
|
||||||
|
|
||||||
struct of_irq {
|
|
||||||
struct device_node *controller; /* Interrupt controller node */
|
|
||||||
u32 size; /* Specifier size */
|
|
||||||
u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* of_irq_map_init - Initialize the irq remapper
|
* of_irq_map_init - Initialize the irq remapper
|
||||||
* @flags: flags defining workarounds to enable
|
* @flags: flags defining workarounds to enable
|
||||||
@ -138,19 +127,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
|
|||||||
u32 ointsize, const u32 *addr,
|
u32 ointsize, const u32 *addr,
|
||||||
struct of_irq *out_irq);
|
struct of_irq *out_irq);
|
||||||
|
|
||||||
/**
|
|
||||||
* of_irq_map_one - Resolve an interrupt for a device
|
|
||||||
* @device: the device whose interrupt is to be resolved
|
|
||||||
* @index: index of the interrupt to resolve
|
|
||||||
* @out_irq: structure of_irq filled by this function
|
|
||||||
*
|
|
||||||
* This function resolves an interrupt, walking the tree, for a given
|
|
||||||
* device-tree node. It's the high level pendant to of_irq_map_raw().
|
|
||||||
* It also implements the workarounds for OldWolrd Macs.
|
|
||||||
*/
|
|
||||||
extern int of_irq_map_one(struct device_node *device, int index,
|
|
||||||
struct of_irq *out_irq);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
||||||
* @pdev: the device whose interrupt is to be resolved
|
* @pdev: the device whose interrupt is to be resolved
|
||||||
|
@ -17,20 +17,10 @@
|
|||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/kernel_stat.h>
|
#include <linux/kernel_stat.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
|
|
||||||
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
|
|
||||||
{
|
|
||||||
struct of_irq oirq;
|
|
||||||
|
|
||||||
if (of_irq_map_one(dev, index, &oirq))
|
|
||||||
return NO_IRQ;
|
|
||||||
|
|
||||||
return oirq.specifier[0];
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
|
|
||||||
|
|
||||||
static u32 concurrent_irq;
|
static u32 concurrent_irq;
|
||||||
|
|
||||||
void __irq_entry do_IRQ(struct pt_regs *regs)
|
void __irq_entry do_IRQ(struct pt_regs *regs)
|
||||||
@ -104,7 +94,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
|
|||||||
EXPORT_SYMBOL_GPL(irq_create_mapping);
|
EXPORT_SYMBOL_GPL(irq_create_mapping);
|
||||||
|
|
||||||
unsigned int irq_create_of_mapping(struct device_node *controller,
|
unsigned int irq_create_of_mapping(struct device_node *controller,
|
||||||
u32 *intspec, unsigned int intsize)
|
const u32 *intspec, unsigned int intsize)
|
||||||
{
|
{
|
||||||
return intspec[0];
|
return intspec[0];
|
||||||
}
|
}
|
||||||
|
@ -300,34 +300,6 @@ extern unsigned int irq_alloc_virt(struct irq_host *host,
|
|||||||
*/
|
*/
|
||||||
extern void irq_free_virt(unsigned int virq, unsigned int count);
|
extern void irq_free_virt(unsigned int virq, unsigned int count);
|
||||||
|
|
||||||
|
|
||||||
/* -- OF helpers -- */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* irq_create_of_mapping - Map a hardware interrupt into linux virq space
|
|
||||||
* @controller: Device node of the interrupt controller
|
|
||||||
* @inspec: Interrupt specifier from the device-tree
|
|
||||||
* @intsize: Size of the interrupt specifier from the device-tree
|
|
||||||
*
|
|
||||||
* This function is identical to irq_create_mapping except that it takes
|
|
||||||
* as input informations straight from the device-tree (typically the results
|
|
||||||
* of the of_irq_map_*() functions.
|
|
||||||
*/
|
|
||||||
extern unsigned int irq_create_of_mapping(struct device_node *controller,
|
|
||||||
const u32 *intspec, unsigned int intsize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
|
|
||||||
* @device: Device node of the device whose interrupt is to be mapped
|
|
||||||
* @index: Index of the interrupt to map
|
|
||||||
*
|
|
||||||
* This function is a wrapper that chains of_irq_map_one() and
|
|
||||||
* irq_create_of_mapping() to make things easier to callers
|
|
||||||
*/
|
|
||||||
extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
|
|
||||||
|
|
||||||
/* -- End OF helpers -- */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* irq_early_init - Init irq remapping subsystem
|
* irq_early_init - Init irq remapping subsystem
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/of_fdt.h>
|
#include <linux/of_fdt.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
@ -108,18 +109,6 @@ extern const void *of_get_mac_address(struct device_node *np);
|
|||||||
* OF interrupt mapping
|
* OF interrupt mapping
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This structure is returned when an interrupt is mapped. The controller
|
|
||||||
* field needs to be put() after use
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
|
|
||||||
|
|
||||||
struct of_irq {
|
|
||||||
struct device_node *controller; /* Interrupt controller node */
|
|
||||||
u32 size; /* Specifier size */
|
|
||||||
u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* of_irq_map_init - Initialize the irq remapper
|
* of_irq_map_init - Initialize the irq remapper
|
||||||
* @flags: flags defining workarounds to enable
|
* @flags: flags defining workarounds to enable
|
||||||
@ -154,20 +143,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
|
|||||||
u32 ointsize, const u32 *addr,
|
u32 ointsize, const u32 *addr,
|
||||||
struct of_irq *out_irq);
|
struct of_irq *out_irq);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* of_irq_map_one - Resolve an interrupt for a device
|
|
||||||
* @device: the device whose interrupt is to be resolved
|
|
||||||
* @index: index of the interrupt to resolve
|
|
||||||
* @out_irq: structure of_irq filled by this function
|
|
||||||
*
|
|
||||||
* This function resolves an interrupt, walking the tree, for a given
|
|
||||||
* device-tree node. It's the high level pendant to of_irq_map_raw().
|
|
||||||
* It also implements the workarounds for OldWolrd Macs.
|
|
||||||
*/
|
|
||||||
extern int of_irq_map_one(struct device_node *device, int index,
|
|
||||||
struct of_irq *out_irq);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
||||||
* @pdev: the device whose interrupt is to be resolved
|
* @pdev: the device whose interrupt is to be resolved
|
||||||
|
@ -53,6 +53,8 @@
|
|||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
@ -813,18 +815,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
|
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
|
||||||
|
|
||||||
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
|
|
||||||
{
|
|
||||||
struct of_irq oirq;
|
|
||||||
|
|
||||||
if (of_irq_map_one(dev, index, &oirq))
|
|
||||||
return NO_IRQ;
|
|
||||||
|
|
||||||
return irq_create_of_mapping(oirq.controller, oirq.specifier,
|
|
||||||
oirq.size);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
|
|
||||||
|
|
||||||
void irq_dispose_mapping(unsigned int virq)
|
void irq_dispose_mapping(unsigned int virq)
|
||||||
{
|
{
|
||||||
struct irq_host *host;
|
struct irq_host *host;
|
||||||
|
@ -56,7 +56,6 @@ extern void of_fill_in_cpu_data(void);
|
|||||||
* register them in the of_device objects, whereas powerpc computes them
|
* register them in the of_device objects, whereas powerpc computes them
|
||||||
* on request.
|
* on request.
|
||||||
*/
|
*/
|
||||||
extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
|
|
||||||
static inline void irq_dispose_mapping(unsigned int virq)
|
static inline void irq_dispose_mapping(unsigned int virq)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,10 @@ config OF_DYNAMIC
|
|||||||
def_bool y
|
def_bool y
|
||||||
depends on OF && PPC_OF
|
depends on OF && PPC_OF
|
||||||
|
|
||||||
|
config OF_IRQ
|
||||||
|
def_bool y
|
||||||
|
depends on OF && !SPARC
|
||||||
|
|
||||||
config OF_DEVICE
|
config OF_DEVICE
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on OF && (SPARC || PPC_OF || MICROBLAZE)
|
depends on OF && (SPARC || PPC_OF || MICROBLAZE)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
obj-y = base.o
|
obj-y = base.o
|
||||||
obj-$(CONFIG_OF_FLATTREE) += fdt.o
|
obj-$(CONFIG_OF_FLATTREE) += fdt.o
|
||||||
|
obj-$(CONFIG_OF_IRQ) += irq.o
|
||||||
obj-$(CONFIG_OF_DEVICE) += device.o platform.o
|
obj-$(CONFIG_OF_DEVICE) += device.o platform.o
|
||||||
obj-$(CONFIG_OF_GPIO) += gpio.o
|
obj-$(CONFIG_OF_GPIO) += gpio.o
|
||||||
obj-$(CONFIG_OF_I2C) += of_i2c.o
|
obj-$(CONFIG_OF_I2C) += of_i2c.o
|
||||||
|
45
drivers/of/irq.c
Normal file
45
drivers/of/irq.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Derived from arch/i386/kernel/irq.c
|
||||||
|
* Copyright (C) 1992 Linus Torvalds
|
||||||
|
* Adapted from arch/i386 by Gary Thomas
|
||||||
|
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||||
|
* Updated and modified by Cort Dougan <cort@fsmlabs.com>
|
||||||
|
* Copyright (C) 1996-2001 Cort Dougan
|
||||||
|
* Adapted for Power Macintosh by Paul Mackerras
|
||||||
|
* Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This file contains the code used to make IRQ descriptions in the
|
||||||
|
* device tree to actual irq numbers on an interrupt controller
|
||||||
|
* driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* irq_of_parse_and_map - Parse and map an interrupt into linux virq space
|
||||||
|
* @device: Device node of the device whose interrupt is to be mapped
|
||||||
|
* @index: Index of the interrupt to map
|
||||||
|
*
|
||||||
|
* This function is a wrapper that chains of_irq_map_one() and
|
||||||
|
* irq_create_of_mapping() to make things easier to callers
|
||||||
|
*/
|
||||||
|
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
|
||||||
|
{
|
||||||
|
struct of_irq oirq;
|
||||||
|
|
||||||
|
if (of_irq_map_one(dev, index, &oirq))
|
||||||
|
return NO_IRQ;
|
||||||
|
|
||||||
|
return irq_create_of_mapping(oirq.controller, oirq.specifier,
|
||||||
|
oirq.size);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
|
@ -15,6 +15,7 @@
|
|||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
#include <linux/of_mdio.h>
|
#include <linux/of_mdio.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
#include <linux/of_spi.h>
|
#include <linux/of_spi.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
41
include/linux/of_irq.h
Normal file
41
include/linux/of_irq.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef __OF_IRQ_H
|
||||||
|
#define __OF_IRQ_H
|
||||||
|
|
||||||
|
#if defined(CONFIG_OF)
|
||||||
|
struct of_irq;
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* irq_of_parse_and_map() is used ba all OF enabled platforms; but SPARC
|
||||||
|
* implements it differently. However, the prototype is the same for all,
|
||||||
|
* so declare it here regardless of the CONFIG_OF_IRQ setting.
|
||||||
|
*/
|
||||||
|
extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
|
||||||
|
|
||||||
|
#if defined(CONFIG_OF_IRQ)
|
||||||
|
/**
|
||||||
|
* of_irq - container for device_node/irq_specifier pair for an irq controller
|
||||||
|
* @controller: pointer to interrupt controller device tree node
|
||||||
|
* @size: size of interrupt specifier
|
||||||
|
* @specifier: array of cells @size long specifing the specific interrupt
|
||||||
|
*
|
||||||
|
* This structure is returned when an interrupt is mapped. The controller
|
||||||
|
* field needs to be put() after use
|
||||||
|
*/
|
||||||
|
#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
|
||||||
|
struct of_irq {
|
||||||
|
struct device_node *controller; /* Interrupt controller node */
|
||||||
|
u32 size; /* Specifier size */
|
||||||
|
u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int of_irq_map_one(struct device_node *device, int index,
|
||||||
|
struct of_irq *out_irq);
|
||||||
|
extern unsigned int irq_create_of_mapping(struct device_node *controller,
|
||||||
|
const u32 *intspec,
|
||||||
|
unsigned int intsize);
|
||||||
|
|
||||||
|
#endif /* CONFIG_OF_IRQ */
|
||||||
|
#endif /* CONFIG_OF */
|
||||||
|
#endif /* __OF_IRQ_H */
|
Loading…
Reference in New Issue
Block a user