drivers/soc/samsung/exynos-usi.c
Source file repositories/reference/linux-study-clean/drivers/soc/samsung/exynos-usi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/soc/samsung/exynos-usi.c- Extension
.c- Size
- 9514 bytes
- Lines
- 356
- Domain
- Driver Families
- Bucket
- drivers/soc
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/array_size.hlinux/clk.hlinux/mfd/syscon.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hlinux/regmap.hdt-bindings/soc/samsung,exynos-usi.h
Detected Declarations
struct exynos_usi_variantstruct exynos_usistruct exynos_usi_modeenum exynos_usi_verfunction protocolfunction behaviorfunction exynos_usi_configurefunction exynos_usi_unconfigurefunction exynos_usi_parse_dtfunction exynos_usi_get_clocksfunction exynos_usi_probefunction exynos_usi_resume_noirq
Annotated Snippet
struct exynos_usi_variant {
enum exynos_usi_ver ver; /* USI IP-core version */
unsigned int sw_conf_mask; /* SW_CONF mask for all protocols */
size_t min_mode; /* first index in exynos_usi_modes[] */
size_t max_mode; /* last index in exynos_usi_modes[] */
size_t num_clks; /* number of clocks to assert */
const char * const *clk_names; /* clock names to assert */
};
struct exynos_usi {
struct device *dev;
void __iomem *regs; /* USI register map */
struct clk_bulk_data *clks; /* USI clocks */
size_t mode; /* current USI SW_CONF mode index */
bool clkreq_on; /* always provide clock to IP */
/* System Register */
struct regmap *sysreg; /* System Register map */
unsigned int sw_conf; /* SW_CONF register offset in sysreg */
const struct exynos_usi_variant *data;
};
struct exynos_usi_mode {
const char *name; /* mode name */
unsigned int val; /* mode register value */
};
#define USI_MODES_MAX (USI_MODE_UART_I2C1 + 1)
static const struct exynos_usi_mode exynos_usi_modes[][USI_MODES_MAX] = {
[USI_VER1] = {
[USI_MODE_NONE] = { .name = "none", .val = USI_V1_SW_CONF_NONE },
[USI_MODE_UART] = { .name = "uart", .val = USI_V1_SW_CONF_UART },
[USI_MODE_SPI] = { .name = "spi", .val = USI_V1_SW_CONF_SPI },
[USI_MODE_I2C] = { .name = "i2c", .val = USI_V1_SW_CONF_I2C0 },
[USI_MODE_I2C1] = { .name = "i2c1", .val = USI_V1_SW_CONF_I2C1 },
[USI_MODE_I2C0_1] = { .name = "i2c0_1", .val = USI_V1_SW_CONF_I2C0_1 },
[USI_MODE_UART_I2C1] = { .name = "uart_i2c1", .val = USI_V1_SW_CONF_UART_I2C1 },
}, [USI_VER2] = {
[USI_MODE_NONE] = { .name = "none", .val = USI_V2_SW_CONF_NONE },
[USI_MODE_UART] = { .name = "uart", .val = USI_V2_SW_CONF_UART },
[USI_MODE_SPI] = { .name = "spi", .val = USI_V2_SW_CONF_SPI },
[USI_MODE_I2C] = { .name = "i2c", .val = USI_V2_SW_CONF_I2C },
},
};
static const char * const exynos850_usi_clk_names[] = { "pclk", "ipclk" };
static const struct exynos_usi_variant exynos850_usi_data = {
.ver = USI_VER2,
.sw_conf_mask = USI_V2_SW_CONF_MASK,
.min_mode = USI_MODE_NONE,
.max_mode = USI_MODE_I2C,
.num_clks = ARRAY_SIZE(exynos850_usi_clk_names),
.clk_names = exynos850_usi_clk_names,
};
static const struct exynos_usi_variant exynos8895_usi_data = {
.ver = USI_VER1,
.sw_conf_mask = USI_V1_SW_CONF_MASK,
.min_mode = USI_MODE_NONE,
.max_mode = USI_MODE_UART_I2C1,
.num_clks = ARRAY_SIZE(exynos850_usi_clk_names),
.clk_names = exynos850_usi_clk_names,
};
static const struct of_device_id exynos_usi_dt_match[] = {
{
.compatible = "samsung,exynos850-usi",
.data = &exynos850_usi_data,
}, {
.compatible = "samsung,exynos8895-usi",
.data = &exynos8895_usi_data,
},
{ } /* sentinel */
};
MODULE_DEVICE_TABLE(of, exynos_usi_dt_match);
/**
* exynos_usi_set_sw_conf - Set USI block configuration mode
* @usi: USI driver object
* @mode: Mode index
*
* Select underlying serial protocol (UART/SPI/I2C) in USI IP-core.
*
* Return: 0 on success, or negative error code on failure.
*/
static int exynos_usi_set_sw_conf(struct exynos_usi *usi, size_t mode)
{
unsigned int val;
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/clk.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/regmap.h`.
- Detected declarations: `struct exynos_usi_variant`, `struct exynos_usi`, `struct exynos_usi_mode`, `enum exynos_usi_ver`, `function protocol`, `function behavior`, `function exynos_usi_configure`, `function exynos_usi_unconfigure`, `function exynos_usi_parse_dt`, `function exynos_usi_get_clocks`.
- Atlas domain: Driver Families / drivers/soc.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.