Use a flexible array member with struct_size to combine the allocations.

Added __counted_by support for extra runtime analysis.

Signed-off-by: Rosen Penev <[email protected]>
---
 v2: update commit title
 drivers/ata/ahci.h             |  3 ++-
 drivers/ata/libahci_platform.c | 33 +++++++++++++++------------------
 2 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 293b7fb216b5..9e8b6319025c 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -357,7 +357,6 @@ struct ahci_host_priv {
         * If platform uses PHYs. There is a 1:1 relation between the port 
number and
         * the PHY position in this array.
         */
-       struct phy              **phys;
        unsigned                nports;         /* Number of ports */
        void                    *plat_data;     /* Other platform data */
        unsigned int            irq;            /* interrupt line */
@@ -379,6 +378,8 @@ struct ahci_host_priv {
        /* only required for per-port MSI(-X) support */
        int                     (*get_irq_vector)(struct ata_host *host,
                                                  int port);
+
+       struct phy              *phys[] __counted_by(nports);
 };

 /*
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index f37247e7a5cb..6e072d681341 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -482,15 +482,29 @@ struct ahci_host_priv *ahci_platform_get_resources(struct 
platform_device *pdev,
        struct ahci_host_priv *hpriv;
        u32 mask_port_map = 0;
        u32 max_port;
+       int nports;

        if (!devres_open_group(dev, NULL, GFP_KERNEL))
                return ERR_PTR(-ENOMEM);

-       hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
+       /* find maximum port id for allocating structures */
+       max_port = ahci_platform_find_max_port_id(dev);
+       /*
+        * Set nports according to maximum port id. Clamp at
+        * AHCI_MAX_PORTS, warning message for invalid port id
+        * is generated later.
+        * When DT has no sub-nodes max_port is 0, nports is 1,
+        * in order to be able to use the
+        * ahci_platform_[en|dis]able_[phys|regulators] functions.
+        */
+       nports = min(AHCI_MAX_PORTS, max_port + 1);
+       hpriv = devres_alloc(ahci_platform_put_resources, struct_size(hpriv, 
phys, nports),
                             GFP_KERNEL);
        if (!hpriv)
                goto err_out;

+       hpriv->nports = nports;
+
        devres_add(dev, hpriv);

        /*
@@ -573,23 +587,6 @@ struct ahci_host_priv *ahci_platform_get_resources(struct 
platform_device *pdev,
                goto err_out;
        }

-       /* find maximum port id for allocating structures */
-       max_port = ahci_platform_find_max_port_id(dev);
-       /*
-        * Set nports according to maximum port id. Clamp at
-        * AHCI_MAX_PORTS, warning message for invalid port id
-        * is generated later.
-        * When DT has no sub-nodes max_port is 0, nports is 1,
-        * in order to be able to use the
-        * ahci_platform_[en|dis]able_[phys|regulators] functions.
-        */
-       hpriv->nports = min(AHCI_MAX_PORTS, max_port + 1);
-
-       hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), 
GFP_KERNEL);
-       if (!hpriv->phys) {
-               rc = -ENOMEM;
-               goto err_out;
-       }
        /*
         * We cannot use devm_ here, since ahci_platform_put_resources() uses
         * target_pwrs after devm_ have freed memory
--
2.53.0


Reply via email to