12 #include <linux/device.h>
17 #include <asm/hw_irq.h>
20 static int query_token, change_token;
22 #define RTAS_QUERY_FN 0
23 #define RTAS_CHANGE_FN 1
24 #define RTAS_RESET_FN 2
25 #define RTAS_CHANGE_MSI_FN 3
26 #define RTAS_CHANGE_MSIX_FN 4
28 static struct pci_dn *get_pdn(
struct pci_dev *pdev)
33 dn = pci_device_to_OF_node(pdev);
35 dev_dbg(&pdev->
dev,
"rtas_msi: No OF device node\n");
56 addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
57 buid = pdn->phb->buid;
62 rc =
rtas_call(change_token, 6, 4, rtas_ret, addr,
63 BUID_HI(buid), BUID_LO(buid),
64 func, num_irqs, seq_num);
66 rc =
rtas_call(change_token, 6, 3, rtas_ret, addr,
67 BUID_HI(buid), BUID_LO(buid),
68 func, num_irqs, seq_num);
70 seq_num = rtas_ret[1];
82 pr_debug(
"rtas_msi: ibm,change_msi(func=%d,num=%d), got %d rc = %d\n",
83 func, num_irqs, rtas_ret[0], rc);
88 static void rtas_disable_msi(
struct pci_dev *pdev)
105 pr_debug(
"rtas_msi: Setting MSIs to 0 failed!\n");
110 static int rtas_query_irq_number(
struct pci_dn *pdn,
int offset)
116 addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
117 buid = pdn->phb->buid;
120 rc =
rtas_call(query_token, 4, 3, rtas_ret, addr,
121 BUID_HI(buid), BUID_LO(buid), offset);
125 pr_debug(
"rtas_msi: error (%d) querying source number\n", rc);
132 static void rtas_teardown_msi_irqs(
struct pci_dev *pdev)
144 rtas_disable_msi(pdev);
147 static int check_req(
struct pci_dev *pdev,
int nvec,
char *prop_name)
165 if (*req_msi < nvec) {
166 pr_debug(
"rtas_msi: %s requests < %d MSIs\n", prop_name, nvec);
177 static int check_req_msi(
struct pci_dev *pdev,
int nvec)
179 return check_req(pdev, nvec,
"ibm,req#msi");
182 static int check_req_msix(
struct pci_dev *pdev,
int nvec)
184 return check_req(pdev, nvec,
"ibm,req#msi-x");
194 dn = of_node_get(pci_device_to_OF_node(dev));
198 pr_debug(
"rtas_msi: found prop on dn %s\n",
213 struct eeh_dev *edev;
217 dn = pci_device_to_OF_node(dev);
222 edev = of_node_to_eeh_dev(dn);
225 dn = eeh_dev_to_of_node(edev);
250 static void *count_non_bridge_devices(
struct device_node *dn,
void *
data)
285 req =
max(req, (
int)*p);
288 if (req < counts->
quota)
290 else if (req > counts->
quota)
302 pr_debug(
"rtas_msi: calc quota for %s, request %d\n", pci_name(dev),
305 pe_dn = find_pe_total_msi(dev, &total);
307 pe_dn = find_pe_dn(dev, &total);
310 pr_err(
"rtas_msi: couldn't find PE for %s\n", pci_name(dev));
322 pr_err(
"rtas_msi: found 0 devices under PE for %s\n",
328 if (request <= counts.
quota)
332 counts.
requestor = pci_device_to_OF_node(dev);
345 request =
min(counts.
quota, request);
347 pr_debug(
"rtas_msi: request clamped to quota %d\n", request);
354 static int rtas_msi_check_device(
struct pci_dev *pdev,
int nvec,
int type)
359 rc = check_req_msix(pdev, nvec);
361 rc = check_req_msi(pdev, nvec);
366 quota = msi_quota_for_device(pdev, nvec);
368 if (quota && quota < nvec)
374 static int check_msix_entries(
struct pci_dev *pdev)
386 pr_debug(
"rtas_msi: bad MSI-X entries.\n");
395 static int rtas_setup_msi_irqs(
struct pci_dev *pdev,
int nvec_in,
int type)
398 int hwirq, virq,
i,
rc;
416 int quota = msi_quota_for_device(pdev, m);
432 pr_debug(
"rtas_msi: trying the old firmware call.\n");
439 if (nvec != nvec_in) {
443 pr_debug(
"rtas_msi: rtas_change_msi() failed\n");
449 hwirq = rtas_query_irq_number(pdn, i++);
451 pr_debug(
"rtas_msi: error (%d) getting hwirq\n", rc);
458 pr_debug(
"rtas_msi: Failed mapping hwirq %d\n", hwirq);
462 dev_dbg(&pdev->
dev,
"rtas_msi: allocated virq %d\n", virq);
473 static void rtas_msi_pci_irq_fixup(
struct pci_dev *pdev)
477 dev_dbg(&pdev->
dev,
"rtas_msi: no LSI, nothing to do.\n");
482 if (check_req_msi(pdev, 1) && check_req_msix(pdev, 1)) {
483 dev_dbg(&pdev->
dev,
"rtas_msi: no req#msi/x, nothing to do.\n");
487 dev_dbg(&pdev->
dev,
"rtas_msi: disabling existing MSI.\n");
488 rtas_disable_msi(pdev);
491 static int rtas_msi_init(
void)
493 query_token =
rtas_token(
"ibm,query-interrupt-source-number");
496 if ((query_token == RTAS_UNKNOWN_SERVICE) ||
497 (change_token == RTAS_UNKNOWN_SERVICE)) {
498 pr_debug(
"rtas_msi: no RTAS tokens, no MSI support.\n");
502 pr_debug(
"rtas_msi: Registering RTAS MSI callbacks.\n");
505 ppc_md.setup_msi_irqs = rtas_setup_msi_irqs;
506 ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs;
507 ppc_md.msi_check_device = rtas_msi_check_device;
510 ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup;