net: qcom/emac: Find sgmii_ops by device_for_each_child()
authorZijun Hu <quic_zijuhu@quicinc.com>
Thu, 3 Oct 2024 17:27:27 +0000 (10:27 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 8 Oct 2024 07:34:06 +0000 (09:34 +0200)
To prepare for constifying the following old driver core API:

struct device *device_find_child(struct device *dev, void *data,
int (*match)(struct device *dev, void *data));
to new:
struct device *device_find_child(struct device *dev, const void *data,
int (*match)(struct device *dev, const void *data));

The new API does not allow its match function (*match)() to modify
caller's match data @*data, but emac_sgmii_acpi_match(), as the old
API's match function, indeed modifies relevant match data, so it is
not suitable for the new API any more, solved by implementing the same
finding sgmii_ops function by correcting the function and using it
as parameter of device_for_each_child() instead of device_find_child().

By the way, this commit does not change any existing logic.

Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
Link: https://patch.msgid.link/20241003-qcom_emac_fix-v6-1-0658e3792ca4@quicinc.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/qualcomm/emac/emac-sgmii.c

index e4bc18009d08799b5462a54bc13e2b5b412f2307..a508ebc4b206f9d71234e5e7dcdfea3637d9f1c6 100644 (file)
@@ -293,6 +293,11 @@ static struct sgmii_ops qdf2400_ops = {
 };
 #endif
 
+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
@@ -303,7 +308,7 @@ static int emac_sgmii_acpi_match(struct device *dev, void *data)
                {}
        };
        const struct acpi_device_id *id = acpi_match_device(match_table, dev);
-       struct sgmii_ops **ops = data;
+       struct emac_match_data *match_data = data;
 
        if (id) {
                acpi_handle handle = ACPI_HANDLE(dev);
@@ -324,10 +329,12 @@ static int emac_sgmii_acpi_match(struct device *dev, void *data)
 
                switch (hrv) {
                case 1:
-                       *ops = &qdf2432_ops;
+                       *match_data->sgmii_ops = &qdf2432_ops;
+                       match_data->target_device = dev;
                        return 1;
                case 2:
-                       *ops = &qdf2400_ops;
+                       *match_data->sgmii_ops = &qdf2400_ops;
+                       match_data->target_device = dev;
                        return 1;
                }
        }
@@ -356,16 +363,21 @@ int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt)
        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;
 
-               dev = device_find_child(&pdev->dev, &phy->sgmii_ops,
-                                       emac_sgmii_acpi_match);
+               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;