drivers/pinctrl/samsung/pinctrl-s3c64xx.c

Source file repositories/reference/linux-study-clean/drivers/pinctrl/samsung/pinctrl-s3c64xx.c

File Facts

System
Linux kernel
Corpus path
drivers/pinctrl/samsung/pinctrl-s3c64xx.c
Extension
.c
Size
20336 bytes
Lines
821
Domain
Driver Families
Bucket
drivers/pinctrl
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 s3c64xx_eint0_data {
	struct samsung_pinctrl_drv_data *drvdata;
	struct irq_domain *domains[NUM_EINT0];
	u8 pins[NUM_EINT0];
};

/**
 * struct s3c64xx_eint0_domain_data - EINT0 per-domain data
 * @bank: pin bank related to the domain
 * @eints: EINT0 interrupts related to the domain
 */
struct s3c64xx_eint0_domain_data {
	struct samsung_pin_bank *bank;
	u8 eints[];
};

/**
 * struct s3c64xx_eint_gpio_data - GPIO EINT data
 * @drvdata: pin controller driver data
 * @domains: array of domains related to EINT interrupt groups
 */
struct s3c64xx_eint_gpio_data {
	struct samsung_pinctrl_drv_data *drvdata;
	struct irq_domain *domains[];
};

/*
 * Common functions for S3C64xx EINT configuration
 */

static int s3c64xx_irq_get_trigger(unsigned int type)
{
	int trigger;

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		trigger = EINT_EDGE_RISING;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		trigger = EINT_EDGE_FALLING;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		trigger = EINT_EDGE_BOTH;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		trigger = EINT_LEVEL_HIGH;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		trigger = EINT_LEVEL_LOW;
		break;
	default:
		return -EINVAL;
	}

	return trigger;
}

static void s3c64xx_pud_value_init(struct samsung_pinctrl_drv_data *drvdata)
{
	unsigned int  *pud_val = drvdata->pud_val;

	pud_val[PUD_PULL_DISABLE] = S3C_PIN_PULL_DISABLE;
	pud_val[PUD_PULL_DOWN] = S3C_PIN_PULL_DOWN;
	pud_val[PUD_PULL_UP] = S3C_PIN_PULL_UP;
}

static void s3c64xx_irq_set_handler(struct irq_data *d, unsigned int type)
{
	/* Edge- and level-triggered interrupts need different handlers */
	if (type & IRQ_TYPE_EDGE_BOTH)
		irq_set_handler_locked(d, handle_edge_irq);
	else
		irq_set_handler_locked(d, handle_level_irq);
}

static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
					struct samsung_pin_bank *bank, int pin)
{
	const struct samsung_pin_bank_type *bank_type = bank->type;
	unsigned long flags;
	void __iomem *reg;
	u8 shift;
	u32 mask;
	u32 val;

	/* Make sure that pin is configured as interrupt */
	reg = d->virt_base + bank->pctl_offset;
	shift = pin;
	if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
		/* 4-bit bank type with 2 con regs */

Annotation

Implementation Notes