drivers/gpio/gpio-tqmx86.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-tqmx86.c
Extension
.c
Size
11794 bytes
Lines
438
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 tqmx86_gpio_data {
	struct gpio_chip	chip;
	void __iomem		*io_base;
	int			irq;
	/* Lock must be held for accessing output and irq_type fields */
	raw_spinlock_t		spinlock;
	DECLARE_BITMAP(output, TQMX86_NGPIO);
	u8			irq_type[TQMX86_NGPIO];
};

static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)
{
	return ioread8(gd->io_base + reg);
}

static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val,
			      unsigned int reg)
{
	iowrite8(val, gd->io_base + reg);
}

static void tqmx86_gpio_clrsetbits(struct tqmx86_gpio_data *gpio,
				   u8 clr, u8 set, unsigned int reg)
	__must_hold(&gpio->spinlock)
{
	u8 val = tqmx86_gpio_read(gpio, reg);

	val &= ~clr;
	val |= set;

	tqmx86_gpio_write(gpio, val, reg);
}

static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);

	return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));
}

static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset,
			     int value)
	__must_hold(&gpio->spinlock)
{
	__assign_bit(offset, gpio->output, value);
	tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
}

static int tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
			   int value)
{
	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);

	guard(raw_spinlock_irqsave)(&gpio->spinlock);

	_tqmx86_gpio_set(gpio, offset, value);

	return 0;
}

static int tqmx86_gpio_direction_input(struct gpio_chip *chip,
				       unsigned int offset)
{
	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);

	guard(raw_spinlock_irqsave)(&gpio->spinlock);

	tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD);

	return 0;
}

static int tqmx86_gpio_direction_output(struct gpio_chip *chip,
					unsigned int offset,
					int value)
{
	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);

	guard(raw_spinlock_irqsave)(&gpio->spinlock);

	_tqmx86_gpio_set(gpio, offset, value);
	tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD);

	return 0;
}

static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
				     unsigned int offset)
{
	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);

Annotation

Implementation Notes