Merge branch 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata updates from Tejun Heo: "Nothing too interesting. Mostly ahci and ahci_platform changes, many around power management" * 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: (22 commits) ata: ahci_platform: enable to get and control reset ata: libahci_platform: add reset control support ata: add an extra argument to ahci_platform_get_resources() ata: sata_rcar: Add r8a77965 support ata: sata_rcar: exclude setting of PHY registers in Gen3 ata: sata_rcar: really mask all interrupts on Gen2 and later Revert "ata: ahci_platform: allow disabling of hotplug to save power" ata: libahci: Allow reconfigure of DEVSLP register ata: libahci: Correct setting of DEVSLP register ata: ahci: Enable DEVSLP by default on x86 with SLP_S0 ata: ahci: Support state with min power but Partial low power state Revert "ata: ahci_platform: convert kcalloc to devm_kcalloc" ata: sata_rcar: Add rudimentary Runtime PM support ata: sata_rcar: Provide a short-hand for &pdev->dev ata: Only output sg element mapped number in verbose debug ata: Guard ata_scsi_dump_cdb() by ATA_VERBOSE_DEBUG ata: ahci_platform: convert kcalloc to devm_kcalloc ata: ahci_platform: convert kzallloc to kcalloc ata: ahci_platform: correct parameter documentation for ahci_platform_shutdown libata: remove ata_sff_data_xfer_noirq() ...
This commit is contained in:
commit
0519359784
|
@ -29,6 +29,7 @@ compatible:
|
|||
Optional properties:
|
||||
- dma-coherent : Present if dma operations are coherent
|
||||
- clocks : a list of phandle + clock specifier pairs
|
||||
- resets : a list of phandle + reset specifier pairs
|
||||
- target-supply : regulator for SATA target power
|
||||
- phys : reference to the SATA PHY node
|
||||
- phy-names : must be "sata-phy"
|
||||
|
|
|
@ -8,6 +8,7 @@ Required properties:
|
|||
- "renesas,sata-r8a7791" for R-Car M2-W
|
||||
- "renesas,sata-r8a7793" for R-Car M2-N
|
||||
- "renesas,sata-r8a7795" for R-Car H3
|
||||
- "renesas,sata-r8a77965" for R-Car M3-N
|
||||
- "renesas,rcar-gen2-sata" for a generic R-Car Gen2 compatible device
|
||||
- "renesas,rcar-gen3-sata" for a generic R-Car Gen3 compatible device
|
||||
- "renesas,rcar-sata" is deprecated
|
||||
|
|
|
@ -118,8 +118,7 @@ PIO data read/write
|
|||
All bmdma-style drivers must implement this hook. This is the low-level
|
||||
operation that actually copies the data bytes during a PIO data
|
||||
transfer. Typically the driver will choose one of
|
||||
:c:func:`ata_sff_data_xfer_noirq`, :c:func:`ata_sff_data_xfer`, or
|
||||
:c:func:`ata_sff_data_xfer32`.
|
||||
:c:func:`ata_sff_data_xfer`, or :c:func:`ata_sff_data_xfer32`.
|
||||
|
||||
ATA command execute
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -610,7 +610,7 @@ static int marvell_enable = 1;
|
|||
module_param(marvell_enable, int, 0644);
|
||||
MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
|
||||
|
||||
static int mobile_lpm_policy = CONFIG_SATA_MOBILE_LPM_POLICY;
|
||||
static int mobile_lpm_policy = -1;
|
||||
module_param(mobile_lpm_policy, int, 0644);
|
||||
MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
|
||||
|
||||
|
@ -1604,6 +1604,37 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
|
|||
return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
|
||||
}
|
||||
|
||||
static void ahci_update_initial_lpm_policy(struct ata_port *ap,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
int policy = CONFIG_SATA_MOBILE_LPM_POLICY;
|
||||
|
||||
|
||||
/* Ignore processing for non mobile platforms */
|
||||
if (!(hpriv->flags & AHCI_HFLAG_IS_MOBILE))
|
||||
return;
|
||||
|
||||
/* user modified policy via module param */
|
||||
if (mobile_lpm_policy != -1) {
|
||||
policy = mobile_lpm_policy;
|
||||
goto update_policy;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
if (policy > ATA_LPM_MED_POWER &&
|
||||
(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
|
||||
if (hpriv->cap & HOST_CAP_PART)
|
||||
policy = ATA_LPM_MIN_POWER_WITH_PARTIAL;
|
||||
else if (hpriv->cap & HOST_CAP_SSC)
|
||||
policy = ATA_LPM_MIN_POWER;
|
||||
}
|
||||
#endif
|
||||
|
||||
update_policy:
|
||||
if (policy >= ATA_LPM_UNKNOWN && policy <= ATA_LPM_MIN_POWER)
|
||||
ap->target_lpm_policy = policy;
|
||||
}
|
||||
|
||||
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
unsigned int board_id = ent->driver_data;
|
||||
|
@ -1807,10 +1838,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (ap->flags & ATA_FLAG_EM)
|
||||
ap->em_message_type = hpriv->em_msg_type;
|
||||
|
||||
if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) &&
|
||||
mobile_lpm_policy >= ATA_LPM_UNKNOWN &&
|
||||
mobile_lpm_policy <= ATA_LPM_MIN_POWER)
|
||||
ap->target_lpm_policy = mobile_lpm_policy;
|
||||
ahci_update_initial_lpm_policy(ap, hpriv);
|
||||
|
||||
/* disabled/not-implemented port */
|
||||
if (!(hpriv->port_map & (1 << i)))
|
||||
|
|
|
@ -350,6 +350,7 @@ struct ahci_host_priv {
|
|||
u32 em_msg_type; /* EM message type */
|
||||
bool got_runtime_pm; /* Did we do pm_runtime_get? */
|
||||
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
|
||||
struct reset_control *rsts; /* Optional */
|
||||
struct regulator **target_pwrs; /* Optional */
|
||||
/*
|
||||
* If platform uses PHYs. There is a 1:1 relation between the port number and
|
||||
|
|
|
@ -425,7 +425,7 @@ static int brcm_ahci_probe(struct platform_device *pdev)
|
|||
|
||||
brcm_sata_phys_enable(priv);
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
hpriv->plat_data = priv;
|
||||
|
|
|
@ -213,7 +213,7 @@ static int ceva_ahci_probe(struct platform_device *pdev)
|
|||
|
||||
cevapriv->ahci_pdev = pdev;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
|
|||
u32 mpy;
|
||||
int rc;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ static int ahci_dm816_probe(struct platform_device *pdev)
|
|||
struct ahci_host_priv *hpriv;
|
||||
int rc;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -1127,7 +1127,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ static int mtk_ahci_probe(struct platform_device *pdev)
|
|||
if (!plat)
|
||||
return -ENOMEM;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
|
|||
const struct mbus_dram_target_info *dram;
|
||||
int rc;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ static int ahci_probe(struct platform_device *pdev)
|
|||
struct ahci_host_priv *hpriv;
|
||||
int rc;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev,
|
||||
AHCI_PLATFORM_GET_RESETS);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
|
|||
struct resource *res;
|
||||
int rc;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ static int ahci_seattle_probe(struct platform_device *pdev)
|
|||
int rc;
|
||||
struct ahci_host_priv *hpriv;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ static int st_ahci_probe(struct platform_device *pdev)
|
|||
if (!drv_data)
|
||||
return -ENOMEM;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
hpriv->plat_data = drv_data;
|
||||
|
|
|
@ -181,7 +181,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
|
|||
struct ahci_host_priv *hpriv;
|
||||
int rc;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
|
|||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -759,7 +759,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
|
|||
&xgene_ahci_v2_port_info };
|
||||
int rc;
|
||||
|
||||
hpriv = ahci_platform_get_resources(pdev);
|
||||
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||
if (IS_ERR(hpriv))
|
||||
return PTR_ERR(hpriv);
|
||||
|
||||
|
|
|
@ -801,6 +801,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|||
cmd |= PORT_CMD_ALPE;
|
||||
if (policy == ATA_LPM_MIN_POWER)
|
||||
cmd |= PORT_CMD_ASP;
|
||||
else if (policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
|
||||
cmd &= ~PORT_CMD_ASP;
|
||||
|
||||
/* write out new cmd value */
|
||||
writel(cmd, port_mmio + PORT_CMD);
|
||||
|
@ -811,7 +813,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|||
if ((hpriv->cap2 & HOST_CAP2_SDS) &&
|
||||
(hpriv->cap2 & HOST_CAP2_SADM) &&
|
||||
(link->device->flags & ATA_DFLAG_DEVSLP)) {
|
||||
if (policy == ATA_LPM_MIN_POWER)
|
||||
if (policy == ATA_LPM_MIN_POWER ||
|
||||
policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
|
||||
ahci_set_aggressive_devslp(ap, true);
|
||||
else
|
||||
ahci_set_aggressive_devslp(ap, false);
|
||||
|
@ -2107,7 +2110,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
|
|||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
struct ata_device *dev = ap->link.device;
|
||||
u32 devslp, dm, dito, mdat, deto;
|
||||
u32 devslp, dm, dito, mdat, deto, dito_conf;
|
||||
int rc;
|
||||
unsigned int err_mask;
|
||||
|
||||
|
@ -2131,8 +2134,15 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
|
|||
return;
|
||||
}
|
||||
|
||||
/* device sleep was already enabled */
|
||||
if (devslp & PORT_DEVSLP_ADSE)
|
||||
dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
|
||||
dito = devslp_idle_timeout / (dm + 1);
|
||||
if (dito > 0x3ff)
|
||||
dito = 0x3ff;
|
||||
|
||||
dito_conf = (devslp >> PORT_DEVSLP_DITO_OFFSET) & 0x3FF;
|
||||
|
||||
/* device sleep was already enabled and same dito */
|
||||
if ((devslp & PORT_DEVSLP_ADSE) && (dito_conf == dito))
|
||||
return;
|
||||
|
||||
/* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */
|
||||
|
@ -2140,11 +2150,6 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
|
|||
if (rc)
|
||||
return;
|
||||
|
||||
dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
|
||||
dito = devslp_idle_timeout / (dm + 1);
|
||||
if (dito > 0x3ff)
|
||||
dito = 0x3ff;
|
||||
|
||||
/* Use the nominal value 10 ms if the read MDAT is zero,
|
||||
* the nominal value of DETO is 20 ms.
|
||||
*/
|
||||
|
@ -2162,6 +2167,8 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
|
|||
deto = 20;
|
||||
}
|
||||
|
||||
/* Make dito, mdat, deto bits to 0s */
|
||||
devslp &= ~GENMASK_ULL(24, 2);
|
||||
devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) |
|
||||
(mdat << PORT_DEVSLP_MDAT_OFFSET) |
|
||||
(deto << PORT_DEVSLP_DETO_OFFSET) |
|
||||
|
@ -2439,6 +2446,8 @@ static void ahci_port_stop(struct ata_port *ap)
|
|||
* re-enabling INTx.
|
||||
*/
|
||||
writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT);
|
||||
|
||||
ahci_rpm_put_port(ap);
|
||||
}
|
||||
|
||||
void ahci_print_info(struct ata_host *host, const char *scc_s)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/phy/phy.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/reset.h>
|
||||
#include "ahci.h"
|
||||
|
||||
static void ahci_host_stop(struct ata_host *host);
|
||||
|
@ -195,7 +196,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
|
|||
* following order:
|
||||
* 1) Regulator
|
||||
* 2) Clocks (through ahci_platform_enable_clks)
|
||||
* 3) Phys
|
||||
* 3) Resets
|
||||
* 4) Phys
|
||||
*
|
||||
* If resource enabling fails at any point the previous enabled resources
|
||||
* are disabled in reverse order.
|
||||
|
@ -215,12 +217,19 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
|
|||
if (rc)
|
||||
goto disable_regulator;
|
||||
|
||||
rc = ahci_platform_enable_phys(hpriv);
|
||||
rc = reset_control_deassert(hpriv->rsts);
|
||||
if (rc)
|
||||
goto disable_clks;
|
||||
|
||||
rc = ahci_platform_enable_phys(hpriv);
|
||||
if (rc)
|
||||
goto disable_resets;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_resets:
|
||||
reset_control_assert(hpriv->rsts);
|
||||
|
||||
disable_clks:
|
||||
ahci_platform_disable_clks(hpriv);
|
||||
|
||||
|
@ -238,13 +247,16 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
|
|||
* This function disables all ahci_platform managed resources in the
|
||||
* following order:
|
||||
* 1) Phys
|
||||
* 2) Clocks (through ahci_platform_disable_clks)
|
||||
* 3) Regulator
|
||||
* 2) Resets
|
||||
* 3) Clocks (through ahci_platform_disable_clks)
|
||||
* 4) Regulator
|
||||
*/
|
||||
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
|
||||
{
|
||||
ahci_platform_disable_phys(hpriv);
|
||||
|
||||
reset_control_assert(hpriv->rsts);
|
||||
|
||||
ahci_platform_disable_clks(hpriv);
|
||||
|
||||
ahci_platform_disable_regulators(hpriv);
|
||||
|
@ -332,6 +344,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
|
|||
/**
|
||||
* ahci_platform_get_resources - Get platform resources
|
||||
* @pdev: platform device to get resources for
|
||||
* @flags: bitmap representing the resource to get
|
||||
*
|
||||
* This function allocates an ahci_host_priv struct, and gets the following
|
||||
* resources, storing a reference to them inside the returned struct:
|
||||
|
@ -340,18 +353,20 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
|
|||
* 2) regulator for controlling the targets power (optional)
|
||||
* 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
|
||||
* or for non devicetree enabled platforms a single clock
|
||||
* 4) phys (optional)
|
||||
* 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional)
|
||||
* 5) phys (optional)
|
||||
*
|
||||
* RETURNS:
|
||||
* The allocated ahci_host_priv on success, otherwise an ERR_PTR value
|
||||
*/
|
||||
struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
|
||||
struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ahci_host_priv *hpriv;
|
||||
struct clk *clk;
|
||||
struct device_node *child;
|
||||
int i, sz, enabled_ports = 0, rc = -ENOMEM, child_nodes;
|
||||
int i, enabled_ports = 0, rc = -ENOMEM, child_nodes;
|
||||
u32 mask_port_map = 0;
|
||||
|
||||
if (!devres_open_group(dev, NULL, GFP_KERNEL))
|
||||
|
@ -393,6 +408,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
|
|||
hpriv->clks[i] = clk;
|
||||
}
|
||||
|
||||
if (flags & AHCI_PLATFORM_GET_RESETS) {
|
||||
hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
|
||||
if (IS_ERR(hpriv->rsts)) {
|
||||
rc = PTR_ERR(hpriv->rsts);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
|
||||
|
||||
/*
|
||||
|
@ -403,14 +426,16 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
|
|||
if (!child_nodes)
|
||||
hpriv->nports = 1;
|
||||
|
||||
sz = hpriv->nports * sizeof(*hpriv->phys);
|
||||
hpriv->phys = devm_kzalloc(dev, sz, GFP_KERNEL);
|
||||
hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
|
||||
if (!hpriv->phys) {
|
||||
rc = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
sz = hpriv->nports * sizeof(*hpriv->target_pwrs);
|
||||
hpriv->target_pwrs = kzalloc(sz, GFP_KERNEL);
|
||||
/*
|
||||
* We cannot use devm_ here, since ahci_platform_put_resources() uses
|
||||
* target_pwrs after devm_ have freed memory
|
||||
*/
|
||||
hpriv->target_pwrs = kcalloc(hpriv->nports, sizeof(*hpriv->target_pwrs), GFP_KERNEL);
|
||||
if (!hpriv->target_pwrs) {
|
||||
rc = -ENOMEM;
|
||||
goto err_out;
|
||||
|
@ -605,7 +630,7 @@ static void ahci_host_stop(struct ata_host *host)
|
|||
|
||||
/**
|
||||
* ahci_platform_shutdown - Disable interrupts and stop DMA for host ports
|
||||
* @dev: platform device pointer for the host
|
||||
* @pdev: 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
|
||||
|
|
|
@ -3970,6 +3970,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|||
scontrol |= (0x6 << 8);
|
||||
break;
|
||||
case ATA_LPM_MED_POWER_WITH_DIPM:
|
||||
case ATA_LPM_MIN_POWER_WITH_PARTIAL:
|
||||
case ATA_LPM_MIN_POWER:
|
||||
if (ata_link_nr_enabled(link) > 0)
|
||||
/* no restrictions on LPM transitions */
|
||||
|
@ -5066,7 +5067,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
|
|||
if (n_elem < 1)
|
||||
return -1;
|
||||
|
||||
DPRINTK("%d sg elements mapped\n", n_elem);
|
||||
VPRINTK("%d sg elements mapped\n", n_elem);
|
||||
qc->orig_n_elem = qc->n_elem;
|
||||
qc->n_elem = n_elem;
|
||||
qc->flags |= ATA_QCFLAG_DMAMAP;
|
||||
|
|
|
@ -110,6 +110,7 @@ static const char *ata_lpm_policy_names[] = {
|
|||
[ATA_LPM_MAX_POWER] = "max_performance",
|
||||
[ATA_LPM_MED_POWER] = "medium_power",
|
||||
[ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm",
|
||||
[ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial",
|
||||
[ATA_LPM_MIN_POWER] = "min_power",
|
||||
};
|
||||
|
||||
|
@ -4288,10 +4289,10 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
|
|||
static inline void ata_scsi_dump_cdb(struct ata_port *ap,
|
||||
struct scsi_cmnd *cmd)
|
||||
{
|
||||
#ifdef ATA_DEBUG
|
||||
#ifdef ATA_VERBOSE_DEBUG
|
||||
struct scsi_device *scsidev = cmd->device;
|
||||
|
||||
DPRINTK("CDB (%u:%d,%d,%lld) %9ph\n",
|
||||
VPRINTK("CDB (%u:%d,%d,%lld) %9ph\n",
|
||||
ap->print_id,
|
||||
scsidev->channel, scsidev->id, scsidev->lun,
|
||||
cmd->cmnd);
|
||||
|
|
|
@ -657,36 +657,6 @@ unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
|
||||
|
||||
/**
|
||||
* ata_sff_data_xfer_noirq - Transfer data by PIO
|
||||
* @qc: queued command
|
||||
* @buf: data buffer
|
||||
* @buflen: buffer length
|
||||
* @rw: read/write
|
||||
*
|
||||
* Transfer data from/to the device data register by PIO. Do the
|
||||
* transfer with interrupts disabled.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*
|
||||
* RETURNS:
|
||||
* Bytes consumed.
|
||||
*/
|
||||
unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc, unsigned char *buf,
|
||||
unsigned int buflen, int rw)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int consumed;
|
||||
|
||||
local_irq_save(flags);
|
||||
consumed = ata_sff_data_xfer32(qc, buf, buflen, rw);
|
||||
local_irq_restore(flags);
|
||||
|
||||
return consumed;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer_noirq);
|
||||
|
||||
/**
|
||||
* ata_pio_sector - Transfer a sector of data.
|
||||
* @qc: Command on going
|
||||
|
|
|
@ -178,7 +178,7 @@ static struct scsi_host_template cmd640_sht = {
|
|||
static struct ata_port_operations cmd640_port_ops = {
|
||||
.inherits = &ata_sff_port_ops,
|
||||
/* In theory xfer_noirq is not needed once we kill the prefetcher */
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
.sff_irq_check = cmd640_sff_irq_check,
|
||||
.qc_issue = cmd640_qc_issue,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
|
|
@ -324,7 +324,7 @@ static struct ata_port_operations pata_icside_port_ops = {
|
|||
.inherits = &ata_bmdma_port_ops,
|
||||
/* no need to build any PRD tables for DMA */
|
||||
.qc_prep = ata_noop_qc_prep,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
.bmdma_setup = pata_icside_bmdma_setup,
|
||||
.bmdma_start = pata_icside_bmdma_start,
|
||||
.bmdma_stop = pata_icside_bmdma_stop,
|
||||
|
|
|
@ -103,7 +103,7 @@ static struct scsi_host_template pata_imx_sht = {
|
|||
|
||||
static struct ata_port_operations pata_imx_port_ops = {
|
||||
.inherits = &ata_sff_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
.set_piomode = pata_imx_set_piomode,
|
||||
};
|
||||
|
|
|
@ -246,12 +246,12 @@ static const struct ata_port_operations legacy_base_port_ops = {
|
|||
|
||||
static struct ata_port_operations simple_port_ops = {
|
||||
.inherits = &legacy_base_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
};
|
||||
|
||||
static struct ata_port_operations legacy_port_ops = {
|
||||
.inherits = &legacy_base_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
.set_mode = legacy_set_mode,
|
||||
};
|
||||
|
||||
|
@ -341,7 +341,7 @@ static unsigned int pdc_data_xfer_vlb(struct ata_queued_cmd *qc,
|
|||
}
|
||||
local_irq_restore(flags);
|
||||
} else
|
||||
buflen = ata_sff_data_xfer_noirq(qc, buf, buflen, rw);
|
||||
buflen = ata_sff_data_xfer32(qc, buf, buflen, rw);
|
||||
|
||||
return buflen;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ static struct scsi_host_template palmld_sht = {
|
|||
|
||||
static struct ata_port_operations palmld_port_ops = {
|
||||
.inherits = &ata_sff_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
};
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ static struct scsi_host_template pcmcia_sht = {
|
|||
|
||||
static struct ata_port_operations pcmcia_port_ops = {
|
||||
.inherits = &ata_sff_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
.set_mode = pcmcia_set_mode,
|
||||
};
|
||||
|
|
|
@ -49,7 +49,7 @@ static struct scsi_host_template pata_platform_sht = {
|
|||
|
||||
static struct ata_port_operations pata_platform_port_ops = {
|
||||
.inherits = &ata_sff_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
.set_mode = pata_platform_set_mode,
|
||||
};
|
||||
|
|
|
@ -471,7 +471,7 @@ static struct ata_port_operations via_port_ops = {
|
|||
|
||||
static struct ata_port_operations via_port_ops_noirq = {
|
||||
.inherits = &via_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <linux/libata.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#define DRV_NAME "sata_rcar"
|
||||
|
@ -109,6 +109,8 @@
|
|||
#define SATAINTMASK_ERRMSK BIT(2)
|
||||
#define SATAINTMASK_ERRCRTMSK BIT(1)
|
||||
#define SATAINTMASK_ATAMSK BIT(0)
|
||||
#define SATAINTMASK_ALL_GEN1 0x7ff
|
||||
#define SATAINTMASK_ALL_GEN2 0xfff
|
||||
|
||||
#define SATA_RCAR_INT_MASK (SATAINTMASK_SERRMSK | \
|
||||
SATAINTMASK_ATAMSK)
|
||||
|
@ -152,7 +154,7 @@ enum sata_rcar_type {
|
|||
|
||||
struct sata_rcar_priv {
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
u32 sataint_mask;
|
||||
enum sata_rcar_type type;
|
||||
};
|
||||
|
||||
|
@ -226,7 +228,7 @@ static void sata_rcar_freeze(struct ata_port *ap)
|
|||
struct sata_rcar_priv *priv = ap->host->private_data;
|
||||
|
||||
/* mask */
|
||||
iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
|
||||
iowrite32(priv->sataint_mask, priv->base + SATAINTMASK_REG);
|
||||
|
||||
ata_sff_freeze(ap);
|
||||
}
|
||||
|
@ -242,7 +244,7 @@ static void sata_rcar_thaw(struct ata_port *ap)
|
|||
ata_sff_thaw(ap);
|
||||
|
||||
/* unmask */
|
||||
iowrite32(0x7ff & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG);
|
||||
iowrite32(priv->sataint_mask & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG);
|
||||
}
|
||||
|
||||
static void sata_rcar_ioread16_rep(void __iomem *reg, void *buffer, int count)
|
||||
|
@ -736,7 +738,7 @@ static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance)
|
|||
if (!sataintstat)
|
||||
goto done;
|
||||
/* ack */
|
||||
iowrite32(~sataintstat & 0x7ff, base + SATAINTSTAT_REG);
|
||||
iowrite32(~sataintstat & priv->sataint_mask, base + SATAINTSTAT_REG);
|
||||
|
||||
ap = host->ports[0];
|
||||
|
||||
|
@ -809,7 +811,7 @@ static void sata_rcar_init_module(struct sata_rcar_priv *priv)
|
|||
|
||||
/* ack and mask */
|
||||
iowrite32(0, base + SATAINTSTAT_REG);
|
||||
iowrite32(0x7ff, base + SATAINTMASK_REG);
|
||||
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||
|
||||
/* enable interrupts */
|
||||
iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
|
||||
|
@ -819,16 +821,20 @@ static void sata_rcar_init_controller(struct ata_host *host)
|
|||
{
|
||||
struct sata_rcar_priv *priv = host->private_data;
|
||||
|
||||
priv->sataint_mask = SATAINTMASK_ALL_GEN2;
|
||||
|
||||
/* reset and setup phy */
|
||||
switch (priv->type) {
|
||||
case RCAR_GEN1_SATA:
|
||||
priv->sataint_mask = SATAINTMASK_ALL_GEN1;
|
||||
sata_rcar_gen1_phy_init(priv);
|
||||
break;
|
||||
case RCAR_GEN2_SATA:
|
||||
case RCAR_GEN3_SATA:
|
||||
case RCAR_R8A7790_ES1_SATA:
|
||||
sata_rcar_gen2_phy_init(priv);
|
||||
break;
|
||||
case RCAR_GEN3_SATA:
|
||||
break;
|
||||
default:
|
||||
dev_warn(host->dev, "SATA phy is not initialized\n");
|
||||
break;
|
||||
|
@ -881,6 +887,7 @@ MODULE_DEVICE_TABLE(of, sata_rcar_match);
|
|||
|
||||
static int sata_rcar_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_host *host;
|
||||
struct sata_rcar_priv *priv;
|
||||
struct resource *mem;
|
||||
|
@ -891,36 +898,31 @@ static int sata_rcar_probe(struct platform_device *pdev)
|
|||
if (irq <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct sata_rcar_priv),
|
||||
GFP_KERNEL);
|
||||
priv = devm_kzalloc(dev, sizeof(struct sata_rcar_priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->type = (enum sata_rcar_type)of_device_get_match_data(&pdev->dev);
|
||||
priv->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(priv->clk)) {
|
||||
dev_err(&pdev->dev, "failed to get access to sata clock\n");
|
||||
return PTR_ERR(priv->clk);
|
||||
}
|
||||
priv->type = (enum sata_rcar_type)of_device_get_match_data(dev);
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
pm_runtime_enable(dev);
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
goto err_pm_disable;
|
||||
|
||||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
host = ata_host_alloc(dev, 1);
|
||||
if (!host) {
|
||||
dev_err(&pdev->dev, "ata_host_alloc failed\n");
|
||||
dev_err(dev, "ata_host_alloc failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
host->private_data = priv;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(&pdev->dev, mem);
|
||||
priv->base = devm_ioremap_resource(dev, mem);
|
||||
if (IS_ERR(priv->base)) {
|
||||
ret = PTR_ERR(priv->base);
|
||||
goto cleanup;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
/* setup port */
|
||||
|
@ -934,9 +936,10 @@ static int sata_rcar_probe(struct platform_device *pdev)
|
|||
if (!ret)
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
|
||||
err_pm_put:
|
||||
pm_runtime_put(dev);
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -952,9 +955,10 @@ static int sata_rcar_remove(struct platform_device *pdev)
|
|||
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
||||
/* ack and mask */
|
||||
iowrite32(0, base + SATAINTSTAT_REG);
|
||||
iowrite32(0x7ff, base + SATAINTMASK_REG);
|
||||
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -972,9 +976,9 @@ static int sata_rcar_suspend(struct device *dev)
|
|||
/* disable interrupts */
|
||||
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
||||
/* mask */
|
||||
iowrite32(0x7ff, base + SATAINTMASK_REG);
|
||||
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
pm_runtime_put(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -987,17 +991,16 @@ static int sata_rcar_resume(struct device *dev)
|
|||
void __iomem *base = priv->base;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret)
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (priv->type == RCAR_GEN3_SATA) {
|
||||
sata_rcar_gen2_phy_init(priv);
|
||||
sata_rcar_init_module(priv);
|
||||
} else {
|
||||
/* ack and mask */
|
||||
iowrite32(0, base + SATAINTSTAT_REG);
|
||||
iowrite32(0x7ff, base + SATAINTMASK_REG);
|
||||
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||
|
||||
/* enable interrupts */
|
||||
iowrite32(ATAPI_INT_ENABLE_SATAINT,
|
||||
|
@ -1012,11 +1015,10 @@ static int sata_rcar_resume(struct device *dev)
|
|||
static int sata_rcar_restore(struct device *dev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
struct sata_rcar_priv *priv = host->private_data;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret)
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sata_rcar_setup_port(host);
|
||||
|
|
|
@ -30,7 +30,7 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv);
|
|||
int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
|
||||
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
|
||||
struct ahci_host_priv *ahci_platform_get_resources(
|
||||
struct platform_device *pdev);
|
||||
struct platform_device *pdev, unsigned int flags);
|
||||
int ahci_platform_init_host(struct platform_device *pdev,
|
||||
struct ahci_host_priv *hpriv,
|
||||
const struct ata_port_info *pi_template,
|
||||
|
@ -43,4 +43,6 @@ int ahci_platform_resume_host(struct device *dev);
|
|||
int ahci_platform_suspend(struct device *dev);
|
||||
int ahci_platform_resume(struct device *dev);
|
||||
|
||||
#define AHCI_PLATFORM_GET_RESETS 0x01
|
||||
|
||||
#endif /* _AHCI_PLATFORM_H */
|
||||
|
|
|
@ -523,7 +523,8 @@ enum ata_lpm_policy {
|
|||
ATA_LPM_MAX_POWER,
|
||||
ATA_LPM_MED_POWER,
|
||||
ATA_LPM_MED_POWER_WITH_DIPM, /* Med power + DIPM as win IRST does */
|
||||
ATA_LPM_MIN_POWER,
|
||||
ATA_LPM_MIN_POWER_WITH_PARTIAL, /* Min Power + partial and slumber */
|
||||
ATA_LPM_MIN_POWER, /* Min power + no partial (slumber only) */
|
||||
};
|
||||
|
||||
enum ata_lpm_hints {
|
||||
|
@ -1858,8 +1859,6 @@ extern unsigned int ata_sff_data_xfer(struct ata_queued_cmd *qc,
|
|||
unsigned char *buf, unsigned int buflen, int rw);
|
||||
extern unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc,
|
||||
unsigned char *buf, unsigned int buflen, int rw);
|
||||
extern unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc,
|
||||
unsigned char *buf, unsigned int buflen, int rw);
|
||||
extern void ata_sff_irq_on(struct ata_port *ap);
|
||||
extern void ata_sff_irq_clear(struct ata_port *ap);
|
||||
extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
|
||||
|
|
Loading…
Reference in New Issue