drivers/media/common/siano/smsdvb-debugfs.c

Source file repositories/reference/linux-study-clean/drivers/media/common/siano/smsdvb-debugfs.c

File Facts

System
Linux kernel
Corpus path
drivers/media/common/siano/smsdvb-debugfs.c
Extension
.c
Size
14569 bytes
Lines
421
Domain
Driver Families
Bucket
drivers/media
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations debugfs_stats_ops = {
	.open = smsdvb_stats_open,
	.poll = smsdvb_stats_poll,
	.read = smsdvb_stats_read,
	.release = smsdvb_stats_release,
	.llseek = generic_file_llseek,
};

/*
 * Functions used by smsdvb, in order to create the interfaces
 */

int smsdvb_debugfs_create(struct smsdvb_client_t *client)
{
	struct smscore_device_t *coredev = client->coredev;
	struct smsdvb_debugfs *debug_data;

	if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
		return -ENODEV;

	debug_data = kzalloc_obj(*client->debug_data);
	if (!debug_data)
		return -ENOMEM;

	client->debugfs = debugfs_create_dir(coredev->devpath,
					     smsdvb_debugfs_usb_root);

	debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
			    client, &debugfs_stats_ops);

	client->debug_data        = debug_data;
	client->prt_dvb_stats     = smsdvb_print_dvb_stats;
	client->prt_isdb_stats    = smsdvb_print_isdb_stats;
	client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;

	init_waitqueue_head(&debug_data->stats_queue);
	spin_lock_init(&debug_data->lock);
	kref_init(&debug_data->refcount);

	return 0;
}

void smsdvb_debugfs_release(struct smsdvb_client_t *client)
{
	if (!client->debugfs)
		return;

	client->prt_dvb_stats     = NULL;
	client->prt_isdb_stats    = NULL;
	client->prt_isdb_stats_ex = NULL;

	debugfs_remove_recursive(client->debugfs);
	kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);

	client->debug_data = NULL;
	client->debugfs = NULL;
}

void smsdvb_debugfs_register(void)
{
	/*
	 * FIXME: This was written to debug Siano USB devices. So, it creates
	 * the debugfs node under <debugfs>/usb.
	 * A similar logic would be needed for Siano sdio devices, but, in that
	 * case, usb_debug_root is not a good choice.
	 *
	 * Perhaps the right fix here would be to create another sysfs root
	 * node for sdio-based boards, but this may need some logic at sdio
	 * subsystem.
	 */
	smsdvb_debugfs_usb_root = debugfs_create_dir("smsdvb", usb_debug_root);
}

void smsdvb_debugfs_unregister(void)
{
	if (!smsdvb_debugfs_usb_root)
		return;
	debugfs_remove_recursive(smsdvb_debugfs_usb_root);
	smsdvb_debugfs_usb_root = NULL;
}

Annotation

Implementation Notes