Skip to content

Commit

Permalink
Merge tag 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/jgarzik/libata-dev

Pull libata changes from Jeff Garzik:
 "Minor libata updates, nothing notable.

   1) Apply -- and then revert -- the FUA feature.  Caused disk
      corruption in linux-next, proving it cannot be turned on by
      default.

      Net effect to upstream tree:  zero

   2) New AHCI platform driver sata_highbank

   3) Improve SCSI MODE SENSE handling; support MODE SELECT

   4) AHCI: support aggressive device sleep (power mgmt)

   5) sata_fsl: minor fix

   6) pata_arasan: clk support"

* tag 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  sata_mv: Fix warnings when no PCI
  [libata] Makefile: Fix build error in sata_highbank
  [libata] export ata_dev_set_feature()
  libata-core: use ATA_LBA in ata_build_rw_tf()
  ata/ahci_platform: Add clock framework support
  pata_arasan: add Device Tree probing capability
  pata_arasan: Add clk_{un}prepare() support
  ata: add platform driver for Calxeda AHCI controller
  sata_fsl: add workaround for data length mismatch on freescale V2 controller
  ahci: implement aggressive SATA device sleep support
  ata: define enum constants for IDENTIFY DEVICE
  Revert "libata: enable SATA disk fua detection on default"
  [libata] scsi: implement MODE SELECT command
  [libata] scsi: support MODE SENSE request for changeable and default parameters
  [libata] scsi: Remove unlikely() from FUA check
  libata: enable SATA disk fua detection on default
  • Loading branch information
torvalds committed Oct 3, 2012
2 parents 7fe0b14 + 13b7408 commit 51562cb
Show file tree
Hide file tree
Showing 19 changed files with 1,025 additions and 60 deletions.
17 changes: 17 additions & 0 deletions Documentation/devicetree/bindings/arm/calxeda/combophy.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Calxeda Highbank Combination Phys for SATA

Properties:
- compatible : Should be "calxeda,hb-combophy"
- #phy-cells: Should be 1.
- reg : Address and size for Combination Phy registers.
- phydev: device ID for programming the combophy.

Example:

combophy5: combo-phy@fff5d000 {
compatible = "calxeda,hb-combophy";
#phy-cells = <1>;
reg = <0xfff5d000 0x1000>;
phydev = <31>;
};

8 changes: 8 additions & 0 deletions Documentation/devicetree/bindings/ata/ahci-platform.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ Required properties:
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>

Optional properties:
- calxeda,port-phys: phandle-combophy and lane assignment, which maps each
SATA port to a combophy and a lane within that
combophy

Example:
sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x1000>;
interrupts = <115>;
calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1
&combophy0 2 &combophy0 3>;

};
17 changes: 17 additions & 0 deletions Documentation/devicetree/bindings/ata/pata-arasan.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
* ARASAN PATA COMPACT FLASH CONTROLLER

Required properties:
- compatible: "arasan,cf-spear1340"
- reg: Address range of the CF registers
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupt: Should contain the CF interrupt number

Example:

cf@fc000000 {
compatible = "arasan,cf-spear1340";
reg = <0xfc000000 0x1000>;
interrupt-parent = <&vic1>;
interrupts = <12>;
};
17 changes: 17 additions & 0 deletions arch/arm/boot/dts/highbank.dts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x10000>;
interrupts = <0 83 4>;
calxeda,port-phys = <&combophy5 0 &combophy0 0
&combophy0 1 &combophy0 2
&combophy0 3>;
};

sdhci@ffe0e000 {
Expand Down Expand Up @@ -306,5 +309,19 @@
reg = <0xfff51000 0x1000>;
interrupts = <0 80 4 0 81 4 0 82 4>;
};

combophy0: combo-phy@fff58000 {
compatible = "calxeda,hb-combophy";
#phy-cells = <1>;
reg = <0xfff58000 0x1000>;
phydev = <5>;
};

combophy5: combo-phy@fff5d000 {
compatible = "calxeda,hb-combophy";
#phy-cells = <1>;
reg = <0xfff5d000 0x1000>;
phydev = <31>;
};
};
};
8 changes: 8 additions & 0 deletions drivers/ata/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@ config SATA_DWC_VDEBUG
help
This option enables the taskfile dumping and NCQ debugging.

config SATA_HIGHBANK
tristate "Calxeda Highbank SATA support"
help
This option enables support for the Calxeda Highbank SoC's
onboard SATA.

If unsure, say N.

config SATA_MV
tristate "Marvell SATA support"
help
Expand Down
1 change: 1 addition & 0 deletions drivers/ata/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o

# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
Expand Down
16 changes: 16 additions & 0 deletions drivers/ata/ahci.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#ifndef _AHCI_H
#define _AHCI_H

#include <linux/clk.h>
#include <linux/libata.h>

