aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 21:15:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 21:15:38 -0500
commitd3f180ea1a44aecba1b0dab2a253428e77f906bf (patch)
tree0be6eaf1eb3fd32c934bd070a3d758696f417c93 /arch/powerpc/platforms/powernv
parent6b00f7efb5303418c231994c91fb8239f5ada260 (diff)
parenta6130ed253a931d2169c26ab0958d81b0dce4d6e (diff)
Merge tag 'powerpc-3.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux
Pull powerpc updates from Michael Ellerman: - Update of all defconfigs - Addition of a bunch of config options to modernise our defconfigs - Some PS3 updates from Geoff - Optimised memcmp for 64 bit from Anton - Fix for kprobes that allows 'perf probe' to work from Naveen - Several cxl updates from Ian & Ryan - Expanded support for the '24x7' PMU from Cody & Sukadev - Freescale updates from Scott: "Highlights include 8xx optimizations, some more work on datapath device tree content, e300 machine check support, t1040 corenet error reporting, and various cleanups and fixes" * tag 'powerpc-3.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux: (102 commits) cxl: Add missing return statement after handling AFU errror cxl: Fail AFU initialisation if an invalid configuration record is found cxl: Export optional AFU configuration record in sysfs powerpc/mm: Warn on flushing tlb page in kernel context powerpc/powernv: Add OPAL soft-poweroff routine powerpc/perf/hv-24x7: Document sysfs event description entries powerpc/perf/hv-gpci: add the remaining gpci requests powerpc/perf/{hv-gpci, hv-common}: generate requests with counters annotated powerpc/perf/hv-24x7: parse catalog and populate sysfs with events perf: define EVENT_DEFINE_RANGE_FORMAT_LITE helper perf: add PMU_EVENT_ATTR_STRING() helper perf: provide sysfs_show for struct perf_pmu_events_attr powerpc/kernel: Avoid initializing device-tree pointer twice powerpc: Remove old compile time disabled syscall tracing code powerpc/kernel: Make syscall_exit a local label cxl: Fix device_node reference counting powerpc/mm: bail out early when flushing TLB page powerpc: defconfigs: add MTD_SPI_NOR (new dependency for M25P80) perf/powerpc: reset event hw state when adding it to the PMU powerpc/qe: Use strlcpy() ...
Diffstat (limited to 'arch/powerpc/platforms/powernv')
-rw-r--r--arch/powerpc/platforms/powernv/Makefile2
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c11
-rw-r--r--arch/powerpc/platforms/powernv/opal-power.c65
-rw-r--r--arch/powerpc/platforms/powernv/opal.c72
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c41
-rw-r--r--arch/powerpc/platforms/powernv/pci.c30
6 files changed, 161 insertions, 60 deletions
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index f241accc053d..6f3c5d33c3af 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,7 +1,7 @@
1obj-y += setup.o opal-wrappers.o opal.o opal-async.o 1obj-y += setup.o opal-wrappers.o opal.o opal-async.o
2obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o 2obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
3obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o 3obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
4obj-y += opal-msglog.o opal-hmi.o 4obj-y += opal-msglog.o opal-hmi.o opal-power.o
5 5
6obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o 6obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o
7obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o 7obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 1d19e7917d7f..e261869adc86 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -68,6 +68,17 @@ static int powernv_eeh_init(void)
68 68
69 if (phb->model == PNV_PHB_MODEL_P7IOC) 69 if (phb->model == PNV_PHB_MODEL_P7IOC)
70 eeh_add_flag(EEH_ENABLE_IO_FOR_LOG); 70 eeh_add_flag(EEH_ENABLE_IO_FOR_LOG);
71
72 /*
73 * PE#0 should be regarded as valid by EEH core
74 * if it's not the reserved one. Currently, we
75 * have the reserved PE#0 and PE#127 for PHB3
76 * and P7IOC separately. So we should regard
77 * PE#0 as valid for P7IOC.
78 */
79 if (phb->ioda.reserved_pe != 0)
80 eeh_add_flag(EEH_VALID_PE_ZERO);
81
71 break; 82 break;
72 } 83 }
73 84
diff --git a/arch/powerpc/platforms/powernv/opal-power.c b/arch/powerpc/platforms/powernv/opal-power.c
new file mode 100644
index 000000000000..48bf5b080bcf
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-power.c
@@ -0,0 +1,65 @@
1/*
2 * PowerNV OPAL power control for graceful shutdown handling
3 *
4 * Copyright 2015 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/reboot.h>
14#include <linux/notifier.h>
15
16#include <asm/opal.h>
17#include <asm/machdep.h>
18
19#define SOFT_OFF 0x00
20#define SOFT_REBOOT 0x01
21
22static int opal_power_control_event(struct notifier_block *nb,
23 unsigned long msg_type, void *msg)
24{
25 struct opal_msg *power_msg = msg;
26 uint64_t type;
27
28 type = be64_to_cpu(power_msg->params[0]);
29
30 switch (type) {
31 case SOFT_REBOOT:
32 /* Fall through. The service processor is responsible for
33 * bringing the machine back up */
34 case SOFT_OFF:
35 pr_info("OPAL: poweroff requested\n");
36 orderly_poweroff(true);
37 break;
38 default:
39 pr_err("OPAL: power control type unexpected %016llx\n", type);
40 }
41
42 return 0;
43}
44
45static struct notifier_block opal_power_control_nb = {
46 .notifier_call = opal_power_control_event,
47 .next = NULL,
48 .priority = 0,
49};
50
51static int __init opal_power_control_init(void)
52{
53 int ret;
54
55 ret = opal_message_notifier_register(OPAL_MSG_SHUTDOWN,
56 &opal_power_control_nb);
57 if (ret) {
58 pr_err("%s: Can't register OPAL event notifier (%d)\n",
59 __func__, ret);
60 return ret;
61 }
62
63 return 0;
64}
65machine_subsys_initcall(powernv, opal_power_control_init);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index f10b9ec8c1f5..18fd4e71c9c1 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -208,7 +208,7 @@ static int __init opal_register_exception_handlers(void)
208 * start catching/handling HMI directly in Linux. 208 * start catching/handling HMI directly in Linux.
209 */ 209 */
210 if (!opal_check_token(OPAL_HANDLE_HMI)) { 210 if (!opal_check_token(OPAL_HANDLE_HMI)) {
211 pr_info("opal: Old firmware detected, OPAL handles HMIs.\n"); 211 pr_info("Old firmware detected, OPAL handles HMIs.\n");
212 opal_register_exception_handler( 212 opal_register_exception_handler(
213 OPAL_HYPERVISOR_MAINTENANCE_HANDLER, 213 OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
214 0, glue); 214 0, glue);
@@ -667,7 +667,13 @@ static void __init opal_dump_region_init(void)
667 667
668 /* Register kernel log buffer */ 668 /* Register kernel log buffer */
669 addr = log_buf_addr_get(); 669 addr = log_buf_addr_get();
670 if (addr == NULL)
671 return;
672
670 size = log_buf_len_get(); 673 size = log_buf_len_get();
674 if (size == 0)
675 return;
676
671 rc = opal_register_dump_region(OPAL_DUMP_REGION_LOG_BUF, 677 rc = opal_register_dump_region(OPAL_DUMP_REGION_LOG_BUF,
672 __pa(addr), size); 678 __pa(addr), size);
673 /* Don't warn if this is just an older OPAL that doesn't 679 /* Don't warn if this is just an older OPAL that doesn't
@@ -695,15 +701,54 @@ static void opal_i2c_create_devs(void)
695 of_platform_device_create(np, NULL, NULL); 701 of_platform_device_create(np, NULL, NULL);
696} 702}
697 703
704static void __init opal_irq_init(struct device_node *dn)
705{
706 const __be32 *irqs;
707 int i, irqlen;
708
709 /* Get interrupt property */
710 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
711 opal_irq_count = irqs ? (irqlen / 4) : 0;
712 pr_debug("Found %d interrupts reserved for OPAL\n", opal_irq_count);
713 if (!opal_irq_count)
714 return;
715
716 /* Install interrupt handlers */
717 opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
718 for (i = 0; irqs && i < opal_irq_count; i++, irqs++) {
719 unsigned int irq, virq;
720 int rc;
721
722 /* Get hardware and virtual IRQ */
723 irq = be32_to_cpup(irqs);
724 virq = irq_create_mapping(NULL, irq);
725 if (virq == NO_IRQ) {
726 pr_warn("Failed to map irq 0x%x\n", irq);
727 continue;
728 }
729
730 /* Install interrupt handler */
731 rc = request_irq(virq, opal_interrupt, 0, "opal", NULL);
732 if (rc) {
733 irq_dispose_mapping(virq);
734 pr_warn("Error %d requesting irq %d (0x%x)\n",
735 rc, virq, irq);
736 continue;
737 }
738
739 /* Cache IRQ */
740 opal_irqs[i] = virq;
741 }
742}
743
698static int __init opal_init(void) 744static int __init opal_init(void)
699{ 745{
700 struct device_node *np, *consoles; 746 struct device_node *np, *consoles;
701 const __be32 *irqs; 747 int rc;
702 int rc, i, irqlen;
703 748
704 opal_node = of_find_node_by_path("/ibm,opal"); 749 opal_node = of_find_node_by_path("/ibm,opal");
705 if (!opal_node) { 750 if (!opal_node) {
706 pr_warn("opal: Node not found\n"); 751 pr_warn("Device node not found\n");
707 return -ENODEV; 752 return -ENODEV;
708 } 753 }
709 754
@@ -725,24 +770,7 @@ static int __init opal_init(void)
725 opal_i2c_create_devs(); 770 opal_i2c_create_devs();
726 771
727 /* Find all OPAL interrupts and request them */ 772 /* Find all OPAL interrupts and request them */
728 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); 773 opal_irq_init(opal_node);
729 pr_debug("opal: Found %d interrupts reserved for OPAL\n",
730 irqs ? (irqlen / 4) : 0);
731 opal_irq_count = irqlen / 4;
732 opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
733 for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
734 unsigned int hwirq = be32_to_cpup(irqs);
735 unsigned int irq = irq_create_mapping(NULL, hwirq);
736 if (irq == NO_IRQ) {
737 pr_warning("opal: Failed to map irq 0x%x\n", hwirq);
738 continue;
739 }
740 rc = request_irq(irq, opal_interrupt, 0, "opal", NULL);
741 if (rc)
742 pr_warning("opal: Error %d requesting irq %d"
743 " (0x%x)\n", rc, irq, hwirq);
744 opal_irqs[i] = irq;
745 }
746 774
747 /* Create "opal" kobject under /sys/firmware */ 775 /* Create "opal" kobject under /sys/firmware */
748 rc = opal_sysfs_init(); 776 rc = opal_sysfs_init();
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index fac88ed8a915..6c9ff2b95119 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -75,6 +75,28 @@ static void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
75#define pe_info(pe, fmt, ...) \ 75#define pe_info(pe, fmt, ...) \
76 pe_level_printk(pe, KERN_INFO, fmt, ##__VA_ARGS__) 76 pe_level_printk(pe, KERN_INFO, fmt, ##__VA_ARGS__)
77 77
78static bool pnv_iommu_bypass_disabled __read_mostly;
79
80static int __init iommu_setup(char *str)
81{
82 if (!str)
83 return -EINVAL;
84
85 while (*str) {
86 if (!strncmp(str, "nobypass", 8)) {
87 pnv_iommu_bypass_disabled = true;
88 pr_info("PowerNV: IOMMU bypass window disabled.\n");
89 break;
90 }
91 str += strcspn(str, ",");
92 if (*str == ',')
93 str++;
94 }
95
96 return 0;
97}
98early_param("iommu", iommu_setup);
99
78/* 100/*
79 * stdcix is only supposed to be used in hypervisor real mode as per 101 * stdcix is only supposed to be used in hypervisor real mode as per
80 * the architecture spec 102 * the architecture spec
@@ -357,6 +379,9 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
357 phb->ioda.m64_segsize = phb->ioda.m64_size / phb->ioda.total_pe; 379 phb->ioda.m64_segsize = phb->ioda.m64_size / phb->ioda.total_pe;
358 phb->ioda.m64_base = pci_addr; 380 phb->ioda.m64_base = pci_addr;
359 381
382 pr_info(" MEM64 0x%016llx..0x%016llx -> 0x%016llx\n",
383 res->start, res->end, pci_addr);
384
360 /* Use last M64 BAR to cover M64 window */ 385 /* Use last M64 BAR to cover M64 window */
361 phb->ioda.m64_bar_idx = 15; 386 phb->ioda.m64_bar_idx = 15;
362 phb->init_m64 = pnv_ioda2_init_m64; 387 phb->init_m64 = pnv_ioda2_init_m64;
@@ -1348,7 +1373,9 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
1348 pnv_ioda_setup_bus_dma(pe, pe->pbus, true); 1373 pnv_ioda_setup_bus_dma(pe, pe->pbus, true);
1349 1374
1350 /* Also create a bypass window */ 1375 /* Also create a bypass window */
1351 pnv_pci_ioda2_setup_bypass_pe(phb, pe); 1376 if (!pnv_iommu_bypass_disabled)
1377 pnv_pci_ioda2_setup_bypass_pe(phb, pe);
1378
1352 return; 1379 return;
1353fail: 1380fail:
1354 if (pe->tce32_seg >= 0) 1381 if (pe->tce32_seg >= 0)
@@ -1460,15 +1487,15 @@ static void set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq)
1460 1487
1461#ifdef CONFIG_CXL_BASE 1488#ifdef CONFIG_CXL_BASE
1462 1489
1463struct device_node *pnv_pci_to_phb_node(struct pci_dev *dev) 1490struct device_node *pnv_pci_get_phb_node(struct pci_dev *dev)
1464{ 1491{
1465 struct pci_controller *hose = pci_bus_to_host(dev->bus); 1492 struct pci_controller *hose = pci_bus_to_host(dev->bus);
1466 1493
1467 return hose->dn; 1494 return of_node_get(hose->dn);
1468} 1495}
1469EXPORT_SYMBOL(pnv_pci_to_phb_node); 1496EXPORT_SYMBOL(pnv_pci_get_phb_node);
1470 1497
1471int pnv_phb_to_cxl(struct pci_dev *dev) 1498int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode)
1472{ 1499{
1473 struct pci_controller *hose = pci_bus_to_host(dev->bus); 1500 struct pci_controller *hose = pci_bus_to_host(dev->bus);
1474 struct pnv_phb *phb = hose->private_data; 1501 struct pnv_phb *phb = hose->private_data;
@@ -1481,13 +1508,13 @@ int pnv_phb_to_cxl(struct pci_dev *dev)
1481 1508
1482 pe_info(pe, "Switching PHB to CXL\n"); 1509 pe_info(pe, "Switching PHB to CXL\n");
1483 1510
1484 rc = opal_pci_set_phb_cxl_mode(phb->opal_id, 1, pe->pe_number); 1511 rc = opal_pci_set_phb_cxl_mode(phb->opal_id, mode, pe->pe_number);
1485 if (rc) 1512 if (rc)
1486 dev_err(&dev->dev, "opal_pci_set_phb_cxl_mode failed: %i\n", rc); 1513 dev_err(&dev->dev, "opal_pci_set_phb_cxl_mode failed: %i\n", rc);
1487 1514
1488 return rc; 1515 return rc;
1489} 1516}
1490EXPORT_SYMBOL(pnv_phb_to_cxl); 1517EXPORT_SYMBOL(pnv_phb_to_cxl_mode);
1491 1518
1492/* Find PHB for cxl dev and allocate MSI hwirqs? 1519/* Find PHB for cxl dev and allocate MSI hwirqs?
1493 * Returns the absolute hardware IRQ number 1520 * Returns the absolute hardware IRQ number
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 4945e87f12dc..e69142f4af08 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -781,35 +781,6 @@ static void pnv_p7ioc_rc_quirk(struct pci_dev *dev)
781} 781}
782DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk); 782DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk);
783 783
784static int pnv_pci_probe_mode(struct pci_bus *bus)
785{
786 struct pci_controller *hose = pci_bus_to_host(bus);
787 const __be64 *tstamp;
788 u64 now, target;
789
790
791 /* We hijack this as a way to ensure we have waited long
792 * enough since the reset was lifted on the PCI bus
793 */
794 if (bus != hose->bus)
795 return PCI_PROBE_NORMAL;
796 tstamp = of_get_property(hose->dn, "reset-clear-timestamp", NULL);
797 if (!tstamp || !*tstamp)
798 return PCI_PROBE_NORMAL;
799
800 now = mftb() / tb_ticks_per_usec;
801 target = (be64_to_cpup(tstamp) / tb_ticks_per_usec)
802 + PCI_RESET_DELAY_US;
803
804 pr_devel("pci %04d: Reset target: 0x%llx now: 0x%llx\n",
805 hose->global_number, target, now);
806
807 if (now < target)
808 msleep((target - now + 999) / 1000);
809
810 return PCI_PROBE_NORMAL;
811}
812
813void __init pnv_pci_init(void) 784void __init pnv_pci_init(void)
814{ 785{
815 struct device_node *np; 786 struct device_node *np;
@@ -856,7 +827,6 @@ void __init pnv_pci_init(void)
856 ppc_md.tce_build_rm = pnv_tce_build_rm; 827 ppc_md.tce_build_rm = pnv_tce_build_rm;
857 ppc_md.tce_free_rm = pnv_tce_free_rm; 828 ppc_md.tce_free_rm = pnv_tce_free_rm;
858 ppc_md.tce_get = pnv_tce_get; 829 ppc_md.tce_get = pnv_tce_get;
859 ppc_md.pci_probe_mode = pnv_pci_probe_mode;
860 set_pci_dma_ops(&dma_iommu_ops); 830 set_pci_dma_ops(&dma_iommu_ops);
861 831
862 /* Configure MSIs */ 832 /* Configure MSIs */