diff options
| -rw-r--r-- | drivers/pci/host/pci-mvebu.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 1309cfbaa719..1ab863551920 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
| @@ -129,6 +129,7 @@ struct mvebu_pcie_port { | |||
| 129 | size_t memwin_size; | 129 | size_t memwin_size; |
| 130 | phys_addr_t iowin_base; | 130 | phys_addr_t iowin_base; |
| 131 | size_t iowin_size; | 131 | size_t iowin_size; |
| 132 | u32 saved_pcie_stat; | ||
| 132 | }; | 133 | }; |
| 133 | 134 | ||
| 134 | static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) | 135 | static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) |
| @@ -899,6 +900,35 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie) | |||
| 899 | pcie->msi->dev = &pcie->pdev->dev; | 900 | pcie->msi->dev = &pcie->pdev->dev; |
| 900 | } | 901 | } |
| 901 | 902 | ||
| 903 | static int mvebu_pcie_suspend(struct device *dev) | ||
| 904 | { | ||
| 905 | struct mvebu_pcie *pcie; | ||
| 906 | int i; | ||
| 907 | |||
| 908 | pcie = dev_get_drvdata(dev); | ||
| 909 | for (i = 0; i < pcie->nports; i++) { | ||
| 910 | struct mvebu_pcie_port *port = pcie->ports + i; | ||
| 911 | port->saved_pcie_stat = mvebu_readl(port, PCIE_STAT_OFF); | ||
| 912 | } | ||
| 913 | |||
| 914 | return 0; | ||
| 915 | } | ||
| 916 | |||
| 917 | static int mvebu_pcie_resume(struct device *dev) | ||
| 918 | { | ||
| 919 | struct mvebu_pcie *pcie; | ||
| 920 | int i; | ||
| 921 | |||
| 922 | pcie = dev_get_drvdata(dev); | ||
| 923 | for (i = 0; i < pcie->nports; i++) { | ||
| 924 | struct mvebu_pcie_port *port = pcie->ports + i; | ||
| 925 | mvebu_writel(port, port->saved_pcie_stat, PCIE_STAT_OFF); | ||
| 926 | mvebu_pcie_setup_hw(port); | ||
| 927 | } | ||
| 928 | |||
| 929 | return 0; | ||
| 930 | } | ||
| 931 | |||
| 902 | static int mvebu_pcie_probe(struct platform_device *pdev) | 932 | static int mvebu_pcie_probe(struct platform_device *pdev) |
| 903 | { | 933 | { |
| 904 | struct mvebu_pcie *pcie; | 934 | struct mvebu_pcie *pcie; |
| @@ -1056,6 +1086,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev) | |||
| 1056 | mvebu_pcie_msi_enable(pcie); | 1086 | mvebu_pcie_msi_enable(pcie); |
| 1057 | mvebu_pcie_enable(pcie); | 1087 | mvebu_pcie_enable(pcie); |
| 1058 | 1088 | ||
| 1089 | platform_set_drvdata(pdev, pcie); | ||
| 1090 | |||
| 1059 | return 0; | 1091 | return 0; |
| 1060 | } | 1092 | } |
| 1061 | 1093 | ||
| @@ -1068,12 +1100,18 @@ static const struct of_device_id mvebu_pcie_of_match_table[] = { | |||
| 1068 | }; | 1100 | }; |
| 1069 | MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table); | 1101 | MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table); |
| 1070 | 1102 | ||
| 1103 | static struct dev_pm_ops mvebu_pcie_pm_ops = { | ||
| 1104 | .suspend_noirq = mvebu_pcie_suspend, | ||
| 1105 | .resume_noirq = mvebu_pcie_resume, | ||
| 1106 | }; | ||
| 1107 | |||
| 1071 | static struct platform_driver mvebu_pcie_driver = { | 1108 | static struct platform_driver mvebu_pcie_driver = { |
| 1072 | .driver = { | 1109 | .driver = { |
| 1073 | .name = "mvebu-pcie", | 1110 | .name = "mvebu-pcie", |
| 1074 | .of_match_table = mvebu_pcie_of_match_table, | 1111 | .of_match_table = mvebu_pcie_of_match_table, |
| 1075 | /* driver unloading/unbinding currently not supported */ | 1112 | /* driver unloading/unbinding currently not supported */ |
| 1076 | .suppress_bind_attrs = true, | 1113 | .suppress_bind_attrs = true, |
| 1114 | .pm = &mvebu_pcie_pm_ops, | ||
| 1077 | }, | 1115 | }, |
| 1078 | .probe = mvebu_pcie_probe, | 1116 | .probe = mvebu_pcie_probe, |
| 1079 | }; | 1117 | }; |
