aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/Kconfig11
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/ahci.c17
-rw-r--r--drivers/ata/ahci_imx.c236
-rw-r--r--drivers/ata/ata_piix.c2
-rw-r--r--drivers/ata/libata-acpi.c282
-rw-r--r--drivers/ata/libata-core.c29
-rw-r--r--drivers/ata/libata-pmp.c12
-rw-r--r--drivers/ata/libata-scsi.c44
-rw-r--r--drivers/ata/libata-transport.c2
-rw-r--r--drivers/ata/libata-zpodd.c12
-rw-r--r--drivers/ata/libata.h19
-rw-r--r--drivers/ata/pata_acpi.c4
-rw-r--r--drivers/ata/pata_arasan_cf.c4
-rw-r--r--drivers/ata/pata_at32.c2
-rw-r--r--drivers/ata/pata_at91.c2
-rw-r--r--drivers/ata/pata_imx.c1
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c4
-rw-r--r--drivers/ata/pata_octeon_cf.c2
-rw-r--r--drivers/ata/pata_platform.c2
-rw-r--r--drivers/ata/pata_pxa.c2
-rw-r--r--drivers/ata/pata_samsung_cf.c10
-rw-r--r--drivers/ata/sata_fsl.c5
-rw-r--r--drivers/ata/sata_highbank.c78
-rw-r--r--drivers/ata/sata_inic162x.c14
-rw-r--r--drivers/ata/sata_mv.c26
-rw-r--r--drivers/ata/sata_rcar.c5
27 files changed, 524 insertions, 304 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 80dc988f01e4..4e737728aee2 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -97,6 +97,15 @@ config SATA_AHCI_PLATFORM
If unsure, say N.
+config AHCI_IMX
+ tristate "Freescale i.MX AHCI SATA support"
+ depends on SATA_AHCI_PLATFORM && MFD_SYSCON
+ help
+ This option enables support for the Freescale i.MX SoC's
+ onboard AHCI SATA.
+
+ If unsure, say N.
+
config SATA_FSL
tristate "Freescale 3.0Gbps SATA support"
depends on FSL_SOC
@@ -107,7 +116,7 @@ config SATA_FSL
If unsure, say N.
config SATA_INIC162X
- tristate "Initio 162x SATA support"
+ tristate "Initio 162x SATA support (Very Experimental)"
depends on PCI
help
This option enables support for Initio 162x Serial ATA.
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index c04d0fd038a3..46518c622460 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
+obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 5064f3ea20f1..9d715ae5ff6b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1146,11 +1146,18 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis)
return rc;
for (i = 0; i < host->n_ports; i++) {
+ const char* desc;
struct ahci_port_priv *pp = host->ports[i]->private_data;
+ /* pp is NULL for dummy ports */
+ if (pp)
+ desc = pp->irq_desc;
+ else
+ desc = dev_driver_string(host->dev);
+
rc = devm_request_threaded_irq(host->dev,
irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED,
- pp->irq_desc, host->ports[i]);
+ desc, host->ports[i]);
if (rc)
goto out_free_irqs;
}
@@ -1288,6 +1295,14 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
if (!(hpriv->flags & AHCI_HFLAG_NO_FPDMA_AA))
pi.flags |= ATA_FLAG_FPDMA_AA;
+
+ /*
+ * All AHCI controllers should be forward-compatible
+ * with the new auxiliary field. This code should be
+ * conditionalized if any buggy AHCI controllers are
+ * encountered.
+ */
+ pi.flags |= ATA_FLAG_FPDMA_AUX;
}
if (hpriv->cap & HOST_CAP_PMP)
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
new file mode 100644
index 000000000000..58debb0acc3a
--- /dev/null
+++ b/drivers/ata/ahci_imx.c
@@ -0,0 +1,236 @@
+/*
+ * Freescale IMX AHCI SATA platform driver
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/ahci_platform.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include "ahci.h"
+
+enum {
+ HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
+};
+
+struct imx_ahci_priv {
+ struct platform_device *ahci_pdev;
+ struct clk *sata_ref_clk;
+ struct clk *ahb_clk;
+ struct regmap *gpr;
+};
+
+static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
+{
+ int ret = 0;
+ unsigned int reg_val;
+ struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+
+ imxpriv->gpr =
+ syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+ if (IS_ERR(imxpriv->gpr)) {
+ dev_err(dev, "failed to find fsl,imx6q-iomux-gpr regmap\n");
+ return PTR_ERR(imxpriv->gpr);
+ }
+
+ ret = clk_prepare_enable(imxpriv->sata_ref_clk);
+ if (ret < 0) {
+ dev_err(dev, "prepare-enable sata_ref clock err:%d\n", ret);
+ return ret;
+ }
+
+ /*
+ * set PHY Paremeters, two steps to configure the GPR13,
+ * one write for rest of parameters, mask of first write
+ * is 0x07fffffd, and the other one write for setting
+ * the mpll_clk_en.
+ */
+ regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK
+ | IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK
+ | IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK
+ | IMX6Q_GPR13_SATA_SPD_MODE_MASK
+ | IMX6Q_GPR13_SATA_MPLL_SS_EN
+ | IMX6Q_GPR13_SATA_TX_ATTEN_MASK
+ | IMX6Q_GPR13_SATA_TX_BOOST_MASK
+ | IMX6Q_GPR13_SATA_TX_LVL_MASK
+ | IMX6Q_GPR13_SATA_TX_EDGE_RATE
+ , IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB
+ | IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M
+ | IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F
+ | IMX6Q_GPR13_SATA_SPD_MODE_3P0G
+ | IMX6Q_GPR13_SATA_MPLL_SS_EN
+ | IMX6Q_GPR13_SATA_TX_ATTEN_9_16
+ | IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB
+ | IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
+ regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+ IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+ usleep_range(100, 200);
+
+ /*
+ * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
+ * and IP vendor specific register HOST_TIMER1MS.
+ * Configure CAP_SSS (support stagered spin up).
+ * Implement the port0.
+ * Get the ahb clock rate, and configure the TIMER1MS register.
+ */
+ reg_val = readl(mmio + HOST_CAP);
+ if (!(reg_val & HOST_CAP_SSS)) {
+ reg_val |= HOST_CAP_SSS;
+ writel(reg_val, mmio + HOST_CAP);
+ }
+ reg_val = readl(mmio + HOST_PORTS_IMPL);
+ if (!(reg_val & 0x1)) {
+ reg_val |= 0x1;
+ writel(reg_val, mmio + HOST_PORTS_IMPL);
+ }
+
+ reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
+ writel(reg_val, mmio + HOST_TIMER1MS);
+
+ return 0;
+}
+
+static void imx6q_sata_exit(struct device *dev)
+{
+ struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+
+ regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+ !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+ clk_disable_unprepare(imxpriv->sata_ref_clk);
+}
+
+static struct ahci_platform_data imx6q_sata_pdata = {
+ .init = imx6q_sata_init,
+ .exit = imx6q_sata_exit,
+};
+
+static const struct of_device_id imx_ahci_of_match[] = {
+ { .compatible = "fsl,imx6q-ahci", .data = &imx6q_sata_pdata},
+ {},
+};
+MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
+
+static int imx_ahci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *mem, *irq, res[2];
+ const struct of_device_id *of_id;
+ const struct ahci_platform_data *pdata = NULL;
+ struct imx_ahci_priv *imxpriv;
+ struct device *ahci_dev;
+ struct platform_device *ahci_pdev;
+ int ret;
+
+ imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
+ if (!imxpriv) {
+ dev_err(dev, "can't alloc ahci_host_priv\n");
+ return -ENOMEM;
+ }
+
+ ahci_pdev = platform_device_alloc("ahci", -1);
+ if (!ahci_pdev)
+ return -ENODEV;
+
+ ahci_dev = &ahci_pdev->dev;
+ ahci_dev->parent = dev;
+
+ imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
+ if (IS_ERR(imxpriv->ahb_clk)) {
+ dev_err(dev, "can't get ahb clock.\n");
+ ret = PTR_ERR(imxpriv->ahb_clk);
+ goto err_out;
+ }
+
+ imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
+ if (IS_ERR(imxpriv->sata_ref_clk)) {
+ dev_err(dev, "can't get sata_ref clock.\n");
+ ret = PTR_ERR(imxpriv->sata_ref_clk);
+ goto err_out;
+ }
+
+ imxpriv->ahci_pdev = ahci_pdev;
+ platform_set_drvdata(pdev, imxpriv);
+
+ of_id = of_match_device(imx_ahci_of_match, dev);
+ if (of_id) {
+ pdata = of_id->data;
+ } else {
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mem || !irq) {
+ dev_err(dev, "no mmio/irq resource\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ res[0] = *mem;
+ res[1] = *irq;
+
+ ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32);
+ ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
+ ahci_dev->of_node = dev->of_node;
+
+ ret = platform_device_add_resources(ahci_pdev, res, 2);
+ if (ret)
+ goto err_out;
+
+ ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
+ if (ret)
+ goto err_out;
+
+ ret = platform_device_add(ahci_pdev);
+ if (ret) {
+err_out:
+ platform_device_put(ahci_pdev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int imx_ahci_remove(struct platform_device *pdev)
+{
+ struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev);
+ struct platform_device *ahci_pdev = imxpriv->ahci_pdev;
+
+ platform_device_unregister(ahci_pdev);
+ return 0;
+}
+
+static struct platform_driver imx_ahci_driver = {
+ .probe = imx_ahci_probe,
+ .remove = imx_ahci_remove,
+ .driver = {
+ .name = "ahci-imx",
+ .owner = THIS_MODULE,
+ .of_match_table = imx_ahci_of_match,
+ },
+};
+module_platform_driver(imx_ahci_driver);
+
+MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver");
+MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ahci:imx");
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index b52a10c8eeb9..513ad7ed0c99 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -330,7 +330,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* SATA Controller IDE (Wellsburg) */
{ 0x8086, 0x8d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Wellsburg) */
- { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+ { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
/* SATA Controller IDE (Wellsburg) */
{ 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Wellsburg) */
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index cf4e7020adac..4ba8b0405572 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -34,14 +34,6 @@ struct ata_acpi_gtf {
u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
} __packed;
-/*
- * Helper - belongs in the PCI layer somewhere eventually
- */
-static int is_pci_dev(struct device *dev)
-{
- return (dev->bus == &pci_bus_type);
-}
-
static void ata_acpi_clear_gtf(struct ata_device *dev)
{
kfree(dev->gtf_cache);
@@ -49,47 +41,18 @@ static void ata_acpi_clear_gtf(struct ata_device *dev)
}
/**
- * ata_ap_acpi_handle - provide the acpi_handle for an ata_port
- * @ap: the acpi_handle returned will correspond to this port
- *
- * Returns the acpi_handle for the ACPI namespace object corresponding to
- * the ata_port passed into the function, or NULL if no such object exists
- */
-acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
-{
- if (ap->flags & ATA_FLAG_ACPI_SATA)
- return NULL;
-
- return ap->scsi_host ?
- DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev) : NULL;
-}
-EXPORT_SYMBOL(ata_ap_acpi_handle);
-
-/**
* ata_dev_acpi_handle - provide the acpi_handle for an ata_device
- * @dev: the acpi_device returned will correspond to this port
+ * @dev: the acpi_handle returned will correspond to this device
*
* Returns the acpi_handle for the ACPI namespace object corresponding to
* the ata_device passed into the function, or NULL if no such object exists
+ * or ACPI is disabled for this device due to consecutive errors.
*/
acpi_handle ata_dev_acpi_handle(struct ata_device *dev)
{
- acpi_integer adr;
- struct ata_port *ap = dev->link->ap;
-
- if (libata_noacpi || dev->flags & ATA_DFLAG_ACPI_DISABLED)
- return NULL;
-
- if (ap->flags & ATA_FLAG_ACPI_SATA) {
- if (!sata_pmp_attached(ap))
- adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
- else
- adr = SATA_ADR(ap->port_no, dev->link->pmp);
- return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), adr);
- } else
- return acpi_get_child(ata_ap_acpi_handle(ap), dev->devno);
+ return dev->flags & ATA_DFLAG_ACPI_DISABLED ?
+ NULL : ACPI_HANDLE(&dev->tdev);
}
-EXPORT_SYMBOL(ata_dev_acpi_handle);
/* @ap and @dev are the same as ata_acpi_handle_hotplug() */
static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
@@ -156,10 +119,8 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
spin_unlock_irqrestore(ap->lock, flags);
- if (wait) {
+ if (wait)
ata_port_wait_eh(ap);
- flush_work(&ap->hotplug_task.work);
- }
}
static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
@@ -216,37 +177,55 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
.uevent = ata_acpi_ap_uevent,
};
-void ata_acpi_hotplug_init(struct ata_host *host)
+/* bind acpi handle to pata port */
+void ata_acpi_bind_port(struct ata_port *ap)
{
- int i;
+ acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- acpi_handle handle;
- struct ata_device *dev;
+ if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_handle)
+ return;
- if (!ap)
- continue;
+ ACPI_HANDLE_SET(&ap->tdev, acpi_get_child(host_handle, ap->port_no));
- handle = ata_ap_acpi_handle(ap);
- if (handle) {
- /* we might be on a docking station */
- register_hotplug_dock_device(handle,
- &ata_acpi_ap_dock_ops, ap,
- NULL, NULL);
- }
+ if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
+ ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
- ata_for_each_dev(dev, &ap->link, ALL) {
- handle = ata_dev_acpi_handle(dev);
- if (!handle)
- continue;
+ /* we might be on a docking station */
+ register_hotplug_dock_device(ACPI_HANDLE(&ap->tdev),
+ &ata_acpi_ap_dock_ops, ap, NULL, NULL);
+}
- /* we might be on a docking station */
- register_hotplug_dock_device(handle,
- &ata_acpi_dev_dock_ops,
- dev, NULL, NULL);
- }
+void ata_acpi_bind_dev(struct ata_device *dev)
+{
+ struct ata_port *ap = dev->link->ap;
+ acpi_handle port_handle = ACPI_HANDLE(&ap->tdev);
+ acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
+ acpi_handle parent_handle;
+ u64 adr;
+
+ /*
+ * For both sata/pata devices, host handle is required.
+ * For pata device, port handle is also required.
+ */
+ if (libata_noacpi || !host_handle ||
+ (!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_handle))
+ return;
+
+ if (ap->flags & ATA_FLAG_ACPI_SATA) {
+ if (!sata_pmp_attached(ap))
+ adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
+ else
+ adr = SATA_ADR(ap->port_no, dev->link->pmp);
+ parent_handle = host_handle;
+ } else {
+ adr = dev->devno;
+ parent_handle = port_handle;
}
+
+ ACPI_HANDLE_SET(&dev->tdev, acpi_get_child(parent_handle, adr));
+
+ register_hotplug_dock_device(ata_dev_acpi_handle(dev),
+ &ata_acpi_dev_dock_ops, dev, NULL, NULL);
}
/**
@@ -270,18 +249,34 @@ void ata_acpi_dissociate(struct ata_host *host)
struct ata_port *ap = host->ports[i];
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
- if (ata_ap_acpi_handle(ap) && gtm)
+ if (ACPI_HANDLE(&ap->tdev) && gtm)
ata_acpi_stm(ap, gtm);
}
}
-static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
- struct ata_acpi_gtm *gtm)
+/**
+ * ata_acpi_gtm - execute _GTM
+ * @ap: target ATA port
+ * @gtm: out parameter for _GTM result
+ *
+ * Evaluate _GTM and store the result in @gtm.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
+ */
+int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
{
struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
union acpi_object *out_obj;
acpi_status status;
int rc = 0;
+ acpi_handle handle = ACPI_HANDLE(&ap->tdev);
+
+ if (!handle)
+ return -EINVAL;
status = acpi_evaluate_object(handle, "_GTM", NULL, &output);
@@ -317,27 +312,6 @@ static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
return rc;
}
-/**
- * ata_acpi_gtm - execute _GTM
- * @ap: target ATA port
- * @gtm: out parameter for _GTM result
- *
- * Evaluate _GTM and store the result in @gtm.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
- */
-int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
-{
- if (ata_ap_acpi_handle(ap))
- return __ata_acpi_gtm(ap, ata_ap_acpi_handle(ap), gtm);
- else
- return -EINVAL;
-}
-
EXPORT_SYMBOL_GPL(ata_acpi_gtm);
/**
@@ -374,8 +348,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
input.count = 3;
input.pointer = in_params;
- status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_STM", &input,
- NULL);
+ status = acpi_evaluate_object(ACPI_HANDLE(&ap->tdev), "_STM",
+ &input, NULL);
if (status == AE_NOT_FOUND)
return -ENOENT;
@@ -850,7 +824,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
struct ata_device *dev;
- if (ata_ap_acpi_handle(ap) && gtm) {
+ if (ACPI_HANDLE(&ap->tdev) && gtm) {
/* _GTM valid */
/* restore timing parameters */
@@ -894,8 +868,7 @@ static int ata_acpi_choose_suspend_state(struct ata_device *dev, bool runtime)
d_max_in = ACPI_STATE_D3_HOT;
out:
- return acpi_pm_device_sleep_state(&dev->sdev->sdev_gendev,
- NULL, d_max_in);
+ return acpi_pm_device_sleep_state(&dev->tdev, NULL, d_max_in);
}
static void sata_acpi_set_state(struct ata_port *ap, pm_message_t state)
@@ -932,7 +905,7 @@ static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
struct ata_device *dev;
acpi_handle port_handle;
- port_handle = ata_ap_acpi_handle(ap);
+ port_handle = ACPI_HANDLE(&ap->tdev);
if (!port_handle)
return;
@@ -947,11 +920,11 @@ static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
continue;
acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ?
- ACPI_STATE_D0 : ACPI_STATE_D3);
+ ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
}
if (!(state.event & PM_EVENT_RESUME))
- acpi_bus_set_power(port_handle, ACPI_STATE_D3);
+ acpi_bus_set_power(port_handle, ACPI_STATE_D3_COLD);
}
/**
@@ -1063,109 +1036,16 @@ void ata_acpi_on_disable(struct ata_device *dev)
ata_acpi_clear_gtf(dev);
}
-static int compat_pci_ata(struct ata_port *ap)
-{
- struct device *dev = ap->tdev.parent;
- struct pci_dev *pdev;
-
- if (!is_pci_dev(dev))
- return 0;
-
- pdev = to_pci_dev(dev);
-
- if ((pdev->class >> 8) != PCI_CLASS_STORAGE_SATA &&
- (pdev->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return 0;
-
- return 1;
-}
-
-static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
-{
- if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA)
- return -ENODEV;
-
- *handle = acpi_get_child(DEVICE_ACPI_HANDLE(ap->tdev.parent),
- ap->port_no);
-
- if (!*handle)
- return -ENODEV;
-
- if (__ata_acpi_gtm(ap, *handle, &ap->__acpi_init_gtm) == 0)
- ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
-
- return 0;
-}
-
-static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
- acpi_handle *handle)
-{
- struct ata_device *ata_dev;
-
- if (ap->flags & ATA_FLAG_ACPI_SATA) {
- if (!sata_pmp_attached(ap))
- ata_dev = &ap->link.device[sdev->id];
- else
- ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
- }
- else {
- ata_dev = &ap->link.device[sdev->id];
- }
-
- *handle = ata_dev_acpi_handle(ata_dev);
-
- if (!*handle)
- return -ENODEV;
-
- return 0;
-}
-
-static int is_ata_port(const struct device *dev)
-{
- return dev->type == &ata_port_type;
-}
-
-static struct ata_port *dev_to_ata_port(struct device *dev)
-{
- while (!is_ata_port(dev)) {
- if (!dev->parent)
- return NULL;
- dev = dev->parent;
- }
- return to_ata_port(dev);
-}
-
-static int ata_acpi_find_device(struct device *dev, acpi_handle *handle)
-{
- struct ata_port *ap = dev_to_ata_port(dev);
-
- if (!ap)
- return -ENODEV;
-
- if (!compat_pci_ata(ap))
- return -ENODEV;
-
- if (scsi_is_host_device(dev))
- return ata_acpi_bind_host(ap, handle);
- else if (scsi_is_sdev_device(dev)) {
- struct scsi_device *sdev = to_scsi_device(dev);
-
- return ata_acpi_bind_device(ap, sdev, handle);
- } else
- return -ENODEV;
-}
-
-static struct acpi_bus_type ata_acpi_bus = {
- .name = "ATA",
- .find_device = ata_acpi_find_device,
-};
-
-int ata_acpi_register(void)
+void ata_scsi_acpi_bind(struct ata_device *dev)
{
- return scsi_register_acpi_bus_type(&ata_acpi_bus);
+ acpi_handle handle = ata_dev_acpi_handle(dev);
+ if (handle)
+ acpi_dev_pm_add_dependent(handle, &dev->sdev->sdev_gendev);
}
-void ata_acpi_unregister(void)
+void ata_scsi_acpi_unbind(struct ata_device *dev)
{
- scsi_unregister_acpi_bus_type(&ata_acpi_bus);
+ acpi_handle handle = ata_dev_acpi_handle(dev);
+ if (handle)
+ acpi_dev_pm_remove_dependent(handle, &dev->sdev->sdev_gendev);
}
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c24354d44f3d..83b1a9fb2d44 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -569,10 +569,10 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis)
fis[14] = 0;
fis[15] = tf->ctl;
- fis[16] = 0;
- fis[17] = 0;
- fis[18] = 0;
- fis[19] = 0;
+ fis[16] = tf->auxiliary & 0xff;
+ fis[17] = (tf->auxiliary >> 8) & 0xff;
+ fis[18] = (tf->auxiliary >> 16) & 0xff;
+ fis[19] = (tf->auxiliary >> 24) & 0xff;
}
/**
@@ -2139,6 +2139,22 @@ static int ata_dev_config_ncq(struct ata_device *dev,
else
snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth,
ddepth, aa_desc);
+
+ if ((ap->flags & ATA_FLAG_FPDMA_AUX) &&
+ ata_id_has_ncq_send_and_recv(dev->id)) {
+ err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV,
+ 0, ap->sector_buf, 1);
+ if (err_mask) {
+ ata_dev_dbg(dev,
+ "failed to get NCQ Send/Recv Log Emask 0x%x\n",
+ err_mask);
+ } else {
+ dev->flags |= ATA_DFLAG_NCQ_SEND_RECV;
+ memcpy(dev->ncq_send_recv_cmds, ap->sector_buf,
+ ATA_LOG_NCQ_SEND_RECV_SIZE);
+ }
+ }
+
return 0;
}
@@ -6150,8 +6166,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
if (rc)
goto err_tadd;
- ata_acpi_hotplug_init(host);
-
/* set cable, sata_spd_limit and report */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
@@ -6632,8 +6646,6 @@ static int __init ata_init(void)
ata_parse_force_param();
- ata_acpi_register();
-
rc = ata_sff_init();
if (rc) {
kfree(ata_force_tbl);
@@ -6660,7 +6672,6 @@ static void __exit ata_exit(void)
ata_release_transport(ata_scsi_transport_template);
libata_transport_exit();
ata_sff_exit();
- ata_acpi_unregister();
kfree(ata_force_tbl);
}
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 1c41722bb7e2..20fd337a5731 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -289,24 +289,24 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
/* Disable sending Early R_OK.
* With "cached read" HDD testing and multiple ports busy on a SATA
- * host controller, 3726 PMP will very rarely drop a deferred
+ * host controller, 3x26 PMP will very rarely drop a deferred
* R_OK that was intended for the host. Symptom will be all
* 5 drives under test will timeout, get reset, and recover.
*/
- if (vendor == 0x1095 && devid == 0x3726) {
+ if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) {
u32 reg;
err_mask = sata_pmp_read(&ap->link, PMP_GSCR_SII_POL, &reg);
if (err_mask) {
rc = -EIO;
- reason = "failed to read Sil3726 Private Register";
+ reason = "failed to read Sil3x26 Private Register";
goto fail;
}
reg &= ~0x1;
err_mask = sata_pmp_write(&ap->link, PMP_GSCR_SII_POL, reg);
if (err_mask) {
rc = -EIO;
- reason = "failed to write Sil3726 Private Register";
+ reason = "failed to write Sil3x26 Private Register";
goto fail;
}
}
@@ -383,8 +383,8 @@ static void sata_pmp_quirks(struct ata_port *ap)
u16 devid = sata_pmp_gscr_devid(gscr);
struct ata_link *link;
- if (vendor == 0x1095 && devid == 0x3726) {
- /* sil3726 quirks */
+ if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) {
+ /* sil3x26 quirks */
ata_for_each_link(link, ap, EDGE) {
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 83c08907e042..97a0cef12959 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -49,7 +49,6 @@
#include <linux/hdreg.h>
#include <linux/uaccess.h>
#include <linux/suspend.h>
-#include <linux/pm_qos.h>
#include <asm/unaligned.h>
#include "libata.h"
@@ -206,8 +205,10 @@ static ssize_t ata_scsi_park_store(struct device *device,
unsigned long flags;
int rc;
- rc = strict_strtol(buf, 10, &input);
- if (rc || input < -2)
+ rc = kstrtol(buf, 10, &input);
+ if (rc)
+ return rc;
+ if (input < -2)
return -EINVAL;
if (input > ATA_TMOUT_MAX_PARK) {
rc = -EOVERFLOW;
@@ -3098,12 +3099,25 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
buf = page_address(sg_page(scsi_sglist(scmd)));
size = ata_set_lba_range_entries(buf, 512, block, n_block);
- tf->protocol = ATA_PROT_DMA;
- tf->hob_feature = 0;
- tf->feature = ATA_DSM_TRIM;
- tf->hob_nsect = (size / 512) >> 8;
- tf->nsect = size / 512;
- tf->command = ATA_CMD_DSM;
+ if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) {
+ /* Newer devices support queued TRIM commands */
+ tf->protocol = ATA_PROT_NCQ;
+ tf->command = ATA_CMD_FPDMA_SEND;
+ tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
+ tf->nsect = qc->tag << 3;
+ tf->hob_feature = (size / 512) >> 8;
+ tf->feature = size / 512;
+
+ tf->auxiliary = 1;
+ } else {
+ tf->protocol = ATA_PROT_DMA;
+ tf->hob_feature = 0;
+ tf->feature = ATA_DSM_TRIM;
+ tf->hob_nsect = (size / 512) >> 8;
+ tf->nsect = size / 512;
+ tf->command = ATA_CMD_DSM;
+ }
+
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
ATA_TFLAG_WRITE;
@@ -3665,9 +3679,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
if (!IS_ERR(sdev)) {
dev->sdev = sdev;
scsi_device_put(sdev);
- if (zpodd_dev_enabled(dev))
- dev_pm_qos_expose_flags(
- &sdev->sdev_gendev, 0);
+ ata_scsi_acpi_bind(dev);
} else {
dev->sdev = NULL;
}
@@ -3755,6 +3767,8 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
struct scsi_device *sdev;
unsigned long flags;
+ ata_scsi_acpi_unbind(dev);
+
/* Alas, we need to grab scan_mutex to ensure SCSI device
* state doesn't change underneath us and thus
* scsi_device_get() always succeeds. The mutex locking can
@@ -3764,9 +3778,6 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
mutex_lock(&ap->scsi_host->scan_mutex);
spin_lock_irqsave(ap->lock, flags);
- if (zpodd_dev_enabled(dev))
- zpodd_exit(dev);
-
/* clearing dev->sdev is protected by host lock */
sdev = dev->sdev;
dev->sdev = NULL;
@@ -3816,6 +3827,9 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
dev->flags &= ~ATA_DFLAG_DETACHED;
spin_unlock_irqrestore(ap->lock, flags);
+ if (zpodd_dev_enabled(dev))
+ zpodd_exit(dev);
+
ata_scsi_remove_dev(dev);
}
}
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index 077a856f5fd0..150a917f0c3c 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -287,6 +287,7 @@ int ata_tport_add(struct device *parent,
dev->release = ata_tport_release;
dev_set_name(dev, "ata%d", ap->print_id);
transport_setup_device(dev);
+ ata_acpi_bind_port(ap);
error = device_add(dev);
if (error) {
goto tport_err;
@@ -644,6 +645,7 @@ static int ata_tdev_add(struct ata_device *ata_dev)
dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
transport_setup_device(dev);
+ ata_acpi_bind_dev(ata_dev);
error = device_add(dev);
if (error) {
ata_tdev_free(ata_dev);
diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c
index cd8daf47188b..68f9e3293e9c 100644
--- a/drivers/ata/libata-zpodd.c
+++ b/drivers/ata/libata-zpodd.c
@@ -2,6 +2,7 @@
#include <linux/cdrom.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>
+#include <linux/pm_qos.h>
#include <scsi/scsi_device.h>
#include "libata.h"
@@ -190,8 +191,8 @@ void zpodd_enable_run_wake(struct ata_device *dev)
sdev_disable_disk_events(dev->sdev);
zpodd->powered_off = true;
- device_set_run_wake(&dev->sdev->sdev_gendev, true);
- acpi_pm_device_run_wake(&dev->sdev->sdev_gendev, true);
+ device_set_run_wake(&dev->tdev, true);
+ acpi_pm_device_run_wake(&dev->tdev, true);
}
/* Disable runtime wake capability if it is enabled */
@@ -200,8 +201,8 @@ void zpodd_disable_run_wake(struct ata_device *dev)
struct zpodd *zpodd = dev->zpodd;
if (zpodd->powered_off) {
- acpi_pm_device_run_wake(&dev->sdev->sdev_gendev, false);
- device_set_run_wake(&dev->sdev->sdev_gendev, false);
+ acpi_pm_device_run_wake(&dev->tdev, false);
+ device_set_run_wake(&dev->tdev, false);
}
}
@@ -262,7 +263,7 @@ static void ata_acpi_add_pm_notifier(struct ata_device *dev)
static void ata_acpi_remove_pm_notifier(struct ata_device *dev)
{
- acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->sdev->sdev_gendev);
+ acpi_handle handle = ata_dev_acpi_handle(dev);
acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, zpodd_wake_dev);
}
@@ -290,6 +291,7 @@ void zpodd_init(struct ata_device *dev)
ata_acpi_add_pm_notifier(dev);
zpodd->dev = dev;
dev->zpodd = zpodd;
+ dev_pm_qos_expose_flags(&dev->tdev, 0);
}
void zpodd_exit(struct ata_device *dev)
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 577d902bc4de..eeeb77845d48 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -118,11 +118,11 @@ extern void ata_acpi_on_resume(struct ata_port *ap);
extern int ata_acpi_on_devcfg(struct ata_device *dev);
extern void ata_acpi_on_disable(struct ata_device *dev);
extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state);
-extern int ata_acpi_register(void);
-extern void ata_acpi_unregister(void);
-extern void ata_acpi_bind(struct ata_device *dev);
-extern void ata_acpi_unbind(struct ata_device *dev);
-extern void ata_acpi_hotplug_init(struct ata_host *host);
+extern void ata_acpi_bind_port(struct ata_port *ap);
+extern void ata_acpi_bind_dev(struct ata_device *dev);
+extern acpi_handle ata_dev_acpi_handle(struct ata_device *dev);
+extern void ata_scsi_acpi_bind(struct ata_device *dev);
+extern void ata_scsi_acpi_unbind(struct ata_device *dev);
#else
static inline void ata_acpi_dissociate(struct ata_host *host) { }
static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
@@ -131,11 +131,10 @@ static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; }
static inline void ata_acpi_on_disable(struct ata_device *dev) { }
static inline void ata_acpi_set_state(struct ata_port *ap,
pm_message_t state) { }
-static inline int ata_acpi_register(void) { return 0; }
-static inline void ata_acpi_unregister(void) { }
-static inline void ata_acpi_bind(struct ata_device *dev) { }
-static inline void ata_acpi_unbind(struct ata_device *dev) { }
-static inline void ata_acpi_hotplug_init(struct ata_host *host) {}
+static inline void ata_acpi_bind_port(struct ata_port *ap) {}
+static inline void ata_acpi_bind_dev(struct ata_device *dev) {}
+static inline void ata_scsi_acpi_bind(struct ata_device *dev) {}
+static inline void ata_scsi_acpi_unbind(struct ata_device *dev) {}
#endif
/* libata-scsi.c */
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 09723b76beac..73212c9c6d5b 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -39,7 +39,7 @@ static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
{
struct ata_port *ap = link->ap;
struct pata_acpi *acpi = ap->private_data;
- if (ata_ap_acpi_handle(ap) == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
+ if (ACPI_HANDLE(&ap->tdev) == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
return -ENODEV;
return ata_sff_prereset(link, deadline);
@@ -195,7 +195,7 @@ static int pacpi_port_start(struct ata_port *ap)
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
struct pata_acpi *acpi;
- if (ata_ap_acpi_handle(ap) == NULL)
+ if (ACPI_HANDLE(&ap->tdev) == NULL)
return -ENODEV;
acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL);
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index 848ed3254ddd..853f610af28f 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -654,7 +654,7 @@ static void arasan_cf_freeze(struct ata_port *ap)
ata_sff_freeze(ap);
}
-void arasan_cf_error_handler(struct ata_port *ap)
+static void arasan_cf_error_handler(struct ata_port *ap)
{
struct arasan_cf_dev *acdev = ap->host->private_data;
@@ -683,7 +683,7 @@ static void arasan_cf_dma_start(struct arasan_cf_dev *acdev)
ata_sff_queue_work(&acdev->work);
}
-unsigned int arasan_cf_qc_issue(struct ata_queued_cmd *qc)
+static unsigned int arasan_cf_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct arasan_cf_dev *acdev = ap->host->private_data;
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c
index 8d493b4a0961..d59d5239405f 100644
--- a/drivers/ata/pata_at32.c
+++ b/drivers/ata/pata_at32.c
@@ -271,7 +271,7 @@ static int __init pata_at32_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct at32_ide_info *info;
- struct ide_platform_data *board = pdev->dev.platform_data;
+ struct ide_platform_data *board = dev_get_platdata(&pdev->dev);
struct resource *res;
int irq;
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c
index 5364f97b42c6..d63ee8f41a4f 100644
--- a/drivers/ata/pata_at91.c
+++ b/drivers/ata/pata_at91.c
@@ -315,7 +315,7 @@ static struct ata_port_operations pata_at91_port_ops = {
static int pata_at91_probe(struct platform_device *pdev)
{
- struct at91_cf_data *board = pdev->dev.platform_data;
+ struct at91_cf_data *board = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct at91_ide_info *info;
struct resource *mem_res;
diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c
index 4ec7c04b3f82..26386f0b89a8 100644
--- a/drivers/ata/pata_imx.c
+++ b/drivers/ata/pata_imx.c
@@ -237,6 +237,7 @@ static const struct of_device_id imx_pata_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, imx_pata_dt_ids);
static struct platform_driver pata_imx_driver = {
.probe = pata_imx_probe,
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index dcc6b243e525..1ec53f8ca96f 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -48,7 +48,7 @@ static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev,
u16 *buf16 = (u16 *) buf;
struct ata_port *ap = dev->link->ap;
void __iomem *mmio = ap->ioaddr.data_addr;
- struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
+ struct ixp4xx_pata_data *data = dev_get_platdata(ap->host->dev);
/* set the expansion bus in 16bit mode and restore
* 8 bit mode after the transaction.
@@ -143,7 +143,7 @@ static int ixp4xx_pata_probe(struct platform_device *pdev)
struct resource *cs0, *cs1;
struct ata_host *host;
struct ata_port *ap;
- struct ixp4xx_pata_data *data = pdev->dev.platform_data;
+ struct ixp4xx_pata_data *data = dev_get_platdata(&pdev->dev);
cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
index e73bef3093d2..c51bbb9ea8e8 100644
--- a/drivers/ata/pata_octeon_cf.c
+++ b/drivers/ata/pata_octeon_cf.c
@@ -1037,7 +1037,7 @@ static void octeon_cf_shutdown(struct device *dev)
union cvmx_mio_boot_dma_cfgx dma_cfg;
union cvmx_mio_boot_dma_intx dma_int;
- struct octeon_cf_port *cf_port = dev->platform_data;
+ struct octeon_cf_port *cf_port = dev_get_platdata(dev);
if (cf_port->dma_base) {
/* Stop and clear the dma engine. */
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 71e093767f4e..02794885de10 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -180,7 +180,7 @@ static int pata_platform_probe(struct platform_device *pdev)
struct resource *io_res;
struct resource *ctl_res;
struct resource *irq_res;
- struct pata_platform_info *pp_info = pdev->dev.platform_data;
+ struct pata_platform_info *pp_info = dev_get_platdata(&pdev->dev);
/*
* Simple resource validation ..
diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c
index 942ef94b29e6..a6f05acad61e 100644
--- a/drivers/ata/pata_pxa.c
+++ b/drivers/ata/pata_pxa.c
@@ -238,7 +238,7 @@ static int pxa_ata_probe(struct platform_device *pdev)
struct resource *ctl_res;
struct resource *dma_res;
struct resource *irq_res;
- struct pata_pxa_pdata *pdata = pdev->dev.platform_data;
+ struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
int ret = 0;
/*
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c
index 6ef27e98c508..898e544a7ae8 100644
--- a/drivers/ata/pata_samsung_cf.c
+++ b/drivers/ata/pata_samsung_cf.c
@@ -241,8 +241,8 @@ static u8 pata_s3c_check_altstatus(struct ata_port *ap)
/*
* pata_s3c_data_xfer - Transfer data by PIO
*/
-unsigned int pata_s3c_data_xfer(struct ata_device *dev, unsigned char *buf,
- unsigned int buflen, int rw)
+static unsigned int pata_s3c_data_xfer(struct ata_device *dev,
+ unsigned char *buf, unsigned int buflen, int rw)
{
struct ata_port *ap = dev->link->ap;
struct s3c_ide_info *info = ap->host->private_data;
@@ -418,7 +418,7 @@ static struct ata_port_operations pata_s5p_port_ops = {
.set_piomode = pata_s3c_set_piomode,
};
-static void pata_s3c_enable(void *s3c_ide_regbase, bool state)
+static void pata_s3c_enable(void __iomem *s3c_ide_regbase, bool state)
{
u32 temp = readl(s3c_ide_regbase + S3C_ATA_CTRL);
temp = state ? (temp | 1) : (temp & ~1);
@@ -475,7 +475,7 @@ static void pata_s3c_hwinit(struct s3c_ide_info *info,
static int __init pata_s3c_probe(struct platform_device *pdev)
{
- struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
+ struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct s3c_ide_info *info;
struct resource *res;
@@ -617,7 +617,7 @@ static int pata_s3c_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct ata_host *host = platform_get_drvdata(pdev);
- struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
+ struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
struct s3c_ide_info *info = host->private_data;
pata_s3c_hwinit(info, pdata);
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 19720a0a4a65..851bd3f43ac6 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -293,6 +293,7 @@ static void fsl_sata_set_irq_coalescing(struct ata_host *host,
{
struct sata_fsl_host_priv *host_priv = host->private_data;
void __iomem *hcr_base = host_priv->hcr_base;
+ unsigned long flags;
if (count > ICC_MAX_INT_COUNT_THRESHOLD)
count = ICC_MAX_INT_COUNT_THRESHOLD;
@@ -305,12 +306,12 @@ static void fsl_sata_set_irq_coalescing(struct ata_host *host,
(count > ICC_MIN_INT_COUNT_THRESHOLD))
ticks = ICC_SAFE_INT_TICKS;
- spin_lock(&host->lock);
+ spin_lock_irqsave(&host->lock, flags);
iowrite32((count << 24 | ticks), hcr_base + ICC);
intr_coalescing_count = count;
intr_coalescing_ticks = ticks;
- spin_unlock(&host->lock);
+ spin_unlock_irqrestore(&host->lock, flags);
DPRINTK("interrupt coalescing, count = 0x%x, ticks = %x\n",
intr_coalescing_count, intr_coalescing_ticks);
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index d047d92a456f..7f5e5d96327f 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -46,14 +46,19 @@
#define CR_BUSY 0x0001
#define CR_START 0x0001
#define CR_WR_RDN 0x0002
+#define CPHY_TX_INPUT_STS 0x2001
#define CPHY_RX_INPUT_STS 0x2002
-#define CPHY_SATA_OVERRIDE 0x4000
-#define CPHY_OVERRIDE 0x2005
+#define CPHY_SATA_TX_OVERRIDE 0x8000
+#define CPHY_SATA_RX_OVERRIDE 0x4000
+#define CPHY_TX_OVERRIDE 0x2004
+#define CPHY_RX_OVERRIDE 0x2005
#define SPHY_LANE 0x100
#define SPHY_HALF_RATE 0x0001
#define CPHY_SATA_DPLL_MODE 0x0700
#define CPHY_SATA_DPLL_SHIFT 8
#define CPHY_SATA_DPLL_RESET (1 << 11)
+#define CPHY_SATA_TX_ATTEN 0x1c00
+#define CPHY_SATA_TX_ATTEN_SHIFT 10
#define CPHY_PHY_COUNT 6
#define CPHY_LANE_COUNT 4
#define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT)
@@ -66,6 +71,7 @@ struct phy_lane_info {
void __iomem *phy_base;
u8 lane_mapping;
u8 phy_devs;
+ u8 tx_atten;
};
static struct phy_lane_info port_data[CPHY_PORT_COUNT];
@@ -76,9 +82,11 @@ static DEFINE_SPINLOCK(sgpio_lock);
#define SGPIO_PINS 3
#define SGPIO_PORTS 8
-/* can be cast as an ahci_host_priv for compatibility with most functions */
struct ecx_plat_data {
u32 n_ports;
+ /* number of extra clocks that the SGPIO PIC controller expects */
+ u32 pre_clocks;
+ u32 post_clocks;
unsigned sgpio_gpio[SGPIO_PINS];
u32 sgpio_pattern;
u32 port_to_sgpio[SGPIO_PORTS];
@@ -86,11 +94,11 @@ struct ecx_plat_data {
#define SGPIO_SIGNALS 3
#define ECX_ACTIVITY_BITS 0x300000
-#define ECX_ACTIVITY_SHIFT 2
+#define ECX_ACTIVITY_SHIFT 0
#define ECX_LOCATE_BITS 0x80000
#define ECX_LOCATE_SHIFT 1
#define ECX_FAULT_BITS 0x400000
-#define ECX_FAULT_SHIFT 0
+#define ECX_FAULT_SHIFT 2
static inline int sgpio_bit_shift(struct ecx_plat_data *pdata, u32 port,
u32 shift)
{
@@ -155,6 +163,9 @@ static ssize_t ecx_transmit_led_message(struct ata_port *ap, u32 state,
spin_lock_irqsave(&sgpio_lock, flags);
ecx_parse_sgpio(pdata, ap->port_no, state);
sgpio_out = pdata->sgpio_pattern;
+ for (i = 0; i < pdata->pre_clocks; i++)
+ ecx_led_cycle_clock(pdata);
+
gpio_set_value(pdata->sgpio_gpio[SLOAD], 1);
ecx_led_cycle_clock(pdata);
gpio_set_value(pdata->sgpio_gpio[SLOAD], 0);
@@ -167,6 +178,8 @@ static ssize_t ecx_transmit_led_message(struct ata_port *ap, u32 state,
sgpio_out >>= 1;
ecx_led_cycle_clock(pdata);
}
+ for (i = 0; i < pdata->post_clocks; i++)
+ ecx_led_cycle_clock(pdata);
/* save off new led state for port/slot */
emp->led_state = state;
@@ -201,6 +214,11 @@ static void highbank_set_em_messages(struct device *dev,
of_property_read_u32_array(np, "calxeda,led-order",
pdata->port_to_sgpio,
pdata->n_ports);
+ if (of_property_read_u32(np, "calxeda,pre-clocks", &pdata->pre_clocks))
+ pdata->pre_clocks = 0;
+ if (of_property_read_u32(np, "calxeda,post-clocks",
+ &pdata->post_clocks))
+ pdata->post_clocks = 0;
/* store em_loc */
hpriv->em_loc = 0;
@@ -259,8 +277,27 @@ static void highbank_cphy_disable_overrides(u8 sata_port)
if (unlikely(port_data[sata_port].phy_base == NULL))
return;
tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
- tmp &= ~CPHY_SATA_OVERRIDE;
- combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+ tmp &= ~CPHY_SATA_RX_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
+}
+
+static void cphy_override_tx_attenuation(u8 sata_port, u32 val)
+{
+ u8 lane = port_data[sata_port].lane_mapping;
+ u32 tmp;
+
+ if (val & 0x8)
+ return;
+
+ tmp = combo_phy_read(sata_port, CPHY_TX_INPUT_STS + lane * SPHY_LANE);
+ tmp &= ~CPHY_SATA_TX_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp |= CPHY_SATA_TX_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp |= (val << CPHY_SATA_TX_ATTEN_SHIFT) & CPHY_SATA_TX_ATTEN;
+ combo_phy_write(sata_port, CPHY_TX_OVERRIDE + lane * SPHY_LANE, tmp);
}
static void cphy_override_rx_mode(u8 sata_port, u32 val)
@@ -268,21 +305,21 @@ static void cphy_override_rx_mode(u8 sata_port, u32 val)
u8 lane = port_data[sata_port].lane_mapping;
u32 tmp;
tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
- tmp &= ~CPHY_SATA_OVERRIDE;
- combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+ tmp &= ~CPHY_SATA_RX_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
- tmp |= CPHY_SATA_OVERRIDE;
- combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+ tmp |= CPHY_SATA_RX_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp &= ~CPHY_SATA_DPLL_MODE;
tmp |= val << CPHY_SATA_DPLL_SHIFT;
- combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+ combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp |= CPHY_SATA_DPLL_RESET;
- combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+ combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
tmp &= ~CPHY_SATA_DPLL_RESET;
- combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+ combo_phy_write(sata_port, CPHY_RX_OVERRIDE + lane * SPHY_LANE, tmp);
msleep(15);
}
@@ -299,16 +336,20 @@ static void highbank_cphy_override_lane(u8 sata_port)
lane * SPHY_LANE);
} while ((tmp & SPHY_HALF_RATE) && (k++ < 1000));
cphy_override_rx_mode(sata_port, 3);
+ cphy_override_tx_attenuation(sata_port, port_data[sata_port].tx_atten);
}
static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
{
struct device_node *sata_node = dev->of_node;
- int phy_count = 0, phy, port = 0;
+ int phy_count = 0, phy, port = 0, i;
void __iomem *cphy_base[CPHY_PHY_COUNT];
struct device_node *phy_nodes[CPHY_PHY_COUNT];
+ u32 tx_atten[CPHY_PORT_COUNT];
+
memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT);
memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT);
+ memset(tx_atten, 0xff, CPHY_PORT_COUNT);
do {
u32 tmp;
@@ -336,6 +377,10 @@ static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
of_node_put(phy_data.np);
port += 1;
} while (port < CPHY_PORT_COUNT);
+ of_property_read_u32_array(sata_node, "calxeda,tx-atten",
+ tx_atten, port);
+ for (i = 0; i < port; i++)
+ port_data[i].tx_atten = (u8) tx_atten[i];
return 0;
}
@@ -479,6 +524,9 @@ static int ahci_highbank_probe(struct platform_device *pdev)
if (hpriv->cap & HOST_CAP_PMP)
pi.flags |= ATA_FLAG_PMP;
+ if (hpriv->cap & HOST_CAP_64)
+ dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
+
/* CAP.NP sometimes indicate the index of the last enabled
* port, at other times, that of the last possible port, so
* determining the maximum port number requires looking at
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index e45131748248..5c54d957370a 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -6,6 +6,18 @@
*
* This file is released under GPL v2.
*
+ * **** WARNING ****
+ *
+ * This driver never worked properly and unfortunately data corruption is
+ * relatively common. There isn't anyone working on the driver and there's
+ * no support from the vendor. Do not use this driver in any production
+ * environment.
+ *
+ * http://thread.gmane.org/gmane.linux.debian.devel.bugs.rc/378525/focus=54491
+ * https://bugzilla.kernel.org/show_bug.cgi?id=60565
+ *
+ * *****************
+ *
* This controller is eccentric and easily locks up if something isn't
* right. Documentation is available at initio's website but it only
* documents registers (not programming model).
@@ -807,6 +819,8 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
ata_print_version_once(&pdev->dev, DRV_VERSION);
+ dev_alert(&pdev->dev, "inic162x support is broken with common data corruption issues and will be disabled by default, contact linux-ide@vger.kernel.org if in production use\n");
+
/* alloc host */
host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS);
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 35c6b6d09c27..56be31819897 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -553,10 +553,15 @@ struct mv_host_priv {
u32 irq_mask_offset;
u32 unmask_all_irqs;
-#if defined(CONFIG_HAVE_CLK)
+ /*
+ * Needed on some devices that require their clocks to be enabled.
+ * These are optional: if the platform device does not have any
+ * clocks, they won't be used. Also, if the underlying hardware
+ * does not support the common clock framework (CONFIG_HAVE_CLK=n),
+ * all the clock operations become no-ops (see clk.h).
+ */
struct clk *clk;
struct clk **port_clks;
-#endif
/*
* These consistent DMA memory pools give us guaranteed
* alignment for hardware-accessed data structures,
@@ -4032,9 +4037,7 @@ static int mv_platform_probe(struct platform_device *pdev)
struct resource *res;
int n_ports = 0, irq = 0;
int rc;
-#if defined(CONFIG_HAVE_CLK)
int port;
-#endif
ata_print_version_once(&pdev->dev, DRV_VERSION);
@@ -4058,7 +4061,7 @@ static int mv_platform_probe(struct platform_device *pdev)
of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports);
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
} else {
- mv_platform_data = pdev->dev.platform_data;
+ mv_platform_data = dev_get_platdata(&pdev->dev);
n_ports = mv_platform_data->n_ports;
irq = platform_get_irq(pdev, 0);
}
@@ -4068,13 +4071,11 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!host || !hpriv)
return -ENOMEM;
-#if defined(CONFIG_HAVE_CLK)
hpriv->port_clks = devm_kzalloc(&pdev->dev,
sizeof(struct clk *) * n_ports,
GFP_KERNEL);
if (!hpriv->port_clks)
return -ENOMEM;
-#endif
host->private_data = hpriv;
hpriv->n_ports = n_ports;
hpriv->board_idx = chip_soc;
@@ -4084,7 +4085,6 @@ static int mv_platform_probe(struct platform_device *pdev)
resource_size(res));
hpriv->base -= SATAHC0_REG_BASE;
-#if defined(CONFIG_HAVE_CLK)
hpriv->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(hpriv->clk))
dev_notice(&pdev->dev, "cannot get optional clkdev\n");
@@ -4098,7 +4098,6 @@ static int mv_platform_probe(struct platform_device *pdev)
if (!IS_ERR(hpriv->port_clks[port]))
clk_prepare_enable(hpriv->port_clks[port]);
}
-#endif
/*
* (Re-)program MBUS remapping windows if we are asked to.
@@ -4124,7 +4123,6 @@ static int mv_platform_probe(struct platform_device *pdev)
return 0;
err:
-#if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) {
clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
@@ -4135,7 +4133,6 @@ err:
clk_put(hpriv->port_clks[port]);
}
}
-#endif
return rc;
}
@@ -4151,13 +4148,10 @@ err:
static int mv_platform_remove(struct platform_device *pdev)
{
struct ata_host *host = platform_get_drvdata(pdev);
-#if defined(CONFIG_HAVE_CLK)
struct mv_host_priv *hpriv = host->private_data;
int port;
-#endif
ata_host_detach(host);
-#if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) {
clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
@@ -4168,7 +4162,6 @@ static int mv_platform_remove(struct platform_device *pdev)
clk_put(hpriv->port_clks[port]);
}
}
-#endif
return 0;
}
@@ -4428,9 +4421,6 @@ static int mv_pci_device_resume(struct pci_dev *pdev)
#endif
#endif
-static int mv_platform_probe(struct platform_device *pdev);
-static int mv_platform_remove(struct platform_device *pdev);
-
static int __init mv_init(void)
{
int rc = -ENODEV;
diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c
index 8108eb065444..c2d95e9fb971 100644
--- a/drivers/ata/sata_rcar.c
+++ b/drivers/ata/sata_rcar.c
@@ -778,10 +778,6 @@ static int sata_rcar_probe(struct platform_device *pdev)
int irq;
int ret = 0;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (mem == NULL)
- return -EINVAL;
-
irq = platform_get_irq(pdev, 0);
if (irq <= 0)
return -EINVAL;
@@ -807,6 +803,7 @@ static int sata_rcar_probe(struct platform_device *pdev)
host->private_data = priv;
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(priv->base)) {
ret = PTR_ERR(priv->base);