drivers/hsi/hsi_core.c
Source file repositories/reference/linux-study-clean/drivers/hsi/hsi_core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hsi/hsi_core.c- Extension
.c- Size
- 18081 bytes
- Lines
- 761
- Domain
- Driver Families
- Bucket
- drivers/hsi
- 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
linux/hsi/hsi.hlinux/compiler.hlinux/list.hlinux/kobject.hlinux/slab.hlinux/string.hlinux/notifier.hlinux/of.hlinux/of_device.hhsi_core.h
Detected Declarations
function Copyrightfunction hsi_bus_ueventfunction hsi_bus_matchfunction hsi_client_releasefunction hsi_scan_board_infofunction list_for_each_entryfunction hsi_of_property_parse_modefunction hsi_of_property_parse_flowfunction hsi_of_property_parse_arb_modefunction hsi_add_client_from_dtfunction hsi_add_clients_from_dtfunction hsi_remove_clientfunction hsi_remove_portfunction hsi_controller_releasefunction hsi_port_releasefunction hsi_port_unregister_clientsfunction hsi_unregister_controllerfunction hsi_register_controllerfunction hsi_register_client_driverfunction hsi_dummy_msgfunction hsi_dummy_clfunction hsi_put_controllerfunction hsi_free_msgfunction hsi_asyncfunction hsi_claim_portfunction hsi_release_portfunction hsi_event_notifier_callfunction hsi_register_port_eventfunction hsi_unregister_port_eventfunction hsi_eventfunction hsi_get_channel_id_by_namefunction hsi_initfunction hsi_exitexport hsi_new_clientexport hsi_add_clients_from_dtexport hsi_remove_clientexport hsi_port_unregister_clientsexport hsi_unregister_controllerexport hsi_register_controllerexport hsi_register_client_driverexport hsi_put_controllerexport hsi_alloc_controllerexport hsi_free_msgexport hsi_alloc_msgexport hsi_asyncexport hsi_claim_portexport hsi_release_portexport hsi_register_port_event
Annotated Snippet
static int hsi_bus_match(struct device *dev, const struct device_driver *driver)
{
if (of_driver_match_device(dev, driver))
return true;
if (strcmp(dev_name(dev), driver->name) == 0)
return true;
return false;
}
static const struct bus_type hsi_bus_type = {
.name = "hsi",
.dev_groups = hsi_bus_dev_groups,
.match = hsi_bus_match,
.uevent = hsi_bus_uevent,
};
static void hsi_client_release(struct device *dev)
{
struct hsi_client *cl = to_hsi_client(dev);
kfree(cl->tx_cfg.channels);
kfree(cl->rx_cfg.channels);
kfree(cl);
}
struct hsi_client *hsi_new_client(struct hsi_port *port,
struct hsi_board_info *info)
{
struct hsi_client *cl;
size_t size;
cl = kzalloc_obj(*cl);
if (!cl)
goto err;
cl->tx_cfg = info->tx_cfg;
if (cl->tx_cfg.channels) {
size = cl->tx_cfg.num_channels * sizeof(*cl->tx_cfg.channels);
cl->tx_cfg.channels = kmemdup(info->tx_cfg.channels, size,
GFP_KERNEL);
if (!cl->tx_cfg.channels)
goto err_tx;
}
cl->rx_cfg = info->rx_cfg;
if (cl->rx_cfg.channels) {
size = cl->rx_cfg.num_channels * sizeof(*cl->rx_cfg.channels);
cl->rx_cfg.channels = kmemdup(info->rx_cfg.channels, size,
GFP_KERNEL);
if (!cl->rx_cfg.channels)
goto err_rx;
}
cl->device.bus = &hsi_bus_type;
cl->device.parent = &port->device;
cl->device.release = hsi_client_release;
dev_set_name(&cl->device, "%s", info->name);
cl->device.platform_data = info->platform_data;
if (info->archdata)
cl->device.archdata = *info->archdata;
if (device_register(&cl->device) < 0) {
pr_err("hsi: failed to register client: %s\n", info->name);
put_device(&cl->device);
goto err;
}
return cl;
err_rx:
kfree(cl->tx_cfg.channels);
err_tx:
kfree(cl);
err:
return NULL;
}
EXPORT_SYMBOL_GPL(hsi_new_client);
static void hsi_scan_board_info(struct hsi_controller *hsi)
{
struct hsi_cl_info *cl_info;
struct hsi_port *p;
list_for_each_entry(cl_info, &hsi_board_list, list)
if (cl_info->info.hsi_id == hsi->id) {
p = hsi_find_port_num(hsi, cl_info->info.port);
if (!p)
continue;
hsi_new_client(p, &cl_info->info);
}
Annotation
- Immediate include surface: `linux/hsi/hsi.h`, `linux/compiler.h`, `linux/list.h`, `linux/kobject.h`, `linux/slab.h`, `linux/string.h`, `linux/notifier.h`, `linux/of.h`.
- Detected declarations: `function Copyright`, `function hsi_bus_uevent`, `function hsi_bus_match`, `function hsi_client_release`, `function hsi_scan_board_info`, `function list_for_each_entry`, `function hsi_of_property_parse_mode`, `function hsi_of_property_parse_flow`, `function hsi_of_property_parse_arb_mode`, `function hsi_add_client_from_dt`.
- Atlas domain: Driver Families / drivers/hsi.
- 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.