diff options
| -rw-r--r-- | Documentation/devicetree/bindings/arm/calxeda/combophy.txt | 17 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/ata/ahci-platform.txt | 8 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/ata/pata-arasan.txt | 17 | ||||
| -rw-r--r-- | arch/arm/boot/dts/highbank.dts | 17 | ||||
| -rw-r--r-- | drivers/ata/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/ata/Makefile | 1 | ||||
| -rw-r--r-- | drivers/ata/ahci.h | 16 | ||||
| -rw-r--r-- | drivers/ata/ahci_platform.c | 58 | ||||
| -rw-r--r-- | drivers/ata/libahci.c | 97 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 32 | ||||
| -rw-r--r-- | drivers/ata/libata-eh.c | 12 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 255 | ||||
| -rw-r--r-- | drivers/ata/libata.h | 2 | ||||
| -rw-r--r-- | drivers/ata/pata_arasan_cf.c | 14 | ||||
| -rw-r--r-- | drivers/ata/sata_fsl.c | 39 | ||||
| -rw-r--r-- | drivers/ata/sata_highbank.c | 450 | ||||
| -rw-r--r-- | drivers/ata/sata_mv.c | 8 | ||||
| -rw-r--r-- | include/linux/ata.h | 30 | ||||
| -rw-r--r-- | include/linux/libata.h | 4 |
19 files changed, 1025 insertions, 60 deletions
diff --git a/Documentation/devicetree/bindings/arm/calxeda/combophy.txt b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt new file mode 100644 index 000000000000..6622bdb2e8bc --- /dev/null +++ b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | Calxeda Highbank Combination Phys for SATA | ||
| 2 | |||
| 3 | Properties: | ||
| 4 | - compatible : Should be "calxeda,hb-combophy" | ||
| 5 | - #phy-cells: Should be 1. | ||
| 6 | - reg : Address and size for Combination Phy registers. | ||
| 7 | - phydev: device ID for programming the combophy. | ||
| 8 | |||
| 9 | Example: | ||
| 10 | |||
| 11 | combophy5: combo-phy@fff5d000 { | ||
| 12 | compatible = "calxeda,hb-combophy"; | ||
| 13 | #phy-cells = <1>; | ||
| 14 | reg = <0xfff5d000 0x1000>; | ||
| 15 | phydev = <31>; | ||
| 16 | }; | ||
| 17 | |||
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index 8bb8a76d42e8..147c1f6653fe 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt | |||
| @@ -8,9 +8,17 @@ Required properties: | |||
| 8 | - interrupts : <interrupt mapping for SATA IRQ> | 8 | - interrupts : <interrupt mapping for SATA IRQ> |
| 9 | - reg : <registers mapping> | 9 | - reg : <registers mapping> |
| 10 | 10 | ||
| 11 | Optional properties: | ||
| 12 | - calxeda,port-phys: phandle-combophy and lane assignment, which maps each | ||
| 13 | SATA port to a combophy and a lane within that | ||
| 14 | combophy | ||
| 15 | |||
| 11 | Example: | 16 | Example: |
| 12 | sata@ffe08000 { | 17 | sata@ffe08000 { |
| 13 | compatible = "calxeda,hb-ahci"; | 18 | compatible = "calxeda,hb-ahci"; |
| 14 | reg = <0xffe08000 0x1000>; | 19 | reg = <0xffe08000 0x1000>; |
| 15 | interrupts = <115>; | 20 | interrupts = <115>; |
| 21 | calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1 | ||
| 22 | &combophy0 2 &combophy0 3>; | ||
| 23 | |||
| 16 | }; | 24 | }; |
diff --git a/Documentation/devicetree/bindings/ata/pata-arasan.txt b/Documentation/devicetree/bindings/ata/pata-arasan.txt new file mode 100644 index 000000000000..95ec7f825ede --- /dev/null +++ b/Documentation/devicetree/bindings/ata/pata-arasan.txt | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | * ARASAN PATA COMPACT FLASH CONTROLLER | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: "arasan,cf-spear1340" | ||
| 5 | - reg: Address range of the CF registers | ||
| 6 | - interrupt-parent: Should be the phandle for the interrupt controller | ||
| 7 | that services interrupts for this device | ||
| 8 | - interrupt: Should contain the CF interrupt number | ||
| 9 | |||
| 10 | Example: | ||
| 11 | |||
| 12 | cf@fc000000 { | ||
| 13 | compatible = "arasan,cf-spear1340"; | ||
| 14 | reg = <0xfc000000 0x1000>; | ||
| 15 | interrupt-parent = <&vic1>; | ||
| 16 | interrupts = <12>; | ||
| 17 | }; | ||
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index 9fecf1ae777b..5204cf73c2d8 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts | |||
| @@ -121,6 +121,9 @@ | |||
| 121 | compatible = "calxeda,hb-ahci"; | 121 | compatible = "calxeda,hb-ahci"; |
| 122 | reg = <0xffe08000 0x10000>; | 122 | reg = <0xffe08000 0x10000>; |
| 123 | interrupts = <0 83 4>; | 123 | interrupts = <0 83 4>; |
| 124 | calxeda,port-phys = <&combophy5 0 &combophy0 0 | ||
| 125 | &combophy0 1 &combophy0 2 | ||
| 126 | &combophy0 3>; | ||
| 124 | }; | 127 | }; |
| 125 | 128 | ||
| 126 | sdhci@ffe0e000 { | 129 | sdhci@ffe0e000 { |
| @@ -306,5 +309,19 @@ | |||
| 306 | reg = <0xfff51000 0x1000>; | 309 | reg = <0xfff51000 0x1000>; |
| 307 | interrupts = <0 80 4 0 81 4 0 82 4>; | 310 | interrupts = <0 80 4 0 81 4 0 82 4>; |
| 308 | }; | 311 | }; |
| 312 | |||
| 313 | combophy0: combo-phy@fff58000 { | ||
| 314 | compatible = "calxeda,hb-combophy"; | ||
| 315 | #phy-cells = <1>; | ||
| 316 | reg = <0xfff58000 0x1000>; | ||
| 317 | phydev = <5>; | ||
| 318 | }; | ||
| 319 | |||
| 320 | combophy5: combo-phy@fff5d000 { | ||
| 321 | compatible = "calxeda,hb-combophy"; | ||
| 322 | #phy-cells = <1>; | ||
| 323 | reg = <0xfff5d000 0x1000>; | ||
| 324 | phydev = <31>; | ||
| 325 | }; | ||
| 309 | }; | 326 | }; |
| 310 | }; | 327 | }; |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 27cecd313e75..e08d322d01d7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
| @@ -214,6 +214,14 @@ config SATA_DWC_VDEBUG | |||
| 214 | help | 214 | help |
| 215 | This option enables the taskfile dumping and NCQ debugging. | 215 | This option enables the taskfile dumping and NCQ debugging. |
| 216 | 216 | ||
| 217 | config SATA_HIGHBANK | ||
| 218 | tristate "Calxeda Highbank SATA support" | ||
| 219 | help | ||
| 220 | This option enables support for the Calxeda Highbank SoC's | ||
| 221 | onboard SATA. | ||
| 222 | |||
| 223 | If unsure, say N. | ||
| 224 | |||
| 217 | config SATA_MV | 225 | config SATA_MV |
| 218 | tristate "Marvell SATA support" | 226 | tristate "Marvell SATA support" |
| 219 | help | 227 | help |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index a454a139b1d2..9329dafba91b 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
| @@ -9,6 +9,7 @@ obj-$(CONFIG_SATA_FSL) += sata_fsl.o | |||
| 9 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o | 9 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o |
| 10 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o | 10 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o |
| 11 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o | 11 | obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o |
| 12 | obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o | ||
| 12 | 13 | ||
| 13 | # SFF w/ custom DMA | 14 | # SFF w/ custom DMA |
| 14 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o | 15 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 57eb1c212a4c..9be471200a07 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #ifndef _AHCI_H | 35 | #ifndef _AHCI_H |
| 36 | #define _AHCI_H | 36 | #define _AHCI_H |
| 37 | 37 | ||
| 38 | #include <linux/clk.h> | ||
| 38 | #include <linux/libata.h> | 39 | #include <linux/libata.h> |
| 39 | 40 | ||
| 40 | /* Enclosure Management Control */ | 41 | /* Enclosure Management Control */ |
| @@ -115,6 +116,9 @@ enum { | |||
| 115 | HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */ | 116 | HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */ |
| 116 | HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */ | 117 | HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */ |
| 117 | HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */ | 118 | HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */ |
| 119 | HOST_CAP2_SDS = (1 << 3), /* Support device sleep */ | ||
| 120 | HOST_CAP2_SADM = (1 << 4), /* Support aggressive DevSlp */ | ||
| 121 | HOST_CAP2_DESO = (1 << 5), /* DevSlp from slumber only */ | ||
| 118 | 122 | ||
| 119 | /* registers for each SATA port */ | 123 | /* registers for each SATA port */ |
| 120 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ | 124 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ |
| @@ -133,6 +137,7 @@ enum { | |||
| 133 | PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ | 137 | PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ |
| 134 | PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ | 138 | PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ |
| 135 | PORT_FBS = 0x40, /* FIS-based Switching */ | 139 | PORT_FBS = 0x40, /* FIS-based Switching */ |
| 140 | PORT_DEVSLP = 0x44, /* device sleep */ | ||
| 136 | 141 | ||
| 137 | /* PORT_IRQ_{STAT,MASK} bits */ | 142 | /* PORT_IRQ_{STAT,MASK} bits */ |
| 138 | PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ | 143 | PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ |
| @@ -186,6 +191,7 @@ enum { | |||
| 186 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ | 191 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ |
| 187 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ | 192 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ |
| 188 | 193 | ||
| 194 | /* PORT_FBS bits */ | ||
| 189 | PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */ | 195 | PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */ |
| 190 | PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */ | 196 | PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */ |
| 191 | PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */ | 197 | PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */ |
| @@ -194,6 +200,15 @@ enum { | |||
| 194 | PORT_FBS_DEC = (1 << 1), /* FBS device error clear */ | 200 | PORT_FBS_DEC = (1 << 1), /* FBS device error clear */ |
| 195 | PORT_FBS_EN = (1 << 0), /* Enable FBS */ | 201 | PORT_FBS_EN = (1 << 0), /* Enable FBS */ |
| 196 | 202 | ||
| 203 | /* PORT_DEVSLP bits */ | ||
| 204 | PORT_DEVSLP_DM_OFFSET = 25, /* DITO multiplier offset */ | ||
| 205 | PORT_DEVSLP_DM_MASK = (0xf << 25), /* DITO multiplier mask */ | ||
| 206 | PORT_DEVSLP_DITO_OFFSET = 15, /* DITO offset */ | ||
| 207 | PORT_DEVSLP_MDAT_OFFSET = 10, /* Minimum assertion time */ | ||
| 208 | PORT_DEVSLP_DETO_OFFSET = 2, /* DevSlp exit timeout */ | ||
| 209 | PORT_DEVSLP_DSP = (1 << 1), /* DevSlp present */ | ||
| 210 | PORT_DEVSLP_ADSE = (1 << 0), /* Aggressive DevSlp enable */ | ||
| 211 | |||
| 197 | /* hpriv->flags bits */ | 212 | /* hpriv->flags bits */ |
| 198 | 213 | ||
| 199 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | 214 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) |
| @@ -302,6 +317,7 @@ struct ahci_host_priv { | |||
| 302 | u32 em_loc; /* enclosure management location */ | 317 | u32 em_loc; /* enclosure management location */ |
| 303 | u32 em_buf_sz; /* EM buffer size in byte */ | 318 | u32 em_buf_sz; /* EM buffer size in byte */ |
| 304 | u32 em_msg_type; /* EM message type */ | 319 | u32 em_msg_type; /* EM message type */ |
| 320 | struct clk *clk; /* Only for platforms supporting clk */ | ||
| 305 | }; | 321 | }; |
| 306 | 322 | ||
| 307 | extern int ahci_ignore_sss; | 323 | extern int ahci_ignore_sss; |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 09728e09cb31..b1ae48054dc5 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | * any later version. | 12 | * any later version. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/clk.h> | ||
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 16 | #include <linux/gfp.h> | 17 | #include <linux/gfp.h> |
| 17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| @@ -118,6 +119,17 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
| 118 | return -ENOMEM; | 119 | return -ENOMEM; |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 122 | hpriv->clk = clk_get(dev, NULL); | ||
| 123 | if (IS_ERR(hpriv->clk)) { | ||
| 124 | dev_err(dev, "can't get clock\n"); | ||
| 125 | } else { | ||
| 126 | rc = clk_prepare_enable(hpriv->clk); | ||
| 127 | if (rc) { | ||
| 128 | dev_err(dev, "clock prepare enable failed"); | ||
| 129 | goto free_clk; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 121 | /* | 133 | /* |
| 122 | * Some platforms might need to prepare for mmio region access, | 134 | * Some platforms might need to prepare for mmio region access, |
| 123 | * which could be done in the following init call. So, the mmio | 135 | * which could be done in the following init call. So, the mmio |
| @@ -127,7 +139,7 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
| 127 | if (pdata && pdata->init) { | 139 | if (pdata && pdata->init) { |
| 128 | rc = pdata->init(dev, hpriv->mmio); | 140 | rc = pdata->init(dev, hpriv->mmio); |
| 129 | if (rc) | 141 | if (rc) |
| 130 | return rc; | 142 | goto disable_unprepare_clk; |
| 131 | } | 143 | } |
| 132 | 144 | ||
| 133 | ahci_save_initial_config(dev, hpriv, | 145 | ahci_save_initial_config(dev, hpriv, |
| @@ -153,7 +165,7 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
| 153 | host = ata_host_alloc_pinfo(dev, ppi, n_ports); | 165 | host = ata_host_alloc_pinfo(dev, ppi, n_ports); |
| 154 | if (!host) { | 166 | if (!host) { |
| 155 | rc = -ENOMEM; | 167 | rc = -ENOMEM; |
| 156 | goto err0; | 168 | goto pdata_exit; |
| 157 | } | 169 | } |
| 158 | 170 | ||
| 159 | host->private_data = hpriv; | 171 | host->private_data = hpriv; |
| @@ -183,7 +195,7 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
| 183 | 195 | ||
| 184 | rc = ahci_reset_controller(host); | 196 | rc = ahci_reset_controller(host); |
| 185 | if (rc) | 197 | if (rc) |
| 186 | goto err0; | 198 | goto pdata_exit; |
| 187 | 199 | ||
| 188 | ahci_init_controller(host); | 200 | ahci_init_controller(host); |
| 189 | ahci_print_info(host, "platform"); | 201 | ahci_print_info(host, "platform"); |
| @@ -191,12 +203,18 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
| 191 | rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, | 203 | rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, |
| 192 | &ahci_platform_sht); | 204 | &ahci_platform_sht); |
| 193 | if (rc) | 205 | if (rc) |
| 194 | goto err0; | 206 | goto pdata_exit; |
| 195 | 207 | ||
| 196 | return 0; | 208 | return 0; |
| 197 | err0: | 209 | pdata_exit: |
| 198 | if (pdata && pdata->exit) | 210 | if (pdata && pdata->exit) |
| 199 | pdata->exit(dev); | 211 | pdata->exit(dev); |
| 212 | disable_unprepare_clk: | ||
| 213 | if (!IS_ERR(hpriv->clk)) | ||
| 214 | clk_disable_unprepare(hpriv->clk); | ||
| 215 | free_clk: | ||
| 216 | if (!IS_ERR(hpriv->clk)) | ||
| 217 | clk_put(hpriv->clk); | ||
| 200 | return rc; | 218 | return rc; |
| 201 | } | 219 | } |
| 202 | 220 | ||
| @@ -205,12 +223,18 @@ static int __devexit ahci_remove(struct platform_device *pdev) | |||
| 205 | struct device *dev = &pdev->dev; | 223 | struct device *dev = &pdev->dev; |
| 206 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | 224 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
| 207 | struct ata_host *host = dev_get_drvdata(dev); | 225 | struct ata_host *host = dev_get_drvdata(dev); |
| 226 | struct ahci_host_priv *hpriv = host->private_data; | ||
| 208 | 227 | ||
| 209 | ata_host_detach(host); | 228 | ata_host_detach(host); |
| 210 | 229 | ||
| 211 | if (pdata && pdata->exit) | 230 | if (pdata && pdata->exit) |
| 212 | pdata->exit(dev); | 231 | pdata->exit(dev); |
| 213 | 232 | ||
| 233 | if (!IS_ERR(hpriv->clk)) { | ||
| 234 | clk_disable_unprepare(hpriv->clk); | ||
| 235 | clk_put(hpriv->clk); | ||
| 236 | } | ||
| 237 | |||
| 214 | return 0; | 238 | return 0; |
| 215 | } | 239 | } |
| 216 | 240 | ||
| @@ -245,6 +269,10 @@ static int ahci_suspend(struct device *dev) | |||
| 245 | 269 | ||
| 246 | if (pdata && pdata->suspend) | 270 | if (pdata && pdata->suspend) |
| 247 | return pdata->suspend(dev); | 271 | return pdata->suspend(dev); |
| 272 | |||
| 273 | if (!IS_ERR(hpriv->clk)) | ||
| 274 | clk_disable_unprepare(hpriv->clk); | ||
| 275 | |||
| 248 | return 0; | 276 | return 0; |
| 249 | } | 277 | } |
| 250 | 278 | ||
| @@ -252,18 +280,27 @@ static int ahci_resume(struct device *dev) | |||
| 252 | { | 280 | { |
| 253 | struct ahci_platform_data *pdata = dev_get_platdata(dev); | 281 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
| 254 | struct ata_host *host = dev_get_drvdata(dev); | 282 | struct ata_host *host = dev_get_drvdata(dev); |
| 283 | struct ahci_host_priv *hpriv = host->private_data; | ||
| 255 | int rc; | 284 | int rc; |
| 256 | 285 | ||
| 286 | if (!IS_ERR(hpriv->clk)) { | ||
| 287 | rc = clk_prepare_enable(hpriv->clk); | ||
| 288 | if (rc) { | ||
| 289 | dev_err(dev, "clock prepare enable failed"); | ||
| 290 | return rc; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 257 | if (pdata && pdata->resume) { | 294 | if (pdata && pdata->resume) { |
| 258 | rc = pdata->resume(dev); | 295 | rc = pdata->resume(dev); |
| 259 | if (rc) | 296 | if (rc) |
| 260 | return rc; | 297 | goto disable_unprepare_clk; |
| 261 | } | 298 | } |
| 262 | 299 | ||
| 263 | if (dev->power.power_state.event == PM_EVENT_SUSPEND) { | 300 | if (dev->power.power_state.event == PM_EVENT_SUSPEND) { |
| 264 | rc = ahci_reset_controller(host); | 301 | rc = ahci_reset_controller(host); |
| 265 | if (rc) | 302 | if (rc) |
| 266 | return rc; | 303 | goto disable_unprepare_clk; |
| 267 | 304 | ||
| 268 | ahci_init_controller(host); | 305 | ahci_init_controller(host); |
| 269 | } | 306 | } |
| @@ -271,13 +308,18 @@ static int ahci_resume(struct device *dev) | |||
| 271 | ata_host_resume(host); | 308 | ata_host_resume(host); |
| 272 | 309 | ||
| 273 | return 0; | 310 | return 0; |
| 311 | |||
| 312 | disable_unprepare_clk: | ||
| 313 | if (!IS_ERR(hpriv->clk)) | ||
| 314 | clk_disable_unprepare(hpriv->clk); | ||
| 315 | |||
| 316 | return rc; | ||
| 274 | } | 317 | } |
| 275 | #endif | 318 | #endif |
| 276 | 319 | ||
| 277 | SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); | 320 | SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); |
| 278 | 321 | ||
| 279 | static const struct of_device_id ahci_of_match[] = { | 322 | static const struct of_device_id ahci_of_match[] = { |
| 280 | { .compatible = "calxeda,hb-ahci", }, | ||
| 281 | { .compatible = "snps,spear-ahci", }, | 323 | { .compatible = "snps,spear-ahci", }, |
| 282 | {}, | 324 | {}, |
| 283 | }; | 325 | }; |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 555c07afa05b..4201e535a8c8 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <scsi/scsi_cmnd.h> | 45 | #include <scsi/scsi_cmnd.h> |
| 46 | #include <linux/libata.h> | 46 | #include <linux/libata.h> |
| 47 | #include "ahci.h" | 47 | #include "ahci.h" |
| 48 | #include "libata.h" | ||
| 48 | 49 | ||
| 49 | static int ahci_skip_host_reset; | 50 | static int ahci_skip_host_reset; |
| 50 | int ahci_ignore_sss; | 51 | int ahci_ignore_sss; |
| @@ -76,6 +77,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc); | |||
| 76 | static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc); | 77 | static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc); |
| 77 | static void ahci_freeze(struct ata_port *ap); | 78 | static void ahci_freeze(struct ata_port *ap); |
| 78 | static void ahci_thaw(struct ata_port *ap); | 79 | static void ahci_thaw(struct ata_port *ap); |
| 80 | static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep); | ||
| 79 | static void ahci_enable_fbs(struct ata_port *ap); | 81 | static void ahci_enable_fbs(struct ata_port *ap); |
| 80 | static void ahci_disable_fbs(struct ata_port *ap); | 82 | static void ahci_disable_fbs(struct ata_port *ap); |
| 81 | static void ahci_pmp_attach(struct ata_port *ap); | 83 | static void ahci_pmp_attach(struct ata_port *ap); |
| @@ -193,6 +195,10 @@ module_param(ahci_em_messages, int, 0444); | |||
| 193 | MODULE_PARM_DESC(ahci_em_messages, | 195 | MODULE_PARM_DESC(ahci_em_messages, |
| 194 | "AHCI Enclosure Management Message control (0 = off, 1 = on)"); | 196 | "AHCI Enclosure Management Message control (0 = off, 1 = on)"); |
| 195 | 197 | ||
| 198 | int devslp_idle_timeout = 1000; /* device sleep idle timeout in ms */ | ||
| 199 | module_param(devslp_idle_timeout, int, 0644); | ||
| 200 | MODULE_PARM_DESC(devslp_idle_timeout, "device sleep idle timeout"); | ||
| 201 | |||
| 196 | static void ahci_enable_ahci(void __iomem *mmio) | 202 | static void ahci_enable_ahci(void __iomem *mmio) |
| 197 | { | 203 | { |
| 198 | int i; | 204 | int i; |
| @@ -702,6 +708,16 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
| 702 | } | 708 | } |
| 703 | } | 709 | } |
| 704 | 710 | ||
| 711 | /* set aggressive device sleep */ | ||
| 712 | if ((hpriv->cap2 & HOST_CAP2_SDS) && | ||
| 713 | (hpriv->cap2 & HOST_CAP2_SADM) && | ||
| 714 | (link->device->flags & ATA_DFLAG_DEVSLP)) { | ||
| 715 | if (policy == ATA_LPM_MIN_POWER) | ||
| 716 | ahci_set_aggressive_devslp(ap, true); | ||
| 717 | else | ||
| 718 | ahci_set_aggressive_devslp(ap, false); | ||
| 719 | } | ||
| 720 | |||
| 705 | if (policy == ATA_LPM_MAX_POWER) { | 721 | if (policy == ATA_LPM_MAX_POWER) { |
| 706 | sata_link_scr_lpm(link, policy, false); | 722 | sata_link_scr_lpm(link, policy, false); |
| 707 | 723 | ||
| @@ -1890,6 +1906,81 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | |||
| 1890 | ahci_kick_engine(ap); | 1906 | ahci_kick_engine(ap); |
| 1891 | } | 1907 | } |
| 1892 | 1908 | ||
| 1909 | static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) | ||
| 1910 | { | ||
| 1911 | void __iomem *port_mmio = ahci_port_base(ap); | ||
| 1912 | struct ata_device *dev = ap->link.device; | ||
| 1913 | u32 devslp, dm, dito, mdat, deto; | ||
| 1914 | int rc; | ||
| 1915 | unsigned int err_mask; | ||
| 1916 | |||
| 1917 | devslp = readl(port_mmio + PORT_DEVSLP); | ||
| 1918 | if (!(devslp & PORT_DEVSLP_DSP)) { | ||
| 1919 | dev_err(ap->host->dev, "port does not support device sleep\n"); | ||
| 1920 | return; | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | /* disable device sleep */ | ||
| 1924 | if (!sleep) { | ||
| 1925 | if (devslp & PORT_DEVSLP_ADSE) { | ||
| 1926 | writel(devslp & ~PORT_DEVSLP_ADSE, | ||
| 1927 | port_mmio + PORT_DEVSLP); | ||
| 1928 | err_mask = ata_dev_set_feature(dev, | ||
| 1929 | SETFEATURES_SATA_DISABLE, | ||
| 1930 | SATA_DEVSLP); | ||
| 1931 | if (err_mask && err_mask != AC_ERR_DEV) | ||
| 1932 | ata_dev_warn(dev, "failed to disable DEVSLP\n"); | ||
| 1933 | } | ||
| 1934 | return; | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | /* device sleep was already enabled */ | ||
| 1938 | if (devslp & PORT_DEVSLP_ADSE) | ||
| 1939 | return; | ||
| 1940 | |||
| 1941 | /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */ | ||
| 1942 | rc = ahci_stop_engine(ap); | ||
| 1943 | if (rc) | ||
| 1944 | return; | ||
| 1945 | |||
| 1946 | dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET; | ||
| 1947 | dito = devslp_idle_timeout / (dm + 1); | ||
| 1948 | if (dito > 0x3ff) | ||
| 1949 | dito = 0x3ff; | ||
| 1950 | |||
| 1951 | /* Use the nominal value 10 ms if the read MDAT is zero, | ||
| 1952 | * the nominal value of DETO is 20 ms. | ||
| 1953 | */ | ||
| 1954 | if (dev->sata_settings[ATA_LOG_DEVSLP_VALID] & | ||
| 1955 | ATA_LOG_DEVSLP_VALID_MASK) { | ||
| 1956 | mdat = dev->sata_settings[ATA_LOG_DEVSLP_MDAT] & | ||
| 1957 | ATA_LOG_DEVSLP_MDAT_MASK; | ||
| 1958 | if (!mdat) | ||
| 1959 | mdat = 10; | ||
| 1960 | deto = dev->sata_settings[ATA_LOG_DEVSLP_DETO]; | ||
| 1961 | if (!deto) | ||
| 1962 | deto = 20; | ||
| 1963 | } else { | ||
| 1964 | mdat = 10; | ||
| 1965 | deto = 20; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) | | ||
| 1969 | (mdat << PORT_DEVSLP_MDAT_OFFSET) | | ||
| 1970 | (deto << PORT_DEVSLP_DETO_OFFSET) | | ||
| 1971 | PORT_DEVSLP_ADSE); | ||
| 1972 | writel(devslp, port_mmio + PORT_DEVSLP); | ||
| 1973 | |||
| 1974 | ahci_start_engine(ap); | ||
| 1975 | |||
| 1976 | /* enable device sleep feature for the drive */ | ||
| 1977 | err_mask = ata_dev_set_feature(dev, | ||
| 1978 | SETFEATURES_SATA_ENABLE, | ||
| 1979 | SATA_DEVSLP); | ||
| 1980 | if (err_mask && err_mask != AC_ERR_DEV) | ||
| 1981 | ata_dev_warn(dev, "failed to enable DEVSLP\n"); | ||
| 1982 | } | ||
| 1983 | |||
| 1893 | static void ahci_enable_fbs(struct ata_port *ap) | 1984 | static void ahci_enable_fbs(struct ata_port *ap) |
| 1894 | { | 1985 | { |
| 1895 | struct ahci_port_priv *pp = ap->private_data; | 1986 | struct ahci_port_priv *pp = ap->private_data; |
| @@ -2164,7 +2255,8 @@ void ahci_print_info(struct ata_host *host, const char *scc_s) | |||
| 2164 | "flags: " | 2255 | "flags: " |
| 2165 | "%s%s%s%s%s%s%s" | 2256 | "%s%s%s%s%s%s%s" |
| 2166 | "%s%s%s%s%s%s%s" | 2257 | "%s%s%s%s%s%s%s" |
| 2167 | "%s%s%s%s%s%s\n" | 2258 | "%s%s%s%s%s%s%s" |
| 2259 | "%s%s\n" | ||
| 2168 | , | 2260 | , |
| 2169 | 2261 | ||
| 2170 | cap & HOST_CAP_64 ? "64bit " : "", | 2262 | cap & HOST_CAP_64 ? "64bit " : "", |
| @@ -2184,6 +2276,9 @@ void ahci_print_info(struct ata_host *host, const char *scc_s) | |||
| 2184 | cap & HOST_CAP_CCC ? "ccc " : "", | 2276 | cap & HOST_CAP_CCC ? "ccc " : "", |
| 2185 | cap & HOST_CAP_EMS ? "ems " : "", | 2277 | cap & HOST_CAP_EMS ? "ems " : "", |
| 2186 | cap & HOST_CAP_SXS ? "sxs " : "", | 2278 | cap & HOST_CAP_SXS ? "sxs " : "", |
| 2279 | cap2 & HOST_CAP2_DESO ? "deso " : "", | ||
| 2280 | cap2 & HOST_CAP2_SADM ? "sadm " : "", | ||
| 2281 | cap2 & HOST_CAP2_SDS ? "sds " : "", | ||
| 2187 | cap2 & HOST_CAP2_APST ? "apst " : "", | 2282 | cap2 & HOST_CAP2_APST ? "apst " : "", |
| 2188 | cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "", | 2283 | cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "", |
| 2189 | cap2 & HOST_CAP2_BOH ? "boh " : "" | 2284 | cap2 & HOST_CAP2_BOH ? "boh " : "" |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8e1039c8e159..3492aa73d3a6 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -774,7 +774,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, | |||
| 774 | tf->lbam = (block >> 8) & 0xff; | 774 | tf->lbam = (block >> 8) & 0xff; |
| 775 | tf->lbal = block & 0xff; | 775 | tf->lbal = block & 0xff; |
| 776 | 776 | ||
| 777 | tf->device = 1 << 6; | 777 | tf->device = ATA_LBA; |
| 778 | if (tf->flags & ATA_TFLAG_FUA) | 778 | if (tf->flags & ATA_TFLAG_FUA) |
| 779 | tf->device |= 1 << 7; | 779 | tf->device |= 1 << 7; |
| 780 | } else if (dev->flags & ATA_DFLAG_LBA) { | 780 | } else if (dev->flags & ATA_DFLAG_LBA) { |
| @@ -2155,6 +2155,7 @@ int ata_dev_configure(struct ata_device *dev) | |||
| 2155 | int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; | 2155 | int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; |
| 2156 | const u16 *id = dev->id; | 2156 | const u16 *id = dev->id; |
| 2157 | unsigned long xfer_mask; | 2157 | unsigned long xfer_mask; |
| 2158 | unsigned int err_mask; | ||
| 2158 | char revbuf[7]; /* XYZ-99\0 */ | 2159 | char revbuf[7]; /* XYZ-99\0 */ |
| 2159 | char fwrevbuf[ATA_ID_FW_REV_LEN+1]; | 2160 | char fwrevbuf[ATA_ID_FW_REV_LEN+1]; |
| 2160 | char modelbuf[ATA_ID_PROD_LEN+1]; | 2161 | char modelbuf[ATA_ID_PROD_LEN+1]; |
| @@ -2323,6 +2324,26 @@ int ata_dev_configure(struct ata_device *dev) | |||
| 2323 | } | 2324 | } |
| 2324 | } | 2325 | } |
| 2325 | 2326 | ||
| 2327 | /* check and mark DevSlp capability */ | ||
| 2328 | if (ata_id_has_devslp(dev->id)) | ||
| 2329 | dev->flags |= ATA_DFLAG_DEVSLP; | ||
| 2330 | |||
| 2331 | /* Obtain SATA Settings page from Identify Device Data Log, | ||
| 2332 | * which contains DevSlp timing variables etc. | ||
| 2333 | * Exclude old devices with ata_id_has_ncq() | ||
| 2334 | */ | ||
| 2335 | if (ata_id_has_ncq(dev->id)) { | ||
| 2336 | err_mask = ata_read_log_page(dev, | ||
| 2337 | ATA_LOG_SATA_ID_DEV_DATA, | ||
| 2338 | ATA_LOG_SATA_SETTINGS, | ||
| 2339 | dev->sata_settings, | ||
| 2340 | 1); | ||
| 2341 | if (err_mask) | ||
| 2342 | ata_dev_dbg(dev, | ||
| 2343 | "failed to get Identify Device Data, Emask 0x%x\n", | ||
| 2344 | err_mask); | ||
| 2345 | } | ||
| 2346 | |||
| 2326 | dev->cdb_len = 16; | 2347 | dev->cdb_len = 16; |
| 2327 | } | 2348 | } |
| 2328 | 2349 | ||
| @@ -2351,8 +2372,6 @@ int ata_dev_configure(struct ata_device *dev) | |||
| 2351 | (ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && | 2372 | (ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && |
| 2352 | (!sata_pmp_attached(ap) || | 2373 | (!sata_pmp_attached(ap) || |
| 2353 | sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { | 2374 | sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { |
| 2354 | unsigned int err_mask; | ||
| 2355 | |||
| 2356 | /* issue SET feature command to turn this on */ | 2375 | /* issue SET feature command to turn this on */ |
| 2357 | err_mask = ata_dev_set_feature(dev, | 2376 | err_mask = ata_dev_set_feature(dev, |
| 2358 | SETFEATURES_SATA_ENABLE, SATA_AN); | 2377 | SETFEATURES_SATA_ENABLE, SATA_AN); |
| @@ -3598,7 +3617,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
| 3598 | switch (policy) { | 3617 | switch (policy) { |
| 3599 | case ATA_LPM_MAX_POWER: | 3618 | case ATA_LPM_MAX_POWER: |
| 3600 | /* disable all LPM transitions */ | 3619 | /* disable all LPM transitions */ |
| 3601 | scontrol |= (0x3 << 8); | 3620 | scontrol |= (0x7 << 8); |
| 3602 | /* initiate transition to active state */ | 3621 | /* initiate transition to active state */ |
| 3603 | if (spm_wakeup) { | 3622 | if (spm_wakeup) { |
| 3604 | scontrol |= (0x4 << 12); | 3623 | scontrol |= (0x4 << 12); |
| @@ -3608,12 +3627,12 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
| 3608 | case ATA_LPM_MED_POWER: | 3627 | case ATA_LPM_MED_POWER: |
| 3609 | /* allow LPM to PARTIAL */ | 3628 | /* allow LPM to PARTIAL */ |
| 3610 | scontrol &= ~(0x1 << 8); | 3629 | scontrol &= ~(0x1 << 8); |
| 3611 | scontrol |= (0x2 << 8); | 3630 | scontrol |= (0x6 << 8); |
| 3612 | break; | 3631 | break; |
| 3613 | case ATA_LPM_MIN_POWER: | 3632 | case ATA_LPM_MIN_POWER: |
| 3614 | if (ata_link_nr_enabled(link) > 0) | 3633 | if (ata_link_nr_enabled(link) > 0) |
| 3615 | /* no restrictions on LPM transitions */ | 3634 | /* no restrictions on LPM transitions */ |
| 3616 | scontrol &= ~(0x3 << 8); | 3635 | scontrol &= ~(0x7 << 8); |
| 3617 | else { | 3636 | else { |
| 3618 | /* empty port, power off */ | 3637 | /* empty port, power off */ |
| 3619 | scontrol &= ~0xf; | 3638 | scontrol &= ~0xf; |
| @@ -4472,6 +4491,7 @@ unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature) | |||
| 4472 | DPRINTK("EXIT, err_mask=%x\n", err_mask); | 4491 | DPRINTK("EXIT, err_mask=%x\n", err_mask); |
| 4473 | return err_mask; | 4492 | return err_mask; |
| 4474 | } | 4493 | } |
| 4494 | EXPORT_SYMBOL_GPL(ata_dev_set_feature); | ||
| 4475 | 4495 | ||
| 4476 | /** | 4496 | /** |
| 4477 | * ata_dev_init_params - Issue INIT DEV PARAMS command | 4497 | * ata_dev_init_params - Issue INIT DEV PARAMS command |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 7d4535e989bf..26598941e1b3 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -1487,6 +1487,7 @@ static const char *ata_err_string(unsigned int err_mask) | |||
| 1487 | /** | 1487 | /** |
| 1488 | * ata_read_log_page - read a specific log page | 1488 | * ata_read_log_page - read a specific log page |
| 1489 | * @dev: target device | 1489 | * @dev: target device |
| 1490 | * @log: log to read | ||
| 1490 | * @page: page to read | 1491 | * @page: page to read |
| 1491 | * @buf: buffer to store read page | 1492 | * @buf: buffer to store read page |
| 1492 | * @sectors: number of sectors to read | 1493 | * @sectors: number of sectors to read |
| @@ -1499,17 +1500,18 @@ static const char *ata_err_string(unsigned int err_mask) | |||
| 1499 | * RETURNS: | 1500 | * RETURNS: |
| 1500 | * 0 on success, AC_ERR_* mask otherwise. | 1501 | * 0 on success, AC_ERR_* mask otherwise. |
| 1501 | */ | 1502 | */ |
| 1502 | static unsigned int ata_read_log_page(struct ata_device *dev, | 1503 | unsigned int ata_read_log_page(struct ata_device *dev, u8 log, |
| 1503 | u8 page, void *buf, unsigned int sectors) | 1504 | u8 page, void *buf, unsigned int sectors) |
| 1504 | { | 1505 | { |
| 1505 | struct ata_taskfile tf; | 1506 | struct ata_taskfile tf; |
| 1506 | unsigned int err_mask; | 1507 | unsigned int err_mask; |
| 1507 | 1508 | ||
| 1508 | DPRINTK("read log page - page %d\n", page); | 1509 | DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page); |
| 1509 | 1510 | ||
| 1510 | ata_tf_init(dev, &tf); | 1511 | ata_tf_init(dev, &tf); |
| 1511 | tf.command = ATA_CMD_READ_LOG_EXT; | 1512 | tf.command = ATA_CMD_READ_LOG_EXT; |
| 1512 | tf.lbal = page; | 1513 | tf.lbal = log; |
| 1514 | tf.lbam = page; | ||
| 1513 | tf.nsect = sectors; | 1515 | tf.nsect = sectors; |
| 1514 | tf.hob_nsect = sectors >> 8; | 1516 | tf.hob_nsect = sectors >> 8; |
| 1515 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE; | 1517 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE; |
| @@ -1545,7 +1547,7 @@ static int ata_eh_read_log_10h(struct ata_device *dev, | |||
| 1545 | u8 csum; | 1547 | u8 csum; |
| 1546 | int i; | 1548 | int i; |
| 1547 | 1549 | ||
| 1548 | err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1); | 1550 | err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1); |
| 1549 | if (err_mask) | 1551 | if (err_mask) |
| 1550 | return -EIO; | 1552 | return -EIO; |
| 1551 | 1553 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 8ec81ca8f659..e3bda074fa12 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -1655,7 +1655,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) | |||
| 1655 | if (unlikely(scmd->cmd_len < 10)) | 1655 | if (unlikely(scmd->cmd_len < 10)) |
| 1656 | goto invalid_fld; | 1656 | goto invalid_fld; |
| 1657 | scsi_10_lba_len(cdb, &block, &n_block); | 1657 | scsi_10_lba_len(cdb, &block, &n_block); |
| 1658 | if (unlikely(cdb[1] & (1 << 3))) | 1658 | if (cdb[1] & (1 << 3)) |
| 1659 | tf_flags |= ATA_TFLAG_FUA; | 1659 | tf_flags |= ATA_TFLAG_FUA; |
| 1660 | break; | 1660 | break; |
| 1661 | case READ_6: | 1661 | case READ_6: |
| @@ -1675,7 +1675,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) | |||
| 1675 | if (unlikely(scmd->cmd_len < 16)) | 1675 | if (unlikely(scmd->cmd_len < 16)) |
| 1676 | goto invalid_fld; | 1676 | goto invalid_fld; |
| 1677 | scsi_16_lba_len(cdb, &block, &n_block); | 1677 | scsi_16_lba_len(cdb, &block, &n_block); |
| 1678 | if (unlikely(cdb[1] & (1 << 3))) | 1678 | if (cdb[1] & (1 << 3)) |
| 1679 | tf_flags |= ATA_TFLAG_FUA; | 1679 | tf_flags |= ATA_TFLAG_FUA; |
| 1680 | break; | 1680 | break; |
| 1681 | default: | 1681 | default: |
| @@ -2205,9 +2205,33 @@ static unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf) | |||
| 2205 | } | 2205 | } |
| 2206 | 2206 | ||
| 2207 | /** | 2207 | /** |
| 2208 | * modecpy - Prepare response for MODE SENSE | ||
| 2209 | * @dest: output buffer | ||
| 2210 | * @src: data being copied | ||
| 2211 | * @n: length of mode page | ||
| 2212 | * @changeable: whether changeable parameters are requested | ||
| 2213 | * | ||
| 2214 | * Generate a generic MODE SENSE page for either current or changeable | ||
| 2215 | * parameters. | ||
| 2216 | * | ||
| 2217 | * LOCKING: | ||
| 2218 | * None. | ||
| 2219 | */ | ||
| 2220 | static void modecpy(u8 *dest, const u8 *src, int n, bool changeable) | ||
| 2221 | { | ||
| 2222 | if (changeable) { | ||
| 2223 | memcpy(dest, src, 2); | ||
| 2224 | memset(dest + 2, 0, n - 2); | ||
| 2225 | } else { | ||
| 2226 | memcpy(dest, src, n); | ||
| 2227 | } | ||
| 2228 | } | ||
| 2229 | |||
| 2230 | /** | ||
| 2208 | * ata_msense_caching - Simulate MODE SENSE caching info page | 2231 | * ata_msense_caching - Simulate MODE SENSE caching info page |
| 2209 | * @id: device IDENTIFY data | 2232 | * @id: device IDENTIFY data |
| 2210 | * @buf: output buffer | 2233 | * @buf: output buffer |
| 2234 | * @changeable: whether changeable parameters are requested | ||
| 2211 | * | 2235 | * |
| 2212 | * Generate a caching info page, which conditionally indicates | 2236 | * Generate a caching info page, which conditionally indicates |
| 2213 | * write caching to the SCSI layer, depending on device | 2237 | * write caching to the SCSI layer, depending on device |
| @@ -2216,12 +2240,12 @@ static unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf) | |||
| 2216 | * LOCKING: | 2240 | * LOCKING: |
| 2217 | * None. | 2241 | * None. |
| 2218 | */ | 2242 | */ |
| 2219 | static unsigned int ata_msense_caching(u16 *id, u8 *buf) | 2243 | static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) |
| 2220 | { | 2244 | { |
| 2221 | memcpy(buf, def_cache_mpage, sizeof(def_cache_mpage)); | 2245 | modecpy(buf, def_cache_mpage, sizeof(def_cache_mpage), changeable); |
| 2222 | if (ata_id_wcache_enabled(id)) | 2246 | if (changeable || ata_id_wcache_enabled(id)) |
| 2223 | buf[2] |= (1 << 2); /* write cache enable */ | 2247 | buf[2] |= (1 << 2); /* write cache enable */ |
| 2224 | if (!ata_id_rahead_enabled(id)) | 2248 | if (!changeable && !ata_id_rahead_enabled(id)) |
| 2225 | buf[12] |= (1 << 5); /* disable read ahead */ | 2249 | buf[12] |= (1 << 5); /* disable read ahead */ |
| 2226 | return sizeof(def_cache_mpage); | 2250 | return sizeof(def_cache_mpage); |
| 2227 | } | 2251 | } |
| @@ -2229,30 +2253,33 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf) | |||
| 2229 | /** | 2253 | /** |
| 2230 | * ata_msense_ctl_mode - Simulate MODE SENSE control mode page | 2254 | * ata_msense_ctl_mode - Simulate MODE SENSE control mode page |
| 2231 | * @buf: output buffer | 2255 | * @buf: output buffer |
| 2256 | * @changeable: whether changeable parameters are requested | ||
| 2232 | * | 2257 | * |
| 2233 | * Generate a generic MODE SENSE control mode page. | 2258 | * Generate a generic MODE SENSE control mode page. |
| 2234 | * | 2259 | * |
| 2235 | * LOCKING: | 2260 | * LOCKING: |
| 2236 | * None. | 2261 | * None. |
| 2237 | */ | 2262 | */ |
| 2238 | static unsigned int ata_msense_ctl_mode(u8 *buf) | 2263 | static unsigned int ata_msense_ctl_mode(u8 *buf, bool changeable) |
| 2239 | { | 2264 | { |
| 2240 | memcpy(buf, def_control_mpage, sizeof(def_control_mpage)); | 2265 | modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable); |
| 2241 | return sizeof(def_control_mpage); | 2266 | return sizeof(def_control_mpage); |
| 2242 | } | 2267 | } |
| 2243 | 2268 | ||
| 2244 | /** | 2269 | /** |
| 2245 | * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page | 2270 | * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page |
| 2246 | * @buf: output buffer | 2271 | * @buf: output buffer |
| 2272 | * @changeable: whether changeable parameters are requested | ||
| 2247 | * | 2273 | * |
| 2248 | * Generate a generic MODE SENSE r/w error recovery page. | 2274 | * Generate a generic MODE SENSE r/w error recovery page. |
| 2249 | * | 2275 | * |
| 2250 | * LOCKING: | 2276 | * LOCKING: |
| 2251 | * None. | 2277 | * None. |
| 2252 | */ | 2278 | */ |
| 2253 | static unsigned int ata_msense_rw_recovery(u8 *buf) | 2279 | static unsigned int ata_msense_rw_recovery(u8 *buf, bool changeable) |
| 2254 | { | 2280 | { |
| 2255 | memcpy(buf, def_rw_recovery_mpage, sizeof(def_rw_recovery_mpage)); | 2281 | modecpy(buf, def_rw_recovery_mpage, sizeof(def_rw_recovery_mpage), |
| 2282 | changeable); | ||
| 2256 | return sizeof(def_rw_recovery_mpage); | 2283 | return sizeof(def_rw_recovery_mpage); |
| 2257 | } | 2284 | } |
| 2258 | 2285 | ||
| @@ -2316,11 +2343,11 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) | |||
| 2316 | page_control = scsicmd[2] >> 6; | 2343 | page_control = scsicmd[2] >> 6; |
| 2317 | switch (page_control) { | 2344 | switch (page_control) { |
| 2318 | case 0: /* current */ | 2345 | case 0: /* current */ |
| 2346 | case 1: /* changeable */ | ||
| 2347 | case 2: /* defaults */ | ||
| 2319 | break; /* supported */ | 2348 | break; /* supported */ |
| 2320 | case 3: /* saved */ | 2349 | case 3: /* saved */ |
| 2321 | goto saving_not_supp; | 2350 | goto saving_not_supp; |
| 2322 | case 1: /* changeable */ | ||
| 2323 | case 2: /* defaults */ | ||
| 2324 | default: | 2351 | default: |
| 2325 | goto invalid_fld; | 2352 | goto invalid_fld; |
| 2326 | } | 2353 | } |
| @@ -2341,21 +2368,21 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) | |||
| 2341 | 2368 | ||
| 2342 | switch(pg) { | 2369 | switch(pg) { |
| 2343 | case RW_RECOVERY_MPAGE: | 2370 | case RW_RECOVERY_MPAGE: |
| 2344 | p += ata_msense_rw_recovery(p); | 2371 | p += ata_msense_rw_recovery(p, page_control == 1); |
| 2345 | break; | 2372 | break; |
| 2346 | 2373 | ||
| 2347 | case CACHE_MPAGE: | 2374 | case CACHE_MPAGE: |
| 2348 | p += ata_msense_caching(args->id, p); | 2375 | p += ata_msense_caching(args->id, p, page_control == 1); |
| 2349 | break; | 2376 | break; |
| 2350 | 2377 | ||
| 2351 | case CONTROL_MPAGE: | 2378 | case CONTROL_MPAGE: |
| 2352 | p += ata_msense_ctl_mode(p); | 2379 | p += ata_msense_ctl_mode(p, page_control == 1); |
| 2353 | break; | 2380 | break; |
| 2354 | 2381 | ||
| 2355 | case ALL_MPAGES: | 2382 | case ALL_MPAGES: |
| 2356 | p += ata_msense_rw_recovery(p); | 2383 | p += ata_msense_rw_recovery(p, page_control == 1); |
| 2357 | p += ata_msense_caching(args->id, p); | 2384 | p += ata_msense_caching(args->id, p, page_control == 1); |
| 2358 | p += ata_msense_ctl_mode(p); | 2385 | p += ata_msense_ctl_mode(p, page_control == 1); |
| 2359 | break; | 2386 | break; |
| 2360 | 2387 | ||
| 2361 | default: /* invalid page code */ | 2388 | default: /* invalid page code */ |
| @@ -3080,6 +3107,188 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) | |||
| 3080 | } | 3107 | } |
| 3081 | 3108 | ||
| 3082 | /** | 3109 | /** |
| 3110 | * ata_mselect_caching - Simulate MODE SELECT for caching info page | ||
| 3111 | * @qc: Storage for translated ATA taskfile | ||
| 3112 | * @buf: input buffer | ||
| 3113 | * @len: number of valid bytes in the input buffer | ||
| 3114 | * | ||
| 3115 | * Prepare a taskfile to modify caching information for the device. | ||
| 3116 | * | ||
| 3117 | * LOCKING: | ||
| 3118 | * None. | ||
| 3119 | */ | ||
| 3120 | static int ata_mselect_caching(struct ata_queued_cmd *qc, | ||
| 3121 | const u8 *buf, int len) | ||
| 3122 | { | ||
| 3123 | struct ata_taskfile *tf = &qc->tf; | ||
| 3124 | struct ata_device *dev = qc->dev; | ||
| 3125 | char mpage[CACHE_MPAGE_LEN]; | ||
| 3126 | u8 wce; | ||
| 3127 | |||
| 3128 | /* | ||
| 3129 | * The first two bytes of def_cache_mpage are a header, so offsets | ||
| 3130 | * in mpage are off by 2 compared to buf. Same for len. | ||
| 3131 | */ | ||
| 3132 | |||
| 3133 | if (len != CACHE_MPAGE_LEN - 2) | ||
| 3134 | return -EINVAL; | ||
| 3135 | |||
| 3136 | wce = buf[0] & (1 << 2); | ||
| 3137 | |||
| 3138 | /* | ||
| 3139 | * Check that read-only bits are not modified. | ||
| 3140 | */ | ||
| 3141 | ata_msense_caching(dev->id, mpage, false); | ||
| 3142 | mpage[2] &= ~(1 << 2); | ||
| 3143 | mpage[2] |= wce; | ||
| 3144 | if (memcmp(mpage + 2, buf, CACHE_MPAGE_LEN - 2) != 0) | ||
| 3145 | return -EINVAL; | ||
| 3146 | |||
| 3147 | tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | ||
| 3148 | tf->protocol = ATA_PROT_NODATA; | ||
| 3149 | tf->nsect = 0; | ||
| 3150 | tf->command = ATA_CMD_SET_FEATURES; | ||
| 3151 | tf->feature = wce ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF; | ||
| 3152 | return 0; | ||
| 3153 | } | ||
| 3154 | |||
| 3155 | /** | ||
| 3156 | * ata_scsiop_mode_select - Simulate MODE SELECT 6, 10 commands | ||
| 3157 | * @qc: Storage for translated ATA taskfile | ||
| 3158 | * | ||
| 3159 | * Converts a MODE SELECT command to an ATA SET FEATURES taskfile. | ||
| 3160 | * Assume this is invoked for direct access devices (e.g. disks) only. | ||
| 3161 | * There should be no block descriptor for other device types. | ||
| 3162 | * | ||
| 3163 | * LOCKING: | ||
| 3164 | * spin_lock_irqsave(host lock) | ||
| 3165 | */ | ||
| 3166 | static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) | ||
| 3167 | { | ||
| 3168 | struct scsi_cmnd *scmd = qc->scsicmd; | ||
| 3169 | const u8 *cdb = scmd->cmnd; | ||
| 3170 | const u8 *p; | ||
| 3171 | u8 pg, spg; | ||
| 3172 | unsigned six_byte, pg_len, hdr_len, bd_len; | ||
| 3173 | int len; | ||
| 3174 | |||
| 3175 | VPRINTK("ENTER\n"); | ||
| 3176 | |||
| 3177 | six_byte = (cdb[0] == MODE_SELECT); | ||
| 3178 | if (six_byte) { | ||
| 3179 | if (scmd->cmd_len < 5) | ||
| 3180 | goto invalid_fld; | ||
| 3181 | |||
| 3182 | len = cdb[4]; | ||
| 3183 | hdr_len = 4; | ||
| 3184 | } else { | ||
| 3185 | if (scmd->cmd_len < 9) | ||
| 3186 | goto invalid_fld; | ||
| 3187 | |||
| 3188 | len = (cdb[7] << 8) + cdb[8]; | ||
| 3189 | hdr_len = 8; | ||
| 3190 | } | ||
| 3191 | |||
| 3192 | /* We only support PF=1, SP=0. */ | ||
| 3193 | if ((cdb[1] & 0x11) != 0x10) | ||
| 3194 | goto invalid_fld; | ||
| 3195 | |||
| 3196 | /* Test early for possible overrun. */ | ||
| 3197 | if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len) | ||
| 3198 | goto invalid_param_len; | ||
| 3199 | |||
| 3200 | p = page_address(sg_page(scsi_sglist(scmd))); | ||
| 3201 | |||
| 3202 | /* Move past header and block descriptors. */ | ||
| 3203 | if (len < hdr_len) | ||
| 3204 | goto invalid_param_len; | ||
| 3205 | |||
| 3206 | if (six_byte) | ||
| 3207 | bd_len = p[3]; | ||
| 3208 | else | ||
| 3209 | bd_len = (p[6] << 8) + p[7]; | ||
| 3210 | |||
| 3211 | len -= hdr_len; | ||
| 3212 | p += hdr_len; | ||
| 3213 | if (len < bd_len) | ||
| 3214 | goto invalid_param_len; | ||
| 3215 | if (bd_len != 0 && bd_len != 8) | ||
| 3216 | goto invalid_param; | ||
| 3217 | |||
| 3218 | len -= bd_len; | ||
| 3219 | p += bd_len; | ||
| 3220 | if (len == 0) | ||
| 3221 | goto skip; | ||
| 3222 | |||
| 3223 | /* Parse both possible formats for the mode page headers. */ | ||
| 3224 | pg = p[0] & 0x3f; | ||
| 3225 | if (p[0] & 0x40) { | ||
| 3226 | if (len < 4) | ||
| 3227 | goto invalid_param_len; | ||
| 3228 | |||
| 3229 | spg = p[1]; | ||
| 3230 | pg_len = (p[2] << 8) | p[3]; | ||
| 3231 | p += 4; | ||
| 3232 | len -= 4; | ||
| 3233 | } else { | ||
| 3234 | if (len < 2) | ||
| 3235 | goto invalid_param_len; | ||
| 3236 | |||
| 3237 | spg = 0; | ||
| 3238 | pg_len = p[1]; | ||
| 3239 | p += 2; | ||
| 3240 | len -= 2; | ||
| 3241 | } | ||
| 3242 | |||
| 3243 | /* | ||
| 3244 | * No mode subpages supported (yet) but asking for _all_ | ||
| 3245 | * subpages may be valid | ||
| 3246 | */ | ||
| 3247 | if (spg && (spg != ALL_SUB_MPAGES)) | ||
| 3248 | goto invalid_param; | ||
| 3249 | if (pg_len > len) | ||
| 3250 | goto invalid_param_len; | ||
| 3251 | |||
| 3252 | switch (pg) { | ||
| 3253 | case CACHE_MPAGE: | ||
| 3254 | if (ata_mselect_caching(qc, p, pg_len) < 0) | ||
| 3255 | goto invalid_param; | ||
| 3256 | break; | ||
| 3257 | |||
| 3258 | default: /* invalid page code */ | ||
| 3259 | goto invalid_param; | ||
| 3260 | } | ||
| 3261 | |||
| 3262 | /* | ||
| 3263 | * Only one page has changeable data, so we only support setting one | ||
| 3264 | * page at a time. | ||
| 3265 | */ | ||
| 3266 | if (len > pg_len) | ||
| 3267 | goto invalid_param; | ||
| 3268 | |||
| 3269 | return 0; | ||
| 3270 | |||
| 3271 | invalid_fld: | ||
| 3272 | /* "Invalid field in CDB" */ | ||
| 3273 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); | ||
| 3274 | return 1; | ||
| 3275 | |||
| 3276 | invalid_param: | ||
| 3277 | /* "Invalid field in parameter list" */ | ||
| 3278 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x26, 0x0); | ||
| 3279 | return 1; | ||
| 3280 | |||
| 3281 | invalid_param_len: | ||
| 3282 | /* "Parameter list length error" */ | ||
| 3283 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x1a, 0x0); | ||
| 3284 | return 1; | ||
| 3285 | |||
| 3286 | skip: | ||
| 3287 | scmd->result = SAM_STAT_GOOD; | ||
| 3288 | return 1; | ||
| 3289 | } | ||
| 3290 | |||
| 3291 | /** | ||
| 3083 | * ata_get_xlat_func - check if SCSI to ATA translation is possible | 3292 | * ata_get_xlat_func - check if SCSI to ATA translation is possible |
| 3084 | * @dev: ATA device | 3293 | * @dev: ATA device |
| 3085 | * @cmd: SCSI command opcode to consider | 3294 | * @cmd: SCSI command opcode to consider |
| @@ -3119,6 +3328,11 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) | |||
| 3119 | case ATA_16: | 3328 | case ATA_16: |
| 3120 | return ata_scsi_pass_thru; | 3329 | return ata_scsi_pass_thru; |
| 3121 | 3330 | ||
| 3331 | case MODE_SELECT: | ||
| 3332 | case MODE_SELECT_10: | ||
| 3333 | return ata_scsi_mode_select_xlat; | ||
| 3334 | break; | ||
| 3335 | |||
| 3122 | case START_STOP: | 3336 | case START_STOP: |
| 3123 | return ata_scsi_start_stop_xlat; | 3337 | return ata_scsi_start_stop_xlat; |
| 3124 | } | 3338 | } |
| @@ -3311,11 +3525,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) | |||
| 3311 | ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); | 3525 | ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); |
| 3312 | break; | 3526 | break; |
| 3313 | 3527 | ||
| 3314 | case MODE_SELECT: /* unconditionally return */ | ||
| 3315 | case MODE_SELECT_10: /* bad-field-in-cdb */ | ||
| 3316 | ata_scsi_invalid_field(cmd); | ||
| 3317 | break; | ||
| 3318 | |||
| 3319 | case READ_CAPACITY: | 3528 | case READ_CAPACITY: |
| 3320 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); | 3529 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); |
| 3321 | break; | 3530 | break; |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 50e4dff0604e..7148a58020b9 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
| @@ -165,6 +165,8 @@ extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, | |||
| 165 | unsigned int action); | 165 | unsigned int action); |
| 166 | extern void ata_eh_done(struct ata_link *link, struct ata_device *dev, | 166 | extern void ata_eh_done(struct ata_link *link, struct ata_device *dev, |
| 167 | unsigned int action); | 167 | unsigned int action); |
| 168 | extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, | ||
| 169 | u8 page, void *buf, unsigned int sectors); | ||
| 168 | extern void ata_eh_autopsy(struct ata_port *ap); | 170 | extern void ata_eh_autopsy(struct ata_port *ap); |
| 169 | const char *ata_get_cmd_descript(u8 command); | 171 | const char *ata_get_cmd_descript(u8 command); |
| 170 | extern void ata_eh_report(struct ata_port *ap); | 172 | extern void ata_eh_report(struct ata_port *ap); |
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index bfaa5cb1629a..26201ebef3ca 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
| 32 | #include <linux/libata.h> | 32 | #include <linux/libata.h> |
| 33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 34 | #include <linux/of.h> | ||
| 34 | #include <linux/pata_arasan_cf_data.h> | 35 | #include <linux/pata_arasan_cf_data.h> |
| 35 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
| 36 | #include <linux/pm.h> | 37 | #include <linux/pm.h> |
| @@ -310,7 +311,7 @@ static int cf_init(struct arasan_cf_dev *acdev) | |||
| 310 | unsigned long flags; | 311 | unsigned long flags; |
| 311 | int ret = 0; | 312 | int ret = 0; |
| 312 | 313 | ||
| 313 | ret = clk_enable(acdev->clk); | 314 | ret = clk_prepare_enable(acdev->clk); |
| 314 | if (ret) { | 315 | if (ret) { |
| 315 | dev_dbg(acdev->host->dev, "clock enable failed"); | 316 | dev_dbg(acdev->host->dev, "clock enable failed"); |
| 316 | return ret; | 317 | return ret; |
| @@ -340,7 +341,7 @@ static void cf_exit(struct arasan_cf_dev *acdev) | |||
| 340 | writel(readl(acdev->vbase + OP_MODE) & ~CFHOST_ENB, | 341 | writel(readl(acdev->vbase + OP_MODE) & ~CFHOST_ENB, |
| 341 | acdev->vbase + OP_MODE); | 342 | acdev->vbase + OP_MODE); |
| 342 | spin_unlock_irqrestore(&acdev->host->lock, flags); | 343 | spin_unlock_irqrestore(&acdev->host->lock, flags); |
| 343 | clk_disable(acdev->clk); | 344 | clk_disable_unprepare(acdev->clk); |
| 344 | } | 345 | } |
| 345 | 346 | ||
| 346 | static void dma_callback(void *dev) | 347 | static void dma_callback(void *dev) |
| @@ -935,6 +936,14 @@ static int arasan_cf_resume(struct device *dev) | |||
| 935 | 936 | ||
| 936 | static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume); | 937 | static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume); |
| 937 | 938 | ||
| 939 | #ifdef CONFIG_OF | ||
| 940 | static const struct of_device_id arasan_cf_id_table[] = { | ||
| 941 | { .compatible = "arasan,cf-spear1340" }, | ||
| 942 | {} | ||
| 943 | }; | ||
| 944 | MODULE_DEVICE_TABLE(of, arasan_cf_id_table); | ||
| 945 | #endif | ||
| 946 | |||
| 938 | static struct platform_driver arasan_cf_driver = { | 947 | static struct platform_driver arasan_cf_driver = { |
| 939 | .probe = arasan_cf_probe, | 948 | .probe = arasan_cf_probe, |
| 940 | .remove = __devexit_p(arasan_cf_remove), | 949 | .remove = __devexit_p(arasan_cf_remove), |
| @@ -942,6 +951,7 @@ static struct platform_driver arasan_cf_driver = { | |||
| 942 | .name = DRIVER_NAME, | 951 | .name = DRIVER_NAME, |
| 943 | .owner = THIS_MODULE, | 952 | .owner = THIS_MODULE, |
| 944 | .pm = &arasan_cf_pm_ops, | 953 | .pm = &arasan_cf_pm_ops, |
| 954 | .of_match_table = of_match_ptr(arasan_cf_id_table), | ||
| 945 | }, | 955 | }, |
| 946 | }; | 956 | }; |
| 947 | 957 | ||
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index d6577b93bee3..124b2c1d9c0b 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
| @@ -123,6 +123,7 @@ enum { | |||
| 123 | ONLINE = (1 << 31), | 123 | ONLINE = (1 << 31), |
| 124 | GOING_OFFLINE = (1 << 30), | 124 | GOING_OFFLINE = (1 << 30), |
| 125 | BIST_ERR = (1 << 29), | 125 | BIST_ERR = (1 << 29), |
| 126 | CLEAR_ERROR = (1 << 27), | ||
| 126 | 127 | ||
| 127 | FATAL_ERR_HC_MASTER_ERR = (1 << 18), | 128 | FATAL_ERR_HC_MASTER_ERR = (1 << 18), |
| 128 | FATAL_ERR_PARITY_ERR_TX = (1 << 17), | 129 | FATAL_ERR_PARITY_ERR_TX = (1 << 17), |
| @@ -143,6 +144,7 @@ enum { | |||
| 143 | FATAL_ERR_CRC_ERR_RX | | 144 | FATAL_ERR_CRC_ERR_RX | |
| 144 | FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX, | 145 | FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX, |
| 145 | 146 | ||
| 147 | INT_ON_DATA_LENGTH_MISMATCH = (1 << 12), | ||
| 146 | INT_ON_FATAL_ERR = (1 << 5), | 148 | INT_ON_FATAL_ERR = (1 << 5), |
| 147 | INT_ON_PHYRDY_CHG = (1 << 4), | 149 | INT_ON_PHYRDY_CHG = (1 << 4), |
| 148 | 150 | ||
| @@ -1181,25 +1183,54 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
| 1181 | u32 hstatus, done_mask = 0; | 1183 | u32 hstatus, done_mask = 0; |
| 1182 | struct ata_queued_cmd *qc; | 1184 | struct ata_queued_cmd *qc; |
| 1183 | u32 SError; | 1185 | u32 SError; |
| 1186 | u32 tag; | ||
| 1187 | u32 status_mask = INT_ON_ERROR; | ||
| 1184 | 1188 | ||
| 1185 | hstatus = ioread32(hcr_base + HSTATUS); | 1189 | hstatus = ioread32(hcr_base + HSTATUS); |
| 1186 | 1190 | ||
| 1187 | sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError); | 1191 | sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError); |
| 1188 | 1192 | ||
| 1193 | /* Read command completed register */ | ||
| 1194 | done_mask = ioread32(hcr_base + CC); | ||
| 1195 | |||
| 1196 | /* Workaround for data length mismatch errata */ | ||
| 1197 | if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) { | ||
| 1198 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { | ||
| 1199 | qc = ata_qc_from_tag(ap, tag); | ||
| 1200 | if (qc && ata_is_atapi(qc->tf.protocol)) { | ||
| 1201 | u32 hcontrol; | ||
| 1202 | /* Set HControl[27] to clear error registers */ | ||
| 1203 | hcontrol = ioread32(hcr_base + HCONTROL); | ||
| 1204 | iowrite32(hcontrol | CLEAR_ERROR, | ||
| 1205 | hcr_base + HCONTROL); | ||
| 1206 | |||
| 1207 | /* Clear HControl[27] */ | ||
| 1208 | iowrite32(hcontrol & ~CLEAR_ERROR, | ||
| 1209 | hcr_base + HCONTROL); | ||
| 1210 | |||
| 1211 | /* Clear SError[E] bit */ | ||
| 1212 | sata_fsl_scr_write(&ap->link, SCR_ERROR, | ||
| 1213 | SError); | ||
| 1214 | |||
| 1215 | /* Ignore fatal error and device error */ | ||
| 1216 | status_mask &= ~(INT_ON_SINGL_DEVICE_ERR | ||
| 1217 | | INT_ON_FATAL_ERR); | ||
| 1218 | break; | ||
| 1219 | } | ||
| 1220 | } | ||
| 1221 | } | ||
| 1222 | |||
| 1189 | if (unlikely(SError & 0xFFFF0000)) { | 1223 | if (unlikely(SError & 0xFFFF0000)) { |
| 1190 | DPRINTK("serror @host_intr : 0x%x\n", SError); | 1224 | DPRINTK("serror @host_intr : 0x%x\n", SError); |
| 1191 | sata_fsl_error_intr(ap); | 1225 | sata_fsl_error_intr(ap); |
| 1192 | } | 1226 | } |
| 1193 | 1227 | ||
| 1194 | if (unlikely(hstatus & INT_ON_ERROR)) { | 1228 | if (unlikely(hstatus & status_mask)) { |
| 1195 | DPRINTK("error interrupt!!\n"); | 1229 | DPRINTK("error interrupt!!\n"); |
| 1196 | sata_fsl_error_intr(ap); | 1230 | sata_fsl_error_intr(ap); |
| 1197 | return; | 1231 | return; |
| 1198 | } | 1232 | } |
| 1199 | 1233 | ||
| 1200 | /* Read command completed register */ | ||
| 1201 | done_mask = ioread32(hcr_base + CC); | ||
| 1202 | |||
| 1203 | VPRINTK("Status of all queues :\n"); | 1234 | VPRINTK("Status of all queues :\n"); |
| 1204 | VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", | 1235 | VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", |
| 1205 | done_mask, | 1236 | done_mask, |
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c new file mode 100644 index 000000000000..0d7c4c2cd26f --- /dev/null +++ b/drivers/ata/sata_highbank.c | |||
| @@ -0,0 +1,450 @@ | |||
| 1 | /* | ||
| 2 | * Calxeda Highbank AHCI SATA platform driver | ||
| 3 | * Copyright 2012 Calxeda, Inc. | ||
| 4 | * | ||
| 5 | * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms and conditions of the GNU General Public License, | ||
| 9 | * version 2, as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 14 | * more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along with | ||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | */ | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/gfp.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/types.h> | ||
| 24 | #include <linux/err.h> | ||
| 25 | #include <linux/io.h> | ||
| 26 | #include <linux/spinlock.h> | ||
| 27 | #include <linux/device.h> | ||
| 28 | #include <linux/of_device.h> | ||
| 29 | #include <linux/of_address.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/libata.h> | ||
| 32 | #include <linux/ahci_platform.h> | ||
| 33 | #include <linux/interrupt.h> | ||
| 34 | #include <linux/delay.h> | ||
| 35 | #include <linux/export.h> | ||
| 36 | #include "ahci.h" | ||
| 37 | |||
| 38 | #define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f)) | ||
| 39 | #define CPHY_ADDR(addr) (((addr) & 0x1ff) << 2) | ||
| 40 | #define SERDES_CR_CTL 0x80a0 | ||
| 41 | #define SERDES_CR_ADDR 0x80a1 | ||
| 42 | #define SERDES_CR_DATA 0x80a2 | ||
| 43 | #define CR_BUSY 0x0001 | ||
| 44 | #define CR_START 0x0001 | ||
| 45 | #define CR_WR_RDN 0x0002 | ||
| 46 | #define CPHY_RX_INPUT_STS 0x2002 | ||
| 47 | #define CPHY_SATA_OVERRIDE 0x4000 | ||
| 48 | #define CPHY_OVERRIDE 0x2005 | ||
| 49 | #define SPHY_LANE 0x100 | ||
| 50 | #define SPHY_HALF_RATE 0x0001 | ||
| 51 | #define CPHY_SATA_DPLL_MODE 0x0700 | ||
| 52 | #define CPHY_SATA_DPLL_SHIFT 8 | ||
| 53 | #define CPHY_SATA_DPLL_RESET (1 << 11) | ||
| 54 | #define CPHY_PHY_COUNT 6 | ||
| 55 | #define CPHY_LANE_COUNT 4 | ||
| 56 | #define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT) | ||
| 57 | |||
| 58 | static DEFINE_SPINLOCK(cphy_lock); | ||
| 59 | /* Each of the 6 phys can have up to 4 sata ports attached to i. Map 0-based | ||
| 60 | * sata ports to their phys and then to their lanes within the phys | ||
| 61 | */ | ||
| 62 | struct phy_lane_info { | ||
| 63 | void __iomem *phy_base; | ||
| 64 | u8 lane_mapping; | ||
| 65 | u8 phy_devs; | ||
| 66 | }; | ||
| 67 | static struct phy_lane_info port_data[CPHY_PORT_COUNT]; | ||
| 68 | |||
| 69 | static u32 __combo_phy_reg_read(u8 sata_port, u32 addr) | ||
| 70 | { | ||
| 71 | u32 data; | ||
| 72 | u8 dev = port_data[sata_port].phy_devs; | ||
| 73 | spin_lock(&cphy_lock); | ||
| 74 | writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800); | ||
| 75 | data = readl(port_data[sata_port].phy_base + CPHY_ADDR(addr)); | ||
| 76 | spin_unlock(&cphy_lock); | ||
| 77 | return data; | ||
| 78 | } | ||
| 79 | |||
| 80 | static void __combo_phy_reg_write(u8 sata_port, u32 addr, u32 data) | ||
| 81 | { | ||
| 82 | u8 dev = port_data[sata_port].phy_devs; | ||
| 83 | spin_lock(&cphy_lock); | ||
| 84 | writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800); | ||
| 85 | writel(data, port_data[sata_port].phy_base + CPHY_ADDR(addr)); | ||
| 86 | spin_unlock(&cphy_lock); | ||
| 87 | } | ||
| 88 | |||
| 89 | static void combo_phy_wait_for_ready(u8 sata_port) | ||
| 90 | { | ||
| 91 | while (__combo_phy_reg_read(sata_port, SERDES_CR_CTL) & CR_BUSY) | ||
| 92 | udelay(5); | ||
| 93 | } | ||
| 94 | |||
| 95 | static u32 combo_phy_read(u8 sata_port, u32 addr) | ||
| 96 | { | ||
| 97 | combo_phy_wait_for_ready(sata_port); | ||
| 98 | __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr); | ||
| 99 | __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_START); | ||
| 100 | combo_phy_wait_for_ready(sata_port); | ||
| 101 | return __combo_phy_reg_read(sata_port, SERDES_CR_DATA); | ||
| 102 | } | ||
| 103 | |||
| 104 | static void combo_phy_write(u8 sata_port, u32 addr, u32 data) | ||
| 105 | { | ||
| 106 | combo_phy_wait_for_ready(sata_port); | ||
| 107 | __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr); | ||
| 108 | __combo_phy_reg_write(sata_port, SERDES_CR_DATA, data); | ||
| 109 | __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_WR_RDN | CR_START); | ||
| 110 | } | ||
| 111 | |||
| 112 | static void highbank_cphy_disable_overrides(u8 sata_port) | ||
| 113 | { | ||
| 114 | u8 lane = port_data[sata_port].lane_mapping; | ||
| 115 | u32 tmp; | ||
| 116 | if (unlikely(port_data[sata_port].phy_base == NULL)) | ||
| 117 | return; | ||
| 118 | tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE); | ||
| 119 | tmp &= ~CPHY_SATA_OVERRIDE; | ||
| 120 | combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); | ||
| 121 | } | ||
| 122 | |||
| 123 | static void cphy_override_rx_mode(u8 sata_port, u32 val) | ||
| 124 | { | ||
| 125 | u8 lane = port_data[sata_port].lane_mapping; | ||
| 126 | u32 tmp; | ||
| 127 | tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE); | ||
| 128 | tmp &= ~CPHY_SATA_OVERRIDE; | ||
| 129 | combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); | ||
| 130 | |||
| 131 | tmp |= CPHY_SATA_OVERRIDE; | ||
| 132 | combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); | ||
| 133 | |||
| 134 | tmp &= ~CPHY_SATA_DPLL_MODE; | ||
| 135 | tmp |= val << CPHY_SATA_DPLL_SHIFT; | ||
| 136 | combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); | ||
| 137 | |||
| 138 | tmp |= CPHY_SATA_DPLL_RESET; | ||
| 139 | combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); | ||
| 140 | |||
| 141 | tmp &= ~CPHY_SATA_DPLL_RESET; | ||
| 142 | combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp); | ||
| 143 | |||
| 144 | msleep(15); | ||
| 145 | } | ||
| 146 | |||
| 147 | static void highbank_cphy_override_lane(u8 sata_port) | ||
| 148 | { | ||
| 149 | u8 lane = port_data[sata_port].lane_mapping; | ||
| 150 | u32 tmp, k = 0; | ||
| 151 | |||
| 152 | if (unlikely(port_data[sata_port].phy_base == NULL)) | ||
| 153 | return; | ||
| 154 | do { | ||
| 155 | tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + | ||
| 156 | lane * SPHY_LANE); | ||
| 157 | } while ((tmp & SPHY_HALF_RATE) && (k++ < 1000)); | ||
| 158 | cphy_override_rx_mode(sata_port, 3); | ||
| 159 | } | ||
| 160 | |||
| 161 | static int highbank_initialize_phys(struct device *dev, void __iomem *addr) | ||
| 162 | { | ||
| 163 | struct device_node *sata_node = dev->of_node; | ||
| 164 | int phy_count = 0, phy, port = 0; | ||
| 165 | void __iomem *cphy_base[CPHY_PHY_COUNT]; | ||
| 166 | struct device_node *phy_nodes[CPHY_PHY_COUNT]; | ||
| 167 | memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT); | ||
| 168 | memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT); | ||
| 169 | |||
| 170 | do { | ||
| 171 | u32 tmp; | ||
| 172 | struct of_phandle_args phy_data; | ||
| 173 | if (of_parse_phandle_with_args(sata_node, | ||
| 174 | "calxeda,port-phys", "#phy-cells", | ||
| 175 | port, &phy_data)) | ||
| 176 | break; | ||
| 177 | for (phy = 0; phy < phy_count; phy++) { | ||
| 178 | if (phy_nodes[phy] == phy_data.np) | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | if (phy_nodes[phy] == NULL) { | ||
| 182 | phy_nodes[phy] = phy_data.np; | ||
| 183 | cphy_base[phy] = of_iomap(phy_nodes[phy], 0); | ||
| 184 | if (cphy_base[phy] == NULL) { | ||
| 185 | return 0; | ||
| 186 | } | ||
| 187 | phy_count += 1; | ||
| 188 | } | ||
| 189 | port_data[port].lane_mapping = phy_data.args[0]; | ||
| 190 | of_property_read_u32(phy_nodes[phy], "phydev", &tmp); | ||
| 191 | port_data[port].phy_devs = tmp; | ||
| 192 | port_data[port].phy_base = cphy_base[phy]; | ||
| 193 | of_node_put(phy_data.np); | ||
| 194 | port += 1; | ||
| 195 | } while (port < CPHY_PORT_COUNT); | ||
| 196 | return 0; | ||
| 197 | } | ||
| 198 | |||
| 199 | static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, | ||
| 200 | unsigned long deadline) | ||
| 201 | { | ||
| 202 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | ||
| 203 | struct ata_port *ap = link->ap; | ||
| 204 | struct ahci_port_priv *pp = ap->private_data; | ||
| 205 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | ||
| 206 | struct ata_taskfile tf; | ||
| 207 | bool online; | ||
| 208 | u32 sstatus; | ||
| 209 | int rc; | ||
| 210 | int retry = 10; | ||
| 211 | |||
| 212 | ahci_stop_engine(ap); | ||
| 213 | |||
| 214 | /* clear D2H reception area to properly wait for D2H FIS */ | ||
| 215 | ata_tf_init(link->device, &tf); | ||
| 216 | tf.command = 0x80; | ||
| 217 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | ||
| 218 | |||
| 219 | do { | ||
| 220 | highbank_cphy_disable_overrides(link->ap->port_no); | ||
| 221 | rc = sata_link_hardreset(link, timing, deadline, &online, NULL); | ||
| 222 | highbank_cphy_override_lane(link->ap->port_no); | ||
| 223 | |||
| 224 | /* If the status is 1, we are connected, but the link did not | ||
| 225 | * come up. So retry resetting the link again. | ||
| 226 | */ | ||
| 227 | if (sata_scr_read(link, SCR_STATUS, &sstatus)) | ||
| 228 | break; | ||
| 229 | if (!(sstatus & 0x3)) | ||
| 230 | break; | ||
| 231 | } while (!online && retry--); | ||
| 232 | |||
| 233 | ahci_start_engine(ap); | ||
| 234 | |||
| 235 | if (online) | ||
| 236 | *class = ahci_dev_classify(ap); | ||
| 237 | |||
| 238 | return rc; | ||
| 239 | } | ||
| 240 | |||
| 241 | static struct ata_port_operations ahci_highbank_ops = { | ||
| 242 | .inherits = &ahci_ops, | ||
| 243 | .hardreset = ahci_highbank_hardreset, | ||
| 244 | }; | ||
| 245 | |||
| 246 | static const struct ata_port_info ahci_highbank_port_info = { | ||
| 247 | .flags = AHCI_FLAG_COMMON, | ||
| 248 | .pio_mask = ATA_PIO4, | ||
| 249 | .udma_mask = ATA_UDMA6, | ||
| 250 | .port_ops = &ahci_highbank_ops, | ||
| 251 | }; | ||
| 252 | |||
| 253 | static struct scsi_host_template ahci_highbank_platform_sht = { | ||
| 254 | AHCI_SHT("highbank-ahci"), | ||
| 255 | }; | ||
| 256 | |||
| 257 | static const struct of_device_id ahci_of_match[] = { | ||
| 258 | { .compatible = "calxeda,hb-ahci" }, | ||
| 259 | {}, | ||
| 260 | }; | ||
| 261 | MODULE_DEVICE_TABLE(of, ahci_of_match); | ||
| 262 | |||
| 263 | static int __init ahci_highbank_probe(struct platform_device *pdev) | ||
| 264 | { | ||
| 265 | struct device *dev = &pdev->dev; | ||
| 266 | struct ahci_host_priv *hpriv; | ||
| 267 | struct ata_host *host; | ||
| 268 | struct resource *mem; | ||
| 269 | int irq; | ||
| 270 | int n_ports; | ||
| 271 | int i; | ||
| 272 | int rc; | ||
| 273 | struct ata_port_info pi = ahci_highbank_port_info; | ||
| 274 | const struct ata_port_info *ppi[] = { &pi, NULL }; | ||
| 275 | |||
| 276 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 277 | if (!mem) { | ||
| 278 | dev_err(dev, "no mmio space\n"); | ||
| 279 | return -EINVAL; | ||
| 280 | } | ||
| 281 | |||
| 282 | irq = platform_get_irq(pdev, 0); | ||
| 283 | if (irq <= 0) { | ||
| 284 | dev_err(dev, "no irq\n"); | ||
| 285 | return -EINVAL; | ||
| 286 | } | ||
| 287 | |||
| 288 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); | ||
| 289 | if (!hpriv) { | ||
| 290 | dev_err(dev, "can't alloc ahci_host_priv\n"); | ||
| 291 | return -ENOMEM; | ||
| 292 | } | ||
| 293 | |||
| 294 | hpriv->flags |= (unsigned long)pi.private_data; | ||
| 295 | |||
| 296 | hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); | ||
| 297 | if (!hpriv->mmio) { | ||
| 298 | dev_err(dev, "can't map %pR\n", mem); | ||
| 299 | return -ENOMEM; | ||
| 300 | } | ||
| 301 | |||
| 302 | rc = highbank_initialize_phys(dev, hpriv->mmio); | ||
| 303 | if (rc) | ||
| 304 | return rc; | ||
| 305 | |||
| 306 | |||
| 307 | ahci_save_initial_config(dev, hpriv, 0, 0); | ||
| 308 | |||
| 309 | /* prepare host */ | ||
| 310 | if (hpriv->cap & HOST_CAP_NCQ) | ||
| 311 | pi.flags |= ATA_FLAG_NCQ; | ||
| 312 | |||
| 313 | if (hpriv->cap & HOST_CAP_PMP) | ||
| 314 | pi.flags |= ATA_FLAG_PMP; | ||
| 315 | |||
| 316 | ahci_set_em_messages(hpriv, &pi); | ||
| 317 | |||
| 318 | /* CAP.NP sometimes indicate the index of the last enabled | ||
| 319 | * port, at other times, that of the last possible port, so | ||
| 320 | * determining the maximum port number requires looking at | ||
| 321 | * both CAP.NP and port_map. | ||
| 322 | */ | ||
| 323 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); | ||
| 324 | |||
| 325 | host = ata_host_alloc_pinfo(dev, ppi, n_ports); | ||
| 326 | if (!host) { | ||
| 327 | rc = -ENOMEM; | ||
| 328 | goto err0; | ||
| 329 | } | ||
| 330 | |||
| 331 | host->private_data = hpriv; | ||
| 332 | |||
| 333 | if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) | ||
| 334 | host->flags |= ATA_HOST_PARALLEL_SCAN; | ||
| 335 | |||
| 336 | if (pi.flags & ATA_FLAG_EM) | ||
| 337 | ahci_reset_em(host); | ||
| 338 | |||
| 339 | for (i = 0; i < host->n_ports; i++) { | ||
| 340 | struct ata_port *ap = host->ports[i]; | ||
| 341 | |||
| 342 | ata_port_desc(ap, "mmio %pR", mem); | ||
| 343 | ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); | ||
| 344 | |||
| 345 | /* set enclosure management message type */ | ||
| 346 | if (ap->flags & ATA_FLAG_EM) | ||
| 347 | ap->em_message_type = hpriv->em_msg_type; | ||
| 348 | |||
| 349 | /* disabled/not-implemented port */ | ||
| 350 | if (!(hpriv->port_map & (1 << i))) | ||
| 351 | ap->ops = &ata_dummy_port_ops; | ||
| 352 | } | ||
| 353 | |||
| 354 | rc = ahci_reset_controller(host); | ||
| 355 | if (rc) | ||
| 356 | goto err0; | ||
| 357 | |||
| 358 | ahci_init_controller(host); | ||
| 359 | ahci_print_info(host, "platform"); | ||
| 360 | |||
| 361 | rc = ata_host_activate(host, irq, ahci_interrupt, 0, | ||
| 362 | &ahci_highbank_platform_sht); | ||
| 363 | if (rc) | ||
| 364 | goto err0; | ||
| 365 | |||
| 366 | return 0; | ||
| 367 | err0: | ||
| 368 | return rc; | ||
| 369 | } | ||
| 370 | |||
| 371 | static int __devexit ahci_highbank_remove(struct platform_device *pdev) | ||
| 372 | { | ||
| 373 | struct device *dev = &pdev->dev; | ||
| 374 | struct ata_host *host = dev_get_drvdata(dev); | ||
| 375 | |||
| 376 | ata_host_detach(host); | ||
| 377 | |||
| 378 | return 0; | ||
| 379 | } | ||
| 380 | |||
| 381 | #ifdef CONFIG_PM | ||
| 382 | static int ahci_highbank_suspend(struct device *dev) | ||
| 383 | { | ||
| 384 | struct ata_host *host = dev_get_drvdata(dev); | ||
| 385 | struct ahci_host_priv *hpriv = host->private_data; | ||
| 386 | void __iomem *mmio = hpriv->mmio; | ||
| 387 | u32 ctl; | ||
| 388 | int rc; | ||
| 389 | |||
| 390 | if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { | ||
| 391 | dev_err(dev, "firmware update required for suspend/resume\n"); | ||
| 392 | return -EIO; | ||
| 393 | } | ||
| 394 | |||
| 395 | /* | ||
| 396 | * AHCI spec rev1.1 section 8.3.3: | ||
| 397 | * Software must disable interrupts prior to requesting a | ||
| 398 | * transition of the HBA to D3 state. | ||
| 399 | */ | ||
| 400 | ctl = readl(mmio + HOST_CTL); | ||
| 401 | ctl &= ~HOST_IRQ_EN; | ||
| 402 | writel(ctl, mmio + HOST_CTL); | ||
| 403 | readl(mmio + HOST_CTL); /* flush */ | ||
| 404 | |||
| 405 | rc = ata_host_suspend(host, PMSG_SUSPEND); | ||
| 406 | if (rc) | ||
| 407 | return rc; | ||
| 408 | |||
| 409 | return 0; | ||
| 410 | } | ||
| 411 | |||
| 412 | static int ahci_highbank_resume(struct device *dev) | ||
| 413 | { | ||
| 414 | struct ata_host *host = dev_get_drvdata(dev); | ||
| 415 | int rc; | ||
| 416 | |||
| 417 | if (dev->power.power_state.event == PM_EVENT_SUSPEND) { | ||
| 418 | rc = ahci_reset_controller(host); | ||
| 419 | if (rc) | ||
| 420 | return rc; | ||
| 421 | |||
| 422 | ahci_init_controller(host); | ||
| 423 | } | ||
| 424 | |||
| 425 | ata_host_resume(host); | ||
| 426 | |||
| 427 | return 0; | ||
| 428 | } | ||
| 429 | #endif | ||
| 430 | |||
| 431 | SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops, | ||
| 432 | ahci_highbank_suspend, ahci_highbank_resume); | ||
| 433 | |||
| 434 | static struct platform_driver ahci_highbank_driver = { | ||
| 435 | .remove = __devexit_p(ahci_highbank_remove), | ||
| 436 | .driver = { | ||
| 437 | .name = "highbank-ahci", | ||
| 438 | .owner = THIS_MODULE, | ||
| 439 | .of_match_table = ahci_of_match, | ||
| 440 | .pm = &ahci_highbank_pm_ops, | ||
| 441 | }, | ||
| 442 | .probe = ahci_highbank_probe, | ||
| 443 | }; | ||
| 444 | |||
| 445 | module_platform_driver(ahci_highbank_driver); | ||
| 446 | |||
| 447 | MODULE_DESCRIPTION("Calxeda Highbank AHCI SATA platform driver"); | ||
| 448 | MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@calxeda.com>"); | ||
| 449 | MODULE_LICENSE("GPL"); | ||
| 450 | MODULE_ALIAS("sata:highbank"); | ||
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 311be18d3f03..68f4fb54d627 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
| @@ -79,8 +79,8 @@ | |||
| 79 | * module options | 79 | * module options |
| 80 | */ | 80 | */ |
| 81 | 81 | ||
| 82 | static int msi; | ||
| 83 | #ifdef CONFIG_PCI | 82 | #ifdef CONFIG_PCI |
| 83 | static int msi; | ||
| 84 | module_param(msi, int, S_IRUGO); | 84 | module_param(msi, int, S_IRUGO); |
| 85 | MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)"); | 85 | MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)"); |
| 86 | #endif | 86 | #endif |
| @@ -652,12 +652,13 @@ static u8 mv_sff_check_status(struct ata_port *ap); | |||
| 652 | * because we have to allow room for worst case splitting of | 652 | * because we have to allow room for worst case splitting of |
| 653 | * PRDs for 64K boundaries in mv_fill_sg(). | 653 | * PRDs for 64K boundaries in mv_fill_sg(). |
| 654 | */ | 654 | */ |
| 655 | #ifdef CONFIG_PCI | ||
| 655 | static struct scsi_host_template mv5_sht = { | 656 | static struct scsi_host_template mv5_sht = { |
| 656 | ATA_BASE_SHT(DRV_NAME), | 657 | ATA_BASE_SHT(DRV_NAME), |
| 657 | .sg_tablesize = MV_MAX_SG_CT / 2, | 658 | .sg_tablesize = MV_MAX_SG_CT / 2, |
| 658 | .dma_boundary = MV_DMA_BOUNDARY, | 659 | .dma_boundary = MV_DMA_BOUNDARY, |
| 659 | }; | 660 | }; |
| 660 | 661 | #endif | |
| 661 | static struct scsi_host_template mv6_sht = { | 662 | static struct scsi_host_template mv6_sht = { |
| 662 | ATA_NCQ_SHT(DRV_NAME), | 663 | ATA_NCQ_SHT(DRV_NAME), |
| 663 | .can_queue = MV_MAX_Q_DEPTH - 1, | 664 | .can_queue = MV_MAX_Q_DEPTH - 1, |
| @@ -1252,7 +1253,7 @@ static void mv_dump_mem(void __iomem *start, unsigned bytes) | |||
| 1252 | } | 1253 | } |
| 1253 | } | 1254 | } |
| 1254 | #endif | 1255 | #endif |
| 1255 | 1256 | #if defined(ATA_DEBUG) || defined(CONFIG_PCI) | |
| 1256 | static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes) | 1257 | static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes) |
| 1257 | { | 1258 | { |
| 1258 | #ifdef ATA_DEBUG | 1259 | #ifdef ATA_DEBUG |
| @@ -1269,6 +1270,7 @@ static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes) | |||
| 1269 | } | 1270 | } |
| 1270 | #endif | 1271 | #endif |
| 1271 | } | 1272 | } |
| 1273 | #endif | ||
| 1272 | static void mv_dump_all_regs(void __iomem *mmio_base, int port, | 1274 | static void mv_dump_all_regs(void __iomem *mmio_base, int port, |
| 1273 | struct pci_dev *pdev) | 1275 | struct pci_dev *pdev) |
| 1274 | { | 1276 | { |
diff --git a/include/linux/ata.h b/include/linux/ata.h index 5713d3ac381a..408da9502177 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
| @@ -77,6 +77,9 @@ enum { | |||
| 77 | ATA_ID_EIDE_PIO_IORDY = 68, | 77 | ATA_ID_EIDE_PIO_IORDY = 68, |
| 78 | ATA_ID_ADDITIONAL_SUPP = 69, | 78 | ATA_ID_ADDITIONAL_SUPP = 69, |
| 79 | ATA_ID_QUEUE_DEPTH = 75, | 79 | ATA_ID_QUEUE_DEPTH = 75, |
| 80 | ATA_ID_SATA_CAPABILITY = 76, | ||
| 81 | ATA_ID_SATA_CAPABILITY_2 = 77, | ||
| 82 | ATA_ID_FEATURE_SUPP = 78, | ||
| 80 | ATA_ID_MAJOR_VER = 80, | 83 | ATA_ID_MAJOR_VER = 80, |
| 81 | ATA_ID_COMMAND_SET_1 = 82, | 84 | ATA_ID_COMMAND_SET_1 = 82, |
| 82 | ATA_ID_COMMAND_SET_2 = 83, | 85 | ATA_ID_COMMAND_SET_2 = 83, |
| @@ -292,6 +295,13 @@ enum { | |||
| 292 | 295 | ||
| 293 | /* READ_LOG_EXT pages */ | 296 | /* READ_LOG_EXT pages */ |
| 294 | ATA_LOG_SATA_NCQ = 0x10, | 297 | ATA_LOG_SATA_NCQ = 0x10, |
| 298 | ATA_LOG_SATA_ID_DEV_DATA = 0x30, | ||
| 299 | ATA_LOG_SATA_SETTINGS = 0x08, | ||
| 300 | ATA_LOG_DEVSLP_MDAT = 0x30, | ||
| 301 | ATA_LOG_DEVSLP_MDAT_MASK = 0x1F, | ||
| 302 | ATA_LOG_DEVSLP_DETO = 0x31, | ||
| 303 | ATA_LOG_DEVSLP_VALID = 0x37, | ||
| 304 | ATA_LOG_DEVSLP_VALID_MASK = 0x80, | ||
| 295 | 305 | ||
| 296 | /* READ/WRITE LONG (obsolete) */ | 306 | /* READ/WRITE LONG (obsolete) */ |
| 297 | ATA_CMD_READ_LONG = 0x22, | 307 | ATA_CMD_READ_LONG = 0x22, |
| @@ -345,6 +355,7 @@ enum { | |||
| 345 | SATA_FPDMA_IN_ORDER = 0x04, /* FPDMA in-order data delivery */ | 355 | SATA_FPDMA_IN_ORDER = 0x04, /* FPDMA in-order data delivery */ |
| 346 | SATA_AN = 0x05, /* Asynchronous Notification */ | 356 | SATA_AN = 0x05, /* Asynchronous Notification */ |
| 347 | SATA_SSP = 0x06, /* Software Settings Preservation */ | 357 | SATA_SSP = 0x06, /* Software Settings Preservation */ |
| 358 | SATA_DEVSLP = 0x09, /* Device Sleep */ | ||
| 348 | 359 | ||
| 349 | /* feature values for SET_MAX */ | 360 | /* feature values for SET_MAX */ |
| 350 | ATA_SET_MAX_ADDR = 0x00, | 361 | ATA_SET_MAX_ADDR = 0x00, |
| @@ -558,15 +569,17 @@ static inline int ata_is_data(u8 prot) | |||
| 558 | #define ata_id_is_ata(id) (((id)[ATA_ID_CONFIG] & (1 << 15)) == 0) | 569 | #define ata_id_is_ata(id) (((id)[ATA_ID_CONFIG] & (1 << 15)) == 0) |
| 559 | #define ata_id_has_lba(id) ((id)[ATA_ID_CAPABILITY] & (1 << 9)) | 570 | #define ata_id_has_lba(id) ((id)[ATA_ID_CAPABILITY] & (1 << 9)) |
| 560 | #define ata_id_has_dma(id) ((id)[ATA_ID_CAPABILITY] & (1 << 8)) | 571 | #define ata_id_has_dma(id) ((id)[ATA_ID_CAPABILITY] & (1 << 8)) |
| 561 | #define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) | 572 | #define ata_id_has_ncq(id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8)) |
| 562 | #define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1) | 573 | #define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1) |
| 563 | #define ata_id_removeable(id) ((id)[ATA_ID_CONFIG] & (1 << 7)) | 574 | #define ata_id_removeable(id) ((id)[ATA_ID_CONFIG] & (1 << 7)) |
| 564 | #define ata_id_has_atapi_AN(id) \ | 575 | #define ata_id_has_atapi_AN(id) \ |
| 565 | ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ | 576 | ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ |
| 566 | ((id)[78] & (1 << 5)) ) | 577 | ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ |
| 578 | ((id)[ATA_ID_FEATURE_SUPP] & (1 << 5))) | ||
| 567 | #define ata_id_has_fpdma_aa(id) \ | 579 | #define ata_id_has_fpdma_aa(id) \ |
| 568 | ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ | 580 | ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ |
| 569 | ((id)[78] & (1 << 2)) ) | 581 | ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ |
| 582 | ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2))) | ||
| 570 | #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) | 583 | #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) |
| 571 | #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) | 584 | #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) |
| 572 | #define ata_id_u32(id,n) \ | 585 | #define ata_id_u32(id,n) \ |
| @@ -578,11 +591,12 @@ static inline int ata_is_data(u8 prot) | |||
| 578 | ((u64) (id)[(n) + 0]) ) | 591 | ((u64) (id)[(n) + 0]) ) |
| 579 | 592 | ||
| 580 | #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) | 593 | #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) |
| 581 | #define ata_id_has_da(id) ((id)[77] & (1 << 4)) | 594 | #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) |
| 595 | #define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)) | ||
| 582 | 596 | ||
| 583 | static inline bool ata_id_has_hipm(const u16 *id) | 597 | static inline bool ata_id_has_hipm(const u16 *id) |
| 584 | { | 598 | { |
| 585 | u16 val = id[76]; | 599 | u16 val = id[ATA_ID_SATA_CAPABILITY]; |
| 586 | 600 | ||
| 587 | if (val == 0 || val == 0xffff) | 601 | if (val == 0 || val == 0xffff) |
| 588 | return false; | 602 | return false; |
| @@ -592,7 +606,7 @@ static inline bool ata_id_has_hipm(const u16 *id) | |||
| 592 | 606 | ||
| 593 | static inline bool ata_id_has_dipm(const u16 *id) | 607 | static inline bool ata_id_has_dipm(const u16 *id) |
| 594 | { | 608 | { |
| 595 | u16 val = id[78]; | 609 | u16 val = id[ATA_ID_FEATURE_SUPP]; |
| 596 | 610 | ||
| 597 | if (val == 0 || val == 0xffff) | 611 | if (val == 0 || val == 0xffff) |
| 598 | return false; | 612 | return false; |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 64f90e17e51d..464e67c2e77a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -162,6 +162,7 @@ enum { | |||
| 162 | ATA_DFLAG_DETACHED = (1 << 25), | 162 | ATA_DFLAG_DETACHED = (1 << 25), |
| 163 | 163 | ||
| 164 | ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ | 164 | ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ |
| 165 | ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */ | ||
| 165 | 166 | ||
| 166 | ATA_DEV_UNKNOWN = 0, /* unknown device */ | 167 | ATA_DEV_UNKNOWN = 0, /* unknown device */ |
| 167 | ATA_DEV_ATA = 1, /* ATA device */ | 168 | ATA_DEV_ATA = 1, /* ATA device */ |
| @@ -649,6 +650,9 @@ struct ata_device { | |||
| 649 | u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */ | 650 | u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */ |
| 650 | }; | 651 | }; |
| 651 | 652 | ||
| 653 | /* Identify Device Data Log (30h), SATA Settings (page 08h) */ | ||
| 654 | u8 sata_settings[ATA_SECT_SIZE]; | ||
| 655 | |||
| 652 | /* error history */ | 656 | /* error history */ |
| 653 | int spdn_cnt; | 657 | int spdn_cnt; |
| 654 | /* ering is CLEAR_END, read comment above CLEAR_END */ | 658 | /* ering is CLEAR_END, read comment above CLEAR_END */ |
