| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * AHCI SATA platform driver | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2004-2005  Red Hat, Inc. | 
					
						
							|  |  |  |  *   Jeff Garzik <jgarzik@pobox.com> | 
					
						
							|  |  |  |  * Copyright 2010  MontaVista Software, LLC. | 
					
						
							|  |  |  |  *   Anton Vorontsov <avorontsov@ru.mvista.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation; either version 2, or (at your option) | 
					
						
							|  |  |  |  * any later version. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							| 
									
										
										
										
											2012-03-16 15:49:55 +05:30
										 |  |  | #include <linux/pm.h>
 | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | #include <linux/device.h>
 | 
					
						
							| 
									
										
										
										
											2014-05-14 14:13:42 +08:00
										 |  |  | #include <linux/of_device.h>
 | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | #include <linux/platform_device.h>
 | 
					
						
							|  |  |  | #include <linux/libata.h>
 | 
					
						
							|  |  |  | #include <linux/ahci_platform.h>
 | 
					
						
							|  |  |  | #include "ahci.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-22 17:22:54 +01:00
										 |  |  | static const struct ata_port_info ahci_port_info = { | 
					
						
							|  |  |  | 	.flags		= AHCI_FLAG_COMMON, | 
					
						
							|  |  |  | 	.pio_mask	= ATA_PIO4, | 
					
						
							|  |  |  | 	.udma_mask	= ATA_UDMA6, | 
					
						
							|  |  |  | 	.port_ops	= &ahci_platform_ops, | 
					
						
							| 
									
										
										
										
											2011-09-28 15:41:54 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-22 16:53:34 +01:00
										 |  |  | static int ahci_probe(struct platform_device *pdev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct device *dev = &pdev->dev; | 
					
						
							|  |  |  | 	struct ahci_platform_data *pdata = dev_get_platdata(dev); | 
					
						
							|  |  |  | 	struct ahci_host_priv *hpriv; | 
					
						
							|  |  |  | 	int rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hpriv = ahci_platform_get_resources(pdev); | 
					
						
							|  |  |  | 	if (IS_ERR(hpriv)) | 
					
						
							|  |  |  | 		return PTR_ERR(hpriv); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rc = ahci_platform_enable_resources(hpriv); | 
					
						
							|  |  |  | 	if (rc) | 
					
						
							|  |  |  | 		return rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Some platforms might need to prepare for mmio region access, | 
					
						
							|  |  |  | 	 * which could be done in the following init call. So, the mmio | 
					
						
							|  |  |  | 	 * region shouldn't be accessed before init (if provided) has | 
					
						
							|  |  |  | 	 * returned successfully. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (pdata && pdata->init) { | 
					
						
							|  |  |  | 		rc = pdata->init(dev, hpriv->mmio); | 
					
						
							|  |  |  | 		if (rc) | 
					
						
							|  |  |  | 			goto disable_resources; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-14 14:13:42 +08:00
										 |  |  | 	if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) | 
					
						
							| 
									
										
										
										
											2014-07-30 20:13:56 +02:00
										 |  |  | 		hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; | 
					
						
							| 
									
										
										
										
											2014-05-14 14:13:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 20:13:56 +02:00
										 |  |  | 	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info); | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | 	if (rc) | 
					
						
							| 
									
										
										
										
											2012-08-27 10:37:19 +05:30
										 |  |  | 		goto pdata_exit; | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2012-08-27 10:37:19 +05:30
										 |  |  | pdata_exit: | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | 	if (pdata && pdata->exit) | 
					
						
							|  |  |  | 		pdata->exit(dev); | 
					
						
							| 
									
										
										
										
											2014-02-22 16:53:33 +01:00
										 |  |  | disable_resources: | 
					
						
							|  |  |  | 	ahci_platform_disable_resources(hpriv); | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | 	return rc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-22 16:53:35 +01:00
										 |  |  | static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, | 
					
						
							|  |  |  | 			 ahci_platform_resume); | 
					
						
							| 
									
										
										
										
											2012-03-16 15:49:55 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-03 21:04:59 -05:00
										 |  |  | static const struct of_device_id ahci_of_match[] = { | 
					
						
							| 
									
										
										
										
											2014-07-30 20:13:58 +02:00
										 |  |  | 	{ .compatible = "generic-ahci", }, | 
					
						
							|  |  |  | 	/* Keep the following compatibles for device tree compatibility */ | 
					
						
							| 
									
										
										
										
											2012-04-21 17:40:12 +05:30
										 |  |  | 	{ .compatible = "snps,spear-ahci", }, | 
					
						
							| 
									
										
										
										
											2013-04-16 14:58:02 +05:30
										 |  |  | 	{ .compatible = "snps,exynos5440-ahci", }, | 
					
						
							| 
									
										
										
										
											2013-11-22 13:08:29 +11:00
										 |  |  | 	{ .compatible = "ibm,476gtr-ahci", }, | 
					
						
							| 
									
										
										
										
											2014-02-22 16:53:38 +01:00
										 |  |  | 	{ .compatible = "snps,dwc-ahci", }, | 
					
						
							| 
									
										
										
										
											2014-05-14 14:13:42 +08:00
										 |  |  | 	{ .compatible = "hisilicon,hisi-ahci", }, | 
					
						
							| 
									
										
										
										
											2010-11-03 21:04:59 -05:00
										 |  |  | 	{}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | MODULE_DEVICE_TABLE(of, ahci_of_match); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | static struct platform_driver ahci_driver = { | 
					
						
							| 
									
										
										
										
											2012-11-02 00:46:15 -07:00
										 |  |  | 	.probe = ahci_probe, | 
					
						
							| 
									
										
										
										
											2012-11-02 00:46:19 -07:00
										 |  |  | 	.remove = ata_platform_remove_one, | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | 	.driver = { | 
					
						
							|  |  |  | 		.name = "ahci", | 
					
						
							|  |  |  | 		.owner = THIS_MODULE, | 
					
						
							| 
									
										
										
										
											2010-11-03 21:04:59 -05:00
										 |  |  | 		.of_match_table = ahci_of_match, | 
					
						
							| 
									
										
										
										
											2011-11-18 11:10:10 -08:00
										 |  |  | 		.pm = &ahci_pm_ops, | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2012-11-02 00:46:16 -07:00
										 |  |  | module_platform_driver(ahci_driver); | 
					
						
							| 
									
										
										
										
											2010-03-04 20:06:06 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | MODULE_DESCRIPTION("AHCI SATA platform driver"); | 
					
						
							|  |  |  | MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>"); | 
					
						
							|  |  |  | MODULE_LICENSE("GPL"); | 
					
						
							|  |  |  | MODULE_ALIAS("platform:ahci"); |