sunxi: driver refresh for 3.13
[openwrt.git] / target / linux / sunxi / patches-3.13 / 160-9-ahci-plat-libraryise-suspend-resume.patch
1 From 041cf8356a4eb91ee8118004b2bc9c78cdd7866c Mon Sep 17 00:00:00 2001
2 From: Hans de Goede <hdegoede@redhat.com>
3 Date: Mon, 20 Jan 2014 15:52:07 +0100
4 Subject: [PATCH] ahci-platform: "Library-ise" suspend / resume functionality
5
6 Split suspend / resume code into host suspend / resume functionality and
7 resource enable / disabling phases, and export the new suspend_ / resume_host
8 functions.
9
10 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
11 ---
12  drivers/ata/ahci_platform.c   | 109 ++++++++++++++++++++++++++++++++++++------
13  include/linux/ahci_platform.h |   5 ++
14  2 files changed, 99 insertions(+), 15 deletions(-)
15
16 diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
17 index 7f3f2ac..bdadec1 100644
18 --- a/drivers/ata/ahci_platform.c
19 +++ b/drivers/ata/ahci_platform.c
20 @@ -452,14 +452,26 @@ static void ahci_host_stop(struct ata_host *host)
21  }
22  
23  #ifdef CONFIG_PM_SLEEP
24 -static int ahci_suspend(struct device *dev)
25 +/**
26 + *     ahci_platform_suspend_host - Suspend an ahci-platform host
27 + *     @dev: device pointer for the host
28 + *
29 + *     This function does all the usual steps needed to suspend an
30 + *     ahci-platform host, note any necessary resources (ie clks, phy, etc.)
31 + *     must be disabled after calling this.
32 + *
33 + *     LOCKING:
34 + *     None.
35 + *
36 + *     RETURNS:
37 + *     0 on success otherwise a negative error code
38 + */
39 +int ahci_platform_suspend_host(struct device *dev)
40  {
41 -       struct ahci_platform_data *pdata = dev_get_platdata(dev);
42         struct ata_host *host = dev_get_drvdata(dev);
43         struct ahci_host_priv *hpriv = host->private_data;
44         void __iomem *mmio = hpriv->mmio;
45         u32 ctl;
46 -       int rc;
47  
48         if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
49                 dev_err(dev, "firmware update required for suspend/resume\n");
50 @@ -476,7 +488,64 @@ static int ahci_suspend(struct device *dev)
51         writel(ctl, mmio + HOST_CTL);
52         readl(mmio + HOST_CTL); /* flush */
53  
54 -       rc = ata_host_suspend(host, PMSG_SUSPEND);
55 +       return ata_host_suspend(host, PMSG_SUSPEND);
56 +}
57 +EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
58 +
59 +/**
60 + *     ahci_platform_resume_host - Resume an ahci-platform host
61 + *     @dev: device pointer for the host
62 + *
63 + *     This function does all the usual steps needed to resume an
64 + *     ahci-platform host, note any necessary resources (ie clks, phy, etc.)
65 + *     must be initialized / enabled before calling this.
66 + *
67 + *     LOCKING:
68 + *     None.
69 + *
70 + *     RETURNS:
71 + *     0 on success otherwise a negative error code
72 + */
73 +int ahci_platform_resume_host(struct device *dev)
74 +{
75 +       struct ata_host *host = dev_get_drvdata(dev);
76 +       int rc;
77 +
78 +       if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
79 +               rc = ahci_reset_controller(host);
80 +               if (rc)
81 +                       return rc;
82 +
83 +               ahci_init_controller(host);
84 +       }
85 +
86 +       ata_host_resume(host);
87 +
88 +       return 0;
89 +}
90 +EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
91 +
92 +/**
93 + *     ahci_platform_suspend - Suspend an ahci-platform device
94 + *     @dev: the platform device to suspend
95 + *
96 + *     This function suspends the host associated with the device, followed
97 + *     by disabling all the resources of the device.
98 + *
99 + *     LOCKING:
100 + *     None.
101 + *
102 + *     RETURNS:
103 + *     0 on success otherwise a negative error code
104 + */
105 +int ahci_platform_suspend(struct device *dev)
106 +{
107 +       struct ahci_platform_data *pdata = dev_get_platdata(dev);
108 +       struct ata_host *host = dev_get_drvdata(dev);
109 +       struct ahci_host_priv *hpriv = host->private_data;
110 +       int rc;
111 +
112 +       rc = ahci_platform_suspend_host(dev);
113         if (rc)
114                 return rc;
115  
116 @@ -487,8 +556,22 @@ static int ahci_suspend(struct device *dev)
117  
118         return 0;
119  }
120 +EXPORT_SYMBOL_GPL(ahci_platform_suspend);
121  
122 -static int ahci_resume(struct device *dev)
123 +/**
124 + *     ahci_platform_resume - Resume an ahci-platform device
125 + *     @dev: the platform device to resume
126 + *
127 + *     This function enables all the resources of the device followed by
128 + *     resuming the host associated with the device.
129 + *
130 + *     LOCKING:
131 + *     None.
132 + *
133 + *     RETURNS:
134 + *     0 on success otherwise a negative error code
135 + */
136 +int ahci_platform_resume(struct device *dev)
137  {
138         struct ahci_platform_data *pdata = dev_get_platdata(dev);
139         struct ata_host *host = dev_get_drvdata(dev);
140 @@ -505,15 +588,9 @@ static int ahci_resume(struct device *dev)
141                         goto disable_resources;
142         }
143  
144 -       if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
145 -               rc = ahci_reset_controller(host);
146 -               if (rc)
147 -                       goto disable_resources;
148 -
149 -               ahci_init_controller(host);
150 -       }
151 -
152 -       ata_host_resume(host);
153 +       rc = ahci_platform_resume_host(dev);
154 +       if (rc)
155 +               goto disable_resources;
156  
157         return 0;
158  
159 @@ -522,9 +599,11 @@ static int ahci_resume(struct device *dev)
160  
161         return rc;
162  }
163 +EXPORT_SYMBOL_GPL(ahci_platform_resume);
164  #endif
165  
166 -static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
167 +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
168 +                        ahci_platform_resume);
169  
170  static const struct of_device_id ahci_of_match[] = {
171         { .compatible = "snps,spear-ahci", },
172 diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
173 index b80c51c..542f268 100644
174 --- a/include/linux/ahci_platform.h
175 +++ b/include/linux/ahci_platform.h
176 @@ -50,4 +50,9 @@ int ahci_platform_init_host(struct platform_device *pdev,
177                             unsigned int force_port_map,
178                             unsigned int mask_port_map);
179  
180 +int ahci_platform_suspend_host(struct device *dev);
181 +int ahci_platform_resume_host(struct device *dev);
182 +int ahci_platform_suspend(struct device *dev);
183 +int ahci_platform_resume(struct device *dev);
184 +
185  #endif /* _AHCI_PLATFORM_H */
186 -- 
187 1.8.5.5
188