forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'for-4.14' of git://git.kernel.org/pub/scm/linux/kernel/…
…git/tj/libata Pull libata updates from Tejun Heo: "Except for the ahci fix that fixes a boot issue, nothing major in this pull request. Some new platform controller support and device specific changes" * 'for-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: libata: zpodd: make arrays cdb static, reduces object code size ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme dt-bindings: ata: add DT bindings for MediaTek SATA controller ata: mediatek: add support for MediaTek SATA controller pata_octeon_cf: use of_property_read_{bool|u32}() cs5536: add support for IDE controller variant ata: sata_gemini: Introduce explicit IDE pin control ata: sata_gemini: Retire custom pin control ata: ahci_platform: Add shutdown handler ata: sata_gemini: explicitly request exclusive reset control ata: Drop unnecessary static ata: Convert to using %pOF instead of full_name
- Loading branch information
Showing
15 changed files
with
347 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
MediaTek Serial ATA controller | ||
|
||
Required properties: | ||
- compatible : Must be "mediatek,<chip>-ahci", "mediatek,mtk-ahci". | ||
When using "mediatek,mtk-ahci" compatible strings, you | ||
need SoC specific ones in addition, one of: | ||
- "mediatek,mt7622-ahci" | ||
- reg : Physical base addresses and length of register sets. | ||
- interrupts : Interrupt associated with the SATA device. | ||
- interrupt-names : Associated name must be: "hostc". | ||
- clocks : A list of phandle and clock specifier pairs, one for each | ||
entry in clock-names. | ||
- clock-names : Associated names must be: "ahb", "axi", "asic", "rbc", "pm". | ||
- phys : A phandle and PHY specifier pair for the PHY port. | ||
- phy-names : Associated name must be: "sata-phy". | ||
- ports-implemented : See ./ahci-platform.txt for details. | ||
|
||
Optional properties: | ||
- power-domains : A phandle and power domain specifier pair to the power | ||
domain which is responsible for collapsing and restoring | ||
power to the peripheral. | ||
- resets : Must contain an entry for each entry in reset-names. | ||
See ../reset/reset.txt for details. | ||
- reset-names : Associated names must be: "axi", "sw", "reg". | ||
- mediatek,phy-mode : A phandle to the system controller, used to enable | ||
SATA function. | ||
|
||
Example: | ||
|
||
sata: sata@1a200000 { | ||
compatible = "mediatek,mt7622-ahci", | ||
"mediatek,mtk-ahci"; | ||
reg = <0 0x1a200000 0 0x1100>; | ||
interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>; | ||
interrupt-names = "hostc"; | ||
clocks = <&pciesys CLK_SATA_AHB_EN>, | ||
<&pciesys CLK_SATA_AXI_EN>, | ||
<&pciesys CLK_SATA_ASIC_EN>, | ||
<&pciesys CLK_SATA_RBC_EN>, | ||
<&pciesys CLK_SATA_PM_EN>; | ||
clock-names = "ahb", "axi", "asic", "rbc", "pm"; | ||
phys = <&u3port1 PHY_TYPE_SATA>; | ||
phy-names = "sata-phy"; | ||
ports-implemented = <0x1>; | ||
power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; | ||
resets = <&pciesys MT7622_SATA_AXI_BUS_RST>, | ||
<&pciesys MT7622_SATA_PHY_SW_RST>, | ||
<&pciesys MT7622_SATA_PHY_REG_RST>; | ||
reset-names = "axi", "sw", "reg"; | ||
mediatek,phy-mode = <&pciesys>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
/* | ||
* MeidaTek AHCI SATA driver | ||
* | ||
* Copyright (c) 2017 MediaTek Inc. | ||
* Author: Ryder Lee <[email protected]> | ||
* | ||
* 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 <linux/ahci_platform.h> | ||
#include <linux/kernel.h> | ||
#include <linux/libata.h> | ||
#include <linux/mfd/syscon.h> | ||
#include <linux/module.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/pm.h> | ||
#include <linux/regmap.h> | ||
#include <linux/reset.h> | ||
#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"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.