drivers/i2c/i2c-core-base.c
Source file repositories/reference/linux-study-clean/drivers/i2c/i2c-core-base.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/i2c-core-base.c- Extension
.c- Size
- 75176 bytes
- Lines
- 2714
- Domain
- Driver Families
- Bucket
- drivers/i2c
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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
dt-bindings/i2c/i2c.hlinux/acpi.hlinux/clk/clk-conf.hlinux/completion.hlinux/debugfs.hlinux/delay.hlinux/err.hlinux/errno.hlinux/gpio/consumer.hlinux/i2c.hlinux/i2c-smbus.hlinux/idr.hlinux/init.hlinux/interrupt.hlinux/irq.hlinux/jump_label.hlinux/kernel.hlinux/module.hlinux/mutex.hlinux/of_device.hlinux/of.hlinux/pinctrl/consumer.hlinux/pinctrl/devinfo.hlinux/pm_domain.hlinux/pm_runtime.hlinux/pm_wakeirq.hlinux/property.hlinux/rwsem.hlinux/slab.hlinux/string_choices.hi2c-core.htrace/events/i2c.h
Detected Declarations
struct i2c_cmd_argfunction i2c_transfer_trace_regfunction i2c_transfer_trace_unregfunction i2c_device_matchfunction i2c_device_ueventfunction get_scl_gpio_valuefunction set_scl_gpio_valuefunction get_sda_gpio_valuefunction set_sda_gpio_valuefunction i2c_generic_bus_freefunction i2c_generic_scl_recoveryfunction i2c_recover_busfunction i2c_gpio_init_pinctrl_recoveryfunction i2c_gpio_init_generic_recoveryfunction i2c_gpio_init_recoveryfunction i2c_init_recoveryfunction i2c_smbus_host_notify_to_irqfunction i2c_device_probefunction i2c_device_removefunction i2c_device_shutdownfunction i2c_client_dev_releasefunction name_showfunction modalias_showfunction i2c_encode_flags_to_addrfunction i2c_check_addr_validityfunction i2c_check_7bit_addr_validity_strictfunction __i2c_check_addr_busyfunction i2c_check_mux_parentsfunction i2c_check_mux_childrenfunction i2c_check_addr_busyfunction i2c_adapter_lock_busfunction i2c_adapter_trylock_busfunction i2c_adapter_unlock_busfunction i2c_dev_set_namefunction i2c_dev_irq_from_resourcesfunction i2c_lock_addrfunction i2c_unlock_addrfunction i2c_new_client_devicefunction i2c_unregister_devicefunction i2c_find_device_by_fwnodefunction dummy_probefunction devm_i2c_release_dummyfunction i2c_adapter_dev_releasefunction i2c_adapter_depthfunction new_device_storefunction delete_device_storefunction i2c_scan_static_board_infofunction i2c_do_add_adapter
Annotated Snippet
static int i2c_device_match(struct device *dev, const struct device_driver *drv)
{
struct i2c_client *client = i2c_verify_client(dev);
const struct i2c_driver *driver;
/* Attempt an OF style match */
if (i2c_of_match_device(drv->of_match_table, client))
return 1;
/* Then ACPI style match */
if (acpi_driver_match_device(dev, drv))
return 1;
driver = to_i2c_driver(drv);
/* Finally an I2C match */
if (i2c_match_id(driver->id_table, client))
return 1;
return 0;
}
static int i2c_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
const struct i2c_client *client = to_i2c_client(dev);
int rc;
rc = of_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
rc = acpi_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
return add_uevent_var(env, "MODALIAS=%s%s", I2C_MODULE_PREFIX, client->name);
}
/* i2c bus recovery routines */
static int get_scl_gpio_value(struct i2c_adapter *adap)
{
return gpiod_get_value_cansleep(adap->bus_recovery_info->scl_gpiod);
}
static void set_scl_gpio_value(struct i2c_adapter *adap, int val)
{
gpiod_set_value_cansleep(adap->bus_recovery_info->scl_gpiod, val);
}
static int get_sda_gpio_value(struct i2c_adapter *adap)
{
return gpiod_get_value_cansleep(adap->bus_recovery_info->sda_gpiod);
}
static void set_sda_gpio_value(struct i2c_adapter *adap, int val)
{
gpiod_set_value_cansleep(adap->bus_recovery_info->sda_gpiod, val);
}
static int i2c_generic_bus_free(struct i2c_adapter *adap)
{
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
int ret = -EOPNOTSUPP;
if (bri->get_bus_free)
ret = bri->get_bus_free(adap);
else if (bri->get_sda)
ret = bri->get_sda(adap);
if (ret < 0)
return ret;
return ret ? 0 : -EBUSY;
}
/*
* We are generating clock pulses. ndelay() determines durating of clk pulses.
* We will generate clock with rate 100 KHz and so duration of both clock levels
* is: delay in ns = (10^6 / 100) / 2
*/
#define RECOVERY_NDELAY 5000
#define RECOVERY_CLK_CNT 9
int i2c_generic_scl_recovery(struct i2c_adapter *adap)
{
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
int i = 0, scl = 1, ret = 0;
if (bri->prepare_recovery)
Annotation
- Immediate include surface: `dt-bindings/i2c/i2c.h`, `linux/acpi.h`, `linux/clk/clk-conf.h`, `linux/completion.h`, `linux/debugfs.h`, `linux/delay.h`, `linux/err.h`, `linux/errno.h`.
- Detected declarations: `struct i2c_cmd_arg`, `function i2c_transfer_trace_reg`, `function i2c_transfer_trace_unreg`, `function i2c_device_match`, `function i2c_device_uevent`, `function get_scl_gpio_value`, `function set_scl_gpio_value`, `function get_sda_gpio_value`, `function set_sda_gpio_value`, `function i2c_generic_bus_free`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.