*/
#include <common.h>
+#include <blk.h>
#include <command.h>
#include <console.h>
+#include <cpu_func.h>
+#include <log.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/fsl_serdes.h>
#include <libata.h>
#include <fis.h>
#include <sata.h>
+#include <linux/delay.h>
#include "fsl_sata.h"
#if CONFIG_IS_ENABLED(BLK)
#include <dm.h>
#include <ahci.h>
#include <blk.h>
+#include <dm/device-internal.h>
#else
#ifndef CONFIG_SYS_SATA1_FLAGS
#define CONFIG_SYS_SATA1_FLAGS FLAGS_DMA
/* Zero all of the device driver struct */
memset((void *)sata, 0, sizeof(fsl_sata_t));
- snprintf(sata->name, 12, "SATA%d:\n", dev);
+ snprintf(sata->name, 12, "SATA%d:", dev);
/* Set the controller register base address to device struct */
#if !CONFIG_IS_ENABLED(BLK)
mdelay(100);
/* print sata device name */
- if (!dev)
- printf("%s ", sata->name);
- else
- printf(" %s ", sata->name);
+ printf("%s ", sata->name);
/* Wait PHY RDY signal changed for 500ms */
ata_wait_register(®->hstatus, HSTATUS_PHY_RDY,
static ulong sata_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
void *buffer)
{
- struct fsl_ata_priv *priv = dev_get_platdata(dev);
+ struct fsl_ata_priv *priv = dev_get_plat(dev);
fsl_sata_t *sata = priv->fsl_sata;
#endif
u32 rc;
static ulong sata_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
const void *buffer)
{
- struct fsl_ata_priv *priv = dev_get_platdata(dev);
+ struct fsl_ata_priv *priv = dev_get_plat(dev);
fsl_sata_t *sata = priv->fsl_sata;
#endif
u32 rc;
#else
static int scan_sata(struct udevice *dev)
{
- struct blk_desc *desc = dev_get_uclass_platdata(dev);
- struct fsl_ata_priv *priv = dev_get_platdata(dev);
+ struct blk_desc *desc = dev_get_uclass_plat(dev);
+ struct fsl_ata_priv *priv = dev_get_plat(dev);
fsl_sata_t *sata = priv->fsl_sata;
#endif
.name = "sata_fsl_blk",
.id = UCLASS_BLK,
.ops = &sata_fsl_blk_ops,
- .platdata_auto_alloc_size = sizeof(struct fsl_ata_priv),
+ .plat_auto = sizeof(struct fsl_ata_priv),
};
-static int fsl_ata_ofdata_to_platdata(struct udevice *dev)
+static int fsl_ata_of_to_plat(struct udevice *dev)
{
struct fsl_ata_priv *priv = dev_get_priv(dev);
return 0;
}
+static int fsl_unbind_device(struct udevice *dev)
+{
+ int ret;
+
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
+ if (ret)
+ return ret;
+
+ ret = device_unbind(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int fsl_ata_probe(struct udevice *dev)
{
struct fsl_ata_priv *blk_priv, *priv;
struct udevice *blk;
+ int failed_number;
char sata_name[10];
int nr_ports;
int ret;
int i;
+ failed_number = 0;
priv = dev_get_priv(dev);
nr_ports = priv->number;
nr_ports = min(nr_ports, CONFIG_SYS_SATA_MAX_DEVICE);
ret = init_sata(priv, i);
if (ret) {
debug("%s: Failed to init sata\n", __func__);
- return ret;
+ ret = fsl_unbind_device(blk);
+ if (ret)
+ return ret;
+
+ failed_number++;
+ continue;
}
- blk_priv = dev_get_platdata(blk);
+ blk_priv = dev_get_plat(blk);
blk_priv->fsl_sata = priv->fsl_sata;
/* Scan SATA port */
ret = scan_sata(blk);
if (ret) {
debug("%s: Failed to scan bus\n", __func__);
- return ret;
+ ret = fsl_unbind_device(blk);
+ if (ret)
+ return ret;
+
+ failed_number++;
+ continue;
}
}
+ if (failed_number == nr_ports)
+ return -ENODEV;
+ else
+ return 0;
+}
+
+static int fsl_ata_remove(struct udevice *dev)
+{
+ fsl_sata_t *sata;
+ struct fsl_ata_priv *priv;
+
+ priv = dev_get_priv(dev);
+ sata = priv->fsl_sata;
+
+ free(sata->cmd_hdr_tbl_offset);
+ free(sata->cmd_desc_offset);
+ free(sata);
+
return 0;
}
.id = UCLASS_AHCI,
.of_match = fsl_ata_ids,
.ops = &sata_fsl_ahci_ops,
- .ofdata_to_platdata = fsl_ata_ofdata_to_platdata,
+ .of_to_plat = fsl_ata_of_to_plat,
.probe = fsl_ata_probe,
- .priv_auto_alloc_size = sizeof(struct fsl_ata_priv),
+ .remove = fsl_ata_remove,
+ .priv_auto = sizeof(struct fsl_ata_priv),
};
#endif