ahci_brcm.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Broadcom SATA3 AHCI Controller Driver
  4. *
  5. * Copyright © 2009-2015 Broadcom Corporation
  6. */
  7. #include <linux/ahci_platform.h>
  8. #include <linux/compiler.h>
  9. #include <linux/device.h>
  10. #include <linux/init.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/io.h>
  13. #include <linux/kernel.h>
  14. #include <linux/libata.h>
  15. #include <linux/module.h>
  16. #include <linux/of.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/reset.h>
  19. #include <linux/string.h>
  20. #include "ahci.h"
  21. #define DRV_NAME "brcm-ahci"
  22. #define SATA_TOP_CTRL_VERSION 0x0
  23. #define SATA_TOP_CTRL_BUS_CTRL 0x4
  24. #define MMIO_ENDIAN_SHIFT 0 /* CPU->AHCI */
  25. #define DMADESC_ENDIAN_SHIFT 2 /* AHCI->DDR */
  26. #define DMADATA_ENDIAN_SHIFT 4 /* AHCI->DDR */
  27. #define PIODATA_ENDIAN_SHIFT 6
  28. #define ENDIAN_SWAP_NONE 0
  29. #define ENDIAN_SWAP_FULL 2
  30. #define SATA_TOP_CTRL_TP_CTRL 0x8
  31. #define SATA_TOP_CTRL_PHY_CTRL 0xc
  32. #define SATA_TOP_CTRL_PHY_CTRL_1 0x0
  33. #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14)
  34. #define SATA_TOP_CTRL_PHY_CTRL_2 0x4
  35. #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0)
  36. #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1)
  37. #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2)
  38. #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3)
  39. #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14)
  40. #define SATA_TOP_CTRL_PHY_OFFS 0x8
  41. #define SATA_TOP_MAX_PHYS 2
  42. #define SATA_FIRST_PORT_CTRL 0x700
  43. #define SATA_NEXT_PORT_CTRL_OFFSET 0x80
  44. #define SATA_PORT_PCTRL6(reg_base) (reg_base + 0x18)
  45. /* On big-endian MIPS, buses are reversed to big endian, so switch them back */
  46. #if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN)
  47. #define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */
  48. #define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */
  49. #else
  50. #define DATA_ENDIAN 0
  51. #define MMIO_ENDIAN 0
  52. #endif
  53. #define BUS_CTRL_ENDIAN_CONF \
  54. ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \
  55. (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \
  56. (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
  57. #define BUS_CTRL_ENDIAN_NSP_CONF \
  58. (0x02 << DMADATA_ENDIAN_SHIFT | 0x02 << DMADESC_ENDIAN_SHIFT)
  59. #define BUS_CTRL_ENDIAN_CONF_MASK \
  60. (0x3 << MMIO_ENDIAN_SHIFT | 0x3 << DMADESC_ENDIAN_SHIFT | \
  61. 0x3 << DMADATA_ENDIAN_SHIFT | 0x3 << PIODATA_ENDIAN_SHIFT)
  62. enum brcm_ahci_version {
  63. BRCM_SATA_BCM7425 = 1,
  64. BRCM_SATA_BCM7445,
  65. BRCM_SATA_NSP,
  66. BRCM_SATA_BCM7216,
  67. };
  68. enum brcm_ahci_quirks {
  69. BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0),
  70. };
  71. struct brcm_ahci_priv {
  72. struct device *dev;
  73. void __iomem *top_ctrl;
  74. u32 port_mask;
  75. u32 quirks;
  76. enum brcm_ahci_version version;
  77. struct reset_control *rcdev_rescal;
  78. struct reset_control *rcdev_ahci;
  79. };
  80. static inline u32 brcm_sata_readreg(void __iomem *addr)
  81. {
  82. /*
  83. * MIPS endianness is configured by boot strap, which also reverses all
  84. * bus endianness (i.e., big-endian CPU + big endian bus ==> native
  85. * endian I/O).
  86. *
  87. * Other architectures (e.g., ARM) either do not support big endian, or
  88. * else leave I/O in little endian mode.
  89. */
  90. if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
  91. return __raw_readl(addr);
  92. else
  93. return readl_relaxed(addr);
  94. }
  95. static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
  96. {
  97. /* See brcm_sata_readreg() comments */
  98. if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
  99. __raw_writel(val, addr);
  100. else
  101. writel_relaxed(val, addr);
  102. }
  103. static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv)
  104. {
  105. struct brcm_ahci_priv *priv = hpriv->plat_data;
  106. u32 port_ctrl, host_caps;
  107. int i;
  108. /* Enable support for ALPM */
  109. host_caps = readl(hpriv->mmio + HOST_CAP);
  110. if (!(host_caps & HOST_CAP_ALPM))
  111. hpriv->flags |= AHCI_HFLAG_YES_ALPM;
  112. /*
  113. * Adjust timeout to allow PLL sufficient time to lock while waking
  114. * up from slumber mode.
  115. */
  116. for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL;
  117. i < SATA_TOP_MAX_PHYS;
  118. i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) {
  119. if (priv->port_mask & BIT(i))
  120. writel(0xff1003fc,
  121. hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl));
  122. }
  123. }
  124. static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port)
  125. {
  126. void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
  127. (port * SATA_TOP_CTRL_PHY_OFFS);
  128. void __iomem *p;
  129. u32 reg;
  130. if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
  131. return;
  132. /* clear PHY_DEFAULT_POWER_STATE */
  133. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
  134. reg = brcm_sata_readreg(p);
  135. reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
  136. brcm_sata_writereg(reg, p);
  137. /* reset the PHY digital logic */
  138. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
  139. reg = brcm_sata_readreg(p);
  140. reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
  141. SATA_TOP_CTRL_2_SW_RST_RX);
  142. reg |= SATA_TOP_CTRL_2_SW_RST_TX;
  143. brcm_sata_writereg(reg, p);
  144. reg = brcm_sata_readreg(p);
  145. reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
  146. brcm_sata_writereg(reg, p);
  147. reg = brcm_sata_readreg(p);
  148. reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
  149. brcm_sata_writereg(reg, p);
  150. (void)brcm_sata_readreg(p);
  151. }
  152. static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port)
  153. {
  154. void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
  155. (port * SATA_TOP_CTRL_PHY_OFFS);
  156. void __iomem *p;
  157. u32 reg;
  158. if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
  159. return;
  160. /* power-off the PHY digital logic */
  161. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
  162. reg = brcm_sata_readreg(p);
  163. reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
  164. SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX |
  165. SATA_TOP_CTRL_2_PHY_GLOBAL_RESET);
  166. brcm_sata_writereg(reg, p);
  167. /* set PHY_DEFAULT_POWER_STATE */
  168. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
  169. reg = brcm_sata_readreg(p);
  170. reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
  171. brcm_sata_writereg(reg, p);
  172. }
  173. static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv)
  174. {
  175. int i;
  176. for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
  177. if (priv->port_mask & BIT(i))
  178. brcm_sata_phy_enable(priv, i);
  179. }
  180. static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv)
  181. {
  182. int i;
  183. for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
  184. if (priv->port_mask & BIT(i))
  185. brcm_sata_phy_disable(priv, i);
  186. }
  187. static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv,
  188. struct brcm_ahci_priv *priv)
  189. {
  190. u32 impl;
  191. impl = readl(hpriv->mmio + HOST_PORTS_IMPL);
  192. if (fls(impl) > SATA_TOP_MAX_PHYS)
  193. dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n",
  194. impl);
  195. else if (!impl)
  196. dev_info(priv->dev, "no ports found\n");
  197. return impl;
  198. }
  199. static void brcm_sata_init(struct brcm_ahci_priv *priv)
  200. {
  201. void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
  202. u32 data;
  203. /* Configure endianness */
  204. data = brcm_sata_readreg(ctrl);
  205. data &= ~BUS_CTRL_ENDIAN_CONF_MASK;
  206. if (priv->version == BRCM_SATA_NSP)
  207. data |= BUS_CTRL_ENDIAN_NSP_CONF;
  208. else
  209. data |= BUS_CTRL_ENDIAN_CONF;
  210. brcm_sata_writereg(data, ctrl);
  211. }
  212. static unsigned int brcm_ahci_read_id(struct ata_device *dev,
  213. struct ata_taskfile *tf, __le16 *id)
  214. {
  215. struct ata_port *ap = dev->link->ap;
  216. struct ata_host *host = ap->host;
  217. struct ahci_host_priv *hpriv = host->private_data;
  218. struct brcm_ahci_priv *priv = hpriv->plat_data;
  219. void __iomem *mmio = hpriv->mmio;
  220. unsigned int err_mask;
  221. unsigned long flags;
  222. int i, rc;
  223. u32 ctl;
  224. /* Try to read the device ID and, if this fails, proceed with the
  225. * recovery sequence below
  226. */
  227. err_mask = ata_do_dev_read_id(dev, tf, id);
  228. if (likely(!err_mask))
  229. return err_mask;
  230. /* Disable host interrupts */
  231. spin_lock_irqsave(&host->lock, flags);
  232. ctl = readl(mmio + HOST_CTL);
  233. ctl &= ~HOST_IRQ_EN;
  234. writel(ctl, mmio + HOST_CTL);
  235. readl(mmio + HOST_CTL); /* flush */
  236. spin_unlock_irqrestore(&host->lock, flags);
  237. /* Perform the SATA PHY reset sequence */
  238. brcm_sata_phy_disable(priv, ap->port_no);
  239. /* Reset the SATA clock */
  240. ahci_platform_disable_clks(hpriv);
  241. msleep(10);
  242. ahci_platform_enable_clks(hpriv);
  243. msleep(10);
  244. /* Bring the PHY back on */
  245. brcm_sata_phy_enable(priv, ap->port_no);
  246. /* Re-initialize and calibrate the PHY */
  247. for (i = 0; i < hpriv->nports; i++) {
  248. rc = phy_init(hpriv->phys[i]);
  249. if (rc)
  250. goto disable_phys;
  251. rc = phy_calibrate(hpriv->phys[i]);
  252. if (rc) {
  253. phy_exit(hpriv->phys[i]);
  254. goto disable_phys;
  255. }
  256. }
  257. /* Re-enable host interrupts */
  258. spin_lock_irqsave(&host->lock, flags);
  259. ctl = readl(mmio + HOST_CTL);
  260. ctl |= HOST_IRQ_EN;
  261. writel(ctl, mmio + HOST_CTL);
  262. readl(mmio + HOST_CTL); /* flush */
  263. spin_unlock_irqrestore(&host->lock, flags);
  264. return ata_do_dev_read_id(dev, tf, id);
  265. disable_phys:
  266. while (--i >= 0) {
  267. phy_power_off(hpriv->phys[i]);
  268. phy_exit(hpriv->phys[i]);
  269. }
  270. return AC_ERR_OTHER;
  271. }
  272. static void brcm_ahci_host_stop(struct ata_host *host)
  273. {
  274. struct ahci_host_priv *hpriv = host->private_data;
  275. ahci_platform_disable_resources(hpriv);
  276. }
  277. static struct ata_port_operations ahci_brcm_platform_ops = {
  278. .inherits = &ahci_ops,
  279. .host_stop = brcm_ahci_host_stop,
  280. .read_id = brcm_ahci_read_id,
  281. };
  282. static const struct ata_port_info ahci_brcm_port_info = {
  283. .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
  284. .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY,
  285. .pio_mask = ATA_PIO4,
  286. .udma_mask = ATA_UDMA6,
  287. .port_ops = &ahci_brcm_platform_ops,
  288. };
  289. static int brcm_ahci_suspend(struct device *dev)
  290. {
  291. struct ata_host *host = dev_get_drvdata(dev);
  292. struct ahci_host_priv *hpriv = host->private_data;
  293. struct brcm_ahci_priv *priv = hpriv->plat_data;
  294. int ret;
  295. brcm_sata_phys_disable(priv);
  296. if (IS_ENABLED(CONFIG_PM_SLEEP))
  297. ret = ahci_platform_suspend(dev);
  298. else
  299. ret = 0;
  300. reset_control_assert(priv->rcdev_ahci);
  301. reset_control_rearm(priv->rcdev_rescal);
  302. return ret;
  303. }
  304. static int __maybe_unused brcm_ahci_resume(struct device *dev)
  305. {
  306. struct ata_host *host = dev_get_drvdata(dev);
  307. struct ahci_host_priv *hpriv = host->private_data;
  308. struct brcm_ahci_priv *priv = hpriv->plat_data;
  309. int ret = 0;
  310. ret = reset_control_deassert(priv->rcdev_ahci);
  311. if (ret)
  312. return ret;
  313. ret = reset_control_reset(priv->rcdev_rescal);
  314. if (ret)
  315. return ret;
  316. /* Make sure clocks are turned on before re-configuration */
  317. ret = ahci_platform_enable_clks(hpriv);
  318. if (ret)
  319. return ret;
  320. ret = ahci_platform_enable_regulators(hpriv);
  321. if (ret)
  322. goto out_disable_clks;
  323. brcm_sata_init(priv);
  324. brcm_sata_phys_enable(priv);
  325. brcm_sata_alpm_init(hpriv);
  326. /* Since we had to enable clocks earlier on, we cannot use
  327. * ahci_platform_resume() as-is since a second call to
  328. * ahci_platform_enable_resources() would bump up the resources
  329. * (regulators, clocks, PHYs) count artificially so we copy the part
  330. * after ahci_platform_enable_resources().
  331. */
  332. ret = ahci_platform_enable_phys(hpriv);
  333. if (ret)
  334. goto out_disable_phys;
  335. ret = ahci_platform_resume_host(dev);
  336. if (ret)
  337. goto out_disable_platform_phys;
  338. /* We resumed so update PM runtime state */
  339. pm_runtime_disable(dev);
  340. pm_runtime_set_active(dev);
  341. pm_runtime_enable(dev);
  342. return 0;
  343. out_disable_platform_phys:
  344. ahci_platform_disable_phys(hpriv);
  345. out_disable_phys:
  346. brcm_sata_phys_disable(priv);
  347. ahci_platform_disable_regulators(hpriv);
  348. out_disable_clks:
  349. ahci_platform_disable_clks(hpriv);
  350. return ret;
  351. }
  352. static struct scsi_host_template ahci_platform_sht = {
  353. AHCI_SHT(DRV_NAME),
  354. };
  355. static const struct of_device_id ahci_of_match[] = {
  356. {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
  357. {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
  358. {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445},
  359. {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
  360. {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216},
  361. { /* sentinel */ }
  362. };
  363. MODULE_DEVICE_TABLE(of, ahci_of_match);
  364. static int brcm_ahci_probe(struct platform_device *pdev)
  365. {
  366. const struct of_device_id *of_id;
  367. struct device *dev = &pdev->dev;
  368. struct brcm_ahci_priv *priv;
  369. struct ahci_host_priv *hpriv;
  370. struct resource *res;
  371. int ret;
  372. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  373. if (!priv)
  374. return -ENOMEM;
  375. of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
  376. if (!of_id)
  377. return -ENODEV;
  378. priv->version = (unsigned long)of_id->data;
  379. priv->dev = dev;
  380. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
  381. priv->top_ctrl = devm_ioremap_resource(dev, res);
  382. if (IS_ERR(priv->top_ctrl))
  383. return PTR_ERR(priv->top_ctrl);
  384. if (priv->version == BRCM_SATA_BCM7216) {
  385. priv->rcdev_rescal = devm_reset_control_get_optional_shared(
  386. &pdev->dev, "rescal");
  387. if (IS_ERR(priv->rcdev_rescal))
  388. return PTR_ERR(priv->rcdev_rescal);
  389. }
  390. priv->rcdev_ahci = devm_reset_control_get_optional(&pdev->dev, "ahci");
  391. if (IS_ERR(priv->rcdev_ahci))
  392. return PTR_ERR(priv->rcdev_ahci);
  393. hpriv = ahci_platform_get_resources(pdev, 0);
  394. if (IS_ERR(hpriv))
  395. return PTR_ERR(hpriv);
  396. hpriv->plat_data = priv;
  397. hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO;
  398. switch (priv->version) {
  399. case BRCM_SATA_BCM7425:
  400. hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE;
  401. fallthrough;
  402. case BRCM_SATA_NSP:
  403. hpriv->flags |= AHCI_HFLAG_NO_NCQ;
  404. priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
  405. break;
  406. default:
  407. break;
  408. }
  409. ret = reset_control_reset(priv->rcdev_rescal);
  410. if (ret)
  411. return ret;
  412. ret = reset_control_deassert(priv->rcdev_ahci);
  413. if (ret)
  414. return ret;
  415. ret = ahci_platform_enable_clks(hpriv);
  416. if (ret)
  417. goto out_reset;
  418. ret = ahci_platform_enable_regulators(hpriv);
  419. if (ret)
  420. goto out_disable_clks;
  421. /* Must be first so as to configure endianness including that
  422. * of the standard AHCI register space.
  423. */
  424. brcm_sata_init(priv);
  425. /* Initializes priv->port_mask which is used below */
  426. priv->port_mask = brcm_ahci_get_portmask(hpriv, priv);
  427. if (!priv->port_mask) {
  428. ret = -ENODEV;
  429. goto out_disable_regulators;
  430. }
  431. /* Must be done before ahci_platform_enable_phys() */
  432. brcm_sata_phys_enable(priv);
  433. brcm_sata_alpm_init(hpriv);
  434. ret = ahci_platform_enable_phys(hpriv);
  435. if (ret)
  436. goto out_disable_phys;
  437. ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info,
  438. &ahci_platform_sht);
  439. if (ret)
  440. goto out_disable_platform_phys;
  441. dev_info(dev, "Broadcom AHCI SATA3 registered\n");
  442. return 0;
  443. out_disable_platform_phys:
  444. ahci_platform_disable_phys(hpriv);
  445. out_disable_phys:
  446. brcm_sata_phys_disable(priv);
  447. out_disable_regulators:
  448. ahci_platform_disable_regulators(hpriv);
  449. out_disable_clks:
  450. ahci_platform_disable_clks(hpriv);
  451. out_reset:
  452. reset_control_assert(priv->rcdev_ahci);
  453. reset_control_rearm(priv->rcdev_rescal);
  454. return ret;
  455. }
  456. static int brcm_ahci_remove(struct platform_device *pdev)
  457. {
  458. struct ata_host *host = dev_get_drvdata(&pdev->dev);
  459. struct ahci_host_priv *hpriv = host->private_data;
  460. struct brcm_ahci_priv *priv = hpriv->plat_data;
  461. brcm_sata_phys_disable(priv);
  462. return ata_platform_remove_one(pdev);
  463. }
  464. static void brcm_ahci_shutdown(struct platform_device *pdev)
  465. {
  466. int ret;
  467. /* All resources releasing happens via devres, but our device, unlike a
  468. * proper remove is not disappearing, therefore using
  469. * brcm_ahci_suspend() here which does explicit power management is
  470. * appropriate.
  471. */
  472. ret = brcm_ahci_suspend(&pdev->dev);
  473. if (ret)
  474. dev_err(&pdev->dev, "failed to shutdown\n");
  475. }
  476. static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
  477. static struct platform_driver brcm_ahci_driver = {
  478. .probe = brcm_ahci_probe,
  479. .remove = brcm_ahci_remove,
  480. .shutdown = brcm_ahci_shutdown,
  481. .driver = {
  482. .name = DRV_NAME,
  483. .of_match_table = ahci_of_match,
  484. .pm = &ahci_brcm_pm_ops,
  485. },
  486. };
  487. module_platform_driver(brcm_ahci_driver);
  488. MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver");
  489. MODULE_AUTHOR("Brian Norris");
  490. MODULE_LICENSE("GPL");
  491. MODULE_ALIAS("platform:sata-brcmstb");