android_kernel_xiaomi_sm7250/include/linux/of_irq.h
Stephen Boyd a323430753 ANDROID: GKI: of: irq: add helper to remap interrupts to another irqdomain
Sometimes interrupts are routed from an interrupt controller to another
in no specific order. Having these in the drives makes it difficult to
maintain when the same drivers supports multiple variants with different
mapping. Also, specifying them in DT makes little sense with a
bunch of numbers like -
	<0, 13>, <5, 32>,
It makes more sense when we can have the parent handle along with
interrupt specifiers for the incoming interrupt as well as that of the
outgoing interrupt like -
	<22 0 &intc 36 0>,
	<24 0 &intc 37 0>,
	<26 0 &intc 38 0>,
And the interrupt specifiers can be interpreted using these properties -
	irqdomain-map-mask = <0xff 0>;
	irqdomain-map-pass-thru = <0 0xff>;

Let's add a helper function to parse this from DT.

Bug: 150637369
Change-Id: Idb3d698ff1d5353d8efc316e21700a1be4ffc542
Patch-mainline: https://lore.kernel.org/patchwork/patch/1026606
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Lina Iyer <ilina@codeaurora.org>
Signed-off-by: Will McVicker <willmcvicker@google.com>
(cherry picked from commit 0303182e48)
2020-03-09 11:32:04 -07:00

120 lines
3.7 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __OF_IRQ_H
#define __OF_IRQ_H
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/ioport.h>
#include <linux/of.h>
typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
/*
* Workarounds only applied to 32bit powermac machines
*/
#define OF_IMAP_OLDWORLD_MAC 0x00000001
#define OF_IMAP_NO_PHANDLE 0x00000002
#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
extern unsigned int of_irq_workarounds;
extern struct device_node *of_irq_dflt_pic;
extern int of_irq_parse_oldworld(struct device_node *device, int index,
struct of_phandle_args *out_irq);
#else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
#define of_irq_workarounds (0)
#define of_irq_dflt_pic (NULL)
static inline int of_irq_parse_oldworld(struct device_node *device, int index,
struct of_phandle_args *out_irq)
{
return -EINVAL;
}
#endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
extern int of_irq_domain_map(const struct irq_fwspec *in, struct irq_fwspec *out);
extern int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq);
extern int of_irq_parse_one(struct device_node *device, int index,
struct of_phandle_args *out_irq);
extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data);
extern int of_irq_to_resource(struct device_node *dev, int index,
struct resource *r);
extern void of_irq_init(const struct of_device_id *matches);
#ifdef CONFIG_OF_IRQ
extern int of_irq_count(struct device_node *dev);
extern int of_irq_get(struct device_node *dev, int index);
extern int of_irq_get_byname(struct device_node *dev, const char *name);
extern int of_irq_to_resource_table(struct device_node *dev,
struct resource *res, int nr_irqs);
extern struct device_node *of_irq_find_parent(struct device_node *child);
extern struct irq_domain *of_msi_get_domain(struct device *dev,
struct device_node *np,
enum irq_domain_bus_token token);
extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
u32 rid);
extern void of_msi_configure(struct device *dev, struct device_node *np);
u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
#else
static inline int of_irq_count(struct device_node *dev)
{
return 0;
}
static inline int of_irq_get(struct device_node *dev, int index)
{
return 0;
}
static inline int of_irq_get_byname(struct device_node *dev, const char *name)
{
return 0;
}
static inline int of_irq_to_resource_table(struct device_node *dev,
struct resource *res, int nr_irqs)
{
return 0;
}
static inline void *of_irq_find_parent(struct device_node *child)
{
return NULL;
}
static inline struct irq_domain *of_msi_get_domain(struct device *dev,
struct device_node *np,
enum irq_domain_bus_token token)
{
return NULL;
}
static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
u32 rid)
{
return NULL;
}
static inline void of_msi_configure(struct device *dev, struct device_node *np)
{
}
static inline u32 of_msi_map_rid(struct device *dev,
struct device_node *msi_np, u32 rid_in)
{
return rid_in;
}
#endif
#if defined(CONFIG_OF_IRQ) || defined(CONFIG_SPARC)
/*
* irq_of_parse_and_map() is used by 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);
#else /* !CONFIG_OF && !CONFIG_SPARC */
static inline unsigned int irq_of_parse_and_map(struct device_node *dev,
int index)
{
return 0;
}
#endif /* !CONFIG_OF */
#endif /* __OF_IRQ_H */