[U-Boot] [PATCH 19/29] dm: ahci: Drop use of probe_ent

Simon Glass sjg at chromium.org
Mon Jun 5 19:15:06 UTC 2017


With driver model we cannot have static data or assume that there is only
one device of each time. Adjust the code so that 'probe_ent' is not needed
with driver model. Add a new ahci_init_dm() function which can init AHCI
for driver model without re-allocating the uclass data. Move over the only
existing driver to use this new function.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 drivers/ata/ahci.c     | 75 +++++++++++++++++++++++++++++++-------------------
 drivers/ata/dwc_ahci.c |  2 +-
 include/ahci.h         |  8 ++++++
 3 files changed, 55 insertions(+), 30 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index e9867656a9..cadf685415 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -26,7 +26,9 @@
 
 static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port);
 
+#ifndef CONFIG_DM_SCSI
 struct ahci_uc_priv *probe_ent = NULL;
+#endif
 
 #define writel_with_flush(a,b)	do { writel(a,b); readl(b); } while (0)
 
@@ -428,25 +430,16 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv)
 
 #ifndef CONFIG_SCSI_AHCI_PLAT
 # if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
-static int ahci_init_one(struct udevice *dev)
+static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev)
 # else
-static int ahci_init_one(pci_dev_t dev)
+static int ahci_init_one(struct ahci_uc_priv *uc_priv, pci_dev_t dev)
 # endif
 {
-	struct ahci_uc_priv *uc_priv;
 #if !defined(CONFIG_DM_SCSI)
 	u16 vendor;
 #endif
 	int rc;
 
-	probe_ent = malloc(sizeof(struct ahci_uc_priv));
-	if (!probe_ent) {
-		printf("%s: No memory for uc_priv\n", __func__);
-		return -ENOMEM;
-	}
-
-	uc_priv = probe_ent;
-	memset(uc_priv, 0, sizeof(struct ahci_uc_priv));
 	uc_priv->dev = dev;
 
 	uc_priv->host_flags = ATA_FLAG_SATA
@@ -998,6 +991,12 @@ void scsi_low_level_init(int busdevfunc)
 	struct ahci_uc_priv *uc_priv;
 
 #ifndef CONFIG_SCSI_AHCI_PLAT
+	probe_ent = calloc(1, sizeof(struct ahci_uc_priv));
+	if (!probe_ent) {
+		printf("%s: No memory for uc_priv\n", __func__);
+		return;
+	}
+	uc_priv = probe_ent;
 # if defined(CONFIG_DM_PCI)
 	struct udevice *dev;
 	int ret;
@@ -1005,12 +1004,13 @@ void scsi_low_level_init(int busdevfunc)
 	ret = dm_pci_bus_find_bdf(busdevfunc, &dev);
 	if (ret)
 		return;
-	ahci_init_one(dev);
+	ahci_init_one(uc_priv, dev);
 # else
-	ahci_init_one(busdevfunc);
+	ahci_init_one(uc_priv, busdevfunc);
 # endif
-#endif
+#else
 	uc_priv = probe_ent;
+#endif
 
 	ahci_start_ports(uc_priv);
 }
@@ -1020,32 +1020,24 @@ void scsi_low_level_init(int busdevfunc)
 # if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
 int achi_init_one_dm(struct udevice *dev)
 {
-	return ahci_init_one(dev);
+	struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	return ahci_init_one(uc_priv, dev);
 }
 #endif
 #endif
 
 int achi_start_ports_dm(struct udevice *dev)
 {
-	struct ahci_uc_priv *uc_priv = probe_ent;
+	struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	return ahci_start_ports(uc_priv);
 }
 
 #ifdef CONFIG_SCSI_AHCI_PLAT
-int ahci_init(void __iomem *base)
+static int ahci_init_common(struct ahci_uc_priv *uc_priv, void __iomem *base)
 {
-	struct ahci_uc_priv *uc_priv;
-	int rc = 0;
-
-	probe_ent = malloc(sizeof(struct ahci_uc_priv));
-	if (!probe_ent) {
-		printf("%s: No memory for uc_priv\n", __func__);
-		return -ENOMEM;
-	}
-
-	uc_priv = probe_ent;
-	memset(uc_priv, 0, sizeof(struct ahci_uc_priv));
+	int rc;
 
 	uc_priv->host_flags = ATA_FLAG_SATA
 				| ATA_FLAG_NO_LEGACY
@@ -1070,11 +1062,36 @@ err_out:
 	return rc;
 }
 
+#ifndef CONFIG_DM_SCSI
+int ahci_init(void __iomem *base)
+{
+	struct ahci_uc_priv *uc_priv;
+
+	probe_ent = malloc(sizeof(struct ahci_uc_priv));
+	if (!probe_ent) {
+		printf("%s: No memory for uc_priv\n", __func__);
+		return -ENOMEM;
+	}
+
+	uc_priv = probe_ent;
+	memset(uc_priv, 0, sizeof(struct ahci_uc_priv));
+
+	return ahci_init_common(uc_priv, base);
+}
+#endif
+
+int ahci_init_dm(struct udevice *dev, void __iomem *base)
+{
+	struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	return ahci_init_common(uc_priv, base);
+}
+
 void __weak scsi_init(void)
 {
 }
 
-#endif
+#endif /* CONFIG_SCSI_AHCI_PLAT */
 
 /*
  * In the general case of generic rotating media it makes sense to have a
diff --git a/drivers/ata/dwc_ahci.c b/drivers/ata/dwc_ahci.c
index eadd77944c..401201717f 100644
--- a/drivers/ata/dwc_ahci.c
+++ b/drivers/ata/dwc_ahci.c
@@ -81,7 +81,7 @@ static int dwc_ahci_probe(struct udevice *dev)
 		writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG);
 	}
 
-	ret = ahci_init(priv->base);
+	ret = ahci_init_dm(dev, priv->base);
 	if (ret)
 		return ret;
 
diff --git a/include/ahci.h b/include/ahci.h
index 8f48178449..648e56a4cf 100644
--- a/include/ahci.h
+++ b/include/ahci.h
@@ -195,4 +195,12 @@ int achi_init_one_dm(struct udevice *dev);
  */
 int achi_start_ports_dm(struct udevice *dev);
 
+/**
+ * ahci_init_dm() - init AHCI for a controller, finding all ports
+ *
+ * @dev: Device to init
+ * @return 0 if OK, -ve on error
+ */
+int ahci_init_dm(struct udevice *dev, void __iomem *base);
+
 #endif
-- 
2.13.0.506.g27d5fe0cd-goog



More information about the U-Boot mailing list