Commit 05193597 authored by Linus Torvalds's avatar Linus Torvalds

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()
  ...
parents 59676610 2d17f460
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment