2323#include <linux/clk.h>
2424#include <mach/reset.h>
2525#include "ahci.h"
26+
2627#ifdef CONFIG_ARCH_M86XXX
2728/* SATA Clocks */
2829static struct clk * sata_oob_clk ; /* Core clock */
2930static struct clk * sata_pmu_clk ; /* PMU alive clock */
3031static 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
82111static 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
178251static 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
188261static 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};
198273module_platform_driver (ahci_driver );
199274
0 commit comments