drivers/gpio/gpio-rockchip.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-rockchip.c
Extension
.c
Size
21551 bytes
Lines
843
Domain
Driver Families
Bucket
drivers/gpio
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

if (div_debounce_support) {
			/* Configure the max debounce from consumers */
			cur_div_reg = readl(bank->reg_base +
					    reg->dbclk_div_con);
			if (cur_div_reg < div_reg)
				writel(div_reg, bank->reg_base +
				       reg->dbclk_div_con);
			rockchip_gpio_writel_bit(bank, offset, 1,
						 reg->dbclk_div_en);
		}

		rockchip_gpio_writel_bit(bank, offset, 1, reg->debounce);
	} else {
		if (div_debounce_support)
			rockchip_gpio_writel_bit(bank, offset, 0,
						 reg->dbclk_div_en);

		rockchip_gpio_writel_bit(bank, offset, 0, reg->debounce);
	}

	raw_spin_unlock_irqrestore(&bank->slock, flags);

	/* Enable or disable dbclk at last */
	if (div_debounce_support) {
		if (debounce)
			clk_prepare_enable(bank->db_clk);
		else
			clk_disable_unprepare(bank->db_clk);
	}

	return 0;
}

static int rockchip_gpio_direction_input(struct gpio_chip *gc,
					 unsigned int offset)
{
	return rockchip_gpio_set_direction(gc, offset, true);
}

static int rockchip_gpio_direction_output(struct gpio_chip *gc,
					  unsigned int offset, int value)
{
	rockchip_gpio_set(gc, offset, value);

	return rockchip_gpio_set_direction(gc, offset, false);
}

/*
 * gpiolib set_config callback function. The setting of the pin
 * mux function as 'gpio output' will be handled by the pinctrl subsystem
 * interface.
 */
static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
				  unsigned long config)
{
	enum pin_config_param param = pinconf_to_config_param(config);

	switch (param) {
	case PIN_CONFIG_INPUT_DEBOUNCE:
		rockchip_gpio_set_debounce(gc, offset, true);
		/*
		 * Rockchip's gpio could only support up to one period
		 * of the debounce clock(pclk), which is far away from
		 * satisftying the requirement, as pclk is usually near
		 * 100MHz shared by all peripherals. So the fact is it
		 * has crippled debounce capability could only be useful
		 * to prevent any spurious glitches from waking up the system
		 * if the gpio is conguired as wakeup interrupt source. Let's
		 * still return -ENOTSUPP as before, to make sure the caller
		 * of gpiod_set_debounce won't change its behaviour.
		 */
		return -ENOTSUPP;
	default:
		return gpiochip_generic_config(gc, offset, config);
	}
}

/*
 * gpiod_to_irq() callback function. Creates a mapping between a GPIO pin
 * and a virtual IRQ, if not already present.
 */
static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
{
	struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
	unsigned int virq;

	if (!bank->domain)
		return -ENXIO;

	virq = irq_create_mapping(bank->domain, offset);

Annotation

Implementation Notes