aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2015-01-28 18:30:29 -0500
committerTejun Heo <tj@kernel.org>2015-01-28 18:45:23 -0500
commit018d5ef2048fcab339467bcbebccf588c9bd2531 (patch)
tree3f6acefe4dc0799f07a100a66b4b3eceb1087fab
parentcedda4c3b1ded2cc4951aeca38fdf862b9b79fb6 (diff)
ata: ahci_platform: fix owner module reference mismatch for scsi host
The owner module reference of the ahci platform's scsi_host is initialized to libahci_platform's one, because these drivers use a scsi_host_template defined in libahci_platform. So these drivers can be unloaded even if the scsi device is being accessed. This fixes it by pushing the scsi_host_template from libahci_platform to all leaf drivers. The scsi_host_template is passed through a new argument of ahci_platform_init_host(). Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Hans de Goede <hdegoede@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: "James E.J. Bottomley" <JBottomley@parallels.com> Cc: linux-ide@vger.kernel.org Cc: linux-scsi@vger.kernel.org
-rw-r--r--drivers/ata/ahci.h4
-rw-r--r--drivers/ata/ahci_da850.c11
-rw-r--r--drivers/ata/ahci_imx.c11
-rw-r--r--drivers/ata/ahci_mvebu.c11
-rw-r--r--drivers/ata/ahci_platform.c11
-rw-r--r--drivers/ata/ahci_st.c11
-rw-r--r--drivers/ata/ahci_sunxi.c11
-rw-r--r--drivers/ata/ahci_tegra.c11
-rw-r--r--drivers/ata/ahci_xgene.c11
-rw-r--r--drivers/ata/libahci_platform.c10
-rw-r--r--include/linux/ahci_platform.h4
-rw-r--r--include/linux/libata.h6
12 files changed, 89 insertions, 23 deletions
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 275358ae0b3f..71262e08648e 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -354,6 +354,10 @@ extern int ahci_ignore_sss;
354extern struct device_attribute *ahci_shost_attrs[]; 354extern struct device_attribute *ahci_shost_attrs[];
355extern struct device_attribute *ahci_sdev_attrs[]; 355extern struct device_attribute *ahci_sdev_attrs[];
356 356
357/*
358 * This must be instantiated by the edge drivers. Read the comments
359 * for ATA_BASE_SHT
360 */
357#define AHCI_SHT(drv_name) \ 361#define AHCI_SHT(drv_name) \
358 ATA_NCQ_SHT(drv_name), \ 362 ATA_NCQ_SHT(drv_name), \
359 .can_queue = AHCI_MAX_CMDS - 1, \ 363 .can_queue = AHCI_MAX_CMDS - 1, \
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index ce8a7a6d6c7f..267a3d3e79f4 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -16,6 +16,8 @@
16#include <linux/ahci_platform.h> 16#include <linux/ahci_platform.h>
17#include "ahci.h" 17#include "ahci.h"
18 18
19#define DRV_NAME "ahci_da850"
20
19/* SATA PHY Control Register offset from AHCI base */ 21/* SATA PHY Control Register offset from AHCI base */
20#define SATA_P0PHYCR_REG 0x178 22#define SATA_P0PHYCR_REG 0x178
21 23
@@ -59,6 +61,10 @@ static const struct ata_port_info ahci_da850_port_info = {
59 .port_ops = &ahci_platform_ops, 61 .port_ops = &ahci_platform_ops,
60}; 62};
61 63
64static struct scsi_host_template ahci_platform_sht = {
65 AHCI_SHT(DRV_NAME),
66};
67
62static int ahci_da850_probe(struct platform_device *pdev) 68static int ahci_da850_probe(struct platform_device *pdev)
63{ 69{
64 struct device *dev = &pdev->dev; 70 struct device *dev = &pdev->dev;
@@ -85,7 +91,8 @@ static int ahci_da850_probe(struct platform_device *pdev)
85 91
86 da850_sata_init(dev, pwrdn_reg, hpriv->mmio); 92 da850_sata_init(dev, pwrdn_reg, hpriv->mmio);
87 93
88 rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info); 94 rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
95 &ahci_platform_sht);
89 if (rc) 96 if (rc)
90 goto disable_resources; 97 goto disable_resources;
91 98
@@ -102,7 +109,7 @@ static struct platform_driver ahci_da850_driver = {
102 .probe = ahci_da850_probe, 109 .probe = ahci_da850_probe,
103 .remove = ata_platform_remove_one, 110 .remove = ata_platform_remove_one,
104 .driver = { 111 .driver = {
105 .name = "ahci_da850", 112 .name = DRV_NAME,
106 .pm = &ahci_da850_pm_ops, 113 .pm = &ahci_da850_pm_ops,
107 }, 114 },
108}; 115};
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 41632e57d46f..3f3a7db208ae 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -28,6 +28,8 @@
28#include <linux/libata.h> 28#include <linux/libata.h>
29#include "ahci.h" 29#include "ahci.h"
30 30
31#define DRV_NAME "ahci-imx"
32
31enum { 33enum {
32 /* Timer 1-ms Register */ 34 /* Timer 1-ms Register */
33 IMX_TIMER1MS = 0x00e0, 35 IMX_TIMER1MS = 0x00e0,
@@ -520,6 +522,10 @@ static u32 imx_ahci_parse_props(struct device *dev,
520 return reg_value; 522 return reg_value;
521} 523}
522 524
525static struct scsi_host_template ahci_platform_sht = {
526 AHCI_SHT(DRV_NAME),
527};
528
523static int imx_ahci_probe(struct platform_device *pdev) 529static int imx_ahci_probe(struct platform_device *pdev)
524{ 530{
525 struct device *dev = &pdev->dev; 531 struct device *dev = &pdev->dev;
@@ -616,7 +622,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
616 reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; 622 reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
617 writel(reg_val, hpriv->mmio + IMX_TIMER1MS); 623 writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
618 624
619 ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info); 625 ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
626 &ahci_platform_sht);
620 if (ret) 627 if (ret)
621 goto disable_sata; 628 goto disable_sata;
622 629
@@ -674,7 +681,7 @@ static struct platform_driver imx_ahci_driver = {
674 .probe = imx_ahci_probe, 681 .probe = imx_ahci_probe,
675 .remove = ata_platform_remove_one, 682 .remove = ata_platform_remove_one,
676 .driver = { 683 .driver = {
677 .name = "ahci-imx", 684 .name = DRV_NAME,
678 .of_match_table = imx_ahci_of_match, 685 .of_match_table = imx_ahci_of_match,
679 .pm = &ahci_imx_pm_ops, 686 .pm = &ahci_imx_pm_ops,
680 }, 687 },
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c
index 64bb08432b69..23716dd8a7ec 100644
--- a/drivers/ata/ahci_mvebu.c
+++ b/drivers/ata/ahci_mvebu.c
@@ -19,6 +19,8 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include "ahci.h" 20#include "ahci.h"
21 21
22#define DRV_NAME "ahci-mvebu"
23
22#define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0 24#define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0
23#define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4 25#define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4
24 26
@@ -67,6 +69,10 @@ static const struct ata_port_info ahci_mvebu_port_info = {
67 .port_ops = &ahci_platform_ops, 69 .port_ops = &ahci_platform_ops,
68}; 70};
69 71
72static struct scsi_host_template ahci_platform_sht = {
73 AHCI_SHT(DRV_NAME),
74};
75
70static int ahci_mvebu_probe(struct platform_device *pdev) 76static int ahci_mvebu_probe(struct platform_device *pdev)
71{ 77{
72 struct ahci_host_priv *hpriv; 78 struct ahci_host_priv *hpriv;
@@ -88,7 +94,8 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
88 ahci_mvebu_mbus_config(hpriv, dram); 94 ahci_mvebu_mbus_config(hpriv, dram);
89 ahci_mvebu_regret_option(hpriv); 95 ahci_mvebu_regret_option(hpriv);
90 96
91 rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info); 97 rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info,
98 &ahci_platform_sht);
92 if (rc) 99 if (rc)
93 goto disable_resources; 100 goto disable_resources;
94 101
@@ -114,7 +121,7 @@ static struct platform_driver ahci_mvebu_driver = {
114 .probe = ahci_mvebu_probe, 121 .probe = ahci_mvebu_probe,
115 .remove = ata_platform_remove_one, 122 .remove = ata_platform_remove_one,
116 .driver = { 123 .driver = {
117 .name = "ahci-mvebu", 124 .name = DRV_NAME,
118 .of_match_table = ahci_mvebu_of_match, 125 .of_match_table = ahci_mvebu_of_match,
119 }, 126 },
120}; 127};
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 18d539837045..78d6ae0b90c4 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -22,6 +22,8 @@
22#include <linux/ahci_platform.h> 22#include <linux/ahci_platform.h>
23#include "ahci.h" 23#include "ahci.h"
24 24
25#define DRV_NAME "ahci"
26
25static const struct ata_port_info ahci_port_info = { 27static const struct ata_port_info ahci_port_info = {
26 .flags = AHCI_FLAG_COMMON, 28 .flags = AHCI_FLAG_COMMON,
27 .pio_mask = ATA_PIO4, 29 .pio_mask = ATA_PIO4,
@@ -29,6 +31,10 @@ static const struct ata_port_info ahci_port_info = {
29 .port_ops = &ahci_platform_ops, 31 .port_ops = &ahci_platform_ops,
30}; 32};
31 33
34static struct scsi_host_template ahci_platform_sht = {
35 AHCI_SHT(DRV_NAME),
36};
37
32static int ahci_probe(struct platform_device *pdev) 38static int ahci_probe(struct platform_device *pdev)
33{ 39{
34 struct device *dev = &pdev->dev; 40 struct device *dev = &pdev->dev;
@@ -46,7 +52,8 @@ static int ahci_probe(struct platform_device *pdev)
46 if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) 52 if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
47 hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; 53 hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
48 54
49 rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info); 55 rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
56 &ahci_platform_sht);
50 if (rc) 57 if (rc)
51 goto disable_resources; 58 goto disable_resources;
52 59
@@ -75,7 +82,7 @@ static struct platform_driver ahci_driver = {
75 .probe = ahci_probe, 82 .probe = ahci_probe,
76 .remove = ata_platform_remove_one, 83 .remove = ata_platform_remove_one,
77 .driver = { 84 .driver = {
78 .name = "ahci", 85 .name = DRV_NAME,
79 .of_match_table = ahci_of_match, 86 .of_match_table = ahci_of_match,
80 .pm = &ahci_pm_ops, 87 .pm = &ahci_pm_ops,
81 }, 88 },
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c
index 2f9e8317cc16..bc971af262e7 100644
--- a/drivers/ata/ahci_st.c
+++ b/drivers/ata/ahci_st.c
@@ -23,6 +23,8 @@
23 23
24#include "ahci.h" 24#include "ahci.h"
25 25
26#define DRV_NAME "st_ahci"
27
26#define ST_AHCI_OOBR 0xbc 28#define ST_AHCI_OOBR 0xbc
27#define ST_AHCI_OOBR_WE BIT(31) 29#define ST_AHCI_OOBR_WE BIT(31)
28#define ST_AHCI_OOBR_CWMIN_SHIFT 24 30#define ST_AHCI_OOBR_CWMIN_SHIFT 24
@@ -140,6 +142,10 @@ static const struct ata_port_info st_ahci_port_info = {
140 .port_ops = &st_ahci_port_ops, 142 .port_ops = &st_ahci_port_ops,
141}; 143};
142 144
145static struct scsi_host_template ahci_platform_sht = {
146 AHCI_SHT(DRV_NAME),
147};
148
143static int st_ahci_probe(struct platform_device *pdev) 149static int st_ahci_probe(struct platform_device *pdev)
144{ 150{
145 struct st_ahci_drv_data *drv_data; 151 struct st_ahci_drv_data *drv_data;
@@ -166,7 +172,8 @@ static int st_ahci_probe(struct platform_device *pdev)
166 if (err) 172 if (err)
167 return err; 173 return err;
168 174
169 err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info); 175 err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
176 &ahci_platform_sht);
170 if (err) { 177 if (err) {
171 ahci_platform_disable_resources(hpriv); 178 ahci_platform_disable_resources(hpriv);
172 return err; 179 return err;
@@ -229,7 +236,7 @@ MODULE_DEVICE_TABLE(of, st_ahci_match);
229 236
230static struct platform_driver st_ahci_driver = { 237static struct platform_driver st_ahci_driver = {
231 .driver = { 238 .driver = {
232 .name = "st_ahci", 239 .name = DRV_NAME,
233 .pm = &st_ahci_pm_ops, 240 .pm = &st_ahci_pm_ops,
234 .of_match_table = of_match_ptr(st_ahci_match), 241 .of_match_table = of_match_ptr(st_ahci_match),
235 }, 242 },
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
index e2e0da539a2f..b26437430163 100644
--- a/drivers/ata/ahci_sunxi.c
+++ b/drivers/ata/ahci_sunxi.c
@@ -27,6 +27,8 @@
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include "ahci.h" 28#include "ahci.h"
29 29
30#define DRV_NAME "ahci-sunxi"
31
30/* Insmod parameters */ 32/* Insmod parameters */
31static bool enable_pmp; 33static bool enable_pmp;
32module_param(enable_pmp, bool, 0); 34module_param(enable_pmp, bool, 0);
@@ -169,6 +171,10 @@ static const struct ata_port_info ahci_sunxi_port_info = {
169 .port_ops = &ahci_platform_ops, 171 .port_ops = &ahci_platform_ops,
170}; 172};
171 173
174static struct scsi_host_template ahci_platform_sht = {
175 AHCI_SHT(DRV_NAME),
176};
177
172static int ahci_sunxi_probe(struct platform_device *pdev) 178static int ahci_sunxi_probe(struct platform_device *pdev)
173{ 179{
174 struct device *dev = &pdev->dev; 180 struct device *dev = &pdev->dev;
@@ -200,7 +206,8 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
200 if (!enable_pmp) 206 if (!enable_pmp)
201 hpriv->flags |= AHCI_HFLAG_NO_PMP; 207 hpriv->flags |= AHCI_HFLAG_NO_PMP;
202 208
203 rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info); 209 rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info,
210 &ahci_platform_sht);
204 if (rc) 211 if (rc)
205 goto disable_resources; 212 goto disable_resources;
206 213
@@ -251,7 +258,7 @@ static struct platform_driver ahci_sunxi_driver = {
251 .probe = ahci_sunxi_probe, 258 .probe = ahci_sunxi_probe,
252 .remove = ata_platform_remove_one, 259 .remove = ata_platform_remove_one,
253 .driver = { 260 .driver = {
254 .name = "ahci-sunxi", 261 .name = DRV_NAME,
255 .of_match_table = ahci_sunxi_of_match, 262 .of_match_table = ahci_sunxi_of_match,
256 .pm = &ahci_sunxi_pm_ops, 263 .pm = &ahci_sunxi_pm_ops,
257 }, 264 },
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index 032904402c95..3a62eb246d80 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -31,6 +31,8 @@
31 31
32#include "ahci.h" 32#include "ahci.h"
33 33
34#define DRV_NAME "tegra-ahci"
35
34#define SATA_CONFIGURATION_0 0x180 36#define SATA_CONFIGURATION_0 0x180
35#define SATA_CONFIGURATION_EN_FPCI BIT(0) 37#define SATA_CONFIGURATION_EN_FPCI BIT(0)
36 38
@@ -289,6 +291,10 @@ static const struct of_device_id tegra_ahci_of_match[] = {
289}; 291};
290MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); 292MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
291 293
294static struct scsi_host_template ahci_platform_sht = {
295 AHCI_SHT(DRV_NAME),
296};
297
292static int tegra_ahci_probe(struct platform_device *pdev) 298static int tegra_ahci_probe(struct platform_device *pdev)
293{ 299{
294 struct ahci_host_priv *hpriv; 300 struct ahci_host_priv *hpriv;
@@ -354,7 +360,8 @@ static int tegra_ahci_probe(struct platform_device *pdev)
354 if (ret) 360 if (ret)
355 return ret; 361 return ret;
356 362
357 ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info); 363 ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
364 &ahci_platform_sht);
358 if (ret) 365 if (ret)
359 goto deinit_controller; 366 goto deinit_controller;
360 367
@@ -370,7 +377,7 @@ static struct platform_driver tegra_ahci_driver = {
370 .probe = tegra_ahci_probe, 377 .probe = tegra_ahci_probe,
371 .remove = ata_platform_remove_one, 378 .remove = ata_platform_remove_one,
372 .driver = { 379 .driver = {
373 .name = "tegra-ahci", 380 .name = DRV_NAME,
374 .of_match_table = tegra_ahci_of_match, 381 .of_match_table = tegra_ahci_of_match,
375 }, 382 },
376 /* LP0 suspend support not implemented */ 383 /* LP0 suspend support not implemented */
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index 7f6887535c1e..e3b8750e8e9d 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -30,6 +30,8 @@
30#include <linux/phy/phy.h> 30#include <linux/phy/phy.h>
31#include "ahci.h" 31#include "ahci.h"
32 32
33#define DRV_NAME "xgene-ahci"
34
33/* Max # of disk per a controller */ 35/* Max # of disk per a controller */
34#define MAX_AHCI_CHN_PERCTR 2 36#define MAX_AHCI_CHN_PERCTR 2
35 37
@@ -621,6 +623,10 @@ static int xgene_ahci_mux_select(struct xgene_ahci_context *ctx)
621 return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0; 623 return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0;
622} 624}
623 625
626static struct scsi_host_template ahci_platform_sht = {
627 AHCI_SHT(DRV_NAME),
628};
629
624static int xgene_ahci_probe(struct platform_device *pdev) 630static int xgene_ahci_probe(struct platform_device *pdev)
625{ 631{
626 struct device *dev = &pdev->dev; 632 struct device *dev = &pdev->dev;
@@ -698,7 +704,8 @@ static int xgene_ahci_probe(struct platform_device *pdev)
698skip_clk_phy: 704skip_clk_phy:
699 hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ; 705 hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ;
700 706
701 rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info); 707 rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info,
708 &ahci_platform_sht);
702 if (rc) 709 if (rc)
703 goto disable_resources; 710 goto disable_resources;
704 711
@@ -720,7 +727,7 @@ static struct platform_driver xgene_ahci_driver = {
720 .probe = xgene_ahci_probe, 727 .probe = xgene_ahci_probe,
721 .remove = ata_platform_remove_one, 728 .remove = ata_platform_remove_one,
722 .driver = { 729 .driver = {
723 .name = "xgene-ahci", 730 .name = DRV_NAME,
724 .of_match_table = xgene_ahci_of_match, 731 .of_match_table = xgene_ahci_of_match,
725 }, 732 },
726}; 733};
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index 504d534ccbfe..077c7a261354 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -35,10 +35,6 @@ struct ata_port_operations ahci_platform_ops = {
35}; 35};
36EXPORT_SYMBOL_GPL(ahci_platform_ops); 36EXPORT_SYMBOL_GPL(ahci_platform_ops);
37 37
38static struct scsi_host_template ahci_platform_sht = {
39 AHCI_SHT("ahci_platform"),
40};
41
42/** 38/**
43 * ahci_platform_enable_phys - Enable PHYs 39 * ahci_platform_enable_phys - Enable PHYs
44 * @hpriv: host private area to store config values 40 * @hpriv: host private area to store config values
@@ -494,6 +490,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
494 * @pdev: platform device pointer for the host 490 * @pdev: platform device pointer for the host
495 * @hpriv: ahci-host private data for the host 491 * @hpriv: ahci-host private data for the host
496 * @pi_template: template for the ata_port_info to use 492 * @pi_template: template for the ata_port_info to use
493 * @sht: scsi_host_template to use when registering
497 * 494 *
498 * This function does all the usual steps needed to bring up an 495 * This function does all the usual steps needed to bring up an
499 * ahci-platform host, note any necessary resources (ie clks, phys, etc.) 496 * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
@@ -504,7 +501,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
504 */ 501 */
505int ahci_platform_init_host(struct platform_device *pdev, 502int ahci_platform_init_host(struct platform_device *pdev,
506 struct ahci_host_priv *hpriv, 503 struct ahci_host_priv *hpriv,
507 const struct ata_port_info *pi_template) 504 const struct ata_port_info *pi_template,
505 struct scsi_host_template *sht)
508{ 506{
509 struct device *dev = &pdev->dev; 507 struct device *dev = &pdev->dev;
510 struct ata_port_info pi = *pi_template; 508 struct ata_port_info pi = *pi_template;
@@ -588,7 +586,7 @@ int ahci_platform_init_host(struct platform_device *pdev,
588 ahci_init_controller(host); 586 ahci_init_controller(host);
589 ahci_print_info(host, "platform"); 587 ahci_print_info(host, "platform");
590 588
591 return ahci_host_activate(host, irq, &ahci_platform_sht); 589 return ahci_host_activate(host, irq, sht);
592} 590}
593EXPORT_SYMBOL_GPL(ahci_platform_init_host); 591EXPORT_SYMBOL_GPL(ahci_platform_init_host);
594 592
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index f65b33809170..a270f25ee7c7 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -21,6 +21,7 @@ struct device;
21struct ata_port_info; 21struct ata_port_info;
22struct ahci_host_priv; 22struct ahci_host_priv;
23struct platform_device; 23struct platform_device;
24struct scsi_host_template;
24 25
25int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); 26int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
26void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); 27void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
@@ -32,7 +33,8 @@ struct ahci_host_priv *ahci_platform_get_resources(
32 struct platform_device *pdev); 33 struct platform_device *pdev);
33int ahci_platform_init_host(struct platform_device *pdev, 34int ahci_platform_init_host(struct platform_device *pdev,
34 struct ahci_host_priv *hpriv, 35 struct ahci_host_priv *hpriv,
35 const struct ata_port_info *pi_template); 36 const struct ata_port_info *pi_template,
37 struct scsi_host_template *sht);
36 38
37int ahci_platform_suspend_host(struct device *dev); 39int ahci_platform_suspend_host(struct device *dev);
38int ahci_platform_resume_host(struct device *dev); 40int ahci_platform_resume_host(struct device *dev);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 2d182413b1db..11beb4196c32 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1338,6 +1338,12 @@ extern const struct ata_port_operations ata_base_port_ops;
1338extern const struct ata_port_operations sata_port_ops; 1338extern const struct ata_port_operations sata_port_ops;
1339extern struct device_attribute *ata_common_sdev_attrs[]; 1339extern struct device_attribute *ata_common_sdev_attrs[];
1340 1340
1341/*
1342 * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated
1343 * by the edge drivers. Because the 'module' field of sht must be the
1344 * edge driver's module reference, otherwise the driver can be unloaded
1345 * even if the scsi_device is being accessed.
1346 */
1341#define ATA_BASE_SHT(drv_name) \ 1347#define ATA_BASE_SHT(drv_name) \
1342 .module = THIS_MODULE, \ 1348 .module = THIS_MODULE, \
1343 .name = drv_name, \ 1349 .name = drv_name, \