Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79f4d1d5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull libata updates from Tejun Heo:

 - Bartlomiej added pata_falcon

 - Christoph is trying to remove use of static 4k buf.  It's still WIP

 - config cleanup around HAS_DMA

 - other fixes and driver-specific changes

* 'for-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: (29 commits)
  ata: pata_of_platform: using of_property_read_u32() helper
  pata_atiixp: Don't use unconnected secondary port on SB600/SB700
  libata-sff: Don't scan disabled ports when checking for legacy mode.
  pata_octeon_cf: remove unused local variables from octeon_cf_set_piomode()
  ahci: qoriq: added ls2088a platforms support
  ahci: qoriq: report error when ecc register address is missing in dts
  ahci: qoriq: added a condition to enable dma coherence
  Revert "libata: switch to dynamic allocation instead of ata_scsi_rbuf"
  ahci: imx: fix building without hwmon or thermal
  ata: add Atari Falcon PATA controller driver
  ata: pass queued command to ->sff_data_xfer method
  ata: allow subsystem to be used on m68k arch
  libata: switch to dynamic allocation instead of ata_scsi_rbuf
  libata: don't call ata_scsi_rbuf_fill for command without a response buffer
  libata: call ->scsi_done from ata_scsi_simulate
  libata: remove the done callback from ata_scsi_args
  libata: move struct ata_scsi_args to libata-scsi.c
  libata: avoid global response buffer in atapi_qc_complete
  libata-eh: Use switch() instead of sparse array for protocol strings
  ata: sata_mv: Convert to devm_ioremap_resource()
  ...
parents 97a229f9 73b29514
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ menuconfig ATA
	tristate "Serial ATA and Parallel ATA drivers (libata)"
	depends on HAS_IOMEM
	depends on BLOCK
	depends on !(M32R || M68K || S390) || BROKEN
	depends on !(M32R || S390) || BROKEN
	select SCSI
	select GLOB
	---help---
@@ -80,6 +80,8 @@ config SATA_PMP
	  This option adds support for SATA Port Multipliers
	  (the SATA version of an ethernet hub, or SAS expander).

if HAS_DMA

comment "Controllers with non-SFF native interface"

config SATA_AHCI
@@ -127,6 +129,7 @@ config AHCI_ST
config AHCI_IMX
	tristate "Freescale i.MX AHCI SATA support"
	depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST)
	depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON
	help
	  This option enables support for the Freescale i.MX SoC's
	  onboard AHCI SATA.
@@ -232,6 +235,8 @@ config SATA_SIL24

	  If unsure, say N.

endif # HAS_DMA

config ATA_SFF
	bool "ATA SFF support (for legacy IDE and PATA)"
	default y
@@ -289,6 +294,7 @@ config SATA_SX4

config ATA_BMDMA
	bool "ATA BMDMA support"
	depends on HAS_DMA
	default y
	help
	  This option adds support for SFF ATA controllers with BMDMA
@@ -344,6 +350,7 @@ config SATA_DWC_VDEBUG

config SATA_HIGHBANK
	tristate "Calxeda Highbank SATA support"
	depends on HAS_DMA
	depends on ARCH_HIGHBANK || COMPILE_TEST
	help
	  This option enables support for the Calxeda Highbank SoC's
@@ -353,6 +360,7 @@ config SATA_HIGHBANK

config SATA_MV
	tristate "Marvell SATA support"
	depends on HAS_DMA
	depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \
		   ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST
	select GENERIC_PHY
@@ -895,6 +903,15 @@ config PATA_CMD640_PCI

	  If unsure, say N.

config PATA_FALCON
	tristate "Atari Falcon PATA support"
	depends on M68K && ATARI
	help
	  This option enables support for the on-board IDE
	  interface on the Atari Falcon.

	  If unsure, say N.

config PATA_ISAPNP
	tristate "ISA Plug and Play PATA support"
	depends on ISAPNP
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
obj-$(CONFIG_PATA_AT32)		+= pata_at32.o
obj-$(CONFIG_PATA_AT91)		+= pata_at91.o
obj-$(CONFIG_PATA_CMD640_PCI)	+= pata_cmd640.o
obj-$(CONFIG_PATA_FALCON)	+= pata_falcon.o
obj-$(CONFIG_PATA_ISAPNP)	+= pata_isapnp.o
obj-$(CONFIG_PATA_IXP4XX_CF)	+= pata_ixp4xx_cf.o
obj-$(CONFIG_PATA_MPIIX)	+= pata_mpiix.o
+196 −0
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/libata.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/thermal.h>
#include "ahci.h"

#define DRV_NAME "ahci-imx"
@@ -214,6 +217,180 @@ static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
	return timeout ? 0 : -ETIMEDOUT;
}

