drivers/gpio/gpio-mvebu.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-mvebu.c
Extension
.c
Size
34674 bytes
Lines
1308
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 mvebu_pwm {
	struct regmap		*regs;
	u32			 offset;
	unsigned long		 clk_rate;
	struct gpio_desc	*gpiod;
	spinlock_t		 lock;
	struct mvebu_gpio_chip	*mvchip;

	/* Used to preserve GPIO/PWM registers across suspend/resume */
	u32			 blink_select;
	u32			 blink_on_duration;
	u32			 blink_off_duration;
};

struct mvebu_gpio_chip {
	struct gpio_chip   chip;
	struct regmap     *regs;
	u32		   offset;
	struct regmap     *percpu_regs;
	int		   irqbase;
	struct irq_domain *domain;
	int		   soc_variant;

	/* Used for PWM support */
	struct clk	  *clk;
	struct mvebu_pwm  *mvpwm;

	/* Used to preserve GPIO registers across suspend/resume */
	u32		   out_reg;
	u32		   io_conf_reg;
	u32		   blink_en_reg;
	u32		   in_pol_reg;
	u32		   edge_mask_regs[4];
	u32		   level_mask_regs[4];
};

/*
 * Functions returning addresses of individual registers for a given
 * GPIO controller.
 */

static void mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvchip,
			 struct regmap **map, unsigned int *offset)
{
	int cpu;

	switch (mvchip->soc_variant) {
	case MVEBU_GPIO_SOC_VARIANT_ORION:
	case MVEBU_GPIO_SOC_VARIANT_MV78200:
	case MVEBU_GPIO_SOC_VARIANT_A8K:
		*map = mvchip->regs;
		*offset = GPIO_EDGE_CAUSE_OFF + mvchip->offset;
		break;
	case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
		cpu = smp_processor_id();
		*map = mvchip->percpu_regs;
		*offset = GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu);
		break;
	default:
		BUG();
	}
}

static u32
mvebu_gpio_read_edge_cause(struct mvebu_gpio_chip *mvchip)
{
	struct regmap *map;
	unsigned int offset;
	u32 val;

	mvebu_gpioreg_edge_cause(mvchip, &map, &offset);
	regmap_read(map, offset, &val);

	return val;
}

static void
mvebu_gpio_write_edge_cause(struct mvebu_gpio_chip *mvchip, u32 val)
{
	struct regmap *map;
	unsigned int offset;

	mvebu_gpioreg_edge_cause(mvchip, &map, &offset);
	regmap_write(map, offset, val);
}

static inline void
mvebu_gpioreg_edge_mask(struct mvebu_gpio_chip *mvchip,
			struct regmap **map, unsigned int *offset)
{

Annotation

Implementation Notes