#define pr_fmt(fmt) …
#include <linux/io.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/irqchip.h>
#include <linux/of.h>
#include <linux/of_address.h>
#define MAX_NUM_CHANNEL …
#define MAX_INPUT_MUX …
#define REG_EDGE_POL …
#define REG_PIN_03_SEL …
#define REG_PIN_47_SEL …
#define REG_FILTER_SEL …
#define REG_PIN_A1_SEL …
#define REG_EDGE_POL_S4 …
#define REG_EDGE_POL_EDGE(params, x) …
#define REG_EDGE_POL_LOW(params, x) …
#define REG_BOTH_EDGE(params, x) …
#define REG_EDGE_POL_MASK(params, x) …
#define REG_PIN_SEL_SHIFT(x) …
#define REG_FILTER_SEL_SHIFT(x) …
struct meson_gpio_irq_controller;
static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
unsigned int channel, unsigned long hwirq);
static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl);
static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
unsigned int channel,
unsigned long hwirq);
static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
unsigned int type, u32 *channel_hwirq);
static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
unsigned int type, u32 *channel_hwirq);
struct irq_ctl_ops { … };
struct meson_gpio_irq_params { … };
#define INIT_MESON_COMMON(irqs, init, sel, type) …
#define INIT_MESON8_COMMON_DATA(irqs) … \
#define INIT_MESON_A1_COMMON_DATA(irqs) … \
#define INIT_MESON_S4_COMMON_DATA(irqs) … \
static const struct meson_gpio_irq_params meson8_params = …;
static const struct meson_gpio_irq_params meson8b_params = …;
static const struct meson_gpio_irq_params gxbb_params = …;
static const struct meson_gpio_irq_params gxl_params = …;
static const struct meson_gpio_irq_params axg_params = …;
static const struct meson_gpio_irq_params sm1_params = …;
static const struct meson_gpio_irq_params a1_params = …;
static const struct meson_gpio_irq_params s4_params = …;
static const struct meson_gpio_irq_params c3_params = …;
static const struct meson_gpio_irq_params t7_params = …;
static const struct of_device_id meson_irq_gpio_matches[] __maybe_unused = …;
struct meson_gpio_irq_controller { … };
static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
unsigned int reg, u32 mask, u32 val)
{ … }
static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
{ … }
static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
unsigned int channel, unsigned long hwirq)
{ … }
static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
unsigned int channel,
unsigned long hwirq)
{ … }
static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
{ … }
static int
meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
unsigned long hwirq,
u32 **channel_hwirq)
{ … }
static unsigned int
meson_gpio_irq_get_channel_idx(struct meson_gpio_irq_controller *ctl,
u32 *channel_hwirq)
{ … }
static void
meson_gpio_irq_release_channel(struct meson_gpio_irq_controller *ctl,
u32 *channel_hwirq)
{ … }
static int meson8_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
unsigned int type, u32 *channel_hwirq)
{ … }
static int meson_s4_gpio_irq_set_type(struct meson_gpio_irq_controller *ctl,
unsigned int type, u32 *channel_hwirq)
{
u32 val = 0;
unsigned int idx;
idx = meson_gpio_irq_get_channel_idx(ctl, channel_hwirq);
type &= IRQ_TYPE_SENSE_MASK;
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(idx), 0);
if (type == IRQ_TYPE_EDGE_BOTH) {
val |= BIT(ctl->params->edge_both_offset + idx);
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
BIT(ctl->params->edge_both_offset + idx), val);
return 0;
}
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
val |= BIT(ctl->params->pol_low_offset + idx);
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
val |= BIT(ctl->params->edge_single_offset + idx);
meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
BIT(idx) | BIT(12 + idx), val);
return 0;
};
static unsigned int meson_gpio_irq_type_output(unsigned int type)
{ … }
static int meson_gpio_irq_set_type(struct irq_data *data, unsigned int type)
{ … }
static struct irq_chip meson_gpio_irq_chip = …;
static int meson_gpio_irq_domain_translate(struct irq_domain *domain,
struct irq_fwspec *fwspec,
unsigned long *hwirq,
unsigned int *type)
{ … }
static int meson_gpio_irq_allocate_gic_irq(struct irq_domain *domain,
unsigned int virq,
u32 hwirq,
unsigned int type)
{ … }
static int meson_gpio_irq_domain_alloc(struct irq_domain *domain,
unsigned int virq,
unsigned int nr_irqs,
void *data)
{ … }
static void meson_gpio_irq_domain_free(struct irq_domain *domain,
unsigned int virq,
unsigned int nr_irqs)
{ … }
static const struct irq_domain_ops meson_gpio_irq_domain_ops = …;
static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_irq_controller *ctl)
{ … }
static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *parent)
{ … }
IRQCHIP_PLATFORM_DRIVER_BEGIN(meson_gpio_intc)
IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init)
IRQCHIP_PLATFORM_DRIVER_END(meson_gpio_intc)
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_ALIAS(…) …;