]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ata: libahci_platform: use flex array for platform PHYs
authorRosen Penev <rosenp@gmail.com>
Mon, 30 Mar 2026 20:37:37 +0000 (13:37 -0700)
committerNiklas Cassel <cassel@kernel.org>
Tue, 31 Mar 2026 08:29:35 +0000 (10:29 +0200)
Modify struct ahci_host_priv to use a flexible array member for an adapter
port PHYs and use struct_size to combine the allocation of this array
together with the adapter private data structure. __counted_by() annotation
is added for the phys field to support runtime analysis.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
drivers/ata/ahci.h
drivers/ata/libahci_platform.c

index 293b7fb216b51738e94998704998cec2100f2d0f..9e8b6319025c440a56bcf6d5096aed48e7535436 100644 (file)
@@ -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);
 };
 
 /*
index f37247e7a5cbdf9324c71790d6634253fd3bc6c0..6e072d681341a58213e9058d445c97838d8e0ec5 100644 (file)
@@ -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