enum {
	/* SATA PHY Register */
	SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT = 0x0001,
	SATA_PHY_CR_CLOCK_DAC_CTL = 0x0008,
	SATA_PHY_CR_CLOCK_RTUNE_CTL = 0x0009,
	SATA_PHY_CR_CLOCK_ADC_OUT = 0x000A,
	SATA_PHY_CR_CLOCK_MPLL_TST = 0x0017,
};

static int read_adc_sum(void *dev, u16 rtune_ctl_reg, void __iomem * mmio)
{
	u16 adc_out_reg, read_sum;
	u32 index, read_attempt;
	const u32 attempt_limit = 100;

	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
	imx_phy_reg_write(rtune_ctl_reg, mmio);

	/* two dummy read */
	index = 0;
	read_attempt = 0;
	adc_out_reg = 0;
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_ADC_OUT, mmio);
	while (index < 2) {
		imx_phy_reg_read(&adc_out_reg, mmio);
		/* check if valid */
		if (adc_out_reg & 0x400)
			index++;

		read_attempt++;
		if (read_attempt > attempt_limit) {
			dev_err(dev, "Read REG more than %d times!\n",
				attempt_limit);
			break;
		}
	}

	index = 0;
	read_attempt = 0;
	read_sum = 0;
	while (index < 80) {
		imx_phy_reg_read(&adc_out_reg, mmio);
		if (adc_out_reg & 0x400) {
			read_sum = read_sum + (adc_out_reg & 0x3FF);
			index++;
		}
		read_attempt++;
		if (read_attempt > attempt_limit) {
			dev_err(dev, "Read REG more than %d times!\n",
				attempt_limit);
			break;
		}
	}

	/* Use the U32 to make 1000 precision */
	return (read_sum * 1000) / 80;
}

/* SATA AHCI temperature monitor */
static int sata_ahci_read_temperature(void *dev, int *temp)
{
	u16 mpll_test_reg, rtune_ctl_reg, dac_ctl_reg, read_sum;
	u32 str1, str2, str3, str4;
	int m1, m2, a;
	struct ahci_host_priv *hpriv = dev_get_drvdata(dev);
	void __iomem *mmio = hpriv->mmio;

	/* check rd-wr to reg */
	read_sum = 0;
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT, mmio);
	imx_phy_reg_write(read_sum, mmio);
	imx_phy_reg_read(&read_sum, mmio);
	if ((read_sum & 0xffff) != 0)
		dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);

	imx_phy_reg_write(0x5A5A, mmio);
	imx_phy_reg_read(&read_sum, mmio);
	if ((read_sum & 0xffff) != 0x5A5A)
		dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);

	imx_phy_reg_write(0x1234, mmio);
	imx_phy_reg_read(&read_sum, mmio);
	if ((read_sum & 0xffff) != 0x1234)
		dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);

	/* start temperature test */
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
	imx_phy_reg_read(&mpll_test_reg, mmio);
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
	imx_phy_reg_read(&rtune_ctl_reg, mmio);
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
	imx_phy_reg_read(&dac_ctl_reg, mmio);

	/* mpll_tst.meas_iv   ([12:2]) */
	str1 = (mpll_test_reg >> 2) & 0x7FF;
	/* rtune_ctl.mode     ([1:0]) */
	str2 = (rtune_ctl_reg) & 0x3;
	/* dac_ctl.dac_mode   ([14:12]) */
	str3 = (dac_ctl_reg >> 12)  & 0x7;
	/* rtune_ctl.sel_atbp ([4]) */
	str4 = (rtune_ctl_reg >> 4);

	/* Calculate the m1 */
	/* mpll_tst.meas_iv */
	mpll_test_reg = (mpll_test_reg & 0xE03) | (512) << 2;
	/* rtune_ctl.mode */
	rtune_ctl_reg = (rtune_ctl_reg & 0xFFC) | (1);
	/* dac_ctl.dac_mode */
	dac_ctl_reg = (dac_ctl_reg & 0x8FF) | (4) << 12;
	/* rtune_ctl.sel_atbp */
	rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (0) << 4;
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
	imx_phy_reg_write(mpll_test_reg, mmio);
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
	imx_phy_reg_write(dac_ctl_reg, mmio);
	m1 = read_adc_sum(dev, rtune_ctl_reg, mmio);

	/* Calculate the m2 */
	/* rtune_ctl.sel_atbp */
	rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (1) << 4;
	m2 = read_adc_sum(dev, rtune_ctl_reg, mmio);

	/* restore the status  */
	/* mpll_tst.meas_iv */
	mpll_test_reg = (mpll_test_reg & 0xE03) | (str1) << 2;
	/* rtune_ctl.mode */
	rtune_ctl_reg = (rtune_ctl_reg & 0xFFC) | (str2);
	/* dac_ctl.dac_mode */
	dac_ctl_reg = (dac_ctl_reg & 0x8FF) | (str3) << 12;
	/* rtune_ctl.sel_atbp */
	rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (str4) << 4;

	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
	imx_phy_reg_write(mpll_test_reg, mmio);
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
	imx_phy_reg_write(dac_ctl_reg, mmio);
	imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
	imx_phy_reg_write(rtune_ctl_reg, mmio);

	/* Compute temperature */
	if (!(m2 / 1000))
		m2 = 1000;
	a = (m2 - m1) / (m2/1000);
	*temp = ((-559) * a * a) / 1000 + (1379) * a + (-458000);

	return 0;
}

