Source
x
// SPDX-License-Identifier: GPL-2.0+
//
// MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
// Copyright 2008 Juergen Beisert, kernel@pengutronix.de
//
// Based on code from Freescale,
// Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
enum mxs_gpio_id {
IMX23_GPIO,
IMX28_GPIO,
};
struct mxs_gpio_port {
void __iomem *base;
int id;
int irq;
struct irq_domain *domain;
struct gpio_chip gc;
struct device *dev;
enum mxs_gpio_id devid;
u32 both_edges;
};
static inline int is_imx23_gpio(struct mxs_gpio_port *port)
{
return port->devid == IMX23_GPIO;
}
static inline int is_imx28_gpio(struct mxs_gpio_port *port)
{
return port->devid == IMX28_GPIO;
}
/* Note: This driver assumes 32 GPIOs are handled in one register */
static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
{
u32 val;
u32 pin_mask = 1 << d->hwirq;
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d);
struct mxs_gpio_port *port = gc->private;
void __iomem *pin_addr;
int edge;
if (!(ct->type & type))
if (irq_setup_alt_chip(d, type))
return -EINVAL;
port->both_edges &= ~pin_mask;
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
val = readl(port->base + PINCTRL_DIN(port)) & pin_mask;
if (val)
edge = GPIO_INT_FALL_EDGE;
else
edge = GPIO_INT_RISE_EDGE;
port->both_edges |= pin_mask;