aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2016-05-20 02:41:41 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-06-21 01:30:58 -0400
commitea0d856cb26d4d78b9529de49a0f89379224e2f9 (patch)
tree3bc16ada897bb1289a663e07177a08eef5ac4a31
parent7e19bf32c8ac977e7702a67d7392a3e0a9644bc8 (diff)
powerpc/powernv: Functions to get/set PCI slot state
This exports 4 functions, which base on the corresponding OPAL APIs to get/set PCI slot status. Those functions are going to be used by PowerNV PCI hotplug driver: pnv_pci_get_device_tree() opal_get_device_tree() pnv_pci_get_presence_state() opal_pci_get_presence_state() pnv_pci_get_power_state() opal_pci_get_power_state() pnv_pci_set_power_state() opal_pci_set_power_state() Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/opal-api.h18
-rw-r--r--arch/powerpc/include/asm/opal.h6
-rw-r--r--arch/powerpc/include/asm/pnv-pci.h6
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S4
-rw-r--r--arch/powerpc/platforms/powernv/pci.c82
5 files changed, 115 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index cd9371b33f1a..72b5f27cd0b8 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -158,7 +158,11 @@
158#define OPAL_LEDS_SET_INDICATOR 115 158#define OPAL_LEDS_SET_INDICATOR 115
159#define OPAL_CEC_REBOOT2 116 159#define OPAL_CEC_REBOOT2 116
160#define OPAL_CONSOLE_FLUSH 117 160#define OPAL_CONSOLE_FLUSH 117
161#define OPAL_LAST 117 161#define OPAL_GET_DEVICE_TREE 118
162#define OPAL_PCI_GET_PRESENCE_STATE 119
163#define OPAL_PCI_GET_POWER_STATE 120
164#define OPAL_PCI_SET_POWER_STATE 121
165#define OPAL_LAST 121
162 166
163/* Device tree flags */ 167/* Device tree flags */
164 168
@@ -344,6 +348,18 @@ enum OpalPciResetState {
344 OPAL_ASSERT_RESET = 1 348 OPAL_ASSERT_RESET = 1
345}; 349};
346 350
351enum OpalPciSlotPresence {
352 OPAL_PCI_SLOT_EMPTY = 0,
353 OPAL_PCI_SLOT_PRESENT = 1
354};
355
356enum OpalPciSlotPower {
357 OPAL_PCI_SLOT_POWER_OFF = 0,
358 OPAL_PCI_SLOT_POWER_ON = 1,
359 OPAL_PCI_SLOT_OFFLINE = 2,
360 OPAL_PCI_SLOT_ONLINE = 3
361};
362
347enum OpalSlotLedType { 363enum OpalSlotLedType {
348 OPAL_SLOT_LED_TYPE_ID = 0, /* IDENTIFY LED */ 364 OPAL_SLOT_LED_TYPE_ID = 0, /* IDENTIFY LED */
349 OPAL_SLOT_LED_TYPE_FAULT = 1, /* FAULT LED */ 365 OPAL_SLOT_LED_TYPE_FAULT = 1, /* FAULT LED */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 348132c00601..fa71fea3b6ee 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -209,6 +209,12 @@ int64_t opal_flash_write(uint64_t id, uint64_t offset, uint64_t buf,
209 uint64_t size, uint64_t token); 209 uint64_t size, uint64_t token);
210int64_t opal_flash_erase(uint64_t id, uint64_t offset, uint64_t size, 210int64_t opal_flash_erase(uint64_t id, uint64_t offset, uint64_t size,
211 uint64_t token); 211 uint64_t token);
212int64_t opal_get_device_tree(uint32_t phandle, uint64_t buf, uint64_t len);
213int64_t opal_pci_get_presence_state(uint64_t id, uint64_t data);
214int64_t opal_pci_get_power_state(uint64_t id, uint64_t data);
215int64_t opal_pci_set_power_state(uint64_t async_token, uint64_t id,
216 uint64_t data);
217int64_t opal_pci_poll2(uint64_t id, uint64_t data);
212 218
213/* Internal functions */ 219/* Internal functions */
214extern int early_init_dt_scan_opal(unsigned long node, const char *uname, 220extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h
index 810cc9a8169f..791db1bbd4b9 100644
--- a/arch/powerpc/include/asm/pnv-pci.h
+++ b/arch/powerpc/include/asm/pnv-pci.h
@@ -12,12 +12,18 @@
12 12
13#include <linux/pci.h> 13#include <linux/pci.h>
14#include <misc/cxl-base.h> 14#include <misc/cxl-base.h>
15#include <asm/opal-api.h>
15 16
16#define PCI_SLOT_ID_PREFIX 0x8000000000000000 17#define PCI_SLOT_ID_PREFIX 0x8000000000000000
17#define PCI_SLOT_ID(phb_id, bdfn) \ 18#define PCI_SLOT_ID(phb_id, bdfn) \
18 (PCI_SLOT_ID_PREFIX | ((uint64_t)(bdfn) << 16) | (phb_id)) 19 (PCI_SLOT_ID_PREFIX | ((uint64_t)(bdfn) << 16) | (phb_id))
19 20
20extern int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id); 21extern int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id);
22extern int pnv_pci_get_device_tree(uint32_t phandle, void *buf, uint64_t len);
23extern int pnv_pci_get_presence_state(uint64_t id, uint8_t *state);
24extern int pnv_pci_get_power_state(uint64_t id, uint8_t *state);
25extern int pnv_pci_set_power_state(uint64_t id, uint8_t state,
26 struct opal_msg *msg);
21 27
22int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode); 28int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode);
23int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq, 29int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq,
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index e45b88a5d7e0..3ea1a8559035 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -302,3 +302,7 @@ OPAL_CALL(opal_prd_msg, OPAL_PRD_MSG);
302OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR); 302OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR);
303OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR); 303OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR);
304OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH); 304OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH);
305OPAL_CALL(opal_get_device_tree, OPAL_GET_DEVICE_TREE);
306OPAL_CALL(opal_pci_get_presence_state, OPAL_PCI_GET_PRESENCE_STATE);
307OPAL_CALL(opal_pci_get_power_state, OPAL_PCI_GET_POWER_STATE);
308OPAL_CALL(opal_pci_set_power_state, OPAL_PCI_SET_POWER_STATE);
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 2607d2923b80..62c7637d4831 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -74,6 +74,88 @@ int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id)
74} 74}
75EXPORT_SYMBOL_GPL(pnv_pci_get_slot_id); 75EXPORT_SYMBOL_GPL(pnv_pci_get_slot_id);
76 76
77int pnv_pci_get_device_tree(uint32_t phandle, void *buf, uint64_t len)
78{
79 int64_t rc;
80
81 if (!opal_check_token(OPAL_GET_DEVICE_TREE))
82 return -ENXIO;
83
84 rc = opal_get_device_tree(phandle, (uint64_t)buf, len);
85 if (rc < OPAL_SUCCESS)
86 return -EIO;
87
88 return rc;
89}
90EXPORT_SYMBOL_GPL(pnv_pci_get_device_tree);
91
92int pnv_pci_get_presence_state(uint64_t id, uint8_t *state)
93{
94 int64_t rc;
95
96 if (!opal_check_token(OPAL_PCI_GET_PRESENCE_STATE))
97 return -ENXIO;
98
99 rc = opal_pci_get_presence_state(id, (uint64_t)state);
100 if (rc != OPAL_SUCCESS)
101 return -EIO;
102
103 return 0;
104}
105EXPORT_SYMBOL_GPL(pnv_pci_get_presence_state);
106
107int pnv_pci_get_power_state(uint64_t id, uint8_t *state)
108{
109 int64_t rc;
110
111 if (!opal_check_token(OPAL_PCI_GET_POWER_STATE))
112 return -ENXIO;
113
114 rc = opal_pci_get_power_state(id, (uint64_t)state);
115 if (rc != OPAL_SUCCESS)
116 return -EIO;
117
118 return 0;
119}
120EXPORT_SYMBOL_GPL(pnv_pci_get_power_state);
121
122int pnv_pci_set_power_state(uint64_t id, uint8_t state, struct opal_msg *msg)
123{
124 struct opal_msg m;
125 int token, ret;
126 int64_t rc;
127
128 if (!opal_check_token(OPAL_PCI_SET_POWER_STATE))
129 return -ENXIO;
130
131 token = opal_async_get_token_interruptible();
132 if (unlikely(token < 0))
133 return token;
134
135 rc = opal_pci_set_power_state(token, id, (uint64_t)&state);
136 if (rc == OPAL_SUCCESS) {
137 ret = 0;
138 goto exit;
139 } else if (rc != OPAL_ASYNC_COMPLETION) {
140 ret = -EIO;
141 goto exit;
142 }
143
144 ret = opal_async_wait_response(token, &m);
145 if (ret < 0)
146 goto exit;
147
148 if (msg) {
149 ret = 1;
150 memcpy(msg, &m, sizeof(m));
151 }
152
153exit:
154 opal_async_release_token(token);
155 return ret;
156}
157EXPORT_SYMBOL_GPL(pnv_pci_set_power_state);
158
77#ifdef CONFIG_PCI_MSI 159#ifdef CONFIG_PCI_MSI
78int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 160int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
79{ 161{