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/init.h> 21 #include <linux/interrupt.h> 22 #include <linux/device.h> 23 #include <linux/platform_device.h> 24 #include <linux/libata.h> 25 #include <linux/ahci_platform.h> 26 #include "ahci.h" 27 28 static void ahci_host_stop(struct ata_host *host); 29 30 enum ahci_type { 31 AHCI, /* standard platform ahci */ 32 IMX53_AHCI, /* ahci on i.mx53 */ 33 STRICT_AHCI, /* delayed DMA engine start */ 34 }; 35 36 static struct platform_device_id ahci_devtype[] = { 37 { 38 .name = "ahci", 39 .driver_data = AHCI, 40 }, { 41 .name = "imx53-ahci", 42 .driver_data = IMX53_AHCI, 43 }, { 44 .name = "strict-ahci", 45 .driver_data = STRICT_AHCI, 46 }, { 47 /* sentinel */ 48 } 49 }; 50 MODULE_DEVICE_TABLE(platform, ahci_devtype); 51 52 static struct ata_port_operations ahci_platform_ops = { 53 .inherits = &ahci_ops, 54 .host_stop = ahci_host_stop, 55 }; 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 static int ahci_probe(struct platform_device *pdev) 90 { 91 struct device *dev = &pdev->dev; 92 struct ahci_platform_data *pdata = dev_get_platdata(dev); 93 const struct platform_device_id *id = platform_get_device_id(pdev); 94 struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0]; 95 const struct ata_port_info *ppi[] = { &pi, NULL }; 96 struct ahci_host_priv *hpriv; 97 struct ata_host *host; 98 struct resource *mem; 99 int irq; 100 int n_ports; 101 int i; 102 int rc; 103 104 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 105 if (!mem) { 106 dev_err(dev, "no mmio space\n"); 107 return -EINVAL; 108 } 109 110 irq = platform_get_irq(pdev, 0); 111 if (irq <= 0) { 112 dev_err(dev, "no irq\n"); 113 return -EINVAL; 114 } 115 116 if (pdata && pdata->ata_port_info) 117 pi = *pdata->ata_port_info; 118 119 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 120 if (!hpriv) { 121 dev_err(dev, "can't alloc ahci_host_priv\n"); 122 return -ENOMEM; 123 } 124 125 hpriv->flags |= (unsigned long)pi.private_data; 126 127 hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); 128 if (!hpriv->mmio) { 129 dev_err(dev, "can't map %pR\n", mem); 130 return -ENOMEM; 131 } 132 133 hpriv->clk = clk_get(dev, NULL); 134 if (IS_ERR(hpriv->clk)) { 135 dev_err(dev, "can't get clock\n"); 136 } else { 137 rc = clk_prepare_enable(hpriv->clk); 138 if (rc) { 139 dev_err(dev, "clock prepare enable failed"); 140 goto free_clk; 141 } 142 } 143 144 /* 145 * Some platforms might need to prepare for mmio region access, 146 * which could be done in the following init call. So, the mmio 147 * region shouldn't be accessed before init (if provided) has 148 * returned successfully. 149 */ 150 if (pdata && pdata->init) { 151 rc = pdata->init(dev, hpriv->mmio); 152 if (rc) 153 goto disable_unprepare_clk; 154 } 155 156 ahci_save_initial_config(dev, hpriv, 157 pdata ? pdata->force_port_map : 0, 158 pdata ? pdata->mask_port_map : 0); 159 160 /* prepare host */ 161 if (hpriv->cap & HOST_CAP_NCQ) 162 pi.flags |= ATA_FLAG_NCQ; 163 164 if (hpriv->cap & HOST_CAP_PMP) 165 pi.flags |= ATA_FLAG_PMP; 166 167 ahci_set_em_messages(hpriv, &pi); 168 169 /* CAP.NP sometimes indicate the index of the last enabled 170 * port, at other times, that of the last possible port, so 171 * determining the maximum port number requires looking at 172 * both CAP.NP and port_map. 173 */ 174 n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); 175 176 host = ata_host_alloc_pinfo(dev, ppi, n_ports); 177 if (!host) { 178 rc = -ENOMEM; 179 goto pdata_exit; 180 } 181 182 host->private_data = hpriv; 183 184 if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) 185 host->flags |= ATA_HOST_PARALLEL_SCAN; 186 else 187 printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); 188 189 if (pi.flags & ATA_FLAG_EM) 190 ahci_reset_em(host); 191 192 for (i = 0; i < host->n_ports; i++) { 193 struct ata_port *ap = host->ports[i]; 194 195 ata_port_desc(ap, "mmio %pR", mem); 196 ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); 197 198 /* set enclosure management message type */ 199 if (ap->flags & ATA_FLAG_EM) 200 ap->em_message_type = hpriv->em_msg_type; 201 202 /* disabled/not-implemented port */ 203 if (!(hpriv->port_map & (1 << i))) 204 ap->ops = &ata_dummy_port_ops; 205 } 206 207 rc = ahci_reset_controller(host); 208 if (rc) 209 goto pdata_exit; 210 211 ahci_init_controller(host); 212 ahci_print_info(host, "platform"); 213 214 rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, 215 &ahci_platform_sht); 216 if (rc) 217 goto pdata_exit; 218 219 return 0; 220 pdata_exit: 221 if (pdata && pdata->exit) 222 pdata->exit(dev); 223 disable_unprepare_clk: 224 if (!IS_ERR(hpriv->clk)) 225 clk_disable_unprepare(hpriv->clk); 226 free_clk: 227 if (!IS_ERR(hpriv->clk)) 228 clk_put(hpriv->clk); 229 return rc; 230 } 231 232 static void ahci_host_stop(struct ata_host *host) 233 { 234 struct device *dev = host->dev; 235 struct ahci_platform_data *pdata = dev_get_platdata(dev); 236 struct ahci_host_priv *hpriv = host->private_data; 237 238 if (pdata && pdata->exit) 239 pdata->exit(dev); 240 241 if (!IS_ERR(hpriv->clk)) { 242 clk_disable_unprepare(hpriv->clk); 243 clk_put(hpriv->clk); 244 } 245 } 246 247 #ifdef CONFIG_PM_SLEEP 248 static int ahci_suspend(struct device *dev) 249 { 250 struct ahci_platform_data *pdata = dev_get_platdata(dev); 251 struct ata_host *host = dev_get_drvdata(dev); 252 struct ahci_host_priv *hpriv = host->private_data; 253 void __iomem *mmio = hpriv->mmio; 254 u32 ctl; 255 int rc; 256 257 if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { 258 dev_err(dev, "firmware update required for suspend/resume\n"); 259 return -EIO; 260 } 261 262 /* 263 * AHCI spec rev1.1 section 8.3.3: 264 * Software must disable interrupts prior to requesting a 265 * transition of the HBA to D3 state. 266 */ 267 ctl = readl(mmio + HOST_CTL); 268 ctl &= ~HOST_IRQ_EN; 269 writel(ctl, mmio + HOST_CTL); 270 readl(mmio + HOST_CTL); /* flush */ 271 272 rc = ata_host_suspend(host, PMSG_SUSPEND); 273 if (rc) 274 return rc; 275 276 if (pdata && pdata->suspend) 277 return pdata->suspend(dev); 278 279 if (!IS_ERR(hpriv->clk)) 280 clk_disable_unprepare(hpriv->clk); 281 282 return 0; 283 } 284 285 static int ahci_resume(struct device *dev) 286 { 287 struct ahci_platform_data *pdata = dev_get_platdata(dev); 288 struct ata_host *host = dev_get_drvdata(dev); 289 struct ahci_host_priv *hpriv = host->private_data; 290 int rc; 291 292 if (!IS_ERR(hpriv->clk)) { 293 rc = clk_prepare_enable(hpriv->clk); 294 if (rc) { 295 dev_err(dev, "clock prepare enable failed"); 296 return rc; 297 } 298 } 299 300 if (pdata && pdata->resume) { 301 rc = pdata->resume(dev); 302 if (rc) 303 goto disable_unprepare_clk; 304 } 305 306 if (dev->power.power_state.event == PM_EVENT_SUSPEND) { 307 rc = ahci_reset_controller(host); 308 if (rc) 309 goto disable_unprepare_clk; 310 311 ahci_init_controller(host); 312 } 313 314 ata_host_resume(host); 315 316 return 0; 317 318 disable_unprepare_clk: 319 if (!IS_ERR(hpriv->clk)) 320 clk_disable_unprepare(hpriv->clk); 321 322 return rc; 323 } 324 #endif 325 326 static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); 327 328 static const struct of_device_id ahci_of_match[] = { 329 { .compatible = "snps,spear-ahci", }, 330 { .compatible = "snps,exynos5440-ahci", }, 331 {}, 332 }; 333 MODULE_DEVICE_TABLE(of, ahci_of_match); 334 335 static struct platform_driver ahci_driver = { 336 .probe = ahci_probe, 337 .remove = ata_platform_remove_one, 338 .driver = { 339 .name = "ahci", 340 .owner = THIS_MODULE, 341 .of_match_table = ahci_of_match, 342 .pm = &ahci_pm_ops, 343 }, 344 .id_table = ahci_devtype, 345 }; 346 module_platform_driver(ahci_driver); 347 348 MODULE_DESCRIPTION("AHCI SATA platform driver"); 349 MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>"); 350 MODULE_LICENSE("GPL"); 351 MODULE_ALIAS("platform:ahci"); 352