drivers/soc/fsl/qe/gpio.c

Source file repositories/reference/linux-study-clean/drivers/soc/fsl/qe/gpio.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/fsl/qe/gpio.c
Extension
.c
Size
8633 bytes
Lines
351
Domain
Driver Families
Bucket
drivers/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 qe_gpio_chip {
	struct gpio_chip gc;
	void __iomem *regs;
	spinlock_t lock;

	/* shadowed data register to clear/set bits safely */
	u32 cpdata;

	/* saved_regs used to restore dedicated functions */
	struct qe_pio_regs saved_regs;
};

static void qe_gpio_save_regs(struct qe_gpio_chip *qe_gc)
{
	struct qe_pio_regs __iomem *regs = qe_gc->regs;

	qe_gc->cpdata = ioread32be(&regs->cpdata);
	qe_gc->saved_regs.cpdata = qe_gc->cpdata;
	qe_gc->saved_regs.cpdir1 = ioread32be(&regs->cpdir1);
	qe_gc->saved_regs.cpdir2 = ioread32be(&regs->cpdir2);
	qe_gc->saved_regs.cppar1 = ioread32be(&regs->cppar1);
	qe_gc->saved_regs.cppar2 = ioread32be(&regs->cppar2);
	qe_gc->saved_regs.cpodr = ioread32be(&regs->cpodr);
}

static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{
	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
	struct qe_pio_regs __iomem *regs = qe_gc->regs;
	u32 pin_mask = PIN_MASK(gpio);

	return !!(ioread32be(&regs->cpdata) & pin_mask);
}

static int qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
{
	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
	struct qe_pio_regs __iomem *regs = qe_gc->regs;
	unsigned long flags;
	u32 pin_mask = PIN_MASK(gpio);

	spin_lock_irqsave(&qe_gc->lock, flags);

	if (val)
		qe_gc->cpdata |= pin_mask;
	else
		qe_gc->cpdata &= ~pin_mask;

	iowrite32be(qe_gc->cpdata, &regs->cpdata);

	spin_unlock_irqrestore(&qe_gc->lock, flags);

	return 0;
}

static int qe_gpio_set_multiple(struct gpio_chip *gc,
				unsigned long *mask, unsigned long *bits)
{
	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
	struct qe_pio_regs __iomem *regs = qe_gc->regs;
	unsigned long flags;
	int i;

	spin_lock_irqsave(&qe_gc->lock, flags);

	for (i = 0; i < gc->ngpio; i++) {
		if (*mask == 0)
			break;
		if (__test_and_clear_bit(i, mask)) {
			if (test_bit(i, bits))
				qe_gc->cpdata |= PIN_MASK(i);
			else
				qe_gc->cpdata &= ~PIN_MASK(i);
		}
	}

	iowrite32be(qe_gc->cpdata, &regs->cpdata);

	spin_unlock_irqrestore(&qe_gc->lock, flags);

	return 0;
}

static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
	struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
	unsigned long flags;

	spin_lock_irqsave(&qe_gc->lock, flags);

Annotation

Implementation Notes