PCI: dwc: dra7xx: Facilitate wrapper and MSI interrupts to be enabled independently
[linux-2.6-block.git] / drivers / pci / dwc / pci-dra7xx.c
CommitLineData
47ff3de9
KVA
1/*
2 * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs
3 *
4 * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Authors: Kishon Vijay Abraham I <kishon@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
47ff3de9
KVA
13#include <linux/err.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/irqdomain.h>
17#include <linux/kernel.h>
d29438d6 18#include <linux/init.h>
78bdcad0 19#include <linux/of_gpio.h>
ab5fe4f4 20#include <linux/of_pci.h>
47ff3de9
KVA
21#include <linux/pci.h>
22#include <linux/phy/phy.h>
23#include <linux/platform_device.h>
24#include <linux/pm_runtime.h>
25#include <linux/resource.h>
26#include <linux/types.h>
27
28#include "pcie-designware.h"
29
30/* PCIe controller wrapper DRA7XX configuration registers */
31
32#define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN 0x0024
33#define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN 0x0028
34#define ERR_SYS BIT(0)
35#define ERR_FATAL BIT(1)
36#define ERR_NONFATAL BIT(2)
37#define ERR_COR BIT(3)
38#define ERR_AXI BIT(4)
39#define ERR_ECRC BIT(5)
40#define PME_TURN_OFF BIT(8)
41#define PME_TO_ACK BIT(9)
42#define PM_PME BIT(10)
43#define LINK_REQ_RST BIT(11)
44#define LINK_UP_EVT BIT(12)
45#define CFG_BME_EVT BIT(13)
46#define CFG_MSE_EVT BIT(14)
47#define INTERRUPTS (ERR_SYS | ERR_FATAL | ERR_NONFATAL | ERR_COR | ERR_AXI | \
48 ERR_ECRC | PME_TURN_OFF | PME_TO_ACK | PM_PME | \
49 LINK_REQ_RST | LINK_UP_EVT | CFG_BME_EVT | CFG_MSE_EVT)
50
51#define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI 0x0034
52#define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI 0x0038
53#define INTA BIT(0)
54#define INTB BIT(1)
55#define INTC BIT(2)
56#define INTD BIT(3)
57#define MSI BIT(4)
58#define LEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD)
59
60#define PCIECTRL_DRA7XX_CONF_DEVICE_CMD 0x0104
61#define LTSSM_EN 0x1
62
63#define PCIECTRL_DRA7XX_CONF_PHY_CS 0x010C
64#define LINK_UP BIT(16)
883cc17c 65#define DRA7XX_CPU_TO_BUS_ADDR 0x0FFFFFFF
47ff3de9 66
ab5fe4f4
KVA
67#define EXP_CAP_ID_OFFSET 0x70
68
47ff3de9 69struct dra7xx_pcie {
442ec4c0 70 struct dw_pcie *pci;
8e5ec414
BH
71 void __iomem *base; /* DT ti_conf */
72 int phy_count; /* DT phy-names count */
73 struct phy **phy;
ab5fe4f4 74 int link_gen;
ebe85a44 75 struct irq_domain *irq_domain;
47ff3de9
KVA
76};
77
442ec4c0 78#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev)
47ff3de9
KVA
79
80static inline u32 dra7xx_pcie_readl(struct dra7xx_pcie *pcie, u32 offset)
81{
82 return readl(pcie->base + offset);
83}
84
85static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
86 u32 value)
87{
88 writel(value, pcie->base + offset);
89}
90
2ed6cc71
KVA
91static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr)
92{
93 return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
94}
95
442ec4c0 96static int dra7xx_pcie_link_up(struct dw_pcie *pci)
47ff3de9 97{
442ec4c0 98 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
47ff3de9
KVA
99 u32 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS);
100
101 return !!(reg & LINK_UP);
102}
103
21baa1c4 104static int dra7xx_pcie_establish_link(struct dra7xx_pcie *dra7xx)
47ff3de9 105{
442ec4c0
KVA
106 struct dw_pcie *pci = dra7xx->pci;
107 struct device *dev = pci->dev;
6cbb247e 108 u32 reg;
ab5fe4f4 109 u32 exp_cap_off = EXP_CAP_ID_OFFSET;
47ff3de9 110
442ec4c0 111 if (dw_pcie_link_up(pci)) {
c7f8146b 112 dev_err(dev, "link is already up\n");
47ff3de9
KVA
113 return 0;
114 }
115
ab5fe4f4 116 if (dra7xx->link_gen == 1) {
442ec4c0 117 dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCAP,
19ce01cc 118 4, &reg);
ab5fe4f4
KVA
119 if ((reg & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
120 reg &= ~((u32)PCI_EXP_LNKCAP_SLS);
121 reg |= PCI_EXP_LNKCAP_SLS_2_5GB;
442ec4c0 122 dw_pcie_write(pci->dbi_base + exp_cap_off +
19ce01cc 123 PCI_EXP_LNKCAP, 4, reg);
ab5fe4f4
KVA
124 }
125
442ec4c0 126 dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCTL2,
19ce01cc 127 2, &reg);
ab5fe4f4
KVA
128 if ((reg & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
129 reg &= ~((u32)PCI_EXP_LNKCAP_SLS);
130 reg |= PCI_EXP_LNKCAP_SLS_2_5GB;
442ec4c0 131 dw_pcie_write(pci->dbi_base + exp_cap_off +
19ce01cc 132 PCI_EXP_LNKCTL2, 2, reg);
ab5fe4f4
KVA
133 }
134 }
135
47ff3de9
KVA
136 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD);
137 reg |= LTSSM_EN;
138 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
139
442ec4c0 140 return dw_pcie_wait_for_link(pci);
47ff3de9
KVA
141}
142
5ffd90a0 143static void dra7xx_pcie_enable_msi_interrupts(struct dra7xx_pcie *dra7xx)
47ff3de9 144{
47ff3de9
KVA
145 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI,
146 ~LEG_EP_INTERRUPTS & ~MSI);
5ffd90a0
KVA
147
148 dra7xx_pcie_writel(dra7xx,
149 PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI,
ebe85a44 150 MSI | LEG_EP_INTERRUPTS);
47ff3de9
KVA
151}
152
5ffd90a0
KVA
153static void dra7xx_pcie_enable_wrapper_interrupts(struct dra7xx_pcie *dra7xx)
154{
155 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN,
156 ~INTERRUPTS);
157 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN,
158 INTERRUPTS);
159}
160
161static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx)
162{
163 dra7xx_pcie_enable_wrapper_interrupts(dra7xx);
164 dra7xx_pcie_enable_msi_interrupts(dra7xx);
165}
166
47ff3de9
KVA
167static void dra7xx_pcie_host_init(struct pcie_port *pp)
168{
442ec4c0
KVA
169 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
170 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
21baa1c4 171
7e57fd14
JZ
172 dw_pcie_setup_rc(pp);
173
21baa1c4 174 dra7xx_pcie_establish_link(dra7xx);
ebe85a44 175 dw_pcie_msi_init(pp);
21baa1c4 176 dra7xx_pcie_enable_interrupts(dra7xx);
47ff3de9
KVA
177}
178
442ec4c0 179static struct dw_pcie_host_ops dra7xx_pcie_host_ops = {
47ff3de9
KVA
180 .host_init = dra7xx_pcie_host_init,
181};
182
183static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
184 irq_hw_number_t hwirq)
185{
186 irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
187 irq_set_chip_data(irq, domain->host_data);
47ff3de9
KVA
188
189 return 0;
190}
191
192static const struct irq_domain_ops intx_domain_ops = {
193 .map = dra7xx_pcie_intx_map,
194};
195
196static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
197{
442ec4c0
KVA
198 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
199 struct device *dev = pci->dev;
200 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
47ff3de9
KVA
201 struct device_node *node = dev->of_node;
202 struct device_node *pcie_intc_node = of_get_next_child(node, NULL);
203
204 if (!pcie_intc_node) {
205 dev_err(dev, "No PCIe Intc node found\n");
991bfef8 206 return -ENODEV;
47ff3de9
KVA
207 }
208
ebe85a44
KVA
209 dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, 4,
210 &intx_domain_ops, pp);
211 if (!dra7xx->irq_domain) {
47ff3de9 212 dev_err(dev, "Failed to get a INTx IRQ domain\n");
991bfef8 213 return -ENODEV;
47ff3de9
KVA
214 }
215
216 return 0;
217}
218
219static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
220{
21baa1c4 221 struct dra7xx_pcie *dra7xx = arg;
442ec4c0
KVA
222 struct dw_pcie *pci = dra7xx->pci;
223 struct pcie_port *pp = &pci->pp;
47ff3de9
KVA
224 u32 reg;
225
226 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
227
228 switch (reg) {
229 case MSI:
230 dw_handle_msi_irq(pp);
231 break;
232 case INTA:
233 case INTB:
234 case INTC:
235 case INTD:
ebe85a44
KVA
236 generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
237 ffs(reg)));
47ff3de9
KVA
238 break;
239 }
240
241 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg);
242
243 return IRQ_HANDLED;
244}
245
246
247static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
248{
249 struct dra7xx_pcie *dra7xx = arg;
442ec4c0
KVA
250 struct dw_pcie *pci = dra7xx->pci;
251 struct device *dev = pci->dev;
47ff3de9
KVA
252 u32 reg;
253
254 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN);
255
256 if (reg & ERR_SYS)
c7f8146b 257 dev_dbg(dev, "System Error\n");
47ff3de9
KVA
258
259 if (reg & ERR_FATAL)
c7f8146b 260 dev_dbg(dev, "Fatal Error\n");
47ff3de9
KVA
261
262 if (reg & ERR_NONFATAL)
c7f8146b 263 dev_dbg(dev, "Non Fatal Error\n");
47ff3de9
KVA
264
265 if (reg & ERR_COR)
c7f8146b 266 dev_dbg(dev, "Correctable Error\n");
47ff3de9
KVA
267
268 if (reg & ERR_AXI)
c7f8146b 269 dev_dbg(dev, "AXI tag lookup fatal Error\n");
47ff3de9
KVA
270
271 if (reg & ERR_ECRC)
c7f8146b 272 dev_dbg(dev, "ECRC Error\n");
47ff3de9
KVA
273
274 if (reg & PME_TURN_OFF)
c7f8146b 275 dev_dbg(dev,
47ff3de9
KVA
276 "Power Management Event Turn-Off message received\n");
277
278 if (reg & PME_TO_ACK)
c7f8146b 279 dev_dbg(dev,
47ff3de9
KVA
280 "Power Management Turn-Off Ack message received\n");
281
282 if (reg & PM_PME)
c7f8146b 283 dev_dbg(dev, "PM Power Management Event message received\n");
47ff3de9
KVA
284
285 if (reg & LINK_REQ_RST)
c7f8146b 286 dev_dbg(dev, "Link Request Reset\n");
47ff3de9
KVA
287
288 if (reg & LINK_UP_EVT)
c7f8146b 289 dev_dbg(dev, "Link-up state change\n");
47ff3de9
KVA
290
291 if (reg & CFG_BME_EVT)
c7f8146b 292 dev_dbg(dev, "CFG 'Bus Master Enable' change\n");
47ff3de9
KVA
293
294 if (reg & CFG_MSE_EVT)
c7f8146b 295 dev_dbg(dev, "CFG 'Memory Space Enable' change\n");
47ff3de9
KVA
296
297 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN, reg);
298
299 return IRQ_HANDLED;
300}
301
e73044a0
JH
302static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
303 struct platform_device *pdev)
47ff3de9
KVA
304{
305 int ret;
442ec4c0
KVA
306 struct dw_pcie *pci = dra7xx->pci;
307 struct pcie_port *pp = &pci->pp;
308 struct device *dev = pci->dev;
47ff3de9 309 struct resource *res;
47ff3de9
KVA
310
311 pp->irq = platform_get_irq(pdev, 1);
312 if (pp->irq < 0) {
313 dev_err(dev, "missing IRQ resource\n");
314 return -EINVAL;
315 }
316
c7f8146b 317 ret = devm_request_irq(dev, pp->irq, dra7xx_pcie_msi_irq_handler,
8ff0ef99 318 IRQF_SHARED | IRQF_NO_THREAD,
21baa1c4 319 "dra7-pcie-msi", dra7xx);
47ff3de9 320 if (ret) {
c7f8146b 321 dev_err(dev, "failed to request irq\n");
47ff3de9
KVA
322 return ret;
323 }
324
ebe85a44
KVA
325 ret = dra7xx_pcie_init_irq_domain(pp);
326 if (ret < 0)
327 return ret;
47ff3de9
KVA
328
329 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics");
442ec4c0
KVA
330 pci->dbi_base = devm_ioremap(dev, res->start, resource_size(res));
331 if (!pci->dbi_base)
47ff3de9
KVA
332 return -ENOMEM;
333
334 ret = dw_pcie_host_init(pp);
335 if (ret) {
c7f8146b 336 dev_err(dev, "failed to initialize host\n");
47ff3de9
KVA
337 return ret;
338 }
339
340 return 0;
341}
342
442ec4c0 343static const struct dw_pcie_ops dw_pcie_ops = {
2ed6cc71 344 .cpu_addr_fixup = dra7xx_pcie_cpu_addr_fixup,
442ec4c0
KVA
345 .link_up = dra7xx_pcie_link_up,
346};
347
1f6c4501
KVA
348static void dra7xx_pcie_disable_phy(struct dra7xx_pcie *dra7xx)
349{
350 int phy_count = dra7xx->phy_count;
351
352 while (phy_count--) {
353 phy_power_off(dra7xx->phy[phy_count]);
354 phy_exit(dra7xx->phy[phy_count]);
355 }
356}
357
358static int dra7xx_pcie_enable_phy(struct dra7xx_pcie *dra7xx)
359{
360 int phy_count = dra7xx->phy_count;
361 int ret;
362 int i;
363
364 for (i = 0; i < phy_count; i++) {
365 ret = phy_init(dra7xx->phy[i]);
366 if (ret < 0)
367 goto err_phy;
368
369 ret = phy_power_on(dra7xx->phy[i]);
370 if (ret < 0) {
371 phy_exit(dra7xx->phy[i]);
372 goto err_phy;
373 }
374 }
375
376 return 0;
377
378err_phy:
379 while (--i >= 0) {
380 phy_power_off(dra7xx->phy[i]);
381 phy_exit(dra7xx->phy[i]);
382 }
383
384 return ret;
385}
386
47ff3de9
KVA
387static int __init dra7xx_pcie_probe(struct platform_device *pdev)
388{
389 u32 reg;
390 int ret;
391 int irq;
392 int i;
393 int phy_count;
394 struct phy **phy;
395 void __iomem *base;
396 struct resource *res;
442ec4c0 397 struct dw_pcie *pci;
150645b9 398 struct pcie_port *pp;
442ec4c0 399 struct dra7xx_pcie *dra7xx;
47ff3de9
KVA
400 struct device *dev = &pdev->dev;
401 struct device_node *np = dev->of_node;
402 char name[10];
602d38bc 403 struct gpio_desc *reset;
47ff3de9
KVA
404
405 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
406 if (!dra7xx)
407 return -ENOMEM;
408
442ec4c0
KVA
409 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
410 if (!pci)
411 return -ENOMEM;
412
413 pci->dev = dev;
414 pci->ops = &dw_pcie_ops;
415
416 pp = &pci->pp;
150645b9
BH
417 pp->ops = &dra7xx_pcie_host_ops;
418
47ff3de9
KVA
419 irq = platform_get_irq(pdev, 0);
420 if (irq < 0) {
421 dev_err(dev, "missing IRQ resource\n");
422 return -EINVAL;
423 }
424
47ff3de9
KVA
425 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf");
426 base = devm_ioremap_nocache(dev, res->start, resource_size(res));
427 if (!base)
428 return -ENOMEM;
429
430 phy_count = of_property_count_strings(np, "phy-names");
431 if (phy_count < 0) {
432 dev_err(dev, "unable to find the strings\n");
433 return phy_count;
434 }
435
436 phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL);
437 if (!phy)
438 return -ENOMEM;
439
440 for (i = 0; i < phy_count; i++) {
441 snprintf(name, sizeof(name), "pcie-phy%d", i);
442 phy[i] = devm_phy_get(dev, name);
443 if (IS_ERR(phy[i]))
444 return PTR_ERR(phy[i]);
47ff3de9
KVA
445 }
446
447 dra7xx->base = base;
448 dra7xx->phy = phy;
442ec4c0 449 dra7xx->pci = pci;
47ff3de9
KVA
450 dra7xx->phy_count = phy_count;
451
1f6c4501
KVA
452 ret = dra7xx_pcie_enable_phy(dra7xx);
453 if (ret) {
454 dev_err(dev, "failed to enable phy\n");
455 return ret;
456 }
457
9bcf0a6f
KVA
458 platform_set_drvdata(pdev, dra7xx);
459
47ff3de9
KVA
460 pm_runtime_enable(dev);
461 ret = pm_runtime_get_sync(dev);
d3f4caa3 462 if (ret < 0) {
47ff3de9 463 dev_err(dev, "pm_runtime_get_sync failed\n");
0e2bdb0e 464 goto err_get_sync;
47ff3de9
KVA
465 }
466
602d38bc
KVA
467 reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
468 if (IS_ERR(reset)) {
469 ret = PTR_ERR(reset);
470 dev_err(&pdev->dev, "gpio request failed, ret %d\n", ret);
78bdcad0 471 goto err_gpio;
47ff3de9
KVA
472 }
473
474 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD);
475 reg &= ~LTSSM_EN;
476 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
477
ab5fe4f4
KVA
478 dra7xx->link_gen = of_pci_get_max_link_speed(np);
479 if (dra7xx->link_gen < 0 || dra7xx->link_gen > 2)
480 dra7xx->link_gen = 2;
481
23926c8d 482 ret = dra7xx_add_pcie_port(dra7xx, pdev);
47ff3de9 483 if (ret < 0)
78bdcad0 484 goto err_gpio;
47ff3de9 485
d4c7d1a0
K
486 ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler,
487 IRQF_SHARED, "dra7xx-pcie-main", dra7xx);
488 if (ret) {
489 dev_err(dev, "failed to request irq\n");
490 goto err_gpio;
491 }
492
47ff3de9
KVA
493 return 0;
494
78bdcad0 495err_gpio:
47ff3de9 496 pm_runtime_put(dev);
0e2bdb0e
KVA
497
498err_get_sync:
47ff3de9 499 pm_runtime_disable(dev);
1f6c4501 500 dra7xx_pcie_disable_phy(dra7xx);
47ff3de9
KVA
501
502 return ret;
503}
504
e52eb445 505#ifdef CONFIG_PM_SLEEP
389c7094
KVA
506static int dra7xx_pcie_suspend(struct device *dev)
507{
508 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
442ec4c0 509 struct dw_pcie *pci = dra7xx->pci;
389c7094
KVA
510 u32 val;
511
512 /* clear MSE */
442ec4c0 513 val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
389c7094 514 val &= ~PCI_COMMAND_MEMORY;
442ec4c0 515 dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
389c7094
KVA
516
517 return 0;
518}
519
520static int dra7xx_pcie_resume(struct device *dev)
521{
522 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
442ec4c0 523 struct dw_pcie *pci = dra7xx->pci;
389c7094
KVA
524 u32 val;
525
526 /* set MSE */
442ec4c0 527 val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
389c7094 528 val |= PCI_COMMAND_MEMORY;
442ec4c0 529 dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
389c7094
KVA
530
531 return 0;
532}
533
e52eb445
KVA
534static int dra7xx_pcie_suspend_noirq(struct device *dev)
535{
536 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
e52eb445 537
1f6c4501 538 dra7xx_pcie_disable_phy(dra7xx);
e52eb445
KVA
539
540 return 0;
541}
542
543static int dra7xx_pcie_resume_noirq(struct device *dev)
544{
545 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
e52eb445 546 int ret;
e52eb445 547
1f6c4501
KVA
548 ret = dra7xx_pcie_enable_phy(dra7xx);
549 if (ret) {
550 dev_err(dev, "failed to enable phy\n");
551 return ret;
e52eb445
KVA
552 }
553
554 return 0;
e52eb445
KVA
555}
556#endif
557
558static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
389c7094 559 SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume)
e52eb445
KVA
560 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq,
561 dra7xx_pcie_resume_noirq)
562};
563
47ff3de9
KVA
564static const struct of_device_id of_dra7xx_pcie_match[] = {
565 { .compatible = "ti,dra7-pcie", },
566 {},
567};
47ff3de9
KVA
568
569static struct platform_driver dra7xx_pcie_driver = {
47ff3de9
KVA
570 .driver = {
571 .name = "dra7-pcie",
47ff3de9 572 .of_match_table = of_dra7xx_pcie_match,
d29438d6 573 .suppress_bind_attrs = true,
e52eb445 574 .pm = &dra7xx_pcie_pm_ops,
47ff3de9
KVA
575 },
576};
d29438d6 577builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);