drivers/gpio/gpio-rcar.c

Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-rcar.c

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-rcar.c
Extension
.c
Size
17070 bytes
Lines
672
Domain
Driver Families
Bucket
drivers/gpio
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct gpio_rcar_bank_info {
	u32 iointsel;
	u32 inoutsel;
	u32 outdt;
	u32 posneg;
	u32 edglevel;
	u32 bothedge;
	u32 intmsk;
};

struct gpio_rcar_info {
	bool has_outdtsel;
	bool has_both_edge_trigger;
	bool has_always_in;
	bool has_inen;
};

struct gpio_rcar_priv {
	void __iomem *base;
	raw_spinlock_t lock;
	struct device *dev;
	struct gpio_chip gpio_chip;
	unsigned int irq_parent;
	atomic_t wakeup_path;
	struct gpio_rcar_info info;
	struct gpio_rcar_bank_info bank_info;
};

#define IOINTSEL	0x00	/* General IO/Interrupt Switching Register */
#define INOUTSEL	0x04	/* General Input/Output Switching Register */
#define OUTDT		0x08	/* General Output Register */
#define INDT		0x0c	/* General Input Register */
#define INTDT		0x10	/* Interrupt Display Register */
#define INTCLR		0x14	/* Interrupt Clear Register */
#define INTMSK		0x18	/* Interrupt Mask Register */
#define MSKCLR		0x1c	/* Interrupt Mask Clear Register */
#define POSNEG		0x20	/* Positive/Negative Logic Select Register */
#define EDGLEVEL	0x24	/* Edge/level Select Register */
#define FILONOFF	0x28	/* Chattering Prevention On/Off Register */
#define OUTDTSEL	0x40	/* Output Data Select Register */
#define BOTHEDGE	0x4c	/* One Edge/Both Edge Select Register */
#define INEN		0x50	/* General Input Enable Register */

#define RCAR_MAX_GPIO_PER_BANK		32

static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs)
{
	return ioread32(p->base + offs);
}

static inline void gpio_rcar_write(struct gpio_rcar_priv *p, int offs,
				   u32 value)
{
	iowrite32(value, p->base + offs);
}

static void gpio_rcar_modify_bit(struct gpio_rcar_priv *p, int offs,
				 int bit, bool value)
{
	u32 tmp = gpio_rcar_read(p, offs);

	if (value)
		tmp |= BIT(bit);
	else
		tmp &= ~BIT(bit);

	gpio_rcar_write(p, offs, tmp);
}

static void gpio_rcar_irq_disable(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct gpio_rcar_priv *p = gpiochip_get_data(gc);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	gpio_rcar_write(p, INTMSK, ~BIT(hwirq));
	gpiochip_disable_irq(gc, hwirq);
}

static void gpio_rcar_irq_enable(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct gpio_rcar_priv *p = gpiochip_get_data(gc);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	gpiochip_enable_irq(gc, hwirq);
	gpio_rcar_write(p, MSKCLR, BIT(hwirq));
}

static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p,

Annotation

Implementation Notes