19e9eaafb1f2ad9c25a93be60bc12cd05bad3afd
[linux-2.6-block.git] / drivers / ata / ahci_platform.c
1 /*
2  * AHCI SATA platform driver
3  *
4  * Copyright 2004-2005  Red Hat, Inc.
5  *   Jeff Garzik <jgarzik@pobox.com>
6  * Copyright 2010  MontaVista Software, LLC.
7  *   Anton Vorontsov <avorontsov@ru.mvista.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2, or (at your option)
12  * any later version.
13  */
14
15 #include <linux/clk.h>
16 #include <linux/kernel.h>
17 #include <linux/gfp.h>
18 #include <linux/module.h>
19 #include <linux/pm.h>
20 #include <linux/interrupt.h>
21 #include <linux/device.h>
22 #include <linux/platform_device.h>
23 #include <linux/libata.h>
24 #include <linux/ahci_platform.h>
25 #include "ahci.h"
26
27 static void ahci_host_stop(struct ata_host *host);
28
29 enum ahci_type {
30         AHCI,           /* standard platform ahci */
31         IMX53_AHCI,     /* ahci on i.mx53 */
32         STRICT_AHCI,    /* delayed DMA engine start */
33 };
34
35 static struct platform_device_id ahci_devtype[] = {
36         {
37                 .name = "ahci",
38                 .driver_data = AHCI,
39         }, {
40                 .name = "imx53-ahci",
41                 .driver_data = IMX53_AHCI,
42         }, {
43                 .name = "strict-ahci",
44                 .driver_data = STRICT_AHCI,
45         }, {
46                 /* sentinel */
47         }
48 };
49 MODULE_DEVICE_TABLE(platform, ahci_devtype);
50
51 struct ata_port_operations ahci_platform_ops = {
52         .inherits       = &ahci_ops,
53         .host_stop      = ahci_host_stop,
54 };
55 EXPORT_SYMBOL_GPL(ahci_platform_ops);
56
57 static struct ata_port_operations ahci_platform_retry_srst_ops = {
58         .inherits       = &ahci_pmp_retry_srst_ops,
59         .host_stop      = ahci_host_stop,
60 };
61
62 static const struct ata_port_info ahci_port_info[] = {
63         /* by features */
64         [AHCI] = {
65                 .flags          = AHCI_FLAG_COMMON,
66                 .pio_mask       = ATA_PIO4,
67                 .udma_mask      = ATA_UDMA6,
68                 .port_ops       = &ahci_platform_ops,
69         },
70         [IMX53_AHCI] = {
71                 .flags          = AHCI_FLAG_COMMON,
72                 .pio_mask       = ATA_PIO4,
73                 .udma_mask      = ATA_UDMA6,
74                 .port_ops       = &ahci_platform_retry_srst_ops,
75         },
76         [STRICT_AHCI] = {
77                 AHCI_HFLAGS     (AHCI_HFLAG_DELAY_ENGINE),
78                 .flags          = AHCI_FLAG_COMMON,
79                 .pio_mask       = ATA_PIO4,
80                 .udma_mask      = ATA_UDMA6,
81                 .port_ops       = &ahci_platform_ops,
82         },
83 };
84
85 static struct scsi_host_template ahci_platform_sht = {
86         AHCI_SHT("ahci_platform"),
87 };
88
89 /**
90  * ahci_platform_enable_clks - Enable platform clocks
91  * @hpriv: host private area to store config values
92  *
93  * This function enables all the clks found in hpriv->clks, starting at
94  * index 0. If any clk fails to enable it disables all the clks already
95  * enabled in reverse order, and then returns an error.
96  *
97  * RETURNS:
98  * 0 on success otherwise a negative error code
99  */
100 int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
101 {
102         int c, rc;
103
104         for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
105                 rc = clk_prepare_enable(hpriv->clks[c]);
106                 if (rc)
107                         goto disable_unprepare_clk;
108         }
109         return 0;
110
111 disable_unprepare_clk:
112         while (--c >= 0)
113                 clk_disable_unprepare(hpriv->clks[c]);
114         return rc;
115 }
116 EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
117
118 /**
119  * ahci_platform_disable_clks - Disable platform clocks
120  * @hpriv: host private area to store config values
121  *
122  * This function disables all the clks found in hpriv->clks, in reverse
123  * order of ahci_platform_enable_clks (starting at the end of the array).
124  */
125 void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
126 {
127         int c;
128
129         for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
130                 if (hpriv->clks[c])
131                         clk_disable_unprepare(hpriv->clks[c]);
132 }
133 EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
134
135 /**
136  * ahci_platform_enable_resources - Enable platform resources
137  * @hpriv: host private area to store config values
138  *
139  * This function enables all ahci_platform managed resources in the
140  * following order:
141  * 1) Regulator
142  * 2) Clocks (through ahci_platform_enable_clks)
143  *
144  * If resource enabling fails at any point the previous enabled resources
145  * are disabled in reverse order.
146  *
147  * RETURNS:
148  * 0 on success otherwise a negative error code
149  */
150 int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
151 {
152         int rc;
153
154         if (hpriv->target_pwr) {
155                 rc = regulator_enable(hpriv->target_pwr);
156                 if (rc)
157                         return rc;
158         }
159
160         rc = ahci_platform_enable_clks(hpriv);
161         if (rc)
162                 goto disable_regulator;
163
164         return 0;
165
166 disable_regulator:
167         if (hpriv->target_pwr)
168                 regulator_disable(hpriv->target_pwr);
169         return rc;
170 }
171 EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
172
173 /**
174  * ahci_platform_disable_resources - Disable platform resources
175  * @hpriv: host private area to store config values
176  *
177  * This function disables all ahci_platform managed resources in the
178  * following order:
179  * 1) Clocks (through ahci_platform_disable_clks)
180  * 2) Regulator
181  */
182 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
183 {
184         ahci_platform_disable_clks(hpriv);
185
186         if (hpriv->target_pwr)
187                 regulator_disable(hpriv->target_pwr);
188 }
189 EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
190
191 static void ahci_platform_put_resources(struct device *dev, void *res)
192 {
193         struct ahci_host_priv *hpriv = res;
194         int c;
195
196         for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
197                 clk_put(hpriv->clks[c]);
198 }
199
200 /**
201  * ahci_platform_get_resources - Get platform resources
202  * @pdev: platform device to get resources for
203  *
204  * This function allocates an ahci_host_priv struct, and gets the following
205  * resources, storing a reference to them inside the returned struct:
206  *
207  * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
208  * 2) regulator for controlling the targets power (optional)
209  * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
210  *    or for non devicetree enabled platforms a single clock
211  *
212  * RETURNS:
213  * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
214  */
215 struct ahci_host_priv *ahci_platform_get_resources(
216         struct platform_device *pdev)
217 {
218         struct device *dev = &pdev->dev;
219         struct ahci_host_priv *hpriv;
220         struct clk *clk;
221         int i, rc = -ENOMEM;
222
223         if (!devres_open_group(dev, NULL, GFP_KERNEL))
224                 return ERR_PTR(-ENOMEM);
225
226         hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
227                              GFP_KERNEL);
228         if (!hpriv)
229                 goto err_out;
230
231         devres_add(dev, hpriv);
232
233         hpriv->mmio = devm_ioremap_resource(dev,
234                               platform_get_resource(pdev, IORESOURCE_MEM, 0));
235         if (!hpriv->mmio) {
236                 dev_err(dev, "no mmio space\n");
237                 goto err_out;
238         }
239
240         hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
241         if (IS_ERR(hpriv->target_pwr)) {
242                 rc = PTR_ERR(hpriv->target_pwr);
243                 if (rc == -EPROBE_DEFER)
244                         goto err_out;
245                 hpriv->target_pwr = NULL;
246         }
247
248         for (i = 0; i < AHCI_MAX_CLKS; i++) {
249                 /*
250                  * For now we must use clk_get(dev, NULL) for the first clock,
251                  * because some platforms (da850, spear13xx) are not yet
252                  * converted to use devicetree for clocks.  For new platforms
253                  * this is equivalent to of_clk_get(dev->of_node, 0).
254                  */
255                 if (i == 0)
256                         clk = clk_get(dev, NULL);
257                 else
258                         clk = of_clk_get(dev->of_node, i);
259
260                 if (IS_ERR(clk)) {
261                         rc = PTR_ERR(clk);
262                         if (rc == -EPROBE_DEFER)
263                                 goto err_out;
264                         break;
265                 }
266                 hpriv->clks[i] = clk;
267         }
268
269         devres_remove_group(dev, NULL);
270         return hpriv;
271
272 err_out:
273         devres_release_group(dev, NULL);
274         return ERR_PTR(rc);
275 }
276 EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
277
278 /**
279  * ahci_platform_init_host - Bring up an ahci-platform host
280  * @pdev: platform device pointer for the host
281  * @hpriv: ahci-host private data for the host
282  * @pi_template: template for the ata_port_info to use
283  * @force_port_map: param passed to ahci_save_initial_config
284  * @mask_port_map: param passed to ahci_save_initial_config
285  *
286  * This function does all the usual steps needed to bring up an
287  * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
288  * must be initialized / enabled before calling this.
289  *
290  * RETURNS:
291  * 0 on success otherwise a negative error code
292  */
293 int ahci_platform_init_host(struct platform_device *pdev,
294                             struct ahci_host_priv *hpriv,
295                             const struct ata_port_info *pi_template,
296                             unsigned int force_port_map,
297                             unsigned int mask_port_map)
298 {
299         struct device *dev = &pdev->dev;
300         struct ata_port_info pi = *pi_template;
301         const struct ata_port_info *ppi[] = { &pi, NULL };
302         struct ata_host *host;
303         int i, irq, n_ports, rc;
304
305         irq = platform_get_irq(pdev, 0);
306         if (irq <= 0) {
307                 dev_err(dev, "no irq\n");
308                 return -EINVAL;
309         }
310
311         /* prepare host */
312         hpriv->flags |= (unsigned long)pi.private_data;
313
314         ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
315
316         if (hpriv->cap & HOST_CAP_NCQ)
317                 pi.flags |= ATA_FLAG_NCQ;
318
319         if (hpriv->cap & HOST_CAP_PMP)
320                 pi.flags |= ATA_FLAG_PMP;
321
322         ahci_set_em_messages(hpriv, &pi);
323
324         /* CAP.NP sometimes indicate the index of the last enabled
325          * port, at other times, that of the last possible port, so
326          * determining the maximum port number requires looking at
327          * both CAP.NP and port_map.
328          */
329         n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
330
331         host = ata_host_alloc_pinfo(dev, ppi, n_ports);
332         if (!host)
333                 return -ENOMEM;
334
335         host->private_data = hpriv;
336
337         if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
338                 host->flags |= ATA_HOST_PARALLEL_SCAN;
339         else
340                 dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
341
342         if (pi.flags & ATA_FLAG_EM)
343                 ahci_reset_em(host);
344
345         for (i = 0; i < host->n_ports; i++) {
346                 struct ata_port *ap = host->ports[i];
347
348                 ata_port_desc(ap, "mmio %pR",
349                               platform_get_resource(pdev, IORESOURCE_MEM, 0));
350                 ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
351
352                 /* set enclosure management message type */
353                 if (ap->flags & ATA_FLAG_EM)
354                         ap->em_message_type = hpriv->em_msg_type;
355
356                 /* disabled/not-implemented port */
357                 if (!(hpriv->port_map & (1 << i)))
358                         ap->ops = &ata_dummy_port_ops;
359         }
360
361         rc = ahci_reset_controller(host);
362         if (rc)
363                 return rc;
364
365         ahci_init_controller(host);
366         ahci_print_info(host, "platform");
367
368         return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
369                                  &ahci_platform_sht);
370 }
371 EXPORT_SYMBOL_GPL(ahci_platform_init_host);
372
373 static int ahci_probe(struct platform_device *pdev)
374 {
375         struct device *dev = &pdev->dev;
376         struct ahci_platform_data *pdata = dev_get_platdata(dev);
377         const struct platform_device_id *id = platform_get_device_id(pdev);
378         const struct ata_port_info *pi_template;
379         struct ahci_host_priv *hpriv;
380         int rc;
381
382         hpriv = ahci_platform_get_resources(pdev);
383         if (IS_ERR(hpriv))
384                 return PTR_ERR(hpriv);
385
386         rc = ahci_platform_enable_resources(hpriv);
387         if (rc)
388                 return rc;
389
390         /*
391          * Some platforms might need to prepare for mmio region access,
392          * which could be done in the following init call. So, the mmio
393          * region shouldn't be accessed before init (if provided) has
394          * returned successfully.
395          */
396         if (pdata && pdata->init) {
397                 rc = pdata->init(dev, hpriv->mmio);
398                 if (rc)
399                         goto disable_resources;
400         }
401
402         if (pdata && pdata->ata_port_info)
403                 pi_template = pdata->ata_port_info;
404         else
405                 pi_template = &ahci_port_info[id ? id->driver_data : 0];
406
407         rc = ahci_platform_init_host(pdev, hpriv, pi_template,
408                                      pdata ? pdata->force_port_map : 0,
409                                      pdata ? pdata->mask_port_map  : 0);
410         if (rc)
411                 goto pdata_exit;
412
413         return 0;
414 pdata_exit:
415         if (pdata && pdata->exit)
416                 pdata->exit(dev);
417 disable_resources:
418         ahci_platform_disable_resources(hpriv);
419         return rc;
420 }
421
422 static void ahci_host_stop(struct ata_host *host)
423 {
424         struct device *dev = host->dev;
425         struct ahci_platform_data *pdata = dev_get_platdata(dev);
426         struct ahci_host_priv *hpriv = host->private_data;
427
428         if (pdata && pdata->exit)
429                 pdata->exit(dev);
430
431         ahci_platform_disable_resources(hpriv);
432 }
433
434 #ifdef CONFIG_PM_SLEEP
435 static int ahci_suspend(struct device *dev)
436 {
437         struct ahci_platform_data *pdata = dev_get_platdata(dev);
438         struct ata_host *host = dev_get_drvdata(dev);
439         struct ahci_host_priv *hpriv = host->private_data;
440         void __iomem *mmio = hpriv->mmio;
441         u32 ctl;
442         int rc;
443
444         if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
445                 dev_err(dev, "firmware update required for suspend/resume\n");
446                 return -EIO;
447         }
448
449         /*
450          * AHCI spec rev1.1 section 8.3.3:
451          * Software must disable interrupts prior to requesting a
452          * transition of the HBA to D3 state.
453          */
454         ctl = readl(mmio + HOST_CTL);
455         ctl &= ~HOST_IRQ_EN;
456         writel(ctl, mmio + HOST_CTL);
457         readl(mmio + HOST_CTL); /* flush */
458
459         rc = ata_host_suspend(host, PMSG_SUSPEND);
460         if (rc)
461                 return rc;
462
463         if (pdata && pdata->suspend)
464                 return pdata->suspend(dev);
465
466         ahci_platform_disable_resources(hpriv);
467
468         return 0;
469 }
470
471 static int ahci_resume(struct device *dev)
472 {
473         struct ahci_platform_data *pdata = dev_get_platdata(dev);
474         struct ata_host *host = dev_get_drvdata(dev);
475         struct ahci_host_priv *hpriv = host->private_data;
476         int rc;
477
478         rc = ahci_platform_enable_resources(hpriv);
479         if (rc)
480                 return rc;
481
482         if (pdata && pdata->resume) {
483                 rc = pdata->resume(dev);
484                 if (rc)
485                         goto disable_resources;
486         }
487
488         if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
489                 rc = ahci_reset_controller(host);
490                 if (rc)
491                         goto disable_resources;
492
493                 ahci_init_controller(host);
494         }
495
496         ata_host_resume(host);
497
498         return 0;
499
500 disable_resources:
501         ahci_platform_disable_resources(hpriv);
502
503         return rc;
504 }
505 #endif
506
507 static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
508
509 static const struct of_device_id ahci_of_match[] = {
510         { .compatible = "snps,spear-ahci", },
511         { .compatible = "snps,exynos5440-ahci", },
512         { .compatible = "ibm,476gtr-ahci", },
513         {},
514 };
515 MODULE_DEVICE_TABLE(of, ahci_of_match);
516
517 static struct platform_driver ahci_driver = {
518         .probe = ahci_probe,
519         .remove = ata_platform_remove_one,
520         .driver = {
521                 .name = "ahci",
522                 .owner = THIS_MODULE,
523                 .of_match_table = ahci_of_match,
524                 .pm = &ahci_pm_ops,
525         },
526         .id_table       = ahci_devtype,
527 };
528 module_platform_driver(ahci_driver);
529
530 MODULE_DESCRIPTION("AHCI SATA platform driver");
531 MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
532 MODULE_LICENSE("GPL");
533 MODULE_ALIAS("platform:ahci");