From cf8984bf84c383ca1a7282bc6409c9684e6dc3a4 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:42:48 -0500 Subject: ata: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Cc: Tejun Heo Cc: linux-ide@vger.kernel.org Signed-off-by: Tejun Heo --- drivers/ata/sata_svw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 0fd6ac7e57ba..a9d692c6c182 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -339,7 +339,7 @@ static int k2_sata_show_info(struct seq_file *m, struct Scsi_Host *shost) if (!reg) continue; if (index == *reg) { - seq_printf(m, "devspec: %s\n", np->full_name); + seq_printf(m, "devspec: %pOF\n", np); break; } } -- cgit v1.2.3-55-g7522 From cea9c8d34464fb11c82bd32b4cd57b9fcc834995 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 Jul 2017 22:07:43 +0200 Subject: ata: Drop unnecessary static Drop static on a local variable, when the variable is initialized before any possible use. Thus, the static has no benefit. The semantic patch that fixes this problem is as follows: (http://coccinelle.lip6.fr/) // @bad exists@ position p; identifier x; type T; @@ static T x@p; ... x = <+...x...+> @@ identifier x; expression e; type T; position p != bad.p; @@ -static T x@p; ... when != x when strict ?x = e; // Signed-off-by: Julia Lawall Acked-by: Linus Walleij Signed-off-by: Tejun Heo --- drivers/ata/sata_gemini.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 8c704523bae7..ab97be63d196 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -305,7 +305,7 @@ static int gemini_sata_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct sata_gemini *sg; - static struct regmap *map; + struct regmap *map; struct resource *res; enum gemini_muxmode muxmode; u32 gmode; -- cgit v1.2.3-55-g7522 From afbd39a42e2d777852a2809298fd4e71b1e5abf7 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Jul 2017 17:25:09 +0200 Subject: ata: sata_gemini: explicitly request exclusive reset control Commit a53e35db70d1 ("reset: Ensure drivers are explicit when requesting reset lines") started to transition the reset control request API calls to explicitly state whether the driver needs exclusive or shared reset control behavior. Convert all drivers requesting exclusive resets to the explicit API call so the temporary transition helpers can be removed. No functional changes. Cc: linux-ide@vger.kernel.org Signed-off-by: Philipp Zabel Acked-by: Linus Walleij Signed-off-by: Tejun Heo --- drivers/ata/sata_gemini.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index ab97be63d196..373051ea8211 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -274,14 +274,14 @@ static int gemini_sata_bridge_init(struct sata_gemini *sg) return ret; } - sg->sata0_reset = devm_reset_control_get(dev, "sata0"); + sg->sata0_reset = devm_reset_control_get_exclusive(dev, "sata0"); if (IS_ERR(sg->sata0_reset)) { dev_err(dev, "no SATA0 reset controller\n"); clk_disable_unprepare(sg->sata1_pclk); clk_disable_unprepare(sg->sata0_pclk); return PTR_ERR(sg->sata0_reset); } - sg->sata1_reset = devm_reset_control_get(dev, "sata1"); + sg->sata1_reset = devm_reset_control_get_exclusive(dev, "sata1"); if (IS_ERR(sg->sata1_reset)) { dev_err(dev, "no SATA1 reset controller\n"); clk_disable_unprepare(sg->sata1_pclk); -- cgit v1.2.3-55-g7522 From 8eede5bc4ef04281fbba7ddfe157052d0e76075d Mon Sep 17 00:00:00 2001 From: Nate Watterson Date: Thu, 20 Jul 2017 15:26:24 -0400 Subject: ata: ahci_platform: Add shutdown handler The newly introduced ahci_platform_shutdown() method is called during system shutdown to disable host controller DMA and interrupts in order to avoid potentially corrupting or otherwise interfering with a new kernel being started with kexec. Signed-off-by: Nate Watterson Signed-off-by: Tejun Heo --- drivers/ata/ahci_platform.c | 1 + drivers/ata/libahci_platform.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/ahci_platform.h | 2 ++ 3 files changed, 37 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 62a04c8fb5c9..99f9a895a459 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -93,6 +93,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match); static struct platform_driver ahci_driver = { .probe = ahci_probe, .remove = ata_platform_remove_one, + .shutdown = ahci_platform_shutdown, .driver = { .name = DRV_NAME, .of_match_table = ahci_of_match, diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index cd2eab6aa92e..a270a1173c8c 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -602,6 +602,40 @@ static void ahci_host_stop(struct ata_host *host) ahci_platform_disable_resources(hpriv); } +/** + * ahci_platform_shutdown - Disable interrupts and stop DMA for host ports + * @dev: platform device pointer for the host + * + * This function is called during system shutdown and performs the minimal + * deconfiguration required to ensure that an ahci_platform host cannot + * corrupt or otherwise interfere with a new kernel being started with kexec. + */ +void ahci_platform_shutdown(struct platform_device *pdev) +{ + struct ata_host *host = platform_get_drvdata(pdev); + struct ahci_host_priv *hpriv = host->private_data; + void __iomem *mmio = hpriv->mmio; + int i; + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + /* Disable port interrupts */ + if (ap->ops->freeze) + ap->ops->freeze(ap); + + /* Stop the port DMA engines */ + if (ap->ops->port_stop) + ap->ops->port_stop(ap); + } + + /* Disable and clear host interrupts */ + writel(readl(mmio + HOST_CTL) & ~HOST_IRQ_EN, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + writel(GENMASK(host->n_ports, 0), mmio + HOST_IRQ_STAT); +} +EXPORT_SYMBOL_GPL(ahci_platform_shutdown); + #ifdef CONFIG_PM_SLEEP /** * ahci_platform_suspend_host - Suspend an ahci-platform host diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index a270f25ee7c7..1b0a17b22cd3 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h @@ -36,6 +36,8 @@ int ahci_platform_init_host(struct platform_device *pdev, const struct ata_port_info *pi_template, struct scsi_host_template *sht); +void ahci_platform_shutdown(struct platform_device *pdev); + int ahci_platform_suspend_host(struct device *dev); int ahci_platform_resume_host(struct device *dev); int ahci_platform_suspend(struct device *dev); -- cgit v1.2.3-55-g7522 From d99058a232e78c580e92ecf2670eabdbd68a5f2c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2017 21:07:04 +0200 Subject: ata: sata_gemini: Retire custom pin control I added a proper pin control driver for the Gemini SoC, so retire this custom code and rely on the pin controller to set up the pads. The "IOMUX" which is routing signals between the ATA and SATA bridge inside of the chip is not about pin control and remains in place. Signed-off-by: Linus Walleij Signed-off-by: Tejun Heo --- drivers/ata/sata_gemini.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 373051ea8211..071e49971f6d 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -43,17 +43,6 @@ struct sata_gemini { struct clk *sata1_pclk; }; -/* Global IDE PAD Skew Control Register */ -#define GEMINI_GLOBAL_IDE_SKEW_CTRL 0x18 -#define GEMINI_IDE1_HOST_STROBE_DELAY_SHIFT 28 -#define GEMINI_IDE1_DEVICE_STROBE_DELAY_SHIFT 24 -#define GEMINI_IDE1_OUTPUT_IO_SKEW_SHIFT 20 -#define GEMINI_IDE1_INPUT_IO_SKEW_SHIFT 16 -#define GEMINI_IDE0_HOST_STROBE_DELAY_SHIFT 12 -#define GEMINI_IDE0_DEVICE_STROBE_DELAY_SHIFT 8 -#define GEMINI_IDE0_OUTPUT_IO_SKEW_SHIFT 4 -#define GEMINI_IDE0_INPUT_IO_SKEW_SHIFT 0 - /* Miscellaneous Control Register */ #define GEMINI_GLOBAL_MISC_CTRL 0x30 /* @@ -91,8 +80,6 @@ struct sata_gemini { #define GEMINI_IDE_IOMUX_MODE2 (2 << 24) #define GEMINI_IDE_IOMUX_MODE3 (3 << 24) #define GEMINI_IDE_IOMUX_SHIFT (24) -#define GEMINI_IDE_PADS_ENABLE BIT(4) -#define GEMINI_PFLASH_PADS_DISABLE BIT(1) /* * Registers directly controlling the PATA<->SATA adapters @@ -310,7 +297,6 @@ static int gemini_sata_probe(struct platform_device *pdev) enum gemini_muxmode muxmode; u32 gmode; u32 gmask; - u32 val; int ret; sg = devm_kzalloc(dev, sizeof(*sg), GFP_KERNEL); @@ -362,16 +348,6 @@ static int gemini_sata_probe(struct platform_device *pdev) gmask = GEMINI_IDE_IOMUX_MASK; gmode = (muxmode << GEMINI_IDE_IOMUX_SHIFT); - /* - * If we mux out the IDE, parallel flash must be disabled. - * SATA0 and SATA1 have dedicated pins and may coexist with - * parallel flash. - */ - if (sg->ide_pins) - gmode |= GEMINI_IDE_PADS_ENABLE | GEMINI_PFLASH_PADS_DISABLE; - else - gmask |= GEMINI_IDE_PADS_ENABLE; - ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, gmask, gmode); if (ret) { dev_err(dev, "unable to set up IDE muxing\n"); @@ -379,16 +355,6 @@ static int gemini_sata_probe(struct platform_device *pdev) goto out_unprep_clk; } - /* FIXME: add more elaborate IDE skew control handling */ - if (sg->ide_pins) { - ret = regmap_read(map, GEMINI_GLOBAL_IDE_SKEW_CTRL, &val); - if (ret) { - dev_err(dev, "cannot read IDE skew control register\n"); - return ret; - } - dev_info(dev, "IDE skew control: %08x\n", val); - } - dev_info(dev, "set up the Gemini IDE/SATA nexus\n"); platform_set_drvdata(pdev, sg); sg_singleton = sg; -- cgit v1.2.3-55-g7522 From d872ced29d5f847b23bb5a7bc24a234a936568bd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2017 21:07:14 +0200 Subject: ata: sata_gemini: Introduce explicit IDE pin control The IDE pins are managed by the pin controller, if we want to use these, we need to ask the pin controller to explicitly enable them as by default, these pins are used for other business and most users just rely on the SATA bridge. Signed-off-by: Linus Walleij Signed-off-by: Tejun Heo --- drivers/ata/sata_gemini.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 071e49971f6d..46950e0267e0 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "sata_gemini.h" #define DRV_NAME "gemini_sata_bridge" @@ -287,6 +288,29 @@ static int gemini_sata_bridge_init(struct sata_gemini *sg) return 0; } +static int gemini_setup_ide_pins(struct device *dev) +{ + struct pinctrl *p; + struct pinctrl_state *ide_state; + int ret; + + p = devm_pinctrl_get(dev); + if (IS_ERR(p)) + return PTR_ERR(p); + + ide_state = pinctrl_lookup_state(p, "ide"); + if (IS_ERR(ide_state)) + return PTR_ERR(ide_state); + + ret = pinctrl_select_state(p, ide_state); + if (ret) { + dev_err(dev, "could not select IDE state\n"); + return ret; + } + + return 0; +} + static int gemini_sata_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -355,6 +379,17 @@ static int gemini_sata_probe(struct platform_device *pdev) goto out_unprep_clk; } + /* + * Route out the IDE pins if desired. + * This is done by looking up a special pin control state called + * "ide" that will route out the IDE pins. + */ + if (sg->ide_pins) { + ret = gemini_setup_ide_pins(dev); + if (ret) + return ret; + } + dev_info(dev, "set up the Gemini IDE/SATA nexus\n"); platform_set_drvdata(pdev, sg); sg_singleton = sg; -- cgit v1.2.3-55-g7522 From 591b6bb605785c12a21e8b07a08a277065b655a5 Mon Sep 17 00:00:00 2001 From: Andrey Korolyov Date: Thu, 10 Aug 2017 13:21:14 +0300 Subject: cs5536: add support for IDE controller variant Several legacy devices such as Geode-based Cisco ASA appliances and DB800 development board do possess CS5536 IDE controller with different PCI id than existing one. Using pata_generic is not always feasible as at least DB800 requires MSR quirk from pata_cs5536 to be used with vendor firmware. Signed-off-by: Andrey Korolyov CC: stable@vger.kernel.org Signed-off-by: Tejun Heo --- drivers/ata/pata_amd.c | 1 + drivers/ata/pata_cs5536.c | 1 + include/linux/pci_ids.h | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 8d4d959a821c..8706533db57b 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -616,6 +616,7 @@ static const struct pci_device_id amd[] = { { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE), 8 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE), 8 }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_DEV_IDE), 9 }, { }, }; diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 6c15a554efbe..dc1255294628 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -289,6 +289,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) static const struct pci_device_id cs5536[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_DEV_IDE), }, { }, }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c71e532da458..4adf6161ec77 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -576,6 +576,7 @@ #define PCI_DEVICE_ID_AMD_CS5536_EHC 0x2095 #define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096 #define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097 +#define PCI_DEVICE_ID_AMD_CS5536_DEV_IDE 0x2092 #define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A #define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 #define PCI_DEVICE_ID_AMD_LX_AES 0x2082 -- cgit v1.2.3-55-g7522 From be1dc3fb290beb394551b8cee45d03e6375b28e6 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 27 Aug 2017 22:55:09 +0300 Subject: pata_octeon_cf: use of_property_read_{bool|u32}() The Octeon CF driver basically open-codes of_property_read_{bool|u32}() using of_{find|get}_property() calls in its probe() method. Using the modern DT APIs saves 2 LoCs and 16 bytes of object code (MIPS gcc 3.4.3). Signed-off-by: Sergei Shtylyov Signed-off-by: Tejun Heo --- drivers/ata/pata_octeon_cf.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 1ba03d6df951..d3d851b014a3 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -840,7 +840,6 @@ static int octeon_cf_probe(struct platform_device *pdev) struct property *reg_prop; int n_addr, n_size, reg_len; struct device_node *node; - const void *prop; void __iomem *cs0; void __iomem *cs1 = NULL; struct ata_host *host; @@ -850,7 +849,7 @@ static int octeon_cf_probe(struct platform_device *pdev) void __iomem *base; struct octeon_cf_port *cf_port; int rv = -ENOMEM; - + u32 bus_width; node = pdev->dev.of_node; if (node == NULL) @@ -860,11 +859,10 @@ static int octeon_cf_probe(struct platform_device *pdev) if (!cf_port) return -ENOMEM; - cf_port->is_true_ide = (of_find_property(node, "cavium,true-ide", NULL) != NULL); + cf_port->is_true_ide = of_property_read_bool(node, "cavium,true-ide"); - prop = of_get_property(node, "cavium,bus-width", NULL); - if (prop) - is_16bit = (be32_to_cpup(prop) == 16); + if (of_property_read_u32(node, "cavium,bus-width", &bus_width) == 0) + is_16bit = (bus_width == 16); else is_16bit = false; -- cgit v1.2.3-55-g7522 From 47269605aa3bc191bdce6d2f6dec2e73d56b9c3b Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Fri, 18 Aug 2017 09:13:07 +0800 Subject: ata: mediatek: add support for MediaTek SATA controller This adds support the AHCI-compliant Serial ATA controller present on MediaTek SoCs. Signed-off-by: Ryder Lee Acked-by: Tejun Heo Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 10 +++ drivers/ata/Makefile | 1 + drivers/ata/ahci_mtk.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 drivers/ata/ahci_mtk.c (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 948fc86980a1..7d3eb47fcdab 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -153,6 +153,16 @@ config AHCI_CEVA If unsure, say N. +config AHCI_MTK + tristate "MediaTek AHCI SATA support" + depends on ARCH_MEDIATEK + select MFD_SYSCON + help + This option enables support for the MediaTek SoC's + onboard AHCI SATA controller. + + If unsure, say N. + config AHCI_MVEBU tristate "Marvell EBU AHCI SATA support" depends on ARCH_MVEBU diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index a26ef5a93919..ff9cd2e37458 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DM816) += ahci_dm816.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o +obj-$(CONFIG_AHCI_MTK) += ahci_mtk.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_OCTEON) += ahci_octeon.o obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c new file mode 100644 index 000000000000..80854f71559a --- /dev/null +++ b/drivers/ata/ahci_mtk.c @@ -0,0 +1,196 @@ +/* + * MeidaTek AHCI SATA driver + * + * Copyright (c) 2017 MediaTek Inc. + * Author: Ryder Lee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ahci.h" + +#define DRV_NAME "ahci" + +#define SYS_CFG 0x14 +#define SYS_CFG_SATA_MSK GENMASK(31, 30) +#define SYS_CFG_SATA_EN BIT(31) + +struct mtk_ahci_plat { + struct regmap *mode; + struct reset_control *axi_rst; + struct reset_control *sw_rst; + struct reset_control *reg_rst; +}; + +static const struct ata_port_info ahci_port_info = { + .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(DRV_NAME), +}; + +static int mtk_ahci_platform_resets(struct ahci_host_priv *hpriv, + struct device *dev) +{ + struct mtk_ahci_plat *plat = hpriv->plat_data; + int err; + + /* reset AXI bus and PHY part */ + plat->axi_rst = devm_reset_control_get_optional_exclusive(dev, "axi"); + if (PTR_ERR(plat->axi_rst) == -EPROBE_DEFER) + return PTR_ERR(plat->axi_rst); + + plat->sw_rst = devm_reset_control_get_optional_exclusive(dev, "sw"); + if (PTR_ERR(plat->sw_rst) == -EPROBE_DEFER) + return PTR_ERR(plat->sw_rst); + + plat->reg_rst = devm_reset_control_get_optional_exclusive(dev, "reg"); + if (PTR_ERR(plat->reg_rst) == -EPROBE_DEFER) + return PTR_ERR(plat->reg_rst); + + err = reset_control_assert(plat->axi_rst); + if (err) { + dev_err(dev, "failed to assert AXI bus\n"); + return err; + } + + err = reset_control_assert(plat->sw_rst); + if (err) { + dev_err(dev, "failed to assert PHY digital part\n"); + return err; + } + + err = reset_control_assert(plat->reg_rst); + if (err) { + dev_err(dev, "failed to assert PHY register part\n"); + return err; + } + + err = reset_control_deassert(plat->reg_rst); + if (err) { + dev_err(dev, "failed to deassert PHY register part\n"); + return err; + } + + err = reset_control_deassert(plat->sw_rst); + if (err) { + dev_err(dev, "failed to deassert PHY digital part\n"); + return err; + } + + err = reset_control_deassert(plat->axi_rst); + if (err) { + dev_err(dev, "failed to deassert AXI bus\n"); + return err; + } + + return 0; +} + +static int mtk_ahci_parse_property(struct ahci_host_priv *hpriv, + struct device *dev) +{ + struct mtk_ahci_plat *plat = hpriv->plat_data; + struct device_node *np = dev->of_node; + + /* enable SATA function if needed */ + if (of_find_property(np, "mediatek,phy-mode", NULL)) { + plat->mode = syscon_regmap_lookup_by_phandle( + np, "mediatek,phy-mode"); + if (IS_ERR(plat->mode)) { + dev_err(dev, "missing phy-mode phandle\n"); + return PTR_ERR(plat->mode); + } + + regmap_update_bits(plat->mode, SYS_CFG, SYS_CFG_SATA_MSK, + SYS_CFG_SATA_EN); + } + + of_property_read_u32(np, "ports-implemented", &hpriv->force_port_map); + + return 0; +} + +static int mtk_ahci_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mtk_ahci_plat *plat; + struct ahci_host_priv *hpriv; + int err; + + plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); + if (!plat) + return -ENOMEM; + + hpriv = ahci_platform_get_resources(pdev); + if (IS_ERR(hpriv)) + return PTR_ERR(hpriv); + + hpriv->plat_data = plat; + + err = mtk_ahci_parse_property(hpriv, dev); + if (err) + return err; + + err = mtk_ahci_platform_resets(hpriv, dev); + if (err) + return err; + + err = ahci_platform_enable_resources(hpriv); + if (err) + return err; + + err = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, + &ahci_platform_sht); + if (err) + goto disable_resources; + + return 0; + +disable_resources: + ahci_platform_disable_resources(hpriv); + return err; +} + +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, + ahci_platform_resume); + +static const struct of_device_id ahci_of_match[] = { + { .compatible = "mediatek,mtk-ahci", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ahci_of_match); + +static struct platform_driver mtk_ahci_driver = { + .probe = mtk_ahci_probe, + .remove = ata_platform_remove_one, + .driver = { + .name = DRV_NAME, + .of_match_table = ahci_of_match, + .pm = &ahci_pm_ops, + }, +}; +module_platform_driver(mtk_ahci_driver); + +MODULE_DESCRIPTION("MeidaTek SATA AHCI Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-55-g7522 From f723fa4e69920f6a5dd5fa0d10ce90e2f14d189c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 5 Sep 2017 18:46:47 +0200 Subject: ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme Intel AHCI controllers that also hide NVMe devices in their bar can't use MSI interrupts, so disable them. Reported-by: John Loy Tested-by: John Loy Signed-off-by: Christoph Hellwig Fixes: d684a90d38e2 ("ahci: per-port msix support") Cc: stable@vger.kernel.org # v4.5+ Signed-off-by: Tejun Heo --- drivers/ata/ahci.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5a5fd0b404eb..cb9b0e9090e3 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1469,7 +1469,14 @@ static void ahci_remap_check(struct pci_dev *pdev, int bar, return; dev_warn(&pdev->dev, "Found %d remapped NVMe devices.\n", count); - dev_warn(&pdev->dev, "Switch your BIOS from RAID to AHCI mode to use them.\n"); + dev_warn(&pdev->dev, + "Switch your BIOS from RAID to AHCI mode to use them.\n"); + + /* + * Don't rely on the msi-x capability in the remap case, + * share the legacy interrupt across ahci and remapped devices. + */ + hpriv->flags |= AHCI_HFLAG_NO_MSI; } static int ahci_get_irq_vector(struct ata_host *host, int port) -- cgit v1.2.3-55-g7522 From 795ef788145ed2fa023efdf11e8d5d7bedc21462 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 6 Sep 2017 09:56:29 +0100 Subject: libata: zpodd: make arrays cdb static, reduces object code size Don't populate the arrays cdb on the stack, instead make them static. Makes the object code smaller by 230 bytes: Before: text data bss dec hex filename 3797 240 0 4037 fc5 drivers/ata/libata-zpodd.o After: text data bss dec hex filename 3407 400 0 3807 edf drivers/ata/libata-zpodd.o Signed-off-by: Colin Ian King Signed-off-by: Tejun Heo --- drivers/ata/libata-zpodd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index 8a01d09ac4db..23a62e4015d0 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -34,7 +34,7 @@ struct zpodd { static int eject_tray(struct ata_device *dev) { struct ata_taskfile tf; - const char cdb[] = { GPCMD_START_STOP_UNIT, + static const char cdb[] = { GPCMD_START_STOP_UNIT, 0, 0, 0, 0x02, /* LoEj */ 0, 0, 0, 0, 0, 0, 0, @@ -55,7 +55,7 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) unsigned int ret; struct rm_feature_desc *desc = (void *)(buf + 8); struct ata_taskfile tf; - char cdb[] = { GPCMD_GET_CONFIGURATION, + static const char cdb[] = { GPCMD_GET_CONFIGURATION, 2, /* only 1 feature descriptor requested */ 0, 3, /* 3, removable medium feature */ 0, 0, 0,/* reserved */ -- cgit v1.2.3-55-g7522