diff options
-rw-r--r-- | arch/powerpc/platforms/85xx/c293pcie.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/corenet_generic.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/ge_imp3a.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc8536_ds.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_cds.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_ds.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_mds.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 10 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/p1010rdb.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/p1022_ds.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/p1022_rdk.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/p1023_rds.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/qemu_e500.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/sbc8548.c | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 245 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.h | 15 |
16 files changed, 264 insertions, 24 deletions
diff --git a/arch/powerpc/platforms/85xx/c293pcie.c b/arch/powerpc/platforms/85xx/c293pcie.c index 6208e49..7afaaff 100644 --- a/arch/powerpc/platforms/85xx/c293pcie.c +++ b/arch/powerpc/platforms/85xx/c293pcie.c @@ -67,6 +67,7 @@ define_machine(c293_pcie) { .init_IRQ = c293_pcie_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index 018ed5d..c086b0b 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -246,6 +246,7 @@ define_machine(corenet_generic) { .init_IRQ = corenet_gen_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_coreint_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/ge_imp3a.c b/arch/powerpc/platforms/85xx/ge_imp3a.c index e6285ae..0b3c041 100644 --- a/arch/powerpc/platforms/85xx/ge_imp3a.c +++ b/arch/powerpc/platforms/85xx/ge_imp3a.c @@ -215,6 +215,7 @@ define_machine(ge_imp3a) { .show_cpuinfo = ge_imp3a_show_cpuinfo, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index 15ce4b5..5c88de0 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -76,6 +76,7 @@ define_machine(mpc8536_ds) { .init_IRQ = mpc8536_ds_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 7a31a0e..633a514 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -385,6 +385,7 @@ define_machine(mpc85xx_cds) { #ifdef CONFIG_PCI .restart = mpc85xx_cds_restart, .pcibios_fixup_bus = mpc85xx_cds_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #else .restart = fsl_rstcr_restart, #endif diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 9ebb91e..e5e4983 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -209,6 +209,7 @@ define_machine(mpc8544_ds) { .init_IRQ = mpc85xx_ds_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -223,6 +224,7 @@ define_machine(mpc8572_ds) { .init_IRQ = mpc85xx_ds_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -237,6 +239,7 @@ define_machine(p2020_ds) { .init_IRQ = mpc85xx_ds_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 3c190b4..c111fba 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -392,6 +392,7 @@ define_machine(mpc8568_mds) { .progress = udbg_progress, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif }; @@ -413,6 +414,7 @@ define_machine(mpc8569_mds) { .progress = udbg_progress, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif }; @@ -435,6 +437,7 @@ define_machine(p1021_mds) { .progress = udbg_progress, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index 71149dc..2746b8b 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c @@ -273,6 +273,7 @@ define_machine(p2020_rdb) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -287,6 +288,7 @@ define_machine(p1020_rdb) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -301,6 +303,7 @@ define_machine(p1021_rdb_pc) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -315,6 +318,7 @@ define_machine(p2020_rdb_pc) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -329,6 +333,7 @@ define_machine(p1025_rdb) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -343,6 +348,7 @@ define_machine(p1020_mbg_pc) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -357,6 +363,7 @@ define_machine(p1020_utm_pc) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -371,6 +378,7 @@ define_machine(p1020_rdb_pc) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -385,6 +393,7 @@ define_machine(p1020_rdb_pd) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, @@ -399,6 +408,7 @@ define_machine(p1024_rdb) { .init_IRQ = mpc85xx_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c index d6a3dd3..1a77ca7 100644 --- a/arch/powerpc/platforms/85xx/p1010rdb.c +++ b/arch/powerpc/platforms/85xx/p1010rdb.c @@ -78,6 +78,7 @@ define_machine(p1010_rdb) { .init_IRQ = p1010_rdb_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 3a68e4b..8a77b12 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -652,6 +652,7 @@ define_machine(p1022_ds) { .init_IRQ = p1022_ds_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c index 8c92971..ba3cc2d 100644 --- a/arch/powerpc/platforms/85xx/p1022_rdk.c +++ b/arch/powerpc/platforms/85xx/p1022_rdk.c @@ -147,6 +147,7 @@ define_machine(p1022_rdk) { .init_IRQ = p1022_rdk_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c index 47cd535..1c5ef8a 100644 --- a/arch/powerpc/platforms/85xx/p1023_rds.c +++ b/arch/powerpc/platforms/85xx/p1023_rds.c @@ -146,6 +146,7 @@ define_machine(p1023_rds) { .progress = udbg_progress, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .init_early = p1023_rds_init_early, }; @@ -162,5 +163,6 @@ define_machine(p1023_rdb) { .init_early = p1023_rds_init_early, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif }; diff --git a/arch/powerpc/platforms/85xx/qemu_e500.c b/arch/powerpc/platforms/85xx/qemu_e500.c index 4677463..a299218 100644 --- a/arch/powerpc/platforms/85xx/qemu_e500.c +++ b/arch/powerpc/platforms/85xx/qemu_e500.c @@ -79,6 +79,7 @@ define_machine(qemu_e500) { .init_IRQ = qemu_e500_pic_init, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .get_irq = mpic_get_coreint_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index f621218..857c532 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c @@ -135,6 +135,7 @@ define_machine(sbc8548) { .restart = fsl_rstcr_restart, #ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, + .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index c89dbac..65be890 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -22,13 +22,17 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/bootmem.h> #include <linux/memblock.h> #include <linux/log2.h> #include <linux/slab.h> +#include <linux/suspend.h> +#include <linux/syscore_ops.h> #include <linux/uaccess.h> #include <asm/io.h> +#include <asm/fsl_pm.h> #include <asm/prom.h> #include <asm/pci-bridge.h> #include <asm/ppc-pci.h> @@ -1153,55 +1157,245 @@ void fsl_pci_assign_primary(void) } } -static int fsl_pci_probe(struct platform_device *pdev) +#ifdef CONFIG_PM_SLEEP +static irqreturn_t fsl_pci_pme_handle(int irq, void *dev_id) { - int ret; - struct device_node *node; + struct pci_controller *hose = dev_id; + struct ccsr_pci __iomem *pci = hose->private_data; + u32 dr; - node = pdev->dev.of_node; - ret = fsl_add_bridge(pdev, fsl_pci_primary == node); + dr = in_be32(&pci->pex_pme_mes_dr); + if (!dr) + return IRQ_NONE; - mpc85xx_pci_err_probe(pdev); + out_be32(&pci->pex_pme_mes_dr, dr); - return ret; + return IRQ_HANDLED; } -#ifdef CONFIG_PM -static int fsl_pci_resume(struct device *dev) +static int fsl_pci_pme_probe(struct pci_controller *hose) { - struct pci_controller *hose; - struct resource pci_rsrc; + struct ccsr_pci __iomem *pci; + struct pci_dev *dev; + int pme_irq; + int res; + u16 pms; + + /* Get hose's pci_dev */ + dev = list_first_entry(&hose->bus->devices, typeof(*dev), bus_list); + + /* PME Disable */ + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms); + pms &= ~PCI_PM_CTRL_PME_ENABLE; + pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms); + + pme_irq = irq_of_parse_and_map(hose->dn, 0); + if (!pme_irq) { + dev_err(&dev->dev, "Failed to map PME interrupt.\n"); + return -ENXIO; + } - hose = pci_find_hose_for_OF_device(dev->of_node); - if (!hose) + res = devm_request_irq(hose->parent, pme_irq, + fsl_pci_pme_handle, + IRQF_SHARED, + "[PCI] PME", hose); + if (res < 0) { + dev_err(&dev->dev, "PCI: Requiest irq %d failed\n", pme_irq); + irq_dispose_mapping(pme_irq); return -ENODEV; + } - if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) { - dev_err(dev, "Get pci register base failed."); - return -ENODEV; + pci = hose->private_data; + + /* Enable PTOD, ENL23D & EXL23D */ + clrbits32(&pci->pex_pme_mes_disr, + PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D); + + out_be32(&pci->pex_pme_mes_ier, 0); + setbits32(&pci->pex_pme_mes_ier, + PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D); + + /* PME Enable */ + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms); + pms |= PCI_PM_CTRL_PME_ENABLE; + pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms); + + return 0; +} + +static int pcie_slot_flag; + +/* Workaround: p1022ds need reset slot when the system wakeup from deep sleep */ +static int reset_pcie_slot(void) +{ +#ifdef CONFIG_P1022_DS + p1022ds_reset_pcie_slot(); +#endif + return 0; +} + +static void send_pme_turnoff_message(struct pci_controller *hose) +{ + struct ccsr_pci __iomem *pci = hose->private_data; + u32 dr; + int i; + + /* Send PME_Turn_Off Message Request */ + setbits32(&pci->pex_pmcr, PEX_PMCR_PTOMR); + + /* Wait trun off done */ + /* RC will get this detect quickly */ + for (i = 0; i < 50; i++) { + dr = in_be32(&pci->pex_pme_mes_dr); + if (dr & ENL23_DETECT_BIT) { + out_be32(&pci->pex_pme_mes_dr, dr); + break; + } + + mdelay(1); } - setup_pci_atmu(hose); + /* + * "PCI Bus Power Management Interface Specification" define + * Minimum System Software Guaranteed Delays + * + * D0, D1 or D2 --> D3, need delay 10ms. + * But based on my test results, we need to delay 30ms when EP + * plug in p1022 slot2. And we need to delay 100ms when EP plug + * in p1022 slot1. So need to get maximum delay. + */ + mdelay(100); +} + +static void fsl_pci_syscore_do_suspend(struct pci_controller *hose) +{ + suspend_state_t pm_state; + pm_state = pm_suspend_state(); + + send_pme_turnoff_message(hose); + + if (pm_state == PM_SUSPEND_MEM) + pcie_slot_flag = 0; +} + +static int fsl_pci_syscore_suspend(void) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + fsl_pci_syscore_do_suspend(hose); return 0; } -static const struct dev_pm_ops pci_pm_ops = { - .resume = fsl_pci_resume, -}; +#define PCIE_RESET_SLOT_WAITTIME 100000 /* wait 100 ms */ +static void fsl_pci_syscore_do_resume(struct pci_controller *hose) +{ + struct ccsr_pci __iomem *pci = hose->private_data; + struct pci_dev *dev; + u32 svr = mfspr(SPRN_SVR); + u32 dr; + suspend_state_t pm_state; + int i; + u16 pms; -#define PCI_PM_OPS (&pci_pm_ops) + /* Send Exit L2 State Message */ + setbits32(&pci->pex_pmcr, PEX_PMCR_EXL2S); -#else + /* Wait exit done */ + /* RC will get this detect quickly */ + for (i = 0; i < 50; i++) { + dr = in_be32(&pci->pex_pme_mes_dr); + if (dr & EXL23_DETECT_BIT) { + out_be32(&pci->pex_pme_mes_dr, dr); + break; + } + + mdelay(1); + } + + /* + * "PCI Bus Power Management Interface Specification" define + * Minimum System Software Guaranteed Delays + * + * D0, D1 or D2 --> D3, need delay 10ms. + * But based on my test results, we need to delay 30ms when EP + * plug in p1022 slot2. And we need to delay 100ms when EP plug + * in p1022 slot1. So need to get maximum delay. + */ + mdelay(100); + + pm_state = pm_suspend_state(); + if (pm_state != PM_SUSPEND_MEM) + goto setup_atmu; + + /* After resume from deep-sleep, we need to restore below registers */ + /* Enable PTOD, ENL23D & EXL23D */ + clrbits32(&pci->pex_pme_mes_disr, + PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D); + + out_be32(&pci->pex_pme_mes_ier, 0); + setbits32(&pci->pex_pme_mes_ier, + PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D); + + /* Get hose's pci_dev */ + dev = list_first_entry(&hose->bus->devices, typeof(*dev), bus_list); -#define PCI_PM_OPS NULL + /* PME Enable */ + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms); + pms |= PCI_PM_CTRL_PME_ENABLE; + pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms); + + /* Only reset slot, we can rework the EP device */ + if (SVR_SOC_VER(svr) == SVR_P1022 && !pcie_slot_flag) { + reset_pcie_slot(); + pcie_slot_flag = 1; + } + + spin_event_timeout(!fsl_pcie_check_link(hose), + PCIE_RESET_SLOT_WAITTIME, 0); + +setup_atmu: + setup_pci_atmu(hose); +} +static void fsl_pci_syscore_resume(void) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + fsl_pci_syscore_do_resume(hose); +} + +static struct syscore_ops pci_syscore_pm_ops = { + .suspend = fsl_pci_syscore_suspend, + .resume = fsl_pci_syscore_resume, +}; +#endif + +void fsl_pcibios_fixup_phb(struct pci_controller *phb) +{ +#ifdef CONFIG_PM_SLEEP + fsl_pci_pme_probe(phb); #endif +} + +static int fsl_pci_probe(struct platform_device *pdev) +{ + int ret; + struct device_node *node; + + node = pdev->dev.of_node; + ret = fsl_add_bridge(pdev, fsl_pci_primary == node); + + mpc85xx_pci_err_probe(pdev); + + return ret; +} static struct platform_driver fsl_pci_driver = { .driver = { .name = "fsl-pci", - .pm = PCI_PM_OPS, .of_match_table = pci_ids, }, .probe = fsl_pci_probe, @@ -1209,6 +1403,9 @@ static struct platform_driver fsl_pci_driver = { static int __init fsl_pci_init(void) { +#ifdef CONFIG_PM_SLEEP + register_syscore_ops(&pci_syscore_pm_ops); +#endif return platform_driver_register(&fsl_pci_driver); } arch_initcall(fsl_pci_init); diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h index f1b39d9..5d74092 100644 --- a/arch/powerpc/sysdev/fsl_pci.h +++ b/arch/powerpc/sysdev/fsl_pci.h @@ -32,6 +32,16 @@ struct platform_device; #define PIWAR_WRITE_SNOOP 0x00005000 #define PIWAR_SZ_MASK 0x0000003f +#define PEX_PMCR_PTOMR 0x1 +#define PEX_PMCR_EXL2S 0x2 + +#define PME_DISR_EN_PTOD 0x00008000 +#define PME_DISR_EN_ENL23D 0x00002000 +#define PME_DISR_EN_EXL23D 0x00001000 + +#define ENL23_DETECT_BIT 0x00002000 +#define EXL23_DETECT_BIT 0x00001000 + #define PAOR_LIODON_MODE 1 /* To access LIODN permission table */ #define PAOR_MSIX_VECTOR_MODE 2 /* To access MSI-X table structure */ #define PAOR_MSIX_PBA_MODE 3 /* To access MSI-X PBA structure */ @@ -193,6 +203,7 @@ struct vf_atmu_regs { extern int fsl_add_bridge(struct platform_device *pdev, int is_primary); extern void fsl_pcibios_fixup_bus(struct pci_bus *bus); +void fsl_pcibios_fixup_phb(struct pci_controller *phb); extern int mpc83xx_add_bridge(struct device_node *dev); u64 fsl_pci_immrbar_base(struct pci_controller *hose); @@ -206,6 +217,10 @@ void fsl_pci_assign_primary(void); static inline void fsl_pci_assign_primary(void) {} #endif +#ifdef CONFIG_P1022_DS +void p1022ds_reset_pcie_slot(void); +#endif + #ifdef CONFIG_EDAC_MPC85XX int mpc85xx_pci_err_probe(struct platform_device *op); #else |