/* Enclosure Management Control */
Expand Down Expand Up @@ -115,6 +116,9 @@ enum {
HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */
HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */
HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */
HOST_CAP2_SDS = (1 << 3), /* Support device sleep */
HOST_CAP2_SADM = (1 << 4), /* Support aggressive DevSlp */
HOST_CAP2_DESO = (1 << 5), /* DevSlp from slumber only */

/* registers for each SATA port */
PORT_LST_ADDR = 0x00, /* command list DMA addr */
Expand All @@ -133,6 +137,7 @@ enum {
PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */
PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */
PORT_FBS = 0x40, /* FIS-based Switching */
PORT_DEVSLP = 0x44, /* device sleep */

/* PORT_IRQ_{STAT,MASK} bits */
PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
Expand Down Expand Up @@ -186,6 +191,7 @@ enum {
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */

/* PORT_FBS bits */
PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */
PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */
PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */
Expand All @@ -194,6 +200,15 @@ enum {
PORT_FBS_DEC = (1 << 1), /* FBS device error clear */
PORT_FBS_EN = (1 << 0), /* Enable FBS */

/* PORT_DEVSLP bits */
PORT_DEVSLP_DM_OFFSET = 25, /* DITO multiplier offset */
PORT_DEVSLP_DM_MASK = (0xf << 25), /* DITO multiplier mask */
PORT_DEVSLP_DITO_OFFSET = 15, /* DITO offset */
PORT_DEVSLP_MDAT_OFFSET = 10, /* Minimum assertion time */
PORT_DEVSLP_DETO_OFFSET = 2, /* DevSlp exit timeout */
PORT_DEVSLP_DSP = (1 << 1), /* DevSlp present */
PORT_DEVSLP_ADSE = (1 << 0), /* Aggressive DevSlp enable */

/* hpriv->flags bits */

#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
Expand Down Expand Up @@ -302,6 +317,7 @@ struct ahci_host_priv {
u32 em_loc; /* enclosure management location */
u32 em_buf_sz; /* EM buffer size in byte */
u32 em_msg_type; /* EM message type */
struct clk *clk; /* Only for platforms supporting clk */
};

extern int ahci_ignore_sss;
Expand Down
58 changes: 50 additions & 8 deletions drivers/ata/ahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* any later version.
*/

#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/module.h>
Expand Down Expand Up @@ -118,6 +119,17 @@ static int __init ahci_probe(struct platform_device *pdev)
return -ENOMEM;
}

hpriv->clk = clk_get(dev, NULL);
if (IS_ERR(hpriv->clk)) {
dev_err(dev, "can't get clock\n");
} else {
rc = clk_prepare_enable(hpriv->clk);
if (rc) {
dev_err(dev, "clock prepare enable failed");
goto free_clk;
}
}

/*
* Some platforms might need to prepare for mmio region access,
* which could be done in the following init call. So, the mmio
Expand All @@ -127,7 +139,7 @@ static int __init ahci_probe(struct platform_device *pdev)
if (pdata && pdata->init) {
rc = pdata->init(dev, hpriv->mmio);
if (rc)
return rc;
goto disable_unprepare_clk;
}

ahci_save_initial_config(dev, hpriv,
Expand All @@ -153,7 +165,7 @@ static int __init ahci_probe(struct platform_device *pdev)
host = ata_host_alloc_pinfo(dev, ppi, n_ports);
if (!host) {
rc = -ENOMEM;
goto err0;
goto pdata_exit;
}

host->private_data = hpriv;
Expand Down Expand Up @@ -183,20 +195,26 @@ static int __init ahci_probe(struct platform_device *pdev)

rc = ahci_reset_controller(host);
if (rc)
goto err0;
goto pdata_exit;

ahci_init_controller(host);
ahci_print_info(host, "platform");

rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
&ahci_platform_sht);
if (rc)
goto err0;
goto pdata_exit;

return 0;
err0:
pdata_exit:
if (pdata && pdata->exit)
pdata->exit(dev);
disable_unprepare_clk:
if (!IS_ERR(hpriv->clk))
clk_disable_unprepare(hpriv->clk);
free_clk:
if (!IS_ERR(hpriv->clk))
clk_put(hpriv->clk);
return rc;
}

Expand All @@ -205,12 +223,18 @@ static int __devexit ahci_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host->private_data;

ata_host_detach(host);

if (pdata && pdata->exit)
pdata->exit(dev);

if (!IS_ERR(hpriv->clk)) {
clk_disable_unprepare(hpriv->clk);
clk_put(hpriv->clk);
}

return 0;
}

Expand Down Expand Up @@ -245,39 +269,57 @@ static int ahci_suspend(struct device *dev)

if (pdata && pdata->suspend)
return pdata->suspend(dev);

if (!IS_ERR(hpriv->clk))
clk_disable_unprepare(hpriv->clk);

return 0;
}

static int ahci_resume(struct device *dev)
{
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host->private_data;
int rc;

if (!IS_ERR(hpriv->clk)) {
rc = clk_prepare_enable(hpriv->clk);
if (rc) {
dev_err(dev, "clock prepare enable failed");
return rc;
}
}

if (pdata && pdata->resume) {
rc = pdata->resume(dev);
if (rc)
return rc;
goto disable_unprepare_clk;
}

if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
rc = ahci_reset_controller(host);
if (rc)
return rc;
goto disable_unprepare_clk;

ahci_init_controller(host);
}

ata_host_resume(host);

return 0;

disable_unprepare_clk:
if (!IS_ERR(hpriv->clk))
clk_disable_unprepare(hpriv->clk);

return rc;
}
#endif

SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);

static const struct of_device_id ahci_of_match[] = {
{ .compatible = "calxeda,hb-ahci", },
{ .compatible = "snps,spear-ahci", },
{},
};
Expand Down
Loading

0 comments on commit 51562cb

Please sign in to comment.