drivers/hwmon/pmbus/pmbus_core.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/pmbus/pmbus_core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/pmbus/pmbus_core.c- Extension
.c- Size
- 96892 bytes
- Lines
- 3860
- Domain
- Driver Families
- Bucket
- drivers/hwmon
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/atomic.hlinux/debugfs.hlinux/delay.hlinux/dcache.hlinux/kernel.hlinux/math64.hlinux/module.hlinux/init.hlinux/err.hlinux/slab.hlinux/i2c.hlinux/hwmon.hlinux/hwmon-sysfs.hlinux/pmbus.hlinux/regulator/driver.hlinux/regulator/machine.hlinux/thermal.hlinux/workqueue.hpmbus.h
Detected Declarations
struct pmbus_sensorstruct pmbus_booleanstruct pmbus_labelstruct pmbus_datastruct pmbus_debugfs_entrystruct pmbus_thermal_datastruct pmbus_limit_attrstruct pmbus_sensor_attrstruct pmbus_samples_attrstruct pmbus_samples_regstruct pmbus_class_attr_mapstruct pmbus_status_assocstruct pmbus_status_categorystruct pmbus_debugfs_datafunction pmbus_clear_cachefunction pmbus_set_updatefunction pmbus_waitfunction pmbus_update_tsfunction pmbus_set_pagefunction pmbus_write_bytefunction _pmbus_write_bytefunction pmbus_write_word_datafunction pmbus_write_virt_regfunction _pmbus_write_word_datafunction _pmbus_write_byte_datafunction _pmbus_read_byte_datafunction pmbus_update_fanfunction pmbus_read_word_datafunction pmbus_read_virt_regfunction _pmbus_read_word_datafunction __pmbus_read_word_datafunction pmbus_read_byte_datafunction pmbus_write_byte_datafunction pmbus_update_byte_datafunction pmbus_read_block_datafunction pmbus_get_fan_ratefunction pmbus_get_fan_rate_devicefunction pmbus_get_fan_rate_cachedfunction pmbus_clear_fault_pagefunction pmbus_clear_faultsfunction pmbus_check_status_cmlfunction pmbus_check_registerfunction pmbus_check_status_registerfunction pmbus_check_byte_registerfunction pmbus_check_word_registerfunction pmbus_check_block_registerfunction pmbus_get_statusfunction pmbus_update_sensor_data
Annotated Snippet
static const struct file_operations pmbus_debugfs_block_ops = {
.llseek = noop_llseek,
.read = pmbus_debugfs_block_read,
.write = NULL,
.open = simple_open,
};
static void pmbus_remove_symlink(void *symlink)
{
debugfs_remove(symlink);
}
struct pmbus_debugfs_data {
u8 reg;
u32 flag;
const char *name;
};
static const struct pmbus_debugfs_data pmbus_debugfs_block_data[] = {
{ .reg = PMBUS_MFR_ID, .name = "mfr_id" },
{ .reg = PMBUS_MFR_MODEL, .name = "mfr_model" },
{ .reg = PMBUS_MFR_REVISION, .name = "mfr_revision" },
{ .reg = PMBUS_MFR_LOCATION, .name = "mfr_location" },
{ .reg = PMBUS_MFR_DATE, .name = "mfr_date" },
{ .reg = PMBUS_MFR_SERIAL, .name = "mfr_serial" },
};
static const struct pmbus_debugfs_data pmbus_debugfs_status_data[] = {
{ .reg = PMBUS_STATUS_VOUT, .flag = PMBUS_HAVE_STATUS_VOUT, .name = "status%d_vout" },
{ .reg = PMBUS_STATUS_IOUT, .flag = PMBUS_HAVE_STATUS_IOUT, .name = "status%d_iout" },
{ .reg = PMBUS_STATUS_INPUT, .flag = PMBUS_HAVE_STATUS_INPUT, .name = "status%d_input" },
{ .reg = PMBUS_STATUS_TEMPERATURE, .flag = PMBUS_HAVE_STATUS_TEMP,
.name = "status%d_temp" },
{ .reg = PMBUS_STATUS_FAN_12, .flag = PMBUS_HAVE_STATUS_FAN12, .name = "status%d_fan12" },
{ .reg = PMBUS_STATUS_FAN_34, .flag = PMBUS_HAVE_STATUS_FAN34, .name = "status%d_fan34" },
{ .reg = PMBUS_STATUS_CML, .name = "status%d_cml" },
{ .reg = PMBUS_STATUS_OTHER, .name = "status%d_other" },
{ .reg = PMBUS_STATUS_MFR_SPECIFIC, .name = "status%d_mfr" },
};
static void pmbus_init_debugfs(struct i2c_client *client,
struct pmbus_data *data)
{
struct dentry *symlink_d, *debugfs = client->debugfs;
struct pmbus_debugfs_entry *entries;
const char *pathname, *symlink;
char name[PMBUS_NAME_SIZE];
int page, i, idx = 0;
/*
* client->debugfs may be NULL or an ERR_PTR(). dentry_path_raw()
* does not check if its parameters are valid, so validate
* client->debugfs before using it.
*/
if (!pmbus_debugfs_dir || IS_ERR_OR_NULL(debugfs))
return;
/*
* Backwards compatibility: Create symlink from /pmbus/<hwmon_device>
* to i2c debugfs directory.
*/
pathname = dentry_path_raw(debugfs, name, sizeof(name));
if (IS_ERR(pathname))
return;
/*
* The path returned by dentry_path_raw() starts with '/'. Prepend it
* with ".." to get the symlink relative to the pmbus root directory.
*/
symlink = kasprintf(GFP_KERNEL, "..%s", pathname);
if (!symlink)
return;
symlink_d = debugfs_create_symlink(dev_name(data->hwmon_dev),
pmbus_debugfs_dir, symlink);
kfree(symlink);
devm_add_action_or_reset(data->dev, pmbus_remove_symlink, symlink_d);
/*
* Allocate the max possible entries we need.
* device specific:
* ARRAY_SIZE(pmbus_debugfs_block_data) + 2
* page specific:
* ARRAY_SIZE(pmbus_debugfs_status_data) + 1
*/
entries = devm_kcalloc(data->dev,
ARRAY_SIZE(pmbus_debugfs_block_data) + 2 +
data->info->pages * (ARRAY_SIZE(pmbus_debugfs_status_data) + 1),
sizeof(*entries), GFP_KERNEL);
Annotation
- Immediate include surface: `linux/atomic.h`, `linux/debugfs.h`, `linux/delay.h`, `linux/dcache.h`, `linux/kernel.h`, `linux/math64.h`, `linux/module.h`, `linux/init.h`.
- Detected declarations: `struct pmbus_sensor`, `struct pmbus_boolean`, `struct pmbus_label`, `struct pmbus_data`, `struct pmbus_debugfs_entry`, `struct pmbus_thermal_data`, `struct pmbus_limit_attr`, `struct pmbus_sensor_attr`, `struct pmbus_samples_attr`, `struct pmbus_samples_reg`.
- Atlas domain: Driver Families / drivers/hwmon.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.