+ if (ret)
+ continue;
+
+ mac_val = prop->integer.value;
+
+ if (mac_val & (~0ULL << 48))
+ continue; /* more than 6 bytes */
+
+ for (j = 0; j < ARRAY_SIZE(mac); j++)
+ mac[j] = (u8)(mac_val >> (8 * j));
+ if (!is_valid_ether_addr(mac))
+ continue;
+
+ memcpy(dst, mac, ETH_ALEN);
+
+ return 0;
+ }
+
+ return ret ? ret : -EINVAL;
+}
+
+static acpi_status bgx_acpi_register_phy(acpi_handle handle,
+ u32 lvl, void *context, void **rv)
+{
+ struct acpi_reference_args args;
+ const union acpi_object *prop;
+ struct bgx *bgx = context;
+ struct acpi_device *adev;
+ struct device *phy_dev;
+ u32 phy_id;
+
+ if (acpi_bus_get_device(handle, &adev))
+ goto out;
+
+ SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
+
+ acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
+
+ bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
+
+ if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
+ goto out;
+
+ if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER,
&prop))
+ goto out;
+
+ phy_id = prop->integer.value;
+
+ phy_dev = bus_find_device(&mdio_bus_type, NULL, (void *)&phy_id,
+ bgx_match_phy_id);
+ if (!phy_dev)
+ goto out;
+
+ bgx->lmac[bgx->lmac_count].phydev = to_phy_device(phy_dev);
+out:
+ bgx->lmac_count++;
+ return AE_OK;
+}
+
+static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
+ void *context, void **ret_val)
+{
+ struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct bgx *bgx = context;
+ char bgx_sel[5];
+
+ snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id);
+ if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &string))) {
+ pr_warn("Invalid link device\n");
+ return AE_OK;
+ }
+
+ if (strncmp(string.pointer, bgx_sel, 4))
+ return AE_OK;
+
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ bgx_acpi_register_phy, NULL, bgx, NULL);
+
+ kfree(string.pointer);
+ return AE_CTRL_TERMINATE;
+}
+
+static int bgx_init_acpi_phy(struct bgx *bgx)
+{
+ acpi_get_devices(NULL, bgx_acpi_match_id, bgx, (void **)NULL);
+ return 0;
+}
+
+#else
+
+static int bgx_init_acpi_phy(struct bgx *bgx)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_ACPI */
+
#if IS_ENABLED(CONFIG_OF_MDIO)
static int bgx_init_of_phy(struct bgx *bgx)
@@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
static int bgx_init_phy(struct bgx *bgx)
{
- return bgx_init_of_phy(bgx);
+ int err = bgx_init_of_phy(bgx);
+
+ if (err != -ENODEV)
+ return err;
+
+ return bgx_init_acpi_phy(bgx);
}
static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html