mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 03:23:53 -04:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
243 lines
5.8 KiB
C
243 lines
5.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright 2015-2016 Vladimir Zapolskiy <vz@mleia.com>
|
|
*/
|
|
|
|
#define pr_fmt(fmt) "%s: " fmt, __func__
|
|
|
|
#include <linux/io.h>
|
|
#include <linux/irqchip.h>
|
|
#include <linux/irqchip/chained_irq.h>
|
|
#include <linux/of_address.h>
|
|
#include <linux/of_irq.h>
|
|
#include <linux/of_platform.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/slab.h>
|
|
#include <asm/exception.h>
|
|
|
|
#define LPC32XX_INTC_MASK 0x00
|
|
#define LPC32XX_INTC_RAW 0x04
|
|
#define LPC32XX_INTC_STAT 0x08
|
|
#define LPC32XX_INTC_POL 0x0C
|
|
#define LPC32XX_INTC_TYPE 0x10
|
|
#define LPC32XX_INTC_FIQ 0x14
|
|
|
|
#define NR_LPC32XX_IC_IRQS 32
|
|
|
|
struct lpc32xx_irq_chip {
|
|
void __iomem *base;
|
|
phys_addr_t addr;
|
|
struct irq_domain *domain;
|
|
};
|
|
|
|
static struct lpc32xx_irq_chip *lpc32xx_mic_irqc;
|
|
|
|
static inline u32 lpc32xx_ic_read(struct lpc32xx_irq_chip *ic, u32 reg)
|
|
{
|
|
return readl_relaxed(ic->base + reg);
|
|
}
|
|
|
|
static inline void lpc32xx_ic_write(struct lpc32xx_irq_chip *ic,
|
|
u32 reg, u32 val)
|
|
{
|
|
writel_relaxed(val, ic->base + reg);
|
|
}
|
|
|
|
static void lpc32xx_irq_mask(struct irq_data *d)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
|
|
u32 val, mask = BIT(d->hwirq);
|
|
|
|
val = lpc32xx_ic_read(ic, LPC32XX_INTC_MASK) & ~mask;
|
|
lpc32xx_ic_write(ic, LPC32XX_INTC_MASK, val);
|
|
}
|
|
|
|
static void lpc32xx_irq_unmask(struct irq_data *d)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
|
|
u32 val, mask = BIT(d->hwirq);
|
|
|
|
val = lpc32xx_ic_read(ic, LPC32XX_INTC_MASK) | mask;
|
|
lpc32xx_ic_write(ic, LPC32XX_INTC_MASK, val);
|
|
}
|
|
|
|
static void lpc32xx_irq_ack(struct irq_data *d)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
|
|
u32 mask = BIT(d->hwirq);
|
|
|
|
lpc32xx_ic_write(ic, LPC32XX_INTC_RAW, mask);
|
|
}
|
|
|
|
static int lpc32xx_irq_set_type(struct irq_data *d, unsigned int type)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
|
|
u32 val, mask = BIT(d->hwirq);
|
|
bool high, edge;
|
|
|
|
switch (type) {
|
|
case IRQ_TYPE_EDGE_RISING:
|
|
edge = true;
|
|
high = true;
|
|
break;
|
|
case IRQ_TYPE_EDGE_FALLING:
|
|
edge = true;
|
|
high = false;
|
|
break;
|
|
case IRQ_TYPE_LEVEL_HIGH:
|
|
edge = false;
|
|
high = true;
|
|
break;
|
|
case IRQ_TYPE_LEVEL_LOW:
|
|
edge = false;
|
|
high = false;
|
|
break;
|
|
default:
|
|
pr_info("unsupported irq type %d\n", type);
|
|
return -EINVAL;
|
|
}
|
|
|
|
irqd_set_trigger_type(d, type);
|
|
|
|
val = lpc32xx_ic_read(ic, LPC32XX_INTC_POL);
|
|
if (high)
|
|
val |= mask;
|
|
else
|
|
val &= ~mask;
|
|
lpc32xx_ic_write(ic, LPC32XX_INTC_POL, val);
|
|
|
|
val = lpc32xx_ic_read(ic, LPC32XX_INTC_TYPE);
|
|
if (edge) {
|
|
val |= mask;
|
|
irq_set_handler_locked(d, handle_edge_irq);
|
|
} else {
|
|
val &= ~mask;
|
|
irq_set_handler_locked(d, handle_level_irq);
|
|
}
|
|
lpc32xx_ic_write(ic, LPC32XX_INTC_TYPE, val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void lpc32xx_irq_print_chip(struct irq_data *d, struct seq_file *p)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = irq_data_get_irq_chip_data(d);
|
|
|
|
if (ic == lpc32xx_mic_irqc)
|
|
seq_printf(p, "%08x.mic", ic->addr);
|
|
else
|
|
seq_printf(p, "%08x.sic", ic->addr);
|
|
}
|
|
|
|
static const struct irq_chip lpc32xx_chip = {
|
|
.irq_ack = lpc32xx_irq_ack,
|
|
.irq_mask = lpc32xx_irq_mask,
|
|
.irq_unmask = lpc32xx_irq_unmask,
|
|
.irq_set_type = lpc32xx_irq_set_type,
|
|
.irq_print_chip = lpc32xx_irq_print_chip,
|
|
};
|
|
|
|
static void __exception_irq_entry lpc32xx_handle_irq(struct pt_regs *regs)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = lpc32xx_mic_irqc;
|
|
u32 hwirq = lpc32xx_ic_read(ic, LPC32XX_INTC_STAT), irq;
|
|
|
|
while (hwirq) {
|
|
irq = __ffs(hwirq);
|
|
hwirq &= ~BIT(irq);
|
|
generic_handle_domain_irq(lpc32xx_mic_irqc->domain, irq);
|
|
}
|
|
}
|
|
|
|
static void lpc32xx_sic_handler(struct irq_desc *desc)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = irq_desc_get_handler_data(desc);
|
|
struct irq_chip *chip = irq_desc_get_chip(desc);
|
|
u32 hwirq = lpc32xx_ic_read(ic, LPC32XX_INTC_STAT), irq;
|
|
|
|
chained_irq_enter(chip, desc);
|
|
|
|
while (hwirq) {
|
|
irq = __ffs(hwirq);
|
|
hwirq &= ~BIT(irq);
|
|
generic_handle_domain_irq(ic->domain, irq);
|
|
}
|
|
|
|
chained_irq_exit(chip, desc);
|
|
}
|
|
|
|
static int lpc32xx_irq_domain_map(struct irq_domain *id, unsigned int virq,
|
|
irq_hw_number_t hw)
|
|
{
|
|
struct lpc32xx_irq_chip *ic = id->host_data;
|
|
|
|
irq_set_chip_data(virq, ic);
|
|
irq_set_chip_and_handler(virq, &lpc32xx_chip, handle_level_irq);
|
|
irq_set_status_flags(virq, IRQ_LEVEL);
|
|
irq_set_noprobe(virq);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void lpc32xx_irq_domain_unmap(struct irq_domain *id, unsigned int virq)
|
|
{
|
|
irq_set_chip_and_handler(virq, NULL, NULL);
|
|
}
|
|
|
|
static const struct irq_domain_ops lpc32xx_irq_domain_ops = {
|
|
.map = lpc32xx_irq_domain_map,
|
|
.unmap = lpc32xx_irq_domain_unmap,
|
|
.xlate = irq_domain_xlate_twocell,
|
|
};
|
|
|
|
static int __init lpc32xx_of_ic_init(struct device_node *node,
|
|
struct device_node *parent)
|
|
{
|
|
struct lpc32xx_irq_chip *irqc;
|
|
bool is_mic = of_device_is_compatible(node, "nxp,lpc3220-mic");
|
|
const __be32 *reg = of_get_property(node, "reg", NULL);
|
|
u32 parent_irq, i, addr = reg ? be32_to_cpu(*reg) : 0;
|
|
|
|
irqc = kzalloc_obj(*irqc);
|
|
if (!irqc)
|
|
return -ENOMEM;
|
|
|
|
irqc->addr = addr;
|
|
irqc->base = of_iomap(node, 0);
|
|
if (!irqc->base) {
|
|
pr_err("%pOF: unable to map registers\n", node);
|
|
kfree(irqc);
|
|
return -EINVAL;
|
|
}
|
|
|
|
irqc->domain = irq_domain_create_linear(of_fwnode_handle(node), NR_LPC32XX_IC_IRQS,
|
|
&lpc32xx_irq_domain_ops, irqc);
|
|
if (!irqc->domain) {
|
|
pr_err("unable to add irq domain\n");
|
|
iounmap(irqc->base);
|
|
kfree(irqc);
|
|
return -ENODEV;
|
|
}
|
|
|
|
if (is_mic) {
|
|
lpc32xx_mic_irqc = irqc;
|
|
set_handle_irq(lpc32xx_handle_irq);
|
|
} else {
|
|
for (i = 0; i < of_irq_count(node); i++) {
|
|
parent_irq = irq_of_parse_and_map(node, i);
|
|
if (parent_irq)
|
|
irq_set_chained_handler_and_data(parent_irq,
|
|
lpc32xx_sic_handler, irqc);
|
|
}
|
|
}
|
|
|
|
lpc32xx_ic_write(irqc, LPC32XX_INTC_MASK, 0x00);
|
|
lpc32xx_ic_write(irqc, LPC32XX_INTC_POL, 0x00);
|
|
lpc32xx_ic_write(irqc, LPC32XX_INTC_TYPE, 0x00);
|
|
|
|
return 0;
|
|
}
|
|
|
|
IRQCHIP_DECLARE(nxp_lpc32xx_mic, "nxp,lpc3220-mic", lpc32xx_of_ic_init);
|
|
IRQCHIP_DECLARE(nxp_lpc32xx_sic, "nxp,lpc3220-sic", lpc32xx_of_ic_init);
|