1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright 2017 IBM Corp.
3 #include <linux/sysfs.h>
4 #include "ocxl_internal.h"
6 static ssize_t
global_mmio_size_show(struct device
*device
,
7 struct device_attribute
*attr
,
10 struct ocxl_afu
*afu
= to_ocxl_afu(device
);
12 return scnprintf(buf
, PAGE_SIZE
, "%d\n",
13 afu
->config
.global_mmio_size
);
16 static ssize_t
pp_mmio_size_show(struct device
*device
,
17 struct device_attribute
*attr
,
20 struct ocxl_afu
*afu
= to_ocxl_afu(device
);
22 return scnprintf(buf
, PAGE_SIZE
, "%d\n",
23 afu
->config
.pp_mmio_stride
);
26 static ssize_t
afu_version_show(struct device
*device
,
27 struct device_attribute
*attr
,
30 struct ocxl_afu
*afu
= to_ocxl_afu(device
);
32 return scnprintf(buf
, PAGE_SIZE
, "%hhu:%hhu\n",
33 afu
->config
.version_major
,
34 afu
->config
.version_minor
);
37 static ssize_t
contexts_show(struct device
*device
,
38 struct device_attribute
*attr
,
41 struct ocxl_afu
*afu
= to_ocxl_afu(device
);
43 return scnprintf(buf
, PAGE_SIZE
, "%d/%d\n",
44 afu
->pasid_count
, afu
->pasid_max
);
47 static struct device_attribute afu_attrs
[] = {
48 __ATTR_RO(global_mmio_size
),
49 __ATTR_RO(pp_mmio_size
),
50 __ATTR_RO(afu_version
),
54 static ssize_t
global_mmio_read(struct file
*filp
, struct kobject
*kobj
,
55 struct bin_attribute
*bin_attr
, char *buf
,
56 loff_t off
, size_t count
)
58 struct ocxl_afu
*afu
= to_ocxl_afu(kobj_to_dev(kobj
));
60 if (count
== 0 || off
< 0 ||
61 off
>= afu
->config
.global_mmio_size
)
63 memcpy_fromio(buf
, afu
->global_mmio_ptr
+ off
, count
);
67 static int global_mmio_fault(struct vm_fault
*vmf
)
69 struct vm_area_struct
*vma
= vmf
->vma
;
70 struct ocxl_afu
*afu
= vma
->vm_private_data
;
73 if (vmf
->pgoff
>= (afu
->config
.global_mmio_size
>> PAGE_SHIFT
))
74 return VM_FAULT_SIGBUS
;
77 offset
+= (afu
->global_mmio_start
>> PAGE_SHIFT
);
78 vm_insert_pfn(vma
, vmf
->address
, offset
);
79 return VM_FAULT_NOPAGE
;
82 static const struct vm_operations_struct global_mmio_vmops
= {
83 .fault
= global_mmio_fault
,
86 static int global_mmio_mmap(struct file
*filp
, struct kobject
*kobj
,
87 struct bin_attribute
*bin_attr
,
88 struct vm_area_struct
*vma
)
90 struct ocxl_afu
*afu
= to_ocxl_afu(kobj_to_dev(kobj
));
92 if ((vma_pages(vma
) + vma
->vm_pgoff
) >
93 (afu
->config
.global_mmio_size
>> PAGE_SHIFT
))
96 vma
->vm_flags
|= VM_IO
| VM_PFNMAP
;
97 vma
->vm_page_prot
= pgprot_noncached(vma
->vm_page_prot
);
98 vma
->vm_ops
= &global_mmio_vmops
;
99 vma
->vm_private_data
= afu
;
103 int ocxl_sysfs_add_afu(struct ocxl_afu
*afu
)
107 for (i
= 0; i
< ARRAY_SIZE(afu_attrs
); i
++) {
108 rc
= device_create_file(&afu
->dev
, &afu_attrs
[i
]);
113 sysfs_attr_init(&afu
->attr_global_mmio
.attr
);
114 afu
->attr_global_mmio
.attr
.name
= "global_mmio_area";
115 afu
->attr_global_mmio
.attr
.mode
= 0600;
116 afu
->attr_global_mmio
.size
= afu
->config
.global_mmio_size
;
117 afu
->attr_global_mmio
.read
= global_mmio_read
;
118 afu
->attr_global_mmio
.mmap
= global_mmio_mmap
;
119 rc
= device_create_bin_file(&afu
->dev
, &afu
->attr_global_mmio
);
122 "Unable to create global mmio attr for afu: %d\n",
130 for (i
--; i
>= 0; i
--)
131 device_remove_file(&afu
->dev
, &afu_attrs
[i
]);
135 void ocxl_sysfs_remove_afu(struct ocxl_afu
*afu
)
139 for (i
= 0; i
< ARRAY_SIZE(afu_attrs
); i
++)
140 device_remove_file(&afu
->dev
, &afu_attrs
[i
]);
141 device_remove_bin_file(&afu
->dev
, &afu
->attr_global_mmio
);