drivers/i2c/muxes/i2c-demux-pinctrl.c
Source file repositories/reference/linux-study-clean/drivers/i2c/muxes/i2c-demux-pinctrl.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/muxes/i2c-demux-pinctrl.c- Extension
.c- Size
- 8582 bytes
- Lines
- 327
- Domain
- Driver Families
- Bucket
- drivers/i2c
- 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/i2c.hlinux/init.hlinux/module.hlinux/of.hlinux/pinctrl/consumer.hlinux/platform_device.hlinux/pm_runtime.hlinux/slab.hlinux/sysfs.h
Detected Declarations
struct i2c_demux_pinctrl_chanstruct i2c_demux_pinctrl_privfunction i2c_demux_master_xferfunction i2c_demux_functionalityfunction i2c_demux_activate_masterfunction i2c_demux_deactivate_masterfunction i2c_demux_change_masterfunction available_masters_showfunction current_master_showfunction current_master_storefunction i2c_demux_pinctrl_probefunction i2c_demux_pinctrl_remove
Annotated Snippet
struct i2c_demux_pinctrl_chan {
struct device_node *parent_np;
struct i2c_adapter *parent_adap;
struct of_changeset chgset;
};
struct i2c_demux_pinctrl_priv {
int cur_chan;
int num_chan;
struct device *dev;
const char *bus_name;
struct i2c_adapter cur_adap;
struct i2c_algorithm algo;
struct i2c_demux_pinctrl_chan chan[] __counted_by(num_chan);
};
static int i2c_demux_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
return __i2c_transfer(parent, msgs, num);
}
static u32 i2c_demux_functionality(struct i2c_adapter *adap)
{
struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
return parent->algo->functionality(parent);
}
static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 new_chan)
{
struct i2c_adapter *adap;
struct pinctrl *p;
int ret;
ret = of_changeset_apply(&priv->chan[new_chan].chgset);
if (ret)
goto err;
adap = of_get_i2c_adapter_by_node(priv->chan[new_chan].parent_np);
if (!adap) {
ret = -ENODEV;
goto err_with_revert;
}
/*
* Check if there are pinctrl states at all. Note: we can't use
* devm_pinctrl_get_select() because we need to distinguish between
* the -ENODEV from devm_pinctrl_get() and pinctrl_lookup_state().
*/
p = devm_pinctrl_get(adap->dev.parent);
if (IS_ERR(p)) {
ret = PTR_ERR(p);
/* continue if just no pinctrl states (e.g. i2c-gpio), otherwise exit */
if (ret != -ENODEV)
goto err_with_put;
} else {
/* there are states. check and use them */
struct pinctrl_state *s = pinctrl_lookup_state(p, priv->bus_name);
if (IS_ERR(s)) {
ret = PTR_ERR(s);
goto err_with_put;
}
ret = pinctrl_select_state(p, s);
if (ret < 0)
goto err_with_put;
}
priv->chan[new_chan].parent_adap = adap;
priv->cur_chan = new_chan;
/* Now fill out current adapter structure. cur_chan must be up to date */
priv->algo.xfer = i2c_demux_master_xfer;
if (adap->algo->master_xfer_atomic)
priv->algo.xfer_atomic = i2c_demux_master_xfer;
priv->algo.functionality = i2c_demux_functionality;
snprintf(priv->cur_adap.name, sizeof(priv->cur_adap.name),
"i2c-demux (master i2c-%d)", i2c_adapter_id(adap));
priv->cur_adap.owner = THIS_MODULE;
priv->cur_adap.algo = &priv->algo;
priv->cur_adap.algo_data = priv;
priv->cur_adap.dev.parent = &adap->dev;
priv->cur_adap.class = adap->class;
priv->cur_adap.retries = adap->retries;
priv->cur_adap.timeout = adap->timeout;
Annotation
- Immediate include surface: `linux/i2c.h`, `linux/init.h`, `linux/module.h`, `linux/of.h`, `linux/pinctrl/consumer.h`, `linux/platform_device.h`, `linux/pm_runtime.h`, `linux/slab.h`.
- Detected declarations: `struct i2c_demux_pinctrl_chan`, `struct i2c_demux_pinctrl_priv`, `function i2c_demux_master_xfer`, `function i2c_demux_functionality`, `function i2c_demux_activate_master`, `function i2c_demux_deactivate_master`, `function i2c_demux_change_master`, `function available_masters_show`, `function current_master_show`, `function current_master_store`.
- Atlas domain: Driver Families / drivers/i2c.
- 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.