drivers/pinctrl/samsung/pinctrl-exynos-arm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/pinctrl/samsung/pinctrl-exynos-arm.c
Extension
.c
Size
34545 bytes
Lines
908
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

// SPDX-License-Identifier: GPL-2.0+
//
// Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
//
// Copyright (c) 2012 Samsung Electronics Co., Ltd.
//		http://www.samsung.com
// Copyright (c) 2012 Linaro Ltd
//		http://www.linaro.org
//
// Author: Thomas Abraham <thomas.ab@samsung.com>
//
// This file contains the Samsung Exynos specific information required by the
// the Samsung pinctrl/gpiolib driver. It also includes the implementation of
// external gpio and wakeup interrupt support.

#include <linux/device.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>

#include "pinctrl-samsung.h"
#include "pinctrl-exynos.h"

static const struct samsung_pin_bank_type bank_type_off = {
	.fld_width = { 4, 1, 2, 2, 2, 2, },
	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
};

static const struct samsung_pin_bank_type bank_type_alive = {
	.fld_width = { 4, 1, 2, 2, },
	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
};

/* Retention control for S5PV210 are located at the end of clock controller */
#define S5P_OTHERS 0xE000

#define S5P_OTHERS_RET_IO		(1 << 31)
#define S5P_OTHERS_RET_CF		(1 << 30)
#define S5P_OTHERS_RET_MMC		(1 << 29)
#define S5P_OTHERS_RET_UART		(1 << 28)

#define S5P_PIN_PULL_DISABLE		0
#define S5P_PIN_PULL_DOWN		1
#define S5P_PIN_PULL_UP			2

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

	pud_val[PUD_PULL_DISABLE] = S5P_PIN_PULL_DISABLE;
	pud_val[PUD_PULL_DOWN] = S5P_PIN_PULL_DOWN;
	pud_val[PUD_PULL_UP] = S5P_PIN_PULL_UP;
}

static void s5pv210_retention_disable(struct samsung_pinctrl_drv_data *drvdata)
{
	void __iomem *clk_base = (void __iomem *)drvdata->retention_ctrl->priv;
	u32 tmp;

	tmp = __raw_readl(clk_base + S5P_OTHERS);
	tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF | S5P_OTHERS_RET_MMC |
		S5P_OTHERS_RET_UART);
	__raw_writel(tmp, clk_base + S5P_OTHERS);
}

static struct samsung_retention_ctrl *
s5pv210_retention_init(struct samsung_pinctrl_drv_data *drvdata,
		       const struct samsung_retention_data *data)
{
	struct samsung_retention_ctrl *ctrl;
	struct device_node *np;
	void __iomem *clk_base;

	ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL);
	if (!ctrl)
		return ERR_PTR(-ENOMEM);

	np = of_find_compatible_node(NULL, NULL, "samsung,s5pv210-clock");
	if (!np) {
		pr_err("%s: failed to find clock controller DT node\n",
			__func__);
		return ERR_PTR(-ENODEV);
	}

	clk_base = of_iomap(np, 0);
	of_node_put(np);
	if (!clk_base) {
		pr_err("%s: failed to map clock registers\n", __func__);
		return ERR_PTR(-EINVAL);

Annotation

Implementation Notes