drivers/platform/x86/lenovo/wmi-capdata.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/lenovo/wmi-capdata.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/lenovo/wmi-capdata.c
Extension
.c
Size
23806 bytes
Lines
829
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

struct lwmi_cd_priv {
	struct notifier_block acpi_nb; /* ACPI events */
	struct wmi_device *wdev;
	struct cd_list *list;

	/*
	 * A capdata device may be a component master of another capdata device.
	 * E.g., lenovo-wmi-other <-> capdata00 <-> capdata_fan
	 *       |- master            |- component
	 *                            |- sub-master
	 *                                          |- sub-component
	 */
	struct lwmi_cd_sub_master_priv {
		struct device *master_dev;
		cd_list_cb_t master_cb;
		struct cd_list *sub_component_list; /* ERR_PTR(-ENODEV) implies no sub-component. */
		bool registered;                    /* Has the sub-master been registered? */
	} *sub_master;
};

struct cd_list {
	struct mutex list_mutex; /* list R/W mutex */
	enum lwmi_cd_type type;
	u8 count;

	union {
		DECLARE_FLEX_ARRAY(struct capdata00, cd00);
		DECLARE_FLEX_ARRAY(struct capdata01, cd01);
		DECLARE_FLEX_ARRAY(struct capdata_fan, cd_fan);
	};
};

static struct wmi_driver lwmi_cd_driver;

/**
 * lwmi_cd_match() - Match rule for the master driver.
 * @dev: Pointer to the capability data parent device.
 * @type: Pointer to capability data type (enum lwmi_cd_type *) to match.
 *
 * Return: int.
 */
static int lwmi_cd_match(struct device *dev, void *type)
{
	struct lwmi_cd_priv *priv;

	if (dev->driver != &lwmi_cd_driver.driver)
		return false;

	priv = dev_get_drvdata(dev);
	return priv->list->type == *(enum lwmi_cd_type *)type;
}

/**
 * lwmi_cd_match_add_all() - Add all match rule for the master driver.
 * @master: Pointer to the master device.
 * @matchptr: Pointer to the returned component_match pointer.
 *
 * Adds all component matches to the list stored in @matchptr for the @master
 * device. @matchptr must be initialized to NULL.
 */
void lwmi_cd_match_add_all(struct device *master, struct component_match **matchptr)
{
	int i;

	if (WARN_ON(*matchptr))
		return;

	for (i = 0; i < ARRAY_SIZE(lwmi_cd_table); i++) {
		/* Skip sub-components. */
		if (lwmi_cd_table[i].type == LENOVO_FAN_TEST_DATA)
			continue;

		component_match_add(master, matchptr, lwmi_cd_match,
				    (void *)&lwmi_cd_table[i].type);
		if (IS_ERR(*matchptr))
			return;
	}
}
EXPORT_SYMBOL_NS_GPL(lwmi_cd_match_add_all, "LENOVO_WMI_CAPDATA");

/**
 * lwmi_cd_call_master_cb() - Call the master callback for the sub-component.
 * @priv: Pointer to the capability data private data.
 *
 * Call the master callback and pass the sub-component list to it if the
 * dependency chain (master <-> sub-master <-> sub-component) is complete.
 */
static void lwmi_cd_call_master_cb(struct lwmi_cd_priv *priv)
{
	struct cd_list *sub_component_list = priv->sub_master->sub_component_list;

Annotation

Implementation Notes