Source
x
return irq_domain_alloc_irqs_parent(dom, virq, nr_irqs, &parent_fwspec);
/*
* Driver for Socionext External Interrupt Unit (EXIU)
*
* Copyright (c) 2017 Linaro, Ltd. <ard.biesheuvel@linaro.org>
*
* Based on irq-tegra.c:
* Copyright (C) 2011 Google, Inc.
* Copyright (C) 2010,2013, NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
struct exiu_irq_data {
void __iomem *base;
u32 spi_base;
};
static void exiu_irq_eoi(struct irq_data *d)
{
struct exiu_irq_data *data = irq_data_get_irq_chip_data(d);
writel(BIT(d->hwirq), data->base + EIREQCLR);
irq_chip_eoi_parent(d);
}
static void exiu_irq_mask(struct irq_data *d)
{
struct exiu_irq_data *data = irq_data_get_irq_chip_data(d);
u32 val;
val = readl_relaxed(data->base + EIMASK) | BIT(d->hwirq);
writel_relaxed(val, data->base + EIMASK);
irq_chip_mask_parent(d);
}
static void exiu_irq_unmask(struct irq_data *d)
{
struct exiu_irq_data *data = irq_data_get_irq_chip_data(d);
u32 val;
val = readl_relaxed(data->base + EIMASK) & ~BIT(d->hwirq);
writel_relaxed(val, data->base + EIMASK);
irq_chip_unmask_parent(d);
}
static void exiu_irq_enable(struct irq_data *d)
{
struct exiu_irq_data *data = irq_data_get_irq_chip_data(d);
u32 val;
/* clear interrupts that were latched while disabled */
writel_relaxed(BIT(d->hwirq), data->base + EIREQCLR);
val = readl_relaxed(data->base + EIMASK) & ~BIT(d->hwirq);
writel_relaxed(val, data->base + EIMASK);
irq_chip_enable_parent(d);
}
static int exiu_irq_set_type(struct irq_data *d, unsigned int type)
{
struct exiu_irq_data *data = irq_data_get_irq_chip_data(d);
u32 val;
val = readl_relaxed(data->base + EILVL);
if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH)
val |= BIT(d->hwirq);
else
val &= ~BIT(d->hwirq);