static ssize_t sata_ahci_show_temp(struct device *dev,
				   struct device_attribute *da,
				   char *buf)
{
	unsigned int temp = 0;
	int err;

	err = sata_ahci_read_temperature(dev, &temp);
	if (err < 0)
		return err;

	return sprintf(buf, "%u\n", temp);
}

static const struct thermal_zone_of_device_ops fsl_sata_ahci_of_thermal_ops = {
	.get_temp = sata_ahci_read_temperature,
};

static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sata_ahci_show_temp, NULL, 0);

static struct attribute *fsl_sata_ahci_attrs[] = {
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	NULL
};
ATTRIBUTE_GROUPS(fsl_sata_ahci);

static int imx_sata_enable(struct ahci_host_priv *hpriv)
{
	struct imx_ahci_priv *imxpriv = hpriv->plat_data;
@@ -597,6 +774,25 @@ static int imx_ahci_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	if (imxpriv->type == AHCI_IMX53 &&
	    IS_ENABLED(CONFIG_HWMON)) {
		/* Add the temperature monitor */
		struct device *hwmon_dev;

		hwmon_dev =
			devm_hwmon_device_register_with_groups(dev,
							"sata_ahci",
							hpriv,
							fsl_sata_ahci_groups);
		if (IS_ERR(hwmon_dev)) {
			ret = PTR_ERR(hwmon_dev);
			goto disable_clk;
		}
		devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev,
					     &fsl_sata_ahci_of_thermal_ops);
		dev_info(dev, "%s: sensor 'sata_ahci'\n", dev_name(hwmon_dev));
	}

	ret = imx_sata_enable(hpriv);
	if (ret)
		goto disable_clk;
+29 −6
Original line number Diff line number Diff line
@@ -46,19 +46,21 @@
#define LS1021A_AXICC_ADDR	0xC0

#define SATA_ECC_DISABLE	0x00020000
#define LS1046A_SATA_ECC_DIS	0x80000000
#define ECC_DIS_ARMV8_CH2	0x80000000

enum ahci_qoriq_type {
	AHCI_LS1021A,
	AHCI_LS1043A,
	AHCI_LS2080A,
	AHCI_LS1046A,
	AHCI_LS2088A,
};

struct ahci_qoriq_priv {
	struct ccsr_ahci *reg_base;
	enum ahci_qoriq_type type;
	void __iomem *ecc_addr;
	bool is_dmacoherent;
};

static const struct of_device_id ahci_qoriq_of_match[] = {
@@ -66,6 +68,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = {
	{ .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
	{ .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
	{ .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
	{ .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
	{},
};
MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
@@ -157,6 +160,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)

	switch (qpriv->type) {
	case AHCI_LS1021A:
		if (!qpriv->ecc_addr)
			return -EINVAL;
		writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
		writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
		writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
@@ -164,25 +169,42 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
		writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
		writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
		writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
		writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
		if (qpriv->is_dmacoherent)
			writel(AHCI_PORT_AXICC_CFG,
					reg_base + LS1021A_AXICC_ADDR);
		break;

	case AHCI_LS1043A:
		if (!qpriv->ecc_addr)
			return -EINVAL;
		writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr);
		writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
		writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
		if (qpriv->is_dmacoherent)
			writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
		break;

	case AHCI_LS2080A:
		writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
		writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
		if (qpriv->is_dmacoherent)
			writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
		break;

	case AHCI_LS1046A:
		writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr);
		if (!qpriv->ecc_addr)
			return -EINVAL;
		writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr);
		writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
		writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
		if (qpriv->is_dmacoherent)
			writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
		break;

	case AHCI_LS2088A:
		writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
		writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
		if (qpriv->is_dmacoherent)
			writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
		break;
	}
@@ -221,6 +243,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
		if (IS_ERR(qoriq_priv->ecc_addr))
			return PTR_ERR(qoriq_priv->ecc_addr);
	}
	qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);

	rc = ahci_platform_enable_resources(hpriv);
	if (rc)
+4 −2
Original line number Diff line number Diff line
@@ -821,8 +821,10 @@ static int xgene_ahci_probe(struct platform_device *pdev)
				dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n",
					__func__);
				version = XGENE_AHCI_V1;
			} else if (info->valid & ACPI_VALID_CID) {
			} else {
				if (info->valid & ACPI_VALID_CID)
					version = XGENE_AHCI_V2;
				kfree(info);
			}
		}
	}
Loading