aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJassi Brar <jassi.brar@samsung.com>2010-06-25 05:21:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-08-01 19:36:03 -0400
commit08354809d6c73eb73973e132502a0a4e53250971 (patch)
treed76f493238c989fd38b226a186752f6e9e8de5ca
parent9fe6206f400646a2322096b56c59891d530e8d51 (diff)
ahci_platform: Provide for vendor specific init
Some AHCI implementations may use Vendor Specific HBA[A0h, FFh] and/or Port[70h, 7Fh] registers to 'prepare' for initialization. For that, the platform needs memory mapped address of AHCI registers. This patch adds the 'mmio' argument and reorders the call to platform init function. Signed-off-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/ahci_platform.c25
-rw-r--r--include/linux/ahci_platform.h4
2 files changed, 18 insertions, 11 deletions
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 5e11b160f247..68ef6b563b7d 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -54,19 +54,13 @@ static int __init ahci_probe(struct platform_device *pdev)
54 return -EINVAL; 54 return -EINVAL;
55 } 55 }
56 56
57 if (pdata && pdata->init) {
58 rc = pdata->init(dev);
59 if (rc)
60 return rc;
61 }
62
63 if (pdata && pdata->ata_port_info) 57 if (pdata && pdata->ata_port_info)
64 pi = *pdata->ata_port_info; 58 pi = *pdata->ata_port_info;
65 59
66 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 60 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
67 if (!hpriv) { 61 if (!hpriv) {
68 rc = -ENOMEM; 62 dev_err(dev, "can't alloc ahci_host_priv\n");
69 goto err0; 63 return -ENOMEM;
70 } 64 }
71 65
72 hpriv->flags |= (unsigned long)pi.private_data; 66 hpriv->flags |= (unsigned long)pi.private_data;
@@ -74,8 +68,19 @@ static int __init ahci_probe(struct platform_device *pdev)
74 hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); 68 hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
75 if (!hpriv->mmio) { 69 if (!hpriv->mmio) {
76 dev_err(dev, "can't map %pR\n", mem); 70 dev_err(dev, "can't map %pR\n", mem);
77 rc = -ENOMEM; 71 return -ENOMEM;
78 goto err0; 72 }
73
74 /*
75 * Some platforms might need to prepare for mmio region access,
76 * which could be done in the following init call. So, the mmio
77 * region shouldn't be accessed before init (if provided) has
78 * returned successfully.
79 */
80 if (pdata && pdata->init) {
81 rc = pdata->init(dev, hpriv->mmio);
82 if (rc)
83 return rc;
79 } 84 }
80 85
81 ahci_save_initial_config(dev, hpriv, 86 ahci_save_initial_config(dev, hpriv,
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index f7dd576dd5a4..be3d9a77d6ed 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -15,11 +15,13 @@
15#ifndef _AHCI_PLATFORM_H 15#ifndef _AHCI_PLATFORM_H
16#define _AHCI_PLATFORM_H 16#define _AHCI_PLATFORM_H
17 17
18#include <linux/compiler.h>
19
18struct device; 20struct device;
19struct ata_port_info; 21struct ata_port_info;
20 22
21struct ahci_platform_data { 23struct ahci_platform_data {
22 int (*init)(struct device *dev); 24 int (*init)(struct device *dev, void __iomem *addr);
23 void (*exit)(struct device *dev); 25 void (*exit)(struct device *dev);
24 const struct ata_port_info *ata_port_info; 26 const struct ata_port_info *ata_port_info;
25 unsigned int force_port_map; 27 unsigned int force_port_map;