Skip to content

Commit 25781ee

Browse files
committed
ata: update from v3.2
1 parent 7ee6edb commit 25781ee

File tree

4 files changed

+119
-23
lines changed

4 files changed

+119
-23
lines changed

drivers/ata/ahci_platform.c

Lines changed: 91 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,56 @@
2323
#include <linux/clk.h>
2424
#include <mach/reset.h>
2525
#include "ahci.h"
26+
2627
#ifdef CONFIG_ARCH_M86XXX
2728
/* SATA Clocks */
2829
static struct clk *sata_oob_clk; /* Core clock */
2930
static struct clk *sata_pmu_clk; /* PMU alive clock */
3031
static struct clk *sata_clk; /* Sata AXI ref clock */
3132
#endif
3233

34+
enum ahci_type {
35+
AHCI, /* standard platform ahci */
36+
IMX53_AHCI, /* ahci on i.mx53 */
37+
};
38+
39+
static struct platform_device_id ahci_devtype[] = {
40+
{
41+
.name = "ahci",
42+
.driver_data = AHCI,
43+
}, {
44+
.name = "imx53-ahci",
45+
.driver_data = IMX53_AHCI,
46+
}, {
47+
/* sentinel */
48+
}
49+
};
50+
MODULE_DEVICE_TABLE(platform, ahci_devtype);
51+
3352

