drivers/gpio/gpio-imx-scu.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpio/gpio-imx-scu.c
Extension
.c
Size
3011 bytes
Lines
135
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

struct scu_gpio_priv {
	struct gpio_chip	chip;
	struct mutex		lock;
	struct device		*dev;
	struct imx_sc_ipc	*handle;
};

static unsigned int scu_rsrc_arr[] = {
	IMX_SC_R_BOARD_R0,
	IMX_SC_R_BOARD_R1,
	IMX_SC_R_BOARD_R2,
	IMX_SC_R_BOARD_R3,
	IMX_SC_R_BOARD_R4,
	IMX_SC_R_BOARD_R5,
	IMX_SC_R_BOARD_R6,
	IMX_SC_R_BOARD_R7,
};

static int imx_scu_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	struct scu_gpio_priv *priv = gpiochip_get_data(chip);
	int level;
	int err;

	scoped_guard(mutex, &priv->lock) {
		/* to read PIN state via scu api */
		err = imx_sc_misc_get_control(priv->handle,
					      scu_rsrc_arr[offset], 0, &level);
	}
	if (err) {
		dev_err(priv->dev, "SCU get failed: %d\n", err);
		return err;
	}

	return level;
}

static int imx_scu_gpio_set(struct gpio_chip *chip, unsigned int offset,
			    int value)
{
	struct scu_gpio_priv *priv = gpiochip_get_data(chip);
	int err;

	scoped_guard(mutex, &priv->lock) {
		/* to set PIN output level via scu api */
		err = imx_sc_misc_set_control(priv->handle,
					      scu_rsrc_arr[offset], 0, value);
	}
	if (err)
		dev_err(priv->dev, "SCU set (%d) failed: %d\n",
				scu_rsrc_arr[offset], err);

	return err;
}

static int imx_scu_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
	return GPIO_LINE_DIRECTION_OUT;
}

static int imx_scu_gpio_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct scu_gpio_priv *priv;
	struct gpio_chip *gc;
	int ret;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	ret = imx_scu_get_handle(&priv->handle);
	if (ret)
		return ret;

	priv->dev = dev;

	ret = devm_mutex_init(&pdev->dev, &priv->lock);
	if (ret)
		return ret;

	gc = &priv->chip;
	gc->base = -1;
	gc->parent = dev;
	gc->ngpio = ARRAY_SIZE(scu_rsrc_arr);
	gc->label = dev_name(dev);
	gc->get = imx_scu_gpio_get;
	gc->set = imx_scu_gpio_set;
	gc->get_direction = imx_scu_gpio_get_direction;

Annotation

Implementation Notes