aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2017-06-14 21:28:38 -0600
committerSimon Glass <sjg@chromium.org>2017-07-11 10:08:19 -0600
commit4279efc4c949116535bb99f4aa74260d93f82b92 (patch)
tree6e2216bdef8a49a4d332d68c1f15187d7cf246d8
parent7cf1afce7fa3fe64189020fe14b93f7326dd0758 (diff)
downloadu-boot-4279efc4c949116535bb99f4aa74260d93f82b92.zip
u-boot-4279efc4c949116535bb99f4aa74260d93f82b92.tar.gz
u-boot-4279efc4c949116535bb99f4aa74260d93f82b92.tar.bz2
dm: ahci: Drop use of probe_ent
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@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r--drivers/ata/ahci.c73
-rw-r--r--drivers/ata/dwc_ahci.c2
-rw-r--r--include/ahci.h7
3 files changed, 52 insertions, 30 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index e986765..2f77e60 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -428,25 +428,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 +989,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 +1002,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 +1018,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 +1060,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 eadd779..4012017 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 ec5b0c7..3d61ad1 100644
--- a/include/ahci.h
+++ b/include/ahci.h
@@ -193,4 +193,11 @@ 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
+ */
+int ahci_init_dm(struct udevice *dev, void __iomem *base);
+
#endif