drivers/acpi/acpi_apd.c

Source file repositories/reference/linux-study-clean/drivers/acpi/acpi_apd.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/acpi_apd.c
Extension
.c
Size
7099 bytes
Lines
281
Domain
Driver Families
Bucket
drivers/acpi
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct apd_device_desc {
	unsigned int fixed_clk_rate;
	struct property_entry *properties;
	int (*setup)(struct apd_private_data *pdata);
};

struct apd_private_data {
	struct clk *clk;
	struct acpi_device *adev;
	const struct apd_device_desc *dev_desc;
};

#if defined(CONFIG_X86_AMD_PLATFORM_DEVICE) || defined(CONFIG_ARM64)
#define APD_ADDR(desc)	((unsigned long)&desc)

static int acpi_apd_setup(struct apd_private_data *pdata)
{
	const struct apd_device_desc *dev_desc = pdata->dev_desc;
	struct clk *clk;

	if (dev_desc->fixed_clk_rate) {
		clk = clk_register_fixed_rate(&pdata->adev->dev,
					dev_name(&pdata->adev->dev),
					NULL, 0, dev_desc->fixed_clk_rate);
		clk_register_clkdev(clk, NULL, dev_name(&pdata->adev->dev));
		pdata->clk = clk;
	}

	return 0;
}

#ifdef CONFIG_X86_AMD_PLATFORM_DEVICE

static int fch_misc_setup(struct apd_private_data *pdata)
{
	struct acpi_device *adev = pdata->adev;
	const union acpi_object *obj;
	struct platform_device *clkdev;
	struct fch_clk_data *clk_data;
	struct resource_entry *rentry;
	struct list_head resource_list;
	int ret;

	clk_data = devm_kzalloc(&adev->dev, sizeof(*clk_data), GFP_KERNEL);
	if (!clk_data)
		return -ENOMEM;

	INIT_LIST_HEAD(&resource_list);
	ret = acpi_dev_get_memory_resources(adev, &resource_list);
	if (ret < 0)
		return -ENOENT;

	if (!acpi_dev_get_property(adev, "clk-name", ACPI_TYPE_STRING, &obj)) {
		clk_data->name = devm_kzalloc(&adev->dev, obj->string.length,
					      GFP_KERNEL);
		if (!clk_data->name)
			return -ENOMEM;

		strscpy(clk_data->name, obj->string.pointer, obj->string.length);
	} else {
		/* Set default name to mclk if entry missing in firmware */
		clk_data->name = "mclk";
	}

	list_for_each_entry(rentry, &resource_list, node) {
		clk_data->base = devm_ioremap(&adev->dev, rentry->res->start,
					      resource_size(rentry->res));
		break;
	}
	if (!clk_data->base)
		return -ENOMEM;

	acpi_dev_free_resource_list(&resource_list);

	clkdev = platform_device_register_data(&adev->dev, "clk-fch",
					       PLATFORM_DEVID_NONE, clk_data,
					       sizeof(*clk_data));
	return PTR_ERR_OR_ZERO(clkdev);
}

static const struct apd_device_desc cz_i2c_desc = {
	.setup = acpi_apd_setup,
	.fixed_clk_rate = 133000000,
};

static const struct apd_device_desc wt_i2c_desc = {
	.setup = acpi_apd_setup,
	.fixed_clk_rate = 150000000,
};

Annotation

Implementation Notes