
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 ---
Changes in v2: None
drivers/ata/ahci.c | 73 ++++++++++++++++++++++++++++++-------------------- drivers/ata/dwc_ahci.c | 2 +- include/ahci.h | 7 +++++ 3 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e9867656a9..2f77e6030d 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 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 ec5b0c7d9d..3d61ad1fce 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