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:
@@ -29,6 +29,7 @@ compatible:
|
|||||||
Optional properties:
|
Optional properties:
|
||||||
- dma-coherent : Present if dma operations are coherent
|
- dma-coherent : Present if dma operations are coherent
|
||||||
- clocks : a list of phandle + clock specifier pairs
|
- clocks : a list of phandle + clock specifier pairs
|
||||||
|
- resets : a list of phandle + reset specifier pairs
|
||||||
- target-supply : regulator for SATA target power
|
- target-supply : regulator for SATA target power
|
||||||
- phys : reference to the SATA PHY node
|
- phys : reference to the SATA PHY node
|
||||||
- phy-names : must be "sata-phy"
|
- phy-names : must be "sata-phy"
|
||||||
|
@@ -8,6 +8,7 @@ Required properties:
|
|||||||
- "renesas,sata-r8a7791" for R-Car M2-W
|
- "renesas,sata-r8a7791" for R-Car M2-W
|
||||||
- "renesas,sata-r8a7793" for R-Car M2-N
|
- "renesas,sata-r8a7793" for R-Car M2-N
|
||||||
- "renesas,sata-r8a7795" for R-Car H3
|
- "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-gen2-sata" for a generic R-Car Gen2 compatible device
|
||||||
- "renesas,rcar-gen3-sata" for a generic R-Car Gen3 compatible device
|
- "renesas,rcar-gen3-sata" for a generic R-Car Gen3 compatible device
|
||||||
- "renesas,rcar-sata" is deprecated
|
- "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
|
All bmdma-style drivers must implement this hook. This is the low-level
|
||||||
operation that actually copies the data bytes during a PIO data
|
operation that actually copies the data bytes during a PIO data
|
||||||
transfer. Typically the driver will choose one of
|
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_xfer`, or :c:func:`ata_sff_data_xfer32`.
|
||||||
:c:func:`ata_sff_data_xfer32`.
|
|
||||||
|
|
||||||
ATA command execute
|
ATA command execute
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
@@ -610,7 +610,7 @@ static int marvell_enable = 1;
|
|||||||
module_param(marvell_enable, int, 0644);
|
module_param(marvell_enable, int, 0644);
|
||||||
MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
|
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_param(mobile_lpm_policy, int, 0644);
|
||||||
MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
|
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);
|
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)
|
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
unsigned int board_id = ent->driver_data;
|
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)
|
if (ap->flags & ATA_FLAG_EM)
|
||||||
ap->em_message_type = hpriv->em_msg_type;
|
ap->em_message_type = hpriv->em_msg_type;
|
||||||
|
|
||||||
if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) &&
|
ahci_update_initial_lpm_policy(ap, hpriv);
|
||||||
mobile_lpm_policy >= ATA_LPM_UNKNOWN &&
|
|
||||||
mobile_lpm_policy <= ATA_LPM_MIN_POWER)
|
|
||||||
ap->target_lpm_policy = mobile_lpm_policy;
|
|
||||||
|
|
||||||
/* disabled/not-implemented port */
|
/* disabled/not-implemented port */
|
||||||
if (!(hpriv->port_map & (1 << i)))
|
if (!(hpriv->port_map & (1 << i)))
|
||||||
|
@@ -350,6 +350,7 @@ struct ahci_host_priv {
|
|||||||
u32 em_msg_type; /* EM message type */
|
u32 em_msg_type; /* EM message type */
|
||||||
bool got_runtime_pm; /* Did we do pm_runtime_get? */
|
bool got_runtime_pm; /* Did we do pm_runtime_get? */
|
||||||
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
|
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
|
||||||
|
struct reset_control *rsts; /* Optional */
|
||||||
struct regulator **target_pwrs; /* Optional */
|
struct regulator **target_pwrs; /* Optional */
|
||||||
/*
|
/*
|
||||||
* If platform uses PHYs. There is a 1:1 relation between the port number and
|
* 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);
|
brcm_sata_phys_enable(priv);
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
hpriv->plat_data = priv;
|
hpriv->plat_data = priv;
|
||||||
|
@@ -213,7 +213,7 @@ static int ceva_ahci_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
cevapriv->ahci_pdev = pdev;
|
cevapriv->ahci_pdev = pdev;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -171,7 +171,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
|
|||||||
u32 mpy;
|
u32 mpy;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -148,7 +148,7 @@ static int ahci_dm816_probe(struct platform_device *pdev)
|
|||||||
struct ahci_host_priv *hpriv;
|
struct ahci_host_priv *hpriv;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -1127,7 +1127,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -142,7 +142,7 @@ static int mtk_ahci_probe(struct platform_device *pdev)
|
|||||||
if (!plat)
|
if (!plat)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_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;
|
const struct mbus_dram_target_info *dram;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -43,7 +43,8 @@ static int ahci_probe(struct platform_device *pdev)
|
|||||||
struct ahci_host_priv *hpriv;
|
struct ahci_host_priv *hpriv;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev,
|
||||||
|
AHCI_PLATFORM_GET_RESETS);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -250,7 +250,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
|
|||||||
struct resource *res;
|
struct resource *res;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -164,7 +164,7 @@ static int ahci_seattle_probe(struct platform_device *pdev)
|
|||||||
int rc;
|
int rc;
|
||||||
struct ahci_host_priv *hpriv;
|
struct ahci_host_priv *hpriv;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -156,7 +156,7 @@ static int st_ahci_probe(struct platform_device *pdev)
|
|||||||
if (!drv_data)
|
if (!drv_data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
hpriv->plat_data = drv_data;
|
hpriv->plat_data = drv_data;
|
||||||
|
@@ -181,7 +181,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
|
|||||||
struct ahci_host_priv *hpriv;
|
struct ahci_host_priv *hpriv;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -494,7 +494,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
|
|||||||
int ret;
|
int ret;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_ERR(hpriv);
|
return PTR_ERR(hpriv);
|
||||||
|
|
||||||
|
@@ -759,7 +759,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
|
|||||||
&xgene_ahci_v2_port_info };
|
&xgene_ahci_v2_port_info };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
hpriv = ahci_platform_get_resources(pdev);
|
hpriv = ahci_platform_get_resources(pdev, 0);
|
||||||
if (IS_ERR(hpriv))
|
if (IS_ERR(hpriv))
|
||||||
return PTR_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;
|
cmd |= PORT_CMD_ALPE;
|
||||||
if (policy == ATA_LPM_MIN_POWER)
|
if (policy == ATA_LPM_MIN_POWER)
|
||||||
cmd |= PORT_CMD_ASP;
|
cmd |= PORT_CMD_ASP;
|
||||||
|
else if (policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
|
||||||
|
cmd &= ~PORT_CMD_ASP;
|
||||||
|
|
||||||
/* write out new cmd value */
|
/* write out new cmd value */
|
||||||
writel(cmd, port_mmio + PORT_CMD);
|
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) &&
|
if ((hpriv->cap2 & HOST_CAP2_SDS) &&
|
||||||
(hpriv->cap2 & HOST_CAP2_SADM) &&
|
(hpriv->cap2 & HOST_CAP2_SADM) &&
|
||||||
(link->device->flags & ATA_DFLAG_DEVSLP)) {
|
(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);
|
ahci_set_aggressive_devslp(ap, true);
|
||||||
else
|
else
|
||||||
ahci_set_aggressive_devslp(ap, false);
|
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;
|
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||||
void __iomem *port_mmio = ahci_port_base(ap);
|
void __iomem *port_mmio = ahci_port_base(ap);
|
||||||
struct ata_device *dev = ap->link.device;
|
struct ata_device *dev = ap->link.device;
|
||||||
u32 devslp, dm, dito, mdat, deto;
|
u32 devslp, dm, dito, mdat, deto, dito_conf;
|
||||||
int rc;
|
int rc;
|
||||||
unsigned int err_mask;
|
unsigned int err_mask;
|
||||||
|
|
||||||
@@ -2131,8 +2134,15 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* device sleep was already enabled */
|
dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
|
||||||
if (devslp & PORT_DEVSLP_ADSE)
|
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;
|
return;
|
||||||
|
|
||||||
/* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */
|
/* 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)
|
if (rc)
|
||||||
return;
|
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,
|
/* Use the nominal value 10 ms if the read MDAT is zero,
|
||||||
* the nominal value of DETO is 20 ms.
|
* 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;
|
deto = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make dito, mdat, deto bits to 0s */
|
||||||
|
devslp &= ~GENMASK_ULL(24, 2);
|
||||||
devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) |
|
devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) |
|
||||||
(mdat << PORT_DEVSLP_MDAT_OFFSET) |
|
(mdat << PORT_DEVSLP_MDAT_OFFSET) |
|
||||||
(deto << PORT_DEVSLP_DETO_OFFSET) |
|
(deto << PORT_DEVSLP_DETO_OFFSET) |
|
||||||
@@ -2439,6 +2446,8 @@ static void ahci_port_stop(struct ata_port *ap)
|
|||||||
* re-enabling INTx.
|
* re-enabling INTx.
|
||||||
*/
|
*/
|
||||||
writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT);
|
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)
|
void ahci_print_info(struct ata_host *host, const char *scc_s)
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <linux/phy/phy.h>
|
#include <linux/phy/phy.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/reset.h>
|
||||||
#include "ahci.h"
|
#include "ahci.h"
|
||||||
|
|
||||||
static void ahci_host_stop(struct ata_host *host);
|
static void ahci_host_stop(struct ata_host *host);
|
||||||
@@ -195,7 +196,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
|
|||||||
* following order:
|
* following order:
|
||||||
* 1) Regulator
|
* 1) Regulator
|
||||||
* 2) Clocks (through ahci_platform_enable_clks)
|
* 2) Clocks (through ahci_platform_enable_clks)
|
||||||
* 3) Phys
|
* 3) Resets
|
||||||
|
* 4) Phys
|
||||||
*
|
*
|
||||||
* If resource enabling fails at any point the previous enabled resources
|
* If resource enabling fails at any point the previous enabled resources
|
||||||
* are disabled in reverse order.
|
* are disabled in reverse order.
|
||||||
@@ -215,12 +217,19 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto disable_regulator;
|
goto disable_regulator;
|
||||||
|
|
||||||
rc = ahci_platform_enable_phys(hpriv);
|
rc = reset_control_deassert(hpriv->rsts);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto disable_clks;
|
goto disable_clks;
|
||||||
|
|
||||||
|
rc = ahci_platform_enable_phys(hpriv);
|
||||||
|
if (rc)
|
||||||
|
goto disable_resets;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
disable_resets:
|
||||||
|
reset_control_assert(hpriv->rsts);
|
||||||
|
|
||||||
disable_clks:
|
disable_clks:
|
||||||
ahci_platform_disable_clks(hpriv);
|
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
|
* This function disables all ahci_platform managed resources in the
|
||||||
* following order:
|
* following order:
|
||||||
* 1) Phys
|
* 1) Phys
|
||||||
* 2) Clocks (through ahci_platform_disable_clks)
|
* 2) Resets
|
||||||
* 3) Regulator
|
* 3) Clocks (through ahci_platform_disable_clks)
|
||||||
|
* 4) Regulator
|
||||||
*/
|
*/
|
||||||
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
|
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
|
||||||
{
|
{
|
||||||
ahci_platform_disable_phys(hpriv);
|
ahci_platform_disable_phys(hpriv);
|
||||||
|
|
||||||
|
reset_control_assert(hpriv->rsts);
|
||||||
|
|
||||||
ahci_platform_disable_clks(hpriv);
|
ahci_platform_disable_clks(hpriv);
|
||||||
|
|
||||||
ahci_platform_disable_regulators(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
|
* ahci_platform_get_resources - Get platform resources
|
||||||
* @pdev: platform device to get resources for
|
* @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
|
* This function allocates an ahci_host_priv struct, and gets the following
|
||||||
* resources, storing a reference to them inside the returned struct:
|
* 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)
|
* 2) regulator for controlling the targets power (optional)
|
||||||
* 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
|
* 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
|
||||||
* or for non devicetree enabled platforms a single clock
|
* 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:
|
* RETURNS:
|
||||||
* The allocated ahci_host_priv on success, otherwise an ERR_PTR value
|
* 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 device *dev = &pdev->dev;
|
||||||
struct ahci_host_priv *hpriv;
|
struct ahci_host_priv *hpriv;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct device_node *child;
|
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;
|
u32 mask_port_map = 0;
|
||||||
|
|
||||||
if (!devres_open_group(dev, NULL, GFP_KERNEL))
|
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;
|
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);
|
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)
|
if (!child_nodes)
|
||||||
hpriv->nports = 1;
|
hpriv->nports = 1;
|
||||||
|
|
||||||
sz = hpriv->nports * sizeof(*hpriv->phys);
|
hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
|
||||||
hpriv->phys = devm_kzalloc(dev, sz, GFP_KERNEL);
|
|
||||||
if (!hpriv->phys) {
|
if (!hpriv->phys) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_out;
|
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) {
|
if (!hpriv->target_pwrs) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_out;
|
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
|
* 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
|
* This function is called during system shutdown and performs the minimal
|
||||||
* deconfiguration required to ensure that an ahci_platform host cannot
|
* 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);
|
scontrol |= (0x6 << 8);
|
||||||
break;
|
break;
|
||||||
case ATA_LPM_MED_POWER_WITH_DIPM:
|
case ATA_LPM_MED_POWER_WITH_DIPM:
|
||||||
|
case ATA_LPM_MIN_POWER_WITH_PARTIAL:
|
||||||
case ATA_LPM_MIN_POWER:
|
case ATA_LPM_MIN_POWER:
|
||||||
if (ata_link_nr_enabled(link) > 0)
|
if (ata_link_nr_enabled(link) > 0)
|
||||||
/* no restrictions on LPM transitions */
|
/* no restrictions on LPM transitions */
|
||||||
@@ -5066,7 +5067,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
|
|||||||
if (n_elem < 1)
|
if (n_elem < 1)
|
||||||
return -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->orig_n_elem = qc->n_elem;
|
||||||
qc->n_elem = n_elem;
|
qc->n_elem = n_elem;
|
||||||
qc->flags |= ATA_QCFLAG_DMAMAP;
|
qc->flags |= ATA_QCFLAG_DMAMAP;
|
||||||
|
@@ -110,6 +110,7 @@ static const char *ata_lpm_policy_names[] = {
|
|||||||
[ATA_LPM_MAX_POWER] = "max_performance",
|
[ATA_LPM_MAX_POWER] = "max_performance",
|
||||||
[ATA_LPM_MED_POWER] = "medium_power",
|
[ATA_LPM_MED_POWER] = "medium_power",
|
||||||
[ATA_LPM_MED_POWER_WITH_DIPM] = "med_power_with_dipm",
|
[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",
|
[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,
|
static inline void ata_scsi_dump_cdb(struct ata_port *ap,
|
||||||
struct scsi_cmnd *cmd)
|
struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
#ifdef ATA_DEBUG
|
#ifdef ATA_VERBOSE_DEBUG
|
||||||
struct scsi_device *scsidev = cmd->device;
|
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,
|
ap->print_id,
|
||||||
scsidev->channel, scsidev->id, scsidev->lun,
|
scsidev->channel, scsidev->id, scsidev->lun,
|
||||||
cmd->cmnd);
|
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);
|
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.
|
* ata_pio_sector - Transfer a sector of data.
|
||||||
* @qc: Command on going
|
* @qc: Command on going
|
||||||
|
@@ -178,7 +178,7 @@ static struct scsi_host_template cmd640_sht = {
|
|||||||
static struct ata_port_operations cmd640_port_ops = {
|
static struct ata_port_operations cmd640_port_ops = {
|
||||||
.inherits = &ata_sff_port_ops,
|
.inherits = &ata_sff_port_ops,
|
||||||
/* In theory xfer_noirq is not needed once we kill the prefetcher */
|
/* 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,
|
.sff_irq_check = cmd640_sff_irq_check,
|
||||||
.qc_issue = cmd640_qc_issue,
|
.qc_issue = cmd640_qc_issue,
|
||||||
.cable_detect = ata_cable_40wire,
|
.cable_detect = ata_cable_40wire,
|
||||||
|
@@ -324,7 +324,7 @@ static struct ata_port_operations pata_icside_port_ops = {
|
|||||||
.inherits = &ata_bmdma_port_ops,
|
.inherits = &ata_bmdma_port_ops,
|
||||||
/* no need to build any PRD tables for DMA */
|
/* no need to build any PRD tables for DMA */
|
||||||
.qc_prep = ata_noop_qc_prep,
|
.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_setup = pata_icside_bmdma_setup,
|
||||||
.bmdma_start = pata_icside_bmdma_start,
|
.bmdma_start = pata_icside_bmdma_start,
|
||||||
.bmdma_stop = pata_icside_bmdma_stop,
|
.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 = {
|
static struct ata_port_operations pata_imx_port_ops = {
|
||||||
.inherits = &ata_sff_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,
|
.cable_detect = ata_cable_unknown,
|
||||||
.set_piomode = pata_imx_set_piomode,
|
.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 = {
|
static struct ata_port_operations simple_port_ops = {
|
||||||
.inherits = &legacy_base_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 = {
|
static struct ata_port_operations legacy_port_ops = {
|
||||||
.inherits = &legacy_base_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,
|
.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);
|
local_irq_restore(flags);
|
||||||
} else
|
} else
|
||||||
buflen = ata_sff_data_xfer_noirq(qc, buf, buflen, rw);
|
buflen = ata_sff_data_xfer32(qc, buf, buflen, rw);
|
||||||
|
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ static struct scsi_host_template palmld_sht = {
|
|||||||
|
|
||||||
static struct ata_port_operations palmld_port_ops = {
|
static struct ata_port_operations palmld_port_ops = {
|
||||||
.inherits = &ata_sff_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,
|
.cable_detect = ata_cable_40wire,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -151,7 +151,7 @@ static struct scsi_host_template pcmcia_sht = {
|
|||||||
|
|
||||||
static struct ata_port_operations pcmcia_port_ops = {
|
static struct ata_port_operations pcmcia_port_ops = {
|
||||||
.inherits = &ata_sff_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,
|
.cable_detect = ata_cable_40wire,
|
||||||
.set_mode = pcmcia_set_mode,
|
.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 = {
|
static struct ata_port_operations pata_platform_port_ops = {
|
||||||
.inherits = &ata_sff_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,
|
.cable_detect = ata_cable_unknown,
|
||||||
.set_mode = pata_platform_set_mode,
|
.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 = {
|
static struct ata_port_operations via_port_ops_noirq = {
|
||||||
.inherits = &via_port_ops,
|
.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/libata.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
|
||||||
#define DRV_NAME "sata_rcar"
|
#define DRV_NAME "sata_rcar"
|
||||||
@@ -109,6 +109,8 @@
|
|||||||
#define SATAINTMASK_ERRMSK BIT(2)
|
#define SATAINTMASK_ERRMSK BIT(2)
|
||||||
#define SATAINTMASK_ERRCRTMSK BIT(1)
|
#define SATAINTMASK_ERRCRTMSK BIT(1)
|
||||||
#define SATAINTMASK_ATAMSK BIT(0)
|
#define SATAINTMASK_ATAMSK BIT(0)
|
||||||
|
#define SATAINTMASK_ALL_GEN1 0x7ff
|
||||||
|
#define SATAINTMASK_ALL_GEN2 0xfff
|
||||||
|
|
||||||
#define SATA_RCAR_INT_MASK (SATAINTMASK_SERRMSK | \
|
#define SATA_RCAR_INT_MASK (SATAINTMASK_SERRMSK | \
|
||||||
SATAINTMASK_ATAMSK)
|
SATAINTMASK_ATAMSK)
|
||||||
@@ -152,7 +154,7 @@ enum sata_rcar_type {
|
|||||||
|
|
||||||
struct sata_rcar_priv {
|
struct sata_rcar_priv {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct clk *clk;
|
u32 sataint_mask;
|
||||||
enum sata_rcar_type type;
|
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;
|
struct sata_rcar_priv *priv = ap->host->private_data;
|
||||||
|
|
||||||
/* mask */
|
/* mask */
|
||||||
iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
|
iowrite32(priv->sataint_mask, priv->base + SATAINTMASK_REG);
|
||||||
|
|
||||||
ata_sff_freeze(ap);
|
ata_sff_freeze(ap);
|
||||||
}
|
}
|
||||||
@@ -242,7 +244,7 @@ static void sata_rcar_thaw(struct ata_port *ap)
|
|||||||
ata_sff_thaw(ap);
|
ata_sff_thaw(ap);
|
||||||
|
|
||||||
/* unmask */
|
/* 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)
|
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)
|
if (!sataintstat)
|
||||||
goto done;
|
goto done;
|
||||||
/* ack */
|
/* ack */
|
||||||
iowrite32(~sataintstat & 0x7ff, base + SATAINTSTAT_REG);
|
iowrite32(~sataintstat & priv->sataint_mask, base + SATAINTSTAT_REG);
|
||||||
|
|
||||||
ap = host->ports[0];
|
ap = host->ports[0];
|
||||||
|
|
||||||
@@ -809,7 +811,7 @@ static void sata_rcar_init_module(struct sata_rcar_priv *priv)
|
|||||||
|
|
||||||
/* ack and mask */
|
/* ack and mask */
|
||||||
iowrite32(0, base + SATAINTSTAT_REG);
|
iowrite32(0, base + SATAINTSTAT_REG);
|
||||||
iowrite32(0x7ff, base + SATAINTMASK_REG);
|
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||||
|
|
||||||
/* enable interrupts */
|
/* enable interrupts */
|
||||||
iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
|
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;
|
struct sata_rcar_priv *priv = host->private_data;
|
||||||
|
|
||||||
|
priv->sataint_mask = SATAINTMASK_ALL_GEN2;
|
||||||
|
|
||||||
/* reset and setup phy */
|
/* reset and setup phy */
|
||||||
switch (priv->type) {
|
switch (priv->type) {
|
||||||
case RCAR_GEN1_SATA:
|
case RCAR_GEN1_SATA:
|
||||||
|
priv->sataint_mask = SATAINTMASK_ALL_GEN1;
|
||||||
sata_rcar_gen1_phy_init(priv);
|
sata_rcar_gen1_phy_init(priv);
|
||||||
break;
|
break;
|
||||||
case RCAR_GEN2_SATA:
|
case RCAR_GEN2_SATA:
|
||||||
case RCAR_GEN3_SATA:
|
|
||||||
case RCAR_R8A7790_ES1_SATA:
|
case RCAR_R8A7790_ES1_SATA:
|
||||||
sata_rcar_gen2_phy_init(priv);
|
sata_rcar_gen2_phy_init(priv);
|
||||||
break;
|
break;
|
||||||
|
case RCAR_GEN3_SATA:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dev_warn(host->dev, "SATA phy is not initialized\n");
|
dev_warn(host->dev, "SATA phy is not initialized\n");
|
||||||
break;
|
break;
|
||||||
@@ -881,6 +887,7 @@ MODULE_DEVICE_TABLE(of, sata_rcar_match);
|
|||||||
|
|
||||||
static int sata_rcar_probe(struct platform_device *pdev)
|
static int sata_rcar_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
struct ata_host *host;
|
struct ata_host *host;
|
||||||
struct sata_rcar_priv *priv;
|
struct sata_rcar_priv *priv;
|
||||||
struct resource *mem;
|
struct resource *mem;
|
||||||
@@ -891,36 +898,31 @@ static int sata_rcar_probe(struct platform_device *pdev)
|
|||||||
if (irq <= 0)
|
if (irq <= 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct sata_rcar_priv),
|
priv = devm_kzalloc(dev, sizeof(struct sata_rcar_priv), GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
priv->type = (enum sata_rcar_type)of_device_get_match_data(&pdev->dev);
|
priv->type = (enum sata_rcar_type)of_device_get_match_data(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(priv->clk);
|
pm_runtime_enable(dev);
|
||||||
if (ret)
|
ret = pm_runtime_get_sync(dev);
|
||||||
return ret;
|
if (ret < 0)
|
||||||
|
goto err_pm_disable;
|
||||||
|
|
||||||
host = ata_host_alloc(&pdev->dev, 1);
|
host = ata_host_alloc(dev, 1);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
dev_err(&pdev->dev, "ata_host_alloc failed\n");
|
dev_err(dev, "ata_host_alloc failed\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto cleanup;
|
goto err_pm_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
host->private_data = priv;
|
host->private_data = priv;
|
||||||
|
|
||||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
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)) {
|
if (IS_ERR(priv->base)) {
|
||||||
ret = PTR_ERR(priv->base);
|
ret = PTR_ERR(priv->base);
|
||||||
goto cleanup;
|
goto err_pm_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup port */
|
/* setup port */
|
||||||
@@ -934,9 +936,10 @@ static int sata_rcar_probe(struct platform_device *pdev)
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
err_pm_put:
|
||||||
clk_disable_unprepare(priv->clk);
|
pm_runtime_put(dev);
|
||||||
|
err_pm_disable:
|
||||||
|
pm_runtime_disable(dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -952,9 +955,10 @@ static int sata_rcar_remove(struct platform_device *pdev)
|
|||||||
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
||||||
/* ack and mask */
|
/* ack and mask */
|
||||||
iowrite32(0, base + SATAINTSTAT_REG);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -972,9 +976,9 @@ static int sata_rcar_suspend(struct device *dev)
|
|||||||
/* disable interrupts */
|
/* disable interrupts */
|
||||||
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
iowrite32(0, base + ATAPI_INT_ENABLE_REG);
|
||||||
/* mask */
|
/* mask */
|
||||||
iowrite32(0x7ff, base + SATAINTMASK_REG);
|
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||||
|
|
||||||
clk_disable_unprepare(priv->clk);
|
pm_runtime_put(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -987,17 +991,16 @@ static int sata_rcar_resume(struct device *dev)
|
|||||||
void __iomem *base = priv->base;
|
void __iomem *base = priv->base;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = clk_prepare_enable(priv->clk);
|
ret = pm_runtime_get_sync(dev);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (priv->type == RCAR_GEN3_SATA) {
|
if (priv->type == RCAR_GEN3_SATA) {
|
||||||
sata_rcar_gen2_phy_init(priv);
|
|
||||||
sata_rcar_init_module(priv);
|
sata_rcar_init_module(priv);
|
||||||
} else {
|
} else {
|
||||||
/* ack and mask */
|
/* ack and mask */
|
||||||
iowrite32(0, base + SATAINTSTAT_REG);
|
iowrite32(0, base + SATAINTSTAT_REG);
|
||||||
iowrite32(0x7ff, base + SATAINTMASK_REG);
|
iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
|
||||||
|
|
||||||
/* enable interrupts */
|
/* enable interrupts */
|
||||||
iowrite32(ATAPI_INT_ENABLE_SATAINT,
|
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)
|
static int sata_rcar_restore(struct device *dev)
|
||||||
{
|
{
|
||||||
struct ata_host *host = dev_get_drvdata(dev);
|
struct ata_host *host = dev_get_drvdata(dev);
|
||||||
struct sata_rcar_priv *priv = host->private_data;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = clk_prepare_enable(priv->clk);
|
ret = pm_runtime_get_sync(dev);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
sata_rcar_setup_port(host);
|
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);
|
int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
|
||||||
void ahci_platform_disable_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 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,
|
int ahci_platform_init_host(struct platform_device *pdev,
|
||||||
struct ahci_host_priv *hpriv,
|
struct ahci_host_priv *hpriv,
|
||||||
const struct ata_port_info *pi_template,
|
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_suspend(struct device *dev);
|
||||||
int ahci_platform_resume(struct device *dev);
|
int ahci_platform_resume(struct device *dev);
|
||||||
|
|
||||||
|
#define AHCI_PLATFORM_GET_RESETS 0x01
|
||||||
|
|
||||||
#endif /* _AHCI_PLATFORM_H */
|
#endif /* _AHCI_PLATFORM_H */
|
||||||
|
@@ -523,7 +523,8 @@ enum ata_lpm_policy {
|
|||||||
ATA_LPM_MAX_POWER,
|
ATA_LPM_MAX_POWER,
|
||||||
ATA_LPM_MED_POWER,
|
ATA_LPM_MED_POWER,
|
||||||
ATA_LPM_MED_POWER_WITH_DIPM, /* Med power + DIPM as win IRST does */
|
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 {
|
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);
|
unsigned char *buf, unsigned int buflen, int rw);
|
||||||
extern unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc,
|
extern unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc,
|
||||||
unsigned char *buf, unsigned int buflen, int rw);
|
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_on(struct ata_port *ap);
|
||||||
extern void ata_sff_irq_clear(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,
|
extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
|
||||||
|
Reference in New Issue
Block a user