From 49fd644c3b0014fb80c2b1db7d8c86a75c4c6b1f Mon Sep 17 00:00:00 2001 From: Philippe Bergheaud Date: Fri, 12 Dec 2014 11:28:53 +0100 Subject: cxl: Update CXL ABI documentation This fixes two typos and explains where shared attributes are stored. Signed-off-by: Philippe Bergheaud Acked-by: Michael Neuling Signed-off-by: Michael Ellerman --- Documentation/ABI/testing/sysfs-class-cxl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index 554405ec1955..2ab97527e186 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -1,3 +1,9 @@ +Note: Attributes that are shared between devices are stored in the directory +pointed to by the symlink device/. +Example: The real path of the attribute /sys/class/cxl/afu0.0s/irqs_max is +/sys/class/cxl/afu0.0s/device/irqs_max, i.e. /sys/class/cxl/afu0.0/irqs_max. + + Slave contexts (eg. /sys/class/cxl/afu0.0s): What: /sys/class/cxl//irqs_max @@ -67,7 +73,7 @@ Contact: linuxppc-dev@lists.ozlabs.org Description: read only Decimal value of the current version of the kernel/user API. -What: /sys/class/cxl//api_version_com +What: /sys/class/cxl//api_version_compatible Date: September 2014 Contact: linuxppc-dev@lists.ozlabs.org Description: read only @@ -75,7 +81,6 @@ Description: read only this this kernel supports. - Master contexts (eg. /sys/class/cxl/afu0.0m) What: /sys/class/cxl/m/mmio_size @@ -106,7 +111,7 @@ Contact: linuxppc-dev@lists.ozlabs.org Description: read only Identifies the CAIA Version the card implements. -What: /sys/class/cxl//psl_version +What: /sys/class/cxl//psl_revision Date: September 2014 Contact: linuxppc-dev@lists.ozlabs.org Description: read only -- cgit v1.2.3 From 95bc11bcd1428afdb48400ec84dc6d5a83926138 Mon Sep 17 00:00:00 2001 From: Ryan Grimm Date: Mon, 19 Jan 2015 11:52:49 -0600 Subject: cxl: Add image control to sysfs load_image_on_perst identifies whether a PERST will cause the image to be flashed to the card. And if so, which image. Valid entries are: "none", "user" and "factory". A value of "none" means PERST will not cause the image to be flashed. A power cycle to the pcie slot is required to load the image. "user" loads the user provided image and "factory" loads the factory image upon PERST. sysfs updates the cxl struct in the driver then calls cxl_update_image_control to write the vals in the VSEC. Signed-off-by: Ryan Grimm Acked-by: Ian Munsie Signed-off-by: Michael Ellerman --- Documentation/ABI/testing/sysfs-class-cxl | 14 +++++++++++ drivers/misc/cxl/sysfs.c | 39 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index 2ab97527e186..5941ff38d4a3 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -132,3 +132,17 @@ Contact: linuxppc-dev@lists.ozlabs.org Description: read only Will return "user" or "factory" depending on the image loaded onto the card. + +What: /sys/class/cxl//load_image_on_perst +Date: December 2014 +Contact: linuxppc-dev@lists.ozlabs.org +Description: read/write + Valid entries are "none", "user", and "factory". + "none" means PERST will not cause image to be loaded to the + card. A power cycle is required to load the image. + "none" could be useful for debugging because the trace arrays + are preserved. + "user" and "factory" means PERST will cause either the user or + user or factory image to be loaded. + Default is to reload on PERST whichever image the card has + loaded. diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index 461bdbd5d483..ed4ad461143c 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -56,11 +56,50 @@ static ssize_t image_loaded_show(struct device *device, return scnprintf(buf, PAGE_SIZE, "factory\n"); } +static ssize_t load_image_on_perst_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct cxl *adapter = to_cxl_adapter(device); + + if (!adapter->perst_loads_image) + return scnprintf(buf, PAGE_SIZE, "none\n"); + + if (adapter->perst_select_user) + return scnprintf(buf, PAGE_SIZE, "user\n"); + return scnprintf(buf, PAGE_SIZE, "factory\n"); +} + +static ssize_t load_image_on_perst_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct cxl *adapter = to_cxl_adapter(device); + int rc; + + if (!strncmp(buf, "none", 4)) + adapter->perst_loads_image = false; + else if (!strncmp(buf, "user", 4)) { + adapter->perst_select_user = true; + adapter->perst_loads_image = true; + } else if (!strncmp(buf, "factory", 7)) { + adapter->perst_select_user = false; + adapter->perst_loads_image = true; + } else + return -EINVAL; + + if ((rc = cxl_update_image_control(adapter))) + return rc; + + return count; +} + static struct device_attribute adapter_attrs[] = { __ATTR_RO(caia_version), __ATTR_RO(psl_revision), __ATTR_RO(base_image), __ATTR_RO(image_loaded), + __ATTR_RW(load_image_on_perst), }; -- cgit v1.2.3 From 62fa19d4b4fd781ad37c9155c6332f28a9e97a2c Mon Sep 17 00:00:00 2001 From: Ryan Grimm Date: Mon, 19 Jan 2015 11:52:51 -0600 Subject: cxl: Add ability to reset the card Adds reset to sysfs which will PERST the card. If load_image_on_perst is set to "user" or "factory", the PERST will cause that image to be loaded. load_image_on_perst is set to "user" for production. "none" could be used for debugging. The PSL trace arrays are preserved which then can be read through debugfs. PERST also triggers CAPP recovery. An HMI comes in, which is handled by EEH. EEH unbinds the driver, calls into Sapphire to reinitialize the PHB, then rebinds the driver. Signed-off-by: Ryan Grimm Acked-by: Ian Munsie Signed-off-by: Michael Ellerman --- Documentation/ABI/testing/sysfs-class-cxl | 7 ++++++ drivers/misc/cxl/cxl.h | 1 + drivers/misc/cxl/pci.c | 37 +++++++++++++++++++++++++++++++ drivers/misc/cxl/sysfs.c | 18 +++++++++++++++ 4 files changed, 63 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index 5941ff38d4a3..9ea01068a16c 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -146,3 +146,10 @@ Description: read/write user or factory image to be loaded. Default is to reload on PERST whichever image the card has loaded. + +What: /sys/class/cxl//reset +Date: October 2014 +Contact: linuxppc-dev@lists.ozlabs.org +Description: write only + Writing 1 will issue a PERST to card which may cause the card + to reload the FPGA depending on load_image_on_perst. diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 518c4c6e6151..6a6a487464c5 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -489,6 +489,7 @@ int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsig void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter); int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq); int cxl_update_image_control(struct cxl *adapter); +int cxl_reset(struct cxl *adapter); /* common == phyp + powernv */ struct cxl_process_element_common { diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index a4a4e0217eed..428ea8ba25fc 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -21,6 +21,7 @@ #include #include /* for struct pci_controller */ #include +#include #include "cxl.h" @@ -741,6 +742,42 @@ static void cxl_remove_afu(struct cxl_afu *afu) device_unregister(&afu->dev); } +int cxl_reset(struct cxl *adapter) +{ + struct pci_dev *dev = to_pci_dev(adapter->dev.parent); + int rc; + int i; + u32 val; + + dev_info(&dev->dev, "CXL reset\n"); + + for (i = 0; i < adapter->slices; i++) + cxl_remove_afu(adapter->afu[i]); + + /* pcie_warm_reset requests a fundamental pci reset which includes a + * PERST assert/deassert. PERST triggers a loading of the image + * if "user" or "factory" is selected in sysfs */ + if ((rc = pci_set_pcie_reset_state(dev, pcie_warm_reset))) { + dev_err(&dev->dev, "cxl: pcie_warm_reset failed\n"); + return rc; + } + + /* the PERST done above fences the PHB. So, reset depends on EEH + * to unbind the driver, tell Sapphire to reinit the PHB, and rebind + * the driver. Do an mmio read explictly to ensure EEH notices the + * fenced PHB. Retry for a few seconds before giving up. */ + i = 0; + while (((val = mmio_read32be(adapter->p1_mmio)) != 0xffffffff) && + (i < 5)) { + msleep(500); + i++; + } + + if (val != 0xffffffff) + dev_err(&dev->dev, "cxl: PERST failed to trigger EEH\n"); + + return rc; +} static int cxl_map_adapter_regs(struct cxl *adapter, struct pci_dev *dev) { diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index ed4ad461143c..adf1f6d84913 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -56,6 +56,23 @@ static ssize_t image_loaded_show(struct device *device, return scnprintf(buf, PAGE_SIZE, "factory\n"); } +static ssize_t reset_adapter_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct cxl *adapter = to_cxl_adapter(device); + int rc; + int val; + + rc = sscanf(buf, "%i", &val); + if ((rc != 1) || (val != 1)) + return -EINVAL; + + if ((rc = cxl_reset(adapter))) + return rc; + return count; +} + static ssize_t load_image_on_perst_show(struct device *device, struct device_attribute *attr, char *buf) @@ -100,6 +117,7 @@ static struct device_attribute adapter_attrs[] = { __ATTR_RO(base_image), __ATTR_RO(image_loaded), __ATTR_RW(load_image_on_perst), + __ATTR(reset, S_IWUSR, NULL, reset_adapter_store), }; -- cgit v1.2.3 From 4e28784024a0d87f6f04250e46e8c9ac4f30e361 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 23 Oct 2014 19:19:35 -0200 Subject: powernv/iommu: disable IOMMU bypass with param iommu=nobypass When IOMMU bypass is enabled, a PCI device can read and write memory that was not mapped by the driver without causing an EEH. That might cause memory corruption, for example. When we disable bypass, DMA reads and writes to addresses not mapped by the IOMMU will cause an EEH, allowing us to debug such issues. Signed-off-by: Thadeu Lima de Souza Cascardo Reviewed-by: Gavin Shan Signed-off-by: Michael Ellerman --- Documentation/kernel-parameters.txt | 2 ++ arch/powerpc/platforms/powernv/pci-ioda.c | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4df73da11adc..7dedfe56c3f3 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1493,6 +1493,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. forcesac soft pt [x86, IA-64] + nobypass [PPC/POWERNV] + Disable IOMMU bypass, using IOMMU for PCI devices. io7= [HW] IO7 for Marvel based alpha systems diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 4f1e43c05e84..85b473823fda 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, #define pe_info(pe, fmt, ...) \ pe_level_printk(pe, KERN_INFO, fmt, ##__VA_ARGS__) +static bool pnv_iommu_bypass_disabled __read_mostly; + +static int __init iommu_setup(char *str) +{ + if (!str) + return -EINVAL; + + while (*str) { + if (!strncmp(str, "nobypass", 8)) { + pnv_iommu_bypass_disabled = true; + pr_info("PowerNV: IOMMU bypass window disabled.\n"); + break; + } + str += strcspn(str, ","); + if (*str == ',') + str++; + } + + return 0; +} +early_param("iommu", iommu_setup); + /* * stdcix is only supposed to be used in hypervisor real mode as per * the architecture spec @@ -1351,7 +1373,9 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, pnv_ioda_setup_bus_dma(pe, pe->pbus, true); /* Also create a bypass window */ - pnv_pci_ioda2_setup_bypass_pe(phb, pe); + if (!pnv_iommu_bypass_disabled) + pnv_pci_ioda2_setup_bypass_pe(phb, pe); + return; fail: if (pe->tce32_seg >= 0) -- cgit v1.2.3 From 7f93c9d90f4dc7084217cf94574e427bad40e37c Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Wed, 28 Jan 2015 19:54:24 +0800 Subject: power/fsl: add MDIO dt binding for FMan This binding is for FMan MDIO, it covers FMan v2 & FMan v3. Signed-off-by: Shaohui Xie [scottwood@freescale.com: mark interrupts required only for external] Signed-off-by: Scott Wood --- .../devicetree/bindings/powerpc/fsl/fman.txt | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt index edeea160ca39..edda55f74004 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt @@ -7,6 +7,7 @@ CONTENTS - FMan MURAM Node - FMan dTSEC/XGEC/mEMAC Node - FMan IEEE 1588 Node + - FMan MDIO Node - Example ============================================================================= @@ -356,6 +357,69 @@ ptp-timer@fe000 { reg = <0xfe000 0x1000>; }; +============================================================================= +FMan MDIO Node + +DESCRIPTION + +The MDIO is a bus to which the PHY devices are connected. + +PROPERTIES + +- compatible + Usage: required + Value type: + Definition: A standard property. + Must include "fsl,fman-mdio" for 1 Gb/s MDIO from FMan v2. + Must include "fsl,fman-xmdio" for 10 Gb/s MDIO from FMan v2. + Must include "fsl,fman-memac-mdio" for 1/10 Gb/s MDIO from + FMan v3. + +- reg + Usage: required + Value type: + Definition: A standard property. + +- bus-frequency + Usage: optional + Value type: + Definition: Specifies the external MDIO bus clock speed to + be used, if different from the standard 2.5 MHz. + This may be due to the standard speed being unsupported (e.g. + due to a hardware problem), or to advertise that all relevant + components in the system support a faster speed. + +- interrupts + Usage: required for external MDIO + Value type: + Definition: Event interrupt of external MDIO controller. + +- fsl,fman-internal-mdio + Usage: required for internal MDIO + Value type: boolean + Definition: Fman has internal MDIO for internal PCS(Physical + Coding Sublayer) PHYs and external MDIO for external PHYs. + The settings and programming routines for internal/external + MDIO are different. Must be included for internal MDIO. + +EXAMPLE + +Example for FMan v2 external MDIO: + +mdio@f1000 { + compatible = "fsl,fman-xmdio"; + reg = <0xf1000 0x1000>; + interrupts = <101 2 0 0>; +}; + +Example for FMan v3 internal MDIO: + +mdio@f1000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0xf1000 0x1000>; + fsl,fman-internal-mdio; +}; + ============================================================================= Example @@ -531,4 +595,10 @@ fman@400000 { compatible = "fsl,fman-ptp-timer"; reg = <0xfe000 0x1000>; }; + + mdio@f1000 { + compatible = "fsl,fman-xmdio"; + reg = <0xf1000 0x1000>; + interrupts = <101 2 0 0>; + }; }; -- cgit v1.2.3 From 1ee9df499b270f259adc8df9cca396d5ef6e9e46 Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Mon, 8 Dec 2014 04:29:16 -0600 Subject: dt/bindings: b/qman: Fix the alloc-ranges in the example(s) 'ranges' are specified as not as Signed-off-by: Emil Medve Signed-off-by: Scott Wood --- Documentation/devicetree/bindings/soc/fsl/bman.txt | 2 +- Documentation/devicetree/bindings/soc/fsl/qman.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/fsl/bman.txt b/Documentation/devicetree/bindings/soc/fsl/bman.txt index 9f80bf8709ac..ee03ef2e265c 100644 --- a/Documentation/devicetree/bindings/soc/fsl/bman.txt +++ b/Documentation/devicetree/bindings/soc/fsl/bman.txt @@ -96,7 +96,7 @@ The example below shows a BMan FBPR dynamic allocation memory node bman_fbpr: bman-fbpr { compatible = "fsl,bman-fbpr"; - alloc-ranges = <0 0 0xf 0xffffffff>; + alloc-ranges = <0 0 0x10 0>; size = <0 0x1000000>; alignment = <0 0x1000000>; }; diff --git a/Documentation/devicetree/bindings/soc/fsl/qman.txt b/Documentation/devicetree/bindings/soc/fsl/qman.txt index 063e3a0b9d04..f3da91ef4287 100644 --- a/Documentation/devicetree/bindings/soc/fsl/qman.txt +++ b/Documentation/devicetree/bindings/soc/fsl/qman.txt @@ -113,13 +113,13 @@ The example below shows a QMan FQD and a PFDR dynamic allocation memory nodes qman_fqd: qman-fqd { compatible = "fsl,qman-fqd"; - alloc-ranges = <0 0 0xf 0xffffffff>; + alloc-ranges = <0 0 0x10 0>; size = <0 0x400000>; alignment = <0 0x400000>; }; qman_pfdr: qman-pfdr { compatible = "fsl,qman-pfdr"; - alloc-ranges = <0 0 0xf 0xffffffff>; + alloc-ranges = <0 0 0x10 0>; size = <0 0x2000000>; alignment = <0 0x2000000>; }; -- cgit v1.2.3 From 7af98c7c4dffaf5b0a082fa9c42785d7807e6235 Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Mon, 8 Dec 2014 04:29:17 -0600 Subject: dt/bindings: b/qman: Add phandle to the portals This supports SoC(s) with multiple B/QMan instances Signed-off-by: Emil Medve Signed-off-by: Scott Wood --- Documentation/devicetree/bindings/soc/fsl/bman.txt | 10 ++++++++++ Documentation/devicetree/bindings/soc/fsl/qman.txt | 10 ++++++++++ 2 files changed, 20 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/fsl/bman.txt b/Documentation/devicetree/bindings/soc/fsl/bman.txt index ee03ef2e265c..47ac834414d8 100644 --- a/Documentation/devicetree/bindings/soc/fsl/bman.txt +++ b/Documentation/devicetree/bindings/soc/fsl/bman.txt @@ -36,6 +36,11 @@ are located at offsets 0xbf8 and 0xbfc Value type: Definition: Standard property. The error interrupt +- fsl,bman-portals + Usage: Required + Value type: + Definition: Phandle to this BMan instance's portals + - fsl,liodn Usage: See pamu.txt Value type: @@ -104,6 +109,10 @@ The example below shows a BMan FBPR dynamic allocation memory node The example below shows a (P4080) BMan CCSR-space node + bportals: bman-portals@ff4000000 { + ... + }; + crypto@300000 { ... fsl,bman = <&bman, 2>; @@ -115,6 +124,7 @@ The example below shows a (P4080) BMan CCSR-space node reg = <0x31a000 0x1000>; interrupts = <16 2 1 2>; fsl,liodn = <0x17>; + fsl,bman-portals = <&bportals>; memory-region = <&bman_fbpr>; }; diff --git a/Documentation/devicetree/bindings/soc/fsl/qman.txt b/Documentation/devicetree/bindings/soc/fsl/qman.txt index f3da91ef4287..556ebb8be75d 100644 --- a/Documentation/devicetree/bindings/soc/fsl/qman.txt +++ b/Documentation/devicetree/bindings/soc/fsl/qman.txt @@ -38,6 +38,11 @@ are located at offsets 0xbf8 and 0xbfc Value type: Definition: Standard property. The error interrupt +- fsl,qman-portals + Usage: Required + Value type: + Definition: Phandle to this QMan instance's portals + - fsl,liodn Usage: See pamu.txt Value type: @@ -127,6 +132,10 @@ The example below shows a QMan FQD and a PFDR dynamic allocation memory nodes The example below shows a (P4080) QMan CCSR-space node + qportals: qman-portals@ff4200000 { + ... + }; + clockgen: global-utilities@e1000 { ... sysclk: sysclk { @@ -154,6 +163,7 @@ The example below shows a (P4080) QMan CCSR-space node reg = <0x318000 0x1000>; interrupts = <16 2 1 3> fsl,liodn = <0x16>; + fsl,qman-portals = <&qportals>; memory-region = <&qman_fqd &qman_pfdr>; clocks = <&platform_pll 1>; }; -- cgit v1.2.3 From 5c65670c9bfa3be1234d29f36b742897c0360ef3 Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Fri, 30 Jan 2015 13:46:03 -0800 Subject: powerpc/perf/hv-24x7: Document sysfs event description entries Signed-off-by: Cody P Schafer Signed-off-by: Sukadev Bhattiprolu Signed-off-by: Michael Ellerman --- .../testing/sysfs-bus-event_source-devices-hv_24x7 | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 index 32f3f5f8bba2..f893337570c1 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 @@ -21,3 +21,25 @@ Contact: Linux on PowerPC Developer List Description: Exposes the "version" field of the 24x7 catalog. This is also extractable from the provided binary "catalog" sysfs entry. + +What: /sys/bus/event_source/devices/hv_24x7/event_descs/ +Date: February 2014 +Contact: Linux on PowerPC Developer List +Description: + Provides the description of a particular event as provided by + the firmware. If firmware does not provide a description, no + file will be created. + + Note that the event-name lacks the domain suffix appended for + events in the events/ dir. + +What: /sys/bus/event_source/devices/hv_24x7/event_long_descs/ +Date: February 2014 +Contact: Linux on PowerPC Developer List +Description: + Provides the "long" description of a particular event as + provided by the firmware. If firmware does not provide a + description, no file will be created. + + Note that the event-name lacks the domain suffix appended for + events in the events/ dir. -- cgit v1.2.3 From b087e6190ddcd9ae4e8ff2c788d2b32f193e946b Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Wed, 4 Feb 2015 19:09:01 +1100 Subject: cxl: Export optional AFU configuration record in sysfs An AFU may optionally contain one or more PCIe like configuration records, which can be used to identify the AFU. This patch adds support for exposing the raw config space and the vendor, device and class code under sysfs. These will appear in a subdirectory of the AFU device corresponding with the configuration record number, e.g. cat /sys/class/cxl/afu0.0/cr0/vendor 0x1014 cat /sys/class/cxl/afu0.0/cr0/device 0x4350 cat /sys/class/cxl/afu0.0/cr0/class 0x120000 hexdump -C /sys/class/cxl/afu0.0/cr0/config 00000000 14 10 50 43 00 00 00 00 06 00 00 12 00 00 00 00 |..PC............| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000100 These files behave in much the same way as the equivalent files for PCI devices, with one exception being that the config file is currently read-only and restricted to the root user. It is not necessarily required to be this strict, but we currently do not have a compelling use-case to make it writable and/or world-readable, so I erred on the side of being restrictive. Signed-off-by: Ian Munsie Signed-off-by: Michael Ellerman --- Documentation/ABI/testing/sysfs-class-cxl | 37 ++++++ drivers/misc/cxl/cxl.h | 13 +++ drivers/misc/cxl/pci.c | 23 ++++ drivers/misc/cxl/sysfs.c | 179 ++++++++++++++++++++++++++++-- 4 files changed, 242 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index 9ea01068a16c..3680364b4048 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -81,6 +81,43 @@ Description: read only this this kernel supports. +AFU configuration records (eg. /sys/class/cxl/afu0.0/cr0): + +An AFU may optionally export one or more PCIe like configuration records, known +as AFU configuration records, which will show up here (if present). + +What: /sys/class/cxl//cr/vendor +Date: February 2015 +Contact: linuxppc-dev@lists.ozlabs.org +Description: read only + Hexadecimal value of the vendor ID found in this AFU + configuration record. + +What: /sys/class/cxl//cr/device +Date: February 2015 +Contact: linuxppc-dev@lists.ozlabs.org +Description: read only + Hexadecimal value of the device ID found in this AFU + configuration record. + +What: /sys/class/cxl//cr/vendor +Date: February 2015 +Contact: linuxppc-dev@lists.ozlabs.org +Description: read only + Hexadecimal value of the class code found in this AFU + configuration record. + +What: /sys/class/cxl//cr/config +Date: February 2015 +Contact: linuxppc-dev@lists.ozlabs.org +Description: read only + This binary file provides raw access to the AFU configuration + record. The format is expected to match the either the standard + or extended configuration space defined by the PCIe + specification. + + + Master contexts (eg. /sys/class/cxl/afu0.0m) What: /sys/class/cxl/m/mmio_size diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 6a6a487464c5..a1cee4767ec6 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -382,6 +382,10 @@ struct cxl_afu { int slice; int modes_supported; int current_mode; + int crs_num; + u64 crs_len; + u64 crs_offset; + struct list_head crs; enum prefault_modes prefault_mode; bool psa; bool pp_psa; @@ -551,6 +555,15 @@ static inline void __iomem *_cxl_p2n_addr(struct cxl_afu *afu, cxl_p2n_reg_t reg #define cxl_p2n_read(afu, reg) \ in_be64(_cxl_p2n_addr(afu, reg)) + +#define cxl_afu_cr_read64(afu, cr, off) \ + in_le64((afu)->afu_desc_mmio + (afu)->crs_offset + ((cr) * (afu)->crs_len) + (off)) +#define cxl_afu_cr_read32(afu, cr, off) \ + in_le32((afu)->afu_desc_mmio + (afu)->crs_offset + ((cr) * (afu)->crs_len) + (off)) +u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off); +u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off); + + struct cxl_calls { void (*cxl_slbia)(struct mm_struct *mm); struct module *owner; diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index cb250673b5c6..2b2e1b80d759 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -114,6 +114,24 @@ #define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63) #define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48) +u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off) +{ + u64 aligned_off = off & ~0x3L; + u32 val; + + val = cxl_afu_cr_read32(afu, cr, aligned_off); + return (val >> ((off & 0x2) * 8)) & 0xffff; +} + +u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off) +{ + u64 aligned_off = off & ~0x3L; + u32 val; + + val = cxl_afu_cr_read32(afu, cr, aligned_off); + return (val >> ((off & 0x3) * 8)) & 0xff; +} + static DEFINE_PCI_DEVICE_TABLE(cxl_pci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), }, { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), }, @@ -556,6 +574,7 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu) val = AFUD_READ_INFO(afu); afu->pp_irqs = AFUD_NUM_INTS_PER_PROC(val); afu->max_procs_virtualised = AFUD_NUM_PROCS(val); + afu->crs_num = AFUD_NUM_CRS(val); if (AFUD_AFU_DIRECTED(val)) afu->modes_supported |= CXL_MODE_DIRECTED; @@ -570,6 +589,10 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu) if ((afu->pp_psa = AFUD_PPPSA_PP(val))) afu->pp_offset = AFUD_READ_PPPSA_OFF(afu); + val = AFUD_READ_CR(afu); + afu->crs_len = AFUD_CR_LEN(val) * 256; + afu->crs_offset = AFUD_READ_CR_OFF(afu); + return 0; } diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index adf1f6d84913..d0c38c7bc0c4 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "cxl.h" @@ -367,8 +368,6 @@ static struct device_attribute afu_attrs[] = { __ATTR(reset, S_IWUSR, NULL, reset_store_afu), }; - - int cxl_sysfs_adapter_add(struct cxl *adapter) { int i, rc; @@ -391,31 +390,191 @@ void cxl_sysfs_adapter_remove(struct cxl *adapter) device_remove_file(&adapter->dev, &adapter_attrs[i]); } +struct afu_config_record { + struct kobject kobj; + struct bin_attribute config_attr; + struct list_head list; + int cr; + u16 device; + u16 vendor; + u32 class; +}; + +#define to_cr(obj) container_of(obj, struct afu_config_record, kobj) + +static ssize_t vendor_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct afu_config_record *cr = to_cr(kobj); + + return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->vendor); +} + +static ssize_t device_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct afu_config_record *cr = to_cr(kobj); + + return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->device); +} + +static ssize_t class_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct afu_config_record *cr = to_cr(kobj); + + return scnprintf(buf, PAGE_SIZE, "0x%.6x\n", cr->class); +} + +static ssize_t afu_read_config(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct afu_config_record *cr = to_cr(kobj); + struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj)); + + u64 i, j, val, size = afu->crs_len; + + if (off > size) + return 0; + if (off + count > size) + count = size - off; + + for (i = 0; i < count;) { + val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7); + for (j = off & 0x7; j < 8 && i < count; i++, j++, off++) + buf[i] = (val >> (j * 8)) & 0xff; + } + + return count; +} + +static struct kobj_attribute vendor_attribute = + __ATTR_RO(vendor); +static struct kobj_attribute device_attribute = + __ATTR_RO(device); +static struct kobj_attribute class_attribute = + __ATTR_RO(class); + +static struct attribute *afu_cr_attrs[] = { + &vendor_attribute.attr, + &device_attribute.attr, + &class_attribute.attr, + NULL, +}; + +static void release_afu_config_record(struct kobject *kobj) +{ + struct afu_config_record *cr = to_cr(kobj); + + kfree(cr); +} + +static struct kobj_type afu_config_record_type = { + .sysfs_ops = &kobj_sysfs_ops, + .release = release_afu_config_record, + .default_attrs = afu_cr_attrs, +}; + +static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int cr_idx) +{ + struct afu_config_record *cr; + int rc; + + cr = kzalloc(sizeof(struct afu_config_record), GFP_KERNEL); + if (!cr) + return ERR_PTR(-ENOMEM); + + cr->cr = cr_idx; + cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID); + cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID); + cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8; + + /* + * Export raw AFU PCIe like config record. For now this is read only by + * root - we can expand that later to be readable by non-root and maybe + * even writable provided we have a good use-case. Once we suport + * exposing AFUs through a virtual PHB they will get that for free from + * Linux' PCI infrastructure, but until then it's not clear that we + * need it for anything since the main use case is just identifying + * AFUs, which can be done via the vendor, device and class attributes. + */ + sysfs_bin_attr_init(&cr->config_attr); + cr->config_attr.attr.name = "config"; + cr->config_attr.attr.mode = S_IRUSR; + cr->config_attr.size = afu->crs_len; + cr->config_attr.read = afu_read_config; + + rc = kobject_init_and_add(&cr->kobj, &afu_config_record_type, + &afu->dev.kobj, "cr%i", cr->cr); + if (rc) + goto err; + + rc = sysfs_create_bin_file(&cr->kobj, &cr->config_attr); + if (rc) + goto err1; + + rc = kobject_uevent(&cr->kobj, KOBJ_ADD); + if (rc) + goto err2; + + return cr; +err2: + sysfs_remove_bin_file(&cr->kobj, &cr->config_attr); +err1: + kobject_put(&cr->kobj); + return ERR_PTR(rc); +err: + kfree(cr); + return ERR_PTR(rc); +} + +void cxl_sysfs_afu_remove(struct cxl_afu *afu) +{ + struct afu_config_record *cr, *tmp; + int i; + + for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) + device_remove_file(&afu->dev, &afu_attrs[i]); + + list_for_each_entry_safe(cr, tmp, &afu->crs, list) { + sysfs_remove_bin_file(&cr->kobj, &cr->config_attr); + kobject_put(&cr->kobj); + } +} + int cxl_sysfs_afu_add(struct cxl_afu *afu) { + struct afu_config_record *cr; int i, rc; + INIT_LIST_HEAD(&afu->crs); + for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) { if ((rc = device_create_file(&afu->dev, &afu_attrs[i]))) goto err; } + for (i = 0; i < afu->crs_num; i++) { + cr = cxl_sysfs_afu_new_cr(afu, i); + if (IS_ERR(cr)) { + rc = PTR_ERR(cr); + goto err1; + } + list_add(&cr->list, &afu->crs); + } + return 0; +err1: + cxl_sysfs_afu_remove(afu); + return rc; err: for (i--; i >= 0; i--) device_remove_file(&afu->dev, &afu_attrs[i]); return rc; } -void cxl_sysfs_afu_remove(struct cxl_afu *afu) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) - device_remove_file(&afu->dev, &afu_attrs[i]); -} - int cxl_sysfs_afu_m_add(struct cxl_afu *afu) { int i, rc; -- cgit v1.2.3