diff options
author | Haojian Zhuang <haojian.zhuang@linaro.org> | 2014-04-03 21:30:19 +0800 |
---|---|---|
committer | Haojian Zhuang <haojian.zhuang@linaro.org> | 2014-04-03 21:30:19 +0800 |
commit | 82d9e993026e44bd72f95271f2e7089aa9efb6f9 (patch) | |
tree | d1954e361dec6b492d8b022c2481b1be263122a6 | |
parent | 469df8a09cdb70db7e4df280e0829a23195f4e33 (diff) |
ata: ahci: support hisilicon devicesata_serdes_0403
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
-rw-r--r-- | drivers/ata/ahci_platform.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 6a76f505ba92..e0e626c7e4d8 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -20,6 +20,8 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/device.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/libata.h> #include <linux/ahci_platform.h> @@ -31,6 +33,7 @@ enum ahci_type { AHCI, /* standard platform ahci */ IMX53_AHCI, /* ahci on i.mx53 */ STRICT_AHCI, /* delayed DMA engine start */ + HIP04_AHCI, /* ahci on HiP04 */ }; static struct platform_device_id ahci_devtype[] = { @@ -81,12 +84,38 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_platform_ops, }, + [HIP04_AHCI] = { + AHCI_HFLAGS (AHCI_HFLAG_NO_FBS), + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_platform_ops, + }, }; static struct scsi_host_template ahci_platform_sht = { AHCI_SHT("ahci_platform"), }; +static const struct of_device_id ahci_of_match[] = { + { .compatible = "snps,spear-ahci", }, + { .compatible = "snps,exynos5440-ahci", }, + { .compatible = "hisilicon,hisi-ahci", .data = (void *)HIP04_AHCI, }, + {}, +}; +MODULE_DEVICE_TABLE(of, ahci_of_match); + +static int ahci_match_of_id(struct platform_device *pdev, + enum ahci_type *ahci_type) +{ + const struct of_device_id *of_id = of_match_device(ahci_of_match, + &pdev->dev); + if (!of_id) + return 1; + *ahci_type = (u32)(of_id->data); + return 0; +} + static int ahci_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -97,6 +126,7 @@ static int ahci_probe(struct platform_device *pdev) struct ahci_host_priv *hpriv; struct ata_host *host; struct resource *mem; + enum ahci_type ahci_type; int irq; int n_ports; int i; @@ -114,7 +144,9 @@ static int ahci_probe(struct platform_device *pdev) return -EINVAL; } - if (pdata && pdata->ata_port_info) + if (!ahci_match_of_id(pdev, &ahci_type)) + pi = ahci_port_info[ahci_type]; + else if (pdata && pdata->ata_port_info) pi = *pdata->ata_port_info; hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); @@ -158,11 +190,6 @@ static int ahci_probe(struct platform_device *pdev) pdata ? pdata->force_port_map : 0, pdata ? pdata->mask_port_map : 0); -#ifdef CONFIG_ARCH_HIP04 - /* hip04 ahci has hardware issue(error bit of FBS feature) */ - hpriv->cap &= ~HOST_CAP_FBS; - hpriv->saved_cap &= ~HOST_CAP_FBS; -#endif /* prepare host */ if (hpriv->cap & HOST_CAP_NCQ) pi.flags |= ATA_FLAG_NCQ; @@ -331,14 +358,6 @@ disable_unprepare_clk: static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); -static const struct of_device_id ahci_of_match[] = { - { .compatible = "snps,spear-ahci", }, - { .compatible = "snps,exynos5440-ahci", }, - { .compatible = "hisilicon,hisi-ahci", }, - {}, -}; -MODULE_DEVICE_TABLE(of, ahci_of_match); - static struct platform_driver ahci_driver = { .probe = ahci_probe, .remove = ata_platform_remove_one, |