IRQCHIP_DECLARE(google_gf_pic, "google,goldfish-pic", goldfish_pic_of_init);
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/interrupt.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#define GFPIC_REG_IRQ_PENDING 0x04
#define GFPIC_REG_IRQ_DISABLE_ALL 0x08
#define GFPIC_REG_IRQ_DISABLE 0x0c
#define GFPIC_REG_IRQ_ENABLE 0x10
struct goldfish_pic_data {
struct irq_domain *irq_domain;
static void goldfish_pic_cascade(struct irq_desc *desc)
struct goldfish_pic_data *gfpic = irq_desc_get_handler_data(desc);
struct irq_chip *host_chip = irq_desc_get_chip(desc);
u32 pending, hwirq, virq;
chained_irq_enter(host_chip, desc);
pending = readl(gfpic->base + GFPIC_REG_IRQ_PENDING);
virq = irq_linear_revmap(gfpic->irq_domain, hwirq);
generic_handle_irq(virq);
pending &= ~(1 << hwirq);
chained_irq_exit(host_chip, desc);
static const struct irq_domain_ops goldfish_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
static int __init goldfish_pic_of_init(struct device_node *of_node,
struct device_node *parent)
struct goldfish_pic_data *gfpic;