aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-class-cxl37
-rw-r--r--drivers/misc/cxl/cxl.h13
-rw-r--r--drivers/misc/cxl/pci.c23
-rw-r--r--drivers/misc/cxl/sysfs.c179
4 files changed, 242 insertions, 10 deletions
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
81 this this kernel supports. 81 this this kernel supports.
82 82
83 83
84AFU configuration records (eg. /sys/class/cxl/afu0.0/cr0):
85
86An AFU may optionally export one or more PCIe like configuration records, known
87as AFU configuration records, which will show up here (if present).
88
89What: /sys/class/cxl/<afu>/cr<config num>/vendor
90Date: February 2015
91Contact: linuxppc-dev@lists.ozlabs.org
92Description: read only
93 Hexadecimal value of the vendor ID found in this AFU
94 configuration record.
95
96What: /sys/class/cxl/<afu>/cr<config num>/device
97Date: February 2015
98Contact: linuxppc-dev@lists.ozlabs.org
99Description: read only
100 Hexadecimal value of the device ID found in this AFU
101 configuration record.
102
103What: /sys/class/cxl/<afu>/cr<config num>/vendor
104Date: February 2015
105Contact: linuxppc-dev@lists.ozlabs.org
106Description: read only
107 Hexadecimal value of the class code found in this AFU
108 configuration record.
109
110What: /sys/class/cxl/<afu>/cr<config num>/config
111Date: February 2015
112Contact: linuxppc-dev@lists.ozlabs.org
113Description: read only
114 This binary file provides raw access to the AFU configuration
115 record. The format is expected to match the either the standard
116 or extended configuration space defined by the PCIe
117 specification.
118
119
120
84Master contexts (eg. /sys/class/cxl/afu0.0m) 121Master contexts (eg. /sys/class/cxl/afu0.0m)
85 122
86What: /sys/class/cxl/<afu>m/mmio_size 123What: /sys/class/cxl/<afu>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 {
382 int slice; 382 int slice;
383 int modes_supported; 383 int modes_supported;
384 int current_mode; 384 int current_mode;
385 int crs_num;
386 u64 crs_len;
387 u64 crs_offset;
388 struct list_head crs;
385 enum prefault_modes prefault_mode; 389 enum prefault_modes prefault_mode;
386 bool psa; 390 bool psa;
387 bool pp_psa; 391 bool pp_psa;
@@ -551,6 +555,15 @@ static inline void __iomem *_cxl_p2n_addr(struct cxl_afu *afu, cxl_p2n_reg_t reg
551#define cxl_p2n_read(afu, reg) \ 555#define cxl_p2n_read(afu, reg) \
552 in_be64(_cxl_p2n_addr(afu, reg)) 556 in_be64(_cxl_p2n_addr(afu, reg))
553 557
558
559#define cxl_afu_cr_read64(afu, cr, off) \
560 in_le64((afu)->afu_desc_mmio + (afu)->crs_offset + ((cr) * (afu)->crs_len) + (off))
561#define cxl_afu_cr_read32(afu, cr, off) \
562 in_le32((afu)->afu_desc_mmio + (afu)->crs_offset + ((cr) * (afu)->crs_len) + (off))
563u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off);
564u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off);
565
566
554struct cxl_calls { 567struct cxl_calls {
555 void (*cxl_slbia)(struct mm_struct *mm); 568 void (*cxl_slbia)(struct mm_struct *mm);
556 struct module *owner; 569 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 @@
114#define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63) 114#define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63)
115#define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48) 115#define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48)
116 116
117u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off)
118{
119 u64 aligned_off = off & ~0x3L;
120 u32 val;
121
122 val = cxl_afu_cr_read32(afu, cr, aligned_off);
123 return (val >> ((off & 0x2) * 8)) & 0xffff;
124}
125
126u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off)
127{
128 u64 aligned_off = off & ~0x3L;
129 u32 val;
130
131 val = cxl_afu_cr_read32(afu, cr, aligned_off);
132 return (val >> ((off & 0x3) * 8)) & 0xff;
133}
134
117static DEFINE_PCI_DEVICE_TABLE(cxl_pci_tbl) = { 135static DEFINE_PCI_DEVICE_TABLE(cxl_pci_tbl) = {
118 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), }, 136 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), },
119 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), }, 137 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), },
@@ -556,6 +574,7 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu)
556 val = AFUD_READ_INFO(afu); 574 val = AFUD_READ_INFO(afu);
557 afu->pp_irqs = AFUD_NUM_INTS_PER_PROC(val); 575 afu->pp_irqs = AFUD_NUM_INTS_PER_PROC(val);
558 afu->max_procs_virtualised = AFUD_NUM_PROCS(val); 576 afu->max_procs_virtualised = AFUD_NUM_PROCS(val);
577 afu->crs_num = AFUD_NUM_CRS(val);
559 578
560 if (AFUD_AFU_DIRECTED(val)) 579 if (AFUD_AFU_DIRECTED(val))
561 afu->modes_supported |= CXL_MODE_DIRECTED; 580 afu->modes_supported |= CXL_MODE_DIRECTED;
@@ -570,6 +589,10 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu)
570 if ((afu->pp_psa = AFUD_PPPSA_PP(val))) 589 if ((afu->pp_psa = AFUD_PPPSA_PP(val)))
571 afu->pp_offset = AFUD_READ_PPPSA_OFF(afu); 590 afu->pp_offset = AFUD_READ_PPPSA_OFF(afu);
572 591
592 val = AFUD_READ_CR(afu);
593 afu->crs_len = AFUD_CR_LEN(val) * 256;
594 afu->crs_offset = AFUD_READ_CR_OFF(afu);
595
573 return 0; 596 return 0;
574} 597}
575 598
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 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/sysfs.h> 12#include <linux/sysfs.h>
13#include <linux/pci_regs.h>
13 14
14#include "cxl.h" 15#include "cxl.h"
15 16
@@ -367,8 +368,6 @@ static struct device_attribute afu_attrs[] = {
367 __ATTR(reset, S_IWUSR, NULL, reset_store_afu), 368 __ATTR(reset, S_IWUSR, NULL, reset_store_afu),
368}; 369};
369 370
370
371
372int cxl_sysfs_adapter_add(struct cxl *adapter) 371int cxl_sysfs_adapter_add(struct cxl *adapter)
373{ 372{
374 int i, rc; 373 int i, rc;
@@ -391,31 +390,191 @@ void cxl_sysfs_adapter_remove(struct cxl *adapter)
391 device_remove_file(&adapter->dev, &adapter_attrs[i]); 390 device_remove_file(&adapter->dev, &adapter_attrs[i]);
392} 391}
393 392
393struct afu_config_record {
394 struct kobject kobj;
395 struct bin_attribute config_attr;
396 struct list_head list;
397 int cr;
398 u16 device;
399 u16 vendor;
400 u32 class;
401};
402
403#define to_cr(obj) container_of(obj, struct afu_config_record, kobj)
404
405static ssize_t vendor_show(struct kobject *kobj,
406 struct kobj_attribute *attr, char *buf)
407{
408 struct afu_config_record *cr = to_cr(kobj);
409
410 return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->vendor);
411}
412
413static ssize_t device_show(struct kobject *kobj,
414 struct kobj_attribute *attr, char *buf)
415{
416 struct afu_config_record *cr = to_cr(kobj);
417
418 return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->device);
419}
420
421static ssize_t class_show(struct kobject *kobj,
422 struct kobj_attribute *attr, char *buf)
423{
424 struct afu_config_record *cr = to_cr(kobj);
425