34-
static const struct ata_port_info ahci_port_info = {
35-
.flags = AHCI_FLAG_COMMON,
36-
.pio_mask = ATA_PIO4,
37-
.udma_mask = ATA_UDMA6,
38-
.port_ops = &ahci_platform_ops,
53+
static const struct ata_port_info ahci_port_info[] = {
54+
/* by features */
55+
[AHCI] = {
56+
.flags = AHCI_FLAG_COMMON,
57+
.pio_mask = ATA_PIO4,
58+
.udma_mask = ATA_UDMA6,
59+
.port_ops = &ahci_ops,
60+
},
61+
[IMX53_AHCI] = {
62+
.flags = AHCI_FLAG_COMMON,
63+
.pio_mask = ATA_PIO4,
64+
.udma_mask = ATA_UDMA6,
65+
.port_ops = &ahci_pmp_retry_srst_ops,
66+
},
3967
};
68+
4069
#ifdef CONFIG_PM
41-
static int ahci_platform_suspend(struct platform_device *pdev, pm_message_t state)
70+
static int sata_ahci_platform_suspend(struct device *dev)
4271
{
43-
struct ata_host *host = platform_get_drvdata(pdev);
72+
struct ata_host *host = dev_get_drvdata(dev);
4473
int ret=0;
4574
if (host)
46-
ret = ata_host_suspend(host, state);
75+
ret = ata_host_suspend(host, PMSG_SUSPEND);
4776

4877
#ifdef CONFIG_ARCH_M86XXX
4978
if (!ret) /* sucessfully done the host suspend */
@@ -58,9 +87,9 @@ static int ahci_platform_suspend(struct platform_device *pdev, pm_message_t stat
5887
return ret;
5988
}
6089

61-
static int ahci_platform_resume(struct platform_device *pdev)
90+
static int sata_ahci_platform_resume(struct device *dev)
6291
{
63-
struct ata_host *host = platform_get_drvdata(pdev);
92+
struct ata_host *host = dev_get_drvdata(dev);
6493

6594
#ifdef CONFIG_ARCH_M86XXX
6695
/* Do the clock enable here PMU,OOB,AXI */
@@ -75,14 +104,16 @@ static int ahci_platform_resume(struct platform_device *pdev)
75104
return 0;
76105
}
77106
#else
78-
#define ahci_platform_suspend NULL
79-
#define ahci_platform_resume NULL
107+
#define sata_ahci_platform_suspend NULL
108+
#define sata_ahci_platform_resume NULL
80109
#endif
81110

82111
static int ahci_probe(struct platform_device *pdev)
83112
{
84113
struct device *dev = &pdev->dev;
85114
struct ahci_platform_data *pdata = dev_get_platdata(dev);
115+
const struct platform_device_id *id = platform_get_device_id(pdev);
116+
struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
86117
struct ahci_host_priv *hpriv;
87118
unsigned long hflags = 0;
88119
int rc;
@@ -143,6 +174,11 @@ static int ahci_probe(struct platform_device *pdev)
143174
if (rc)
144175
return rc;
145176

177+
if (pdata && pdata->ata_port_info)
178+
pi = *pdata->ata_port_info;
179+
180+
hflags |= (unsigned long)pi.private_data;
181+
146182
/*
147183
* Some platforms might need to prepare for mmio region access,
148184
* which could be done in the following init call. So, the mmio
@@ -158,8 +194,10 @@ static int ahci_probe(struct platform_device *pdev)
158194
if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
159195
hflags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
160196

161-
rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
162-
hflags, 0, 0);
197+
rc = ahci_platform_init_host(pdev, hpriv, &pi,
198+
hflags,
199+
pdata ? pdata->force_port_map : 0,
200+
pdata ? pdata->mask_port_map : 0);
163201
if (rc)
164202
goto pdata_exit;
165203

@@ -172,8 +210,43 @@ static int ahci_probe(struct platform_device *pdev)
172210
return rc;
173211
}
174212

175-
static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
176-
ahci_platform_resume);
213+
static int ahci_remove(struct platform_device *pdev)
214+
{
215+
struct device *dev = &pdev->dev;
216+
struct ahci_platform_data *pdata = dev_get_platdata(dev);
217+
struct ata_host *host = dev_get_drvdata(dev);
218+
219+
ata_host_detach(host);
220+
221+
if (pdata && pdata->exit)
222+
pdata->exit(dev);
223+
#ifdef CONFIG_ARCH_M86XXX
224+
/* Disbale the SATA clocks Here */
225+
clk_disable(sata_clk);
226+
clk_put(sata_clk);
227+
clk_disable(sata_oob_clk);
228+
clk_put(sata_oob_clk);
229+
clk_disable(sata_pmu_clk);
230+
clk_put(sata_pmu_clk);
231+
/*Putting SATA in reset state
232+
* Sata axi clock domain in reset state
233+
* Serdes 1/2 in reset state, this depends upon PCIE1 and SGMII
234+
* sata 0/1 serdes controller in reset state
235+
*/
236+
c2000_block_reset(COMPONENT_AXI_SATA,1);
237+
238+
c2000_block_reset(COMPONENT_SERDES1,1);
239+
c2000_block_reset(COMPONENT_SERDES_SATA0,1);
240+
241+
c2000_block_reset(COMPONENT_SERDES2,1);
242+
c2000_block_reset(COMPONENT_SERDES_SATA1,1);
243+
#endif
244+
245+
return 0;
246+
}
247+
248+
static SIMPLE_DEV_PM_OPS(ahci_pm_ops, sata_ahci_platform_suspend,
249+
sata_ahci_platform_resume);
177250

178251
static const struct of_device_id ahci_of_match[] = {
179252
{ .compatible = "snps,spear-ahci", },
@@ -187,13 +260,15 @@ MODULE_DEVICE_TABLE(of, ahci_of_match);
187260

188261
static struct platform_driver ahci_driver = {
189262
.probe = ahci_probe,
263+
.remove = ahci_remove,
190264
.remove = ata_platform_remove_one,
191265
.driver = {
192266
.name = "ahci",
193267
.owner = THIS_MODULE,
194268
.of_match_table = ahci_of_match,
195269
.pm = &ahci_pm_ops,
196270
},
271+
.id_table = ahci_devtype,
197272
};
198273
module_platform_driver(ahci_driver);
199274

drivers/ata/libahci_platform.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,12 @@ int ahci_platform_init_host(struct platform_device *pdev,
364364
if (ap->flags & ATA_FLAG_EM)
365365
ap->em_message_type = hpriv->em_msg_type;
366366

367+
#ifdef CONFIG_ARCH_M86XXX
368+
/* Optimized PFE/SATA DDR interaction,
369+
limit read burst size of SATA controller */
370+
writel(0x41, ahci_port_base(ap) + 0x70);
371+
#endif
372+
367373
/* disabled/not-implemented port */
368374
if (!(hpriv->port_map & (1 << i)))
369375
ap->ops = &ata_dummy_port_ops;

drivers/ata/libata-core.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2311,7 +2311,7 @@ int ata_dev_configure(struct ata_device *dev)
23112311

23122312
if (ata_id_has_lba(id)) {
23132313
const char *lba_desc;
2314-
char ncq_desc[24];
2314+
char ncq_desc[32];
23152315

23162316
lba_desc = "LBA";
23172317
dev->flags |= ATA_DFLAG_LBA;
@@ -3788,6 +3788,8 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
37883788
{
37893789
u32 scontrol;
37903790
int rc;
3791+
int try_count=0;
3792+
u32 sstatus;
37913793

37923794
DPRINTK("ENTER\n");
37933795

@@ -3811,6 +3813,8 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
38113813
sata_set_spd(link);
38123814
}
38133815

3816+
keep_trying:
3817+
38143818
/* issue phy wake/reset */
38153819
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
38163820
goto out;
@@ -3829,6 +3833,20 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
38293833
rc = sata_link_resume(link, timing, deadline);
38303834
if (rc)
38313835
goto out;
3836+
3837+
try_count++;
3838+
sata_scr_read(link, SCR_STATUS, &sstatus);
3839+
3840+
/*Few HDDs showed issue with the detection.So the WA is it to restart
3841+
the communication. The following code check the PHY status and does the
3842+
SATA port reset when it sees the PHY is not ready. Doing port reset will
3843+
invoke a COMRESET on the interface and start a re-establishment of Phy layer
3844+
communications*/
3845+
3846+
//Check if PHY not ready
3847+
if (((sstatus & 0xf) == 0x1) && (try_count < 7))
3848+
goto keep_trying;
3849+
38323850
/* if link is offline nothing more to do */
38333851
if (ata_phys_link_offline(link))
38343852
goto out;

include/linux/ahci_platform.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,14 @@ struct ata_port_info;
2222
struct ahci_host_priv;
2323
struct platform_device;
2424

25-
/*
26-
* Note ahci_platform_data is deprecated, it is only kept around for use
27-
* by the old da850 and spear13xx ahci code.
28-
* New drivers should instead declare their own platform_driver struct, and
29-
* use ahci_platform* functions in their own probe, suspend and resume methods.
30-
*/
3125
struct ahci_platform_data {
3226
int (*init)(struct device *dev, void __iomem *addr);
3327
void (*exit)(struct device *dev);
3428
int (*suspend)(struct device *dev);
3529
int (*resume)(struct device *dev);
30+
const struct ata_port_info *ata_port_info;
31+
unsigned int force_port_map;
32+
unsigned int mask_port_map;
3633
};
3734

3835
int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);

0 commit comments

Comments
 (0)