drivers/hid/amd-sfh-hid/amd_sfh_client.c
Source file repositories/reference/linux-study-clean/drivers/hid/amd-sfh-hid/amd_sfh_client.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hid/amd-sfh-hid/amd_sfh_client.c- Extension
.c- Size
- 11730 bytes
- Lines
- 386
- Domain
- Driver Families
- Bucket
- drivers/hid
- 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/dma-mapping.hlinux/hid.hlinux/list.hlinux/slab.hlinux/workqueue.hlinux/errno.hhid_descriptor/amd_sfh_hid_desc.hamd_sfh_pcie.hamd_sfh_hid.h
Detected Declarations
function amd_sfh_set_reportfunction amd_sfh_get_reportfunction amd_sfh_workfunction amd_sfh_work_bufferfunction amd_sfh_wait_for_responsefunction amd_sfh_resumefunction amd_sfh_suspendfunction amd_sfh_hid_client_initfunction amd_sfh_hid_client_deinit
Annotated Snippet
if (cli_data->hid_sensor_hubs[i] == hid) {
cli_data->cur_hid_dev = i;
break;
}
}
amdtp_hid_wakeup(hid);
}
int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type)
{
struct amdtp_hid_data *hid_data = hid->driver_data;
struct amdtp_cl_data *cli_data = hid_data->cli_data;
struct request_list *req_list = &cli_data->req_list;
struct amd_input_data *in_data = cli_data->in_data;
struct amd_mp2_dev *mp2;
int i;
mp2 = container_of(in_data, struct amd_mp2_dev, in_data);
guard(mutex)(&mp2->lock);
for (i = 0; i < cli_data->num_hid_devices; i++) {
if (cli_data->hid_sensor_hubs[i] == hid) {
struct request_list *new = kzalloc_obj(*new);
if (!new)
return -ENOMEM;
new->current_index = i;
new->sensor_idx = cli_data->sensor_idx[i];
new->hid = hid;
new->report_type = report_type;
new->report_id = report_id;
cli_data->report_id[i] = report_id;
cli_data->request_done[i] = false;
list_add(&new->list, &req_list->list);
break;
}
}
schedule_delayed_work(&cli_data->work, 0);
return 0;
}
void amd_sfh_work(struct work_struct *work)
{
struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work.work);
struct request_list *req_list = &cli_data->req_list;
struct amd_input_data *in_data = cli_data->in_data;
struct request_list *req_node;
u8 current_index, sensor_index;
struct amd_mp2_ops *mp2_ops;
struct amd_mp2_dev *mp2;
u8 report_id, node_type;
u8 report_size = 0;
mp2 = container_of(in_data, struct amd_mp2_dev, in_data);
guard(mutex)(&mp2->lock);
req_node = list_last_entry(&req_list->list, struct request_list, list);
list_del(&req_node->list);
current_index = req_node->current_index;
sensor_index = req_node->sensor_idx;
report_id = req_node->report_id;
node_type = req_node->report_type;
kfree(req_node);
mp2_ops = mp2->mp2_ops;
if (node_type == HID_FEATURE_REPORT) {
report_size = mp2_ops->get_feat_rep(sensor_index, report_id,
cli_data->feature_report[current_index]);
if (report_size)
hid_input_report(cli_data->hid_sensor_hubs[current_index],
cli_data->report_type[current_index],
cli_data->feature_report[current_index], report_size, 0);
else
pr_err("AMDSFH: Invalid report size\n");
} else if (node_type == HID_INPUT_REPORT) {
report_size = mp2_ops->get_in_rep(current_index, sensor_index, report_id, in_data);
if (report_size)
hid_input_report(cli_data->hid_sensor_hubs[current_index],
cli_data->report_type[current_index],
in_data->input_report[current_index], report_size, 0);
else
pr_err("AMDSFH: Invalid report size\n");
}
cli_data->cur_hid_dev = current_index;
cli_data->sensor_requested_cnt[current_index] = 0;
amdtp_hid_wakeup(cli_data->hid_sensor_hubs[current_index]);
if (!list_empty(&req_list->list))
schedule_delayed_work(&cli_data->work, 0);
}
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/hid.h`, `linux/list.h`, `linux/slab.h`, `linux/workqueue.h`, `linux/errno.h`, `hid_descriptor/amd_sfh_hid_desc.h`, `amd_sfh_pcie.h`.
- Detected declarations: `function amd_sfh_set_report`, `function amd_sfh_get_report`, `function amd_sfh_work`, `function amd_sfh_work_buffer`, `function amd_sfh_wait_for_response`, `function amd_sfh_resume`, `function amd_sfh_suspend`, `function amd_sfh_hid_client_init`, `function amd_sfh_hid_client_deinit`.
- Atlas domain: Driver Families / drivers/hid.
- 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.