Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Broadcom SATA3 AHCI Controller Driver
0004  *
0005  * Copyright © 2009-2015 Broadcom Corporation
0006  */
0007 
0008 #include <linux/ahci_platform.h>
0009 #include <linux/compiler.h>
0010 #include <linux/device.h>
0011 #include <linux/init.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/kernel.h>
0015 #include <linux/libata.h>
0016 #include <linux/module.h>
0017 #include <linux/of.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/reset.h>
0020 #include <linux/string.h>
0021 
0022 #include "ahci.h"
0023 
0024 #define DRV_NAME                    "brcm-ahci"
0025 
0026 #define SATA_TOP_CTRL_VERSION               0x0
0027 #define SATA_TOP_CTRL_BUS_CTRL              0x4
0028  #define MMIO_ENDIAN_SHIFT              0 /* CPU->AHCI */
0029  #define DMADESC_ENDIAN_SHIFT               2 /* AHCI->DDR */
0030  #define DMADATA_ENDIAN_SHIFT               4 /* AHCI->DDR */
0031  #define PIODATA_ENDIAN_SHIFT               6
0032   #define ENDIAN_SWAP_NONE              0
0033   #define ENDIAN_SWAP_FULL              2
0034 #define SATA_TOP_CTRL_TP_CTRL               0x8
0035 #define SATA_TOP_CTRL_PHY_CTRL              0xc
0036  #define SATA_TOP_CTRL_PHY_CTRL_1           0x0
0037   #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE   BIT(14)
0038  #define SATA_TOP_CTRL_PHY_CTRL_2           0x4
0039   #define SATA_TOP_CTRL_2_SW_RST_MDIOREG        BIT(0)
0040   #define SATA_TOP_CTRL_2_SW_RST_OOB            BIT(1)
0041   #define SATA_TOP_CTRL_2_SW_RST_RX         BIT(2)
0042   #define SATA_TOP_CTRL_2_SW_RST_TX         BIT(3)
0043   #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET      BIT(14)
0044  #define SATA_TOP_CTRL_PHY_OFFS             0x8
0045  #define SATA_TOP_MAX_PHYS              2
0046 
0047 #define SATA_FIRST_PORT_CTRL                0x700
0048 #define SATA_NEXT_PORT_CTRL_OFFSET          0x80
0049 #define SATA_PORT_PCTRL6(reg_base)          (reg_base + 0x18)
0050 
0051 /* On big-endian MIPS, buses are reversed to big endian, so switch them back */
0052 #if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN)
0053 #define DATA_ENDIAN          2 /* AHCI->DDR inbound accesses */
0054 #define MMIO_ENDIAN          2 /* CPU->AHCI outbound accesses */
0055 #else
0056 #define DATA_ENDIAN          0
0057 #define MMIO_ENDIAN          0
0058 #endif
0059 
0060 #define BUS_CTRL_ENDIAN_CONF                \
0061     ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) |    \
0062     (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) |     \
0063     (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
0064 
0065 #define BUS_CTRL_ENDIAN_NSP_CONF            \
0066     (0x02 << DMADATA_ENDIAN_SHIFT | 0x02 << DMADESC_ENDIAN_SHIFT)
0067 
0068 #define BUS_CTRL_ENDIAN_CONF_MASK           \
0069     (0x3 << MMIO_ENDIAN_SHIFT | 0x3 << DMADESC_ENDIAN_SHIFT |   \
0070      0x3 << DMADATA_ENDIAN_SHIFT | 0x3 << PIODATA_ENDIAN_SHIFT)
0071 
0072 enum brcm_ahci_version {
0073     BRCM_SATA_BCM7425 = 1,
0074     BRCM_SATA_BCM7445,
0075     BRCM_SATA_NSP,
0076     BRCM_SATA_BCM7216,
0077 };
0078 
0079 enum brcm_ahci_quirks {
0080     BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0),
0081 };
0082 
0083 struct brcm_ahci_priv {
0084     struct device *dev;
0085     void __iomem *top_ctrl;
0086     u32 port_mask;
0087     u32 quirks;
0088     enum brcm_ahci_version version;
0089     struct reset_control *rcdev_rescal;
0090     struct reset_control *rcdev_ahci;
0091 };
0092 
0093 static inline u32 brcm_sata_readreg(void __iomem *addr)
0094 {
0095     /*
0096      * MIPS endianness is configured by boot strap, which also reverses all
0097      * bus endianness (i.e., big-endian CPU + big endian bus ==> native
0098      * endian I/O).
0099      *
0100      * Other architectures (e.g., ARM) either do not support big endian, or
0101      * else leave I/O in little endian mode.
0102      */
0103     if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
0104         return __raw_readl(addr);
0105     else
0106         return readl_relaxed(addr);
0107 }
0108 
0109 static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
0110 {
0111     /* See brcm_sata_readreg() comments */
0112     if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
0113         __raw_writel(val, addr);
0114     else
0115         writel_relaxed(val, addr);
0116 }
0117 
0118 static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv)
0119 {
0120     struct brcm_ahci_priv *priv = hpriv->plat_data;
0121     u32 port_ctrl, host_caps;
0122     int i;
0123 
0124     /* Enable support for ALPM */
0125     host_caps = readl(hpriv->mmio + HOST_CAP);
0126     if (!(host_caps & HOST_CAP_ALPM))
0127         hpriv->flags |= AHCI_HFLAG_YES_ALPM;
0128 
0129     /*
0130      * Adjust timeout to allow PLL sufficient time to lock while waking
0131      * up from slumber mode.
0132      */
0133     for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL;
0134          i < SATA_TOP_MAX_PHYS;
0135          i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) {
0136         if (priv->port_mask & BIT(i))
0137             writel(0xff1003fc,
0138                    hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl));
0139     }
0140 }
0141 
0142 static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port)
0143 {
0144     void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
0145                 (port * SATA_TOP_CTRL_PHY_OFFS);
0146     void __iomem *p;
0147     u32 reg;
0148 
0149     if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
0150         return;
0151 
0152     /* clear PHY_DEFAULT_POWER_STATE */
0153     p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
0154     reg = brcm_sata_readreg(p);
0155     reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
0156     brcm_sata_writereg(reg, p);
0157 
0158     /* reset the PHY digital logic */
0159     p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
0160     reg = brcm_sata_readreg(p);
0161     reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
0162          SATA_TOP_CTRL_2_SW_RST_RX);
0163     reg |= SATA_TOP_CTRL_2_SW_RST_TX;
0164     brcm_sata_writereg(reg, p);
0165     reg = brcm_sata_readreg(p);
0166     reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
0167     brcm_sata_writereg(reg, p);
0168     reg = brcm_sata_readreg(p);
0169     reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
0170     brcm_sata_writereg(reg, p);
0171     (void)brcm_sata_readreg(p);
0172 }
0173 
0174 static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port)
0175 {
0176     void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
0177                 (port * SATA_TOP_CTRL_PHY_OFFS);
0178     void __iomem *p;
0179     u32 reg;
0180 
0181     if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
0182         return;
0183 
0184     /* power-off the PHY digital logic */
0185     p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
0186     reg = brcm_sata_readreg(p);
0187     reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
0188         SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX |
0189         SATA_TOP_CTRL_2_PHY_GLOBAL_RESET);
0190     brcm_sata_writereg(reg, p);
0191 
0192     /* set PHY_DEFAULT_POWER_STATE */
0193     p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
0194     reg = brcm_sata_readreg(p);
0195     reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
0196     brcm_sata_writereg(reg, p);
0197 }
0198 
0199 static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv)
0200 {
0201     int i;
0202 
0203     for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
0204         if (priv->port_mask & BIT(i))
0205             brcm_sata_phy_enable(priv, i);
0206 }
0207 
0208 static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv)
0209 {
0210     int i;
0211 
0212     for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
0213         if (priv->port_mask & BIT(i))
0214             brcm_sata_phy_disable(priv, i);
0215 }
0216 
0217 static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv,
0218                   struct brcm_ahci_priv *priv)
0219 {
0220     u32 impl;
0221 
0222     impl = readl(hpriv->mmio + HOST_PORTS_IMPL);
0223 
0224     if (fls(impl) > SATA_TOP_MAX_PHYS)
0225         dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n",
0226              impl);
0227     else if (!impl)
0228         dev_info(priv->dev, "no ports found\n");
0229 
0230     return impl;
0231 }
0232 
0233 static void brcm_sata_init(struct brcm_ahci_priv *priv)
0234 {
0235     void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
0236     u32 data;
0237 
0238     /* Configure endianness */
0239     data = brcm_sata_readreg(ctrl);
0240     data &= ~BUS_CTRL_ENDIAN_CONF_MASK;
0241     if (priv->version == BRCM_SATA_NSP)
0242         data |= BUS_CTRL_ENDIAN_NSP_CONF;
0243     else
0244         data |= BUS_CTRL_ENDIAN_CONF;
0245     brcm_sata_writereg(data, ctrl);
0246 }
0247 
0248 static unsigned int brcm_ahci_read_id(struct ata_device *dev,
0249                       struct ata_taskfile *tf, __le16 *id)
0250 {
0251     struct ata_port *ap = dev->link->ap;
0252     struct ata_host *host = ap->host;
0253     struct ahci_host_priv *hpriv = host->private_data;
0254     struct brcm_ahci_priv *priv = hpriv->plat_data;
0255     void __iomem *mmio = hpriv->mmio;
0256     unsigned int err_mask;
0257     unsigned long flags;
0258     int i, rc;
0259     u32 ctl;
0260 
0261     /* Try to read the device ID and, if this fails, proceed with the
0262      * recovery sequence below
0263      */
0264     err_mask = ata_do_dev_read_id(dev, tf, id);
0265     if (likely(!err_mask))
0266         return err_mask;
0267 
0268     /* Disable host interrupts */
0269     spin_lock_irqsave(&host->lock, flags);
0270     ctl = readl(mmio + HOST_CTL);
0271     ctl &= ~HOST_IRQ_EN;
0272     writel(ctl, mmio + HOST_CTL);
0273     readl(mmio + HOST_CTL); /* flush */
0274     spin_unlock_irqrestore(&host->lock, flags);
0275 
0276     /* Perform the SATA PHY reset sequence */
0277     brcm_sata_phy_disable(priv, ap->port_no);
0278 
0279     /* Reset the SATA clock */
0280     ahci_platform_disable_clks(hpriv);
0281     msleep(10);
0282 
0283     ahci_platform_enable_clks(hpriv);
0284     msleep(10);
0285 
0286     /* Bring the PHY back on */
0287     brcm_sata_phy_enable(priv, ap->port_no);
0288 
0289     /* Re-initialize and calibrate the PHY */
0290     for (i = 0; i < hpriv->nports; i++) {
0291         rc = phy_init(hpriv->phys[i]);
0292         if (rc)
0293             goto disable_phys;
0294 
0295         rc = phy_calibrate(hpriv->phys[i]);
0296         if (rc) {
0297             phy_exit(hpriv->phys[i]);
0298             goto disable_phys;
0299         }
0300     }
0301 
0302     /* Re-enable host interrupts */
0303     spin_lock_irqsave(&host->lock, flags);
0304     ctl = readl(mmio + HOST_CTL);
0305     ctl |= HOST_IRQ_EN;
0306     writel(ctl, mmio + HOST_CTL);
0307     readl(mmio + HOST_CTL); /* flush */
0308     spin_unlock_irqrestore(&host->lock, flags);
0309 
0310     return ata_do_dev_read_id(dev, tf, id);
0311 
0312 disable_phys:
0313     while (--i >= 0) {
0314         phy_power_off(hpriv->phys[i]);
0315         phy_exit(hpriv->phys[i]);
0316     }
0317 
0318     return AC_ERR_OTHER;
0319 }
0320 
0321 static void brcm_ahci_host_stop(struct ata_host *host)
0322 {
0323     struct ahci_host_priv *hpriv = host->private_data;
0324 
0325     ahci_platform_disable_resources(hpriv);
0326 }
0327 
0328 static struct ata_port_operations ahci_brcm_platform_ops = {
0329     .inherits   = &ahci_ops,
0330     .host_stop  = brcm_ahci_host_stop,
0331     .read_id    = brcm_ahci_read_id,
0332 };
0333 
0334 static const struct ata_port_info ahci_brcm_port_info = {
0335     .flags      = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
0336     .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY,
0337     .pio_mask   = ATA_PIO4,
0338     .udma_mask  = ATA_UDMA6,
0339     .port_ops   = &ahci_brcm_platform_ops,
0340 };
0341 
0342 static int brcm_ahci_suspend(struct device *dev)
0343 {
0344     struct ata_host *host = dev_get_drvdata(dev);
0345     struct ahci_host_priv *hpriv = host->private_data;
0346     struct brcm_ahci_priv *priv = hpriv->plat_data;
0347     int ret;
0348 
0349     brcm_sata_phys_disable(priv);
0350 
0351     if (IS_ENABLED(CONFIG_PM_SLEEP))
0352         ret = ahci_platform_suspend(dev);
0353     else
0354         ret = 0;
0355 
0356     reset_control_assert(priv->rcdev_ahci);
0357     reset_control_rearm(priv->rcdev_rescal);
0358 
0359     return ret;
0360 }
0361 
0362 static int __maybe_unused brcm_ahci_resume(struct device *dev)
0363 {
0364     struct ata_host *host = dev_get_drvdata(dev);
0365     struct ahci_host_priv *hpriv = host->private_data;
0366     struct brcm_ahci_priv *priv = hpriv->plat_data;
0367     int ret = 0;
0368 
0369     ret = reset_control_deassert(priv->rcdev_ahci);
0370     if (ret)
0371         return ret;
0372     ret = reset_control_reset(priv->rcdev_rescal);
0373     if (ret)
0374         return ret;
0375 
0376     /* Make sure clocks are turned on before re-configuration */
0377     ret = ahci_platform_enable_clks(hpriv);
0378     if (ret)
0379         return ret;
0380 
0381     ret = ahci_platform_enable_regulators(hpriv);
0382     if (ret)
0383         goto out_disable_clks;
0384 
0385     brcm_sata_init(priv);
0386     brcm_sata_phys_enable(priv);
0387     brcm_sata_alpm_init(hpriv);
0388 
0389     /* Since we had to enable clocks earlier on, we cannot use
0390      * ahci_platform_resume() as-is since a second call to
0391      * ahci_platform_enable_resources() would bump up the resources
0392      * (regulators, clocks, PHYs) count artificially so we copy the part
0393      * after ahci_platform_enable_resources().
0394      */
0395     ret = ahci_platform_enable_phys(hpriv);
0396     if (ret)
0397         goto out_disable_phys;
0398 
0399     ret = ahci_platform_resume_host(dev);
0400     if (ret)
0401         goto out_disable_platform_phys;
0402 
0403     /* We resumed so update PM runtime state */
0404     pm_runtime_disable(dev);
0405     pm_runtime_set_active(dev);
0406     pm_runtime_enable(dev);
0407 
0408     return 0;
0409 
0410 out_disable_platform_phys:
0411     ahci_platform_disable_phys(hpriv);
0412 out_disable_phys:
0413     brcm_sata_phys_disable(priv);
0414     ahci_platform_disable_regulators(hpriv);
0415 out_disable_clks:
0416     ahci_platform_disable_clks(hpriv);
0417     return ret;
0418 }
0419 
0420 static struct scsi_host_template ahci_platform_sht = {
0421     AHCI_SHT(DRV_NAME),
0422 };
0423 
0424 static const struct of_device_id ahci_of_match[] = {
0425     {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
0426     {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
0427     {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445},
0428     {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
0429     {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216},
0430     { /* sentinel */ }
0431 };
0432 MODULE_DEVICE_TABLE(of, ahci_of_match);
0433 
0434 static int brcm_ahci_probe(struct platform_device *pdev)
0435 {
0436     const struct of_device_id *of_id;
0437     struct device *dev = &pdev->dev;
0438     struct brcm_ahci_priv *priv;
0439     struct ahci_host_priv *hpriv;
0440     struct resource *res;
0441     int ret;
0442 
0443     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0444     if (!priv)
0445         return -ENOMEM;
0446 
0447     of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
0448     if (!of_id)
0449         return -ENODEV;
0450 
0451     priv->version = (enum brcm_ahci_version)of_id->data;
0452     priv->dev = dev;
0453 
0454     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
0455     priv->top_ctrl = devm_ioremap_resource(dev, res);
0456     if (IS_ERR(priv->top_ctrl))
0457         return PTR_ERR(priv->top_ctrl);
0458 
0459     if (priv->version == BRCM_SATA_BCM7216) {
0460         priv->rcdev_rescal = devm_reset_control_get_optional_shared(
0461             &pdev->dev, "rescal");
0462         if (IS_ERR(priv->rcdev_rescal))
0463             return PTR_ERR(priv->rcdev_rescal);
0464     }
0465     priv->rcdev_ahci = devm_reset_control_get_optional(&pdev->dev, "ahci");
0466     if (IS_ERR(priv->rcdev_ahci))
0467         return PTR_ERR(priv->rcdev_ahci);
0468 
0469     hpriv = ahci_platform_get_resources(pdev, 0);
0470     if (IS_ERR(hpriv))
0471         return PTR_ERR(hpriv);
0472 
0473     hpriv->plat_data = priv;
0474     hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO;
0475 
0476     switch (priv->version) {
0477     case BRCM_SATA_BCM7425:
0478         hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE;
0479         fallthrough;
0480     case BRCM_SATA_NSP:
0481         hpriv->flags |= AHCI_HFLAG_NO_NCQ;
0482         priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
0483         break;
0484     default:
0485         break;
0486     }
0487 
0488     ret = reset_control_reset(priv->rcdev_rescal);
0489     if (ret)
0490         return ret;
0491     ret = reset_control_deassert(priv->rcdev_ahci);
0492     if (ret)
0493         return ret;
0494 
0495     ret = ahci_platform_enable_clks(hpriv);
0496     if (ret)
0497         goto out_reset;
0498 
0499     ret = ahci_platform_enable_regulators(hpriv);
0500     if (ret)
0501         goto out_disable_clks;
0502 
0503     /* Must be first so as to configure endianness including that
0504      * of the standard AHCI register space.
0505      */
0506     brcm_sata_init(priv);
0507 
0508     /* Initializes priv->port_mask which is used below */
0509     priv->port_mask = brcm_ahci_get_portmask(hpriv, priv);
0510     if (!priv->port_mask) {
0511         ret = -ENODEV;
0512         goto out_disable_regulators;
0513     }
0514 
0515     /* Must be done before ahci_platform_enable_phys() */
0516     brcm_sata_phys_enable(priv);
0517 
0518     brcm_sata_alpm_init(hpriv);
0519 
0520     ret = ahci_platform_enable_phys(hpriv);
0521     if (ret)
0522         goto out_disable_phys;
0523 
0524     ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info,
0525                       &ahci_platform_sht);
0526     if (ret)
0527         goto out_disable_platform_phys;
0528 
0529     dev_info(dev, "Broadcom AHCI SATA3 registered\n");
0530 
0531     return 0;
0532 
0533 out_disable_platform_phys:
0534     ahci_platform_disable_phys(hpriv);
0535 out_disable_phys:
0536     brcm_sata_phys_disable(priv);
0537 out_disable_regulators:
0538     ahci_platform_disable_regulators(hpriv);
0539 out_disable_clks:
0540     ahci_platform_disable_clks(hpriv);
0541 out_reset:
0542     reset_control_assert(priv->rcdev_ahci);
0543     reset_control_rearm(priv->rcdev_rescal);
0544     return ret;
0545 }
0546 
0547 static int brcm_ahci_remove(struct platform_device *pdev)
0548 {
0549     struct ata_host *host = dev_get_drvdata(&pdev->dev);
0550     struct ahci_host_priv *hpriv = host->private_data;
0551     struct brcm_ahci_priv *priv = hpriv->plat_data;
0552 
0553     brcm_sata_phys_disable(priv);
0554 
0555     return ata_platform_remove_one(pdev);
0556 }
0557 
0558 static void brcm_ahci_shutdown(struct platform_device *pdev)
0559 {
0560     int ret;
0561 
0562     /* All resources releasing happens via devres, but our device, unlike a
0563      * proper remove is not disappearing, therefore using
0564      * brcm_ahci_suspend() here which does explicit power management is
0565      * appropriate.
0566      */
0567     ret = brcm_ahci_suspend(&pdev->dev);
0568     if (ret)
0569         dev_err(&pdev->dev, "failed to shutdown\n");
0570 }
0571 
0572 static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
0573 
0574 static struct platform_driver brcm_ahci_driver = {
0575     .probe = brcm_ahci_probe,
0576     .remove = brcm_ahci_remove,
0577     .shutdown = brcm_ahci_shutdown,
0578     .driver = {
0579         .name = DRV_NAME,
0580         .of_match_table = ahci_of_match,
0581         .pm = &ahci_brcm_pm_ops,
0582     },
0583 };
0584 module_platform_driver(brcm_ahci_driver);
0585 
0586 MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver");
0587 MODULE_AUTHOR("Brian Norris");
0588 MODULE_LICENSE("GPL");
0589 MODULE_ALIAS("platform:sata-brcmstb");