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

Commit 13aa7e0b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull libata changes from Tejun Heo:
 "Nothing too interesting.  Only two minor fixes in libata core.  Most
  changes are specific to hardware which isn't too common"

* 'for-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
  ahci: Add Device IDs for Intel Wildcat Point-LP
  sata_rcar: Convert to clk_prepare/unprepare
  drivers/libata: Set max sector to 65535 for Slimtype DVD A DS8A9SH drive
  libata: Add some missing command descriptions
  sata_highbank: clear whole array in highbank_initialize_phys()
  ahci: disabled FBS prior to issuing software reset
  libata: Fix display of sata speed
  ahci: imx: setup power saving methods
  ata_piix: minor typo and a printk fix
  ahci: Changing two module params with static and __read_mostly
parents c08acff0 9f961a5f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -292,6 +292,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
	{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
	{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */
	{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
	{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
	{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */

	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+2 −0
Original line number Diff line number Diff line
@@ -339,6 +339,7 @@ extern struct device_attribute *ahci_sdev_attrs[];
	.sdev_attrs		= ahci_sdev_attrs

extern struct ata_port_operations ahci_ops;
extern struct ata_port_operations ahci_platform_ops;
extern struct ata_port_operations ahci_pmp_retry_srst_ops;

unsigned int ahci_dev_classify(struct ata_port *ap);
@@ -368,6 +369,7 @@ irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance);
irqreturn_t ahci_thread_fn(int irq, void *dev_instance);
void ahci_print_info(struct ata_host *host, const char *scc_s);
int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis);
void ahci_error_handler(struct ata_port *ap);

static inline void __iomem *__ahci_port_base(struct ata_host *host,
					     unsigned int port_no)
+99 −2
Original line number Diff line number Diff line
/*
 * copyright (c) 2013 Freescale Semiconductor, Inc.
 * Freescale IMX AHCI SATA platform driver
 * Copyright 2013 Freescale Semiconductor, Inc.
 *
 * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
 *
@@ -25,9 +25,12 @@
#include <linux/of_device.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/libata.h>
#include "ahci.h"

enum {
	PORT_PHY_CTL = 0x178,			/* Port0 PHY Control */
	PORT_PHY_CTL_PDDQ_LOC = 0x100000,	/* PORT_PHY_CTL bits */
	HOST_TIMER1MS = 0xe0,			/* Timer 1-ms */
};

@@ -36,6 +39,56 @@ struct imx_ahci_priv {
	struct clk *sata_ref_clk;
	struct clk *ahb_clk;
	struct regmap *gpr;
	bool no_device;
	bool first_time;
};

static int ahci_imx_hotplug;
module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");

static void ahci_imx_error_handler(struct ata_port *ap)
{
	u32 reg_val;
	struct ata_device *dev;
	struct ata_host *host = dev_get_drvdata(ap->dev);
	struct ahci_host_priv *hpriv = host->private_data;
	void __iomem *mmio = hpriv->mmio;
	struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);

	ahci_error_handler(ap);

	if (!(imxpriv->first_time) || ahci_imx_hotplug)
		return;

	imxpriv->first_time = false;

	ata_for_each_dev(dev, &ap->link, ENABLED)
		return;
	/*
	 * Disable link to save power.  An imx ahci port can't be recovered
	 * without full reset once the pddq mode is enabled making it
	 * impossible to use as part of libata LPM.
	 */
	reg_val = readl(mmio + PORT_PHY_CTL);
	writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL);
	regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
			IMX6Q_GPR13_SATA_MPLL_CLK_EN,
			!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
	clk_disable_unprepare(imxpriv->sata_ref_clk);
	imxpriv->no_device = true;
}

static struct ata_port_operations ahci_imx_ops = {
	.inherits	= &ahci_platform_ops,
	.error_handler	= ahci_imx_error_handler,
};

static const struct ata_port_info ahci_imx_port_info = {
	.flags		= AHCI_FLAG_COMMON,
	.pio_mask	= ATA_PIO4,
	.udma_mask	= ATA_UDMA6,
	.port_ops	= &ahci_imx_ops,
};

static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
@@ -117,9 +170,51 @@ static void imx6q_sata_exit(struct device *dev)
	clk_disable_unprepare(imxpriv->sata_ref_clk);
}

static int imx_ahci_suspend(struct device *dev)
{
	struct imx_ahci_priv *imxpriv =  dev_get_drvdata(dev->parent);

	/*
	 * If no_device is set, The CLKs had been gated off in the
	 * initialization so don't do it again here.
	 */
	if (!imxpriv->no_device) {
		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
				IMX6Q_GPR13_SATA_MPLL_CLK_EN,
				!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
		clk_disable_unprepare(imxpriv->sata_ref_clk);
	}

	return 0;
}

static int imx_ahci_resume(struct device *dev)
{
	struct imx_ahci_priv *imxpriv =  dev_get_drvdata(dev->parent);
	int ret;

	if (!imxpriv->no_device) {
		ret = clk_prepare_enable(imxpriv->sata_ref_clk);
		if (ret < 0) {
			dev_err(dev, "pre-enable sata_ref clock err:%d\n", ret);
			return ret;
		}

		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
				IMX6Q_GPR13_SATA_MPLL_CLK_EN,
				IMX6Q_GPR13_SATA_MPLL_CLK_EN);
		usleep_range(1000, 2000);
	}

	return 0;
}

static struct ahci_platform_data imx6q_sata_pdata = {
	.init = imx6q_sata_init,
	.exit = imx6q_sata_exit,
	.ata_port_info = &ahci_imx_port_info,
	.suspend = imx_ahci_suspend,
	.resume = imx_ahci_resume,
};

static const struct of_device_id imx_ahci_of_match[] = {
@@ -152,6 +247,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
	ahci_dev = &ahci_pdev->dev;
	ahci_dev->parent = dev;

	imxpriv->no_device = false;
	imxpriv->first_time = true;
	imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
	if (IS_ERR(imxpriv->ahb_clk)) {
		dev_err(dev, "can't get ahb clock.\n");
+2 −1
Original line number Diff line number Diff line
@@ -49,10 +49,11 @@ static struct platform_device_id ahci_devtype[] = {
};
MODULE_DEVICE_TABLE(platform, ahci_devtype);

static struct ata_port_operations ahci_platform_ops = {
struct ata_port_operations ahci_platform_ops = {
	.inherits	= &ahci_ops,
	.host_stop	= ahci_host_stop,
};
EXPORT_SYMBOL_GPL(ahci_platform_ops);

static struct ata_port_operations ahci_platform_retry_srst_ops = {
	.inherits	= &ahci_pmp_retry_srst_ops,
+10 −9
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@

enum {
	PIIX_IOCFG		= 0x54, /* IDE I/O configuration register */
	ICH5_PMR		= 0x90, /* port mapping register */
	ICH5_PMR		= 0x90, /* address map register */
	ICH5_PCS		= 0x92,	/* port control and status */
	PIIX_SIDPR_BAR		= 5,
	PIIX_SIDPR_LEN		= 16,
@@ -233,7 +233,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
	  PCI_CLASS_STORAGE_IDE << 8, 0xffff00, ich6m_sata },
	/* 82801GB/GR/GH (ICH7, identical to ICH6) */
	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
	/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
	/* 82801GBM/GHM (ICH7M, identical to ICH6M)  */
	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata },
	/* Enterprise Southbridge 2 (631xESB/632xESB) */
	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
@@ -517,7 +517,7 @@ static int ich_pata_cable_detect(struct ata_port *ap)
	const struct ich_laptop *lap = &ich_laptop[0];
	u8 mask;

	/* Check for specials - Acer Aspire 5602WLMi */
	/* Check for specials */
	while (lap->device) {
		if (lap->device == pdev->device &&
		    lap->subvendor == pdev->subsystem_vendor &&
@@ -1366,38 +1366,39 @@ static const int *piix_init_sata_map(struct pci_dev *pdev,
	const int *map;
	int i, invalid_map = 0;
	u8 map_value;
	char buf[32];
	char *p = buf, *end = buf + sizeof(buf);

	pci_read_config_byte(pdev, ICH5_PMR, &map_value);

	map = map_db->map[map_value & map_db->mask];

	dev_info(&pdev->dev, "MAP [");
	for (i = 0; i < 4; i++) {
		switch (map[i]) {
		case RV:
			invalid_map = 1;
			pr_cont(" XX");
			p += scnprintf(p, end - p, " XX");
			break;

		case NA:
			pr_cont(" --");
			p += scnprintf(p, end - p, " --");
			break;

		case IDE:
			WARN_ON((i & 1) || map[i + 1] != IDE);
			pinfo[i / 2] = piix_port_info[ich_pata_100];
			i++;
			pr_cont(" IDE IDE");
			p += scnprintf(p, end - p, " IDE IDE");
			break;

		default:
			pr_cont(" P%d", map[i]);
			p += scnprintf(p, end - p, " P%d", map[i]);
			if (i & 1)
				pinfo[i / 2].flags |= ATA_FLAG_SLAVE_POSS;
			break;
		}
	}
	pr_cont(" ]\n");
	dev_info(&pdev->dev, "MAP [%s ]\n", buf);

	if (invalid_map)
		dev_err(&pdev->dev, "invalid MAP value %u\n", map_value);
Loading