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