drivers/net/ethernet/qualcomm/emac/emac-sgmii.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
Extension
.c
Size
11380 bytes
Lines
459
Domain
Driver Families
Bucket
drivers/net
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 emac_match_data {
	struct sgmii_ops **sgmii_ops;
	struct device *target_device;
};

static int emac_sgmii_acpi_match(struct device *dev, void *data)
{
#ifdef CONFIG_ACPI
	static const struct acpi_device_id match_table[] = {
		{
			.id = "QCOM8071",
		},
		{}
	};
	const struct acpi_device_id *id = acpi_match_device(match_table, dev);
	struct emac_match_data *match_data = data;

	if (id) {
		acpi_handle handle = ACPI_HANDLE(dev);
		unsigned long long hrv;
		acpi_status status;

		status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
		if (status) {
			if (status == AE_NOT_FOUND)
				/* Older versions of the QDF2432 ACPI tables do
				 * not have an _HRV property.
				 */
				hrv = 1;
			else
				/* Something is wrong with the tables */
				return 0;
		}

		switch (hrv) {
		case 1:
			*match_data->sgmii_ops = &qdf2432_ops;
			match_data->target_device = dev;
			return 1;
		case 2:
			*match_data->sgmii_ops = &qdf2400_ops;
			match_data->target_device = dev;
			return 1;
		}
	}
#endif

	return 0;
}

static const struct of_device_id emac_sgmii_dt_match[] = {
	{
		.compatible = "qcom,fsm9900-emac-sgmii",
		.data = &fsm9900_ops,
	},
	{
		.compatible = "qcom,qdf2432-emac-sgmii",
		.data = &qdf2432_ops,
	},
	{}
};

int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt)
{
	struct platform_device *sgmii_pdev = NULL;
	struct emac_sgmii *phy = &adpt->phy;
	struct resource *res;
	int ret;

	if (has_acpi_companion(&pdev->dev)) {
		struct emac_match_data match_data = {
			.sgmii_ops = &phy->sgmii_ops,
			.target_device = NULL,
		};
		struct device *dev;

		device_for_each_child(&pdev->dev, &match_data, emac_sgmii_acpi_match);
		dev = match_data.target_device;

		if (!dev) {
			dev_warn(&pdev->dev, "cannot find internal phy node\n");
			return 0;
		}

		get_device(dev);
		sgmii_pdev = to_platform_device(dev);
	} else {
		const struct of_device_id *match;
		struct device_node *np;

Annotation

Implementation Notes