Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0+
  2// Copyright 2017 IBM Corp.
  3#include <linux/sysfs.h>
  4#include "ocxl_internal.h"
  5
  6static ssize_t global_mmio_size_show(struct device *device,
  7				struct device_attribute *attr,
  8				char *buf)
  9{
 10	struct ocxl_afu *afu = to_ocxl_afu(device);
 11
 12	return scnprintf(buf, PAGE_SIZE, "%d\n",
 13			afu->config.global_mmio_size);
 14}
 15
 16static ssize_t pp_mmio_size_show(struct device *device,
 17				struct device_attribute *attr,
 18				char *buf)
 19{
 20	struct ocxl_afu *afu = to_ocxl_afu(device);
 21
 22	return scnprintf(buf, PAGE_SIZE, "%d\n",
 23			afu->config.pp_mmio_stride);
 24}
 25
 26static ssize_t afu_version_show(struct device *device,
 27				struct device_attribute *attr,
 28				char *buf)
 29{
 30	struct ocxl_afu *afu = to_ocxl_afu(device);
 31
 32	return scnprintf(buf, PAGE_SIZE, "%hhu:%hhu\n",
 33			afu->config.version_major,
 34			afu->config.version_minor);
 35}
 36
 37static ssize_t contexts_show(struct device *device,
 38		struct device_attribute *attr,
 39		char *buf)
 40{
 41	struct ocxl_afu *afu = to_ocxl_afu(device);
 42
 43	return scnprintf(buf, PAGE_SIZE, "%d/%d\n",
 44			afu->pasid_count, afu->pasid_max);
 45}
 46
 47static struct device_attribute afu_attrs[] = {
 48	__ATTR_RO(global_mmio_size),
 49	__ATTR_RO(pp_mmio_size),
 50	__ATTR_RO(afu_version),
 51	__ATTR_RO(contexts),
 52};
 53
 54static 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)
 57{
 58	struct ocxl_afu *afu = to_ocxl_afu(kobj_to_dev(kobj));
 59
 60	if (count == 0 || off < 0 ||
 61		off >= afu->config.global_mmio_size)
 62		return 0;
 63	memcpy_fromio(buf, afu->global_mmio_ptr + off, count);
 64	return count;
 65}
 66
 67static int global_mmio_fault(struct vm_fault *vmf)
 68{
 69	struct vm_area_struct *vma = vmf->vma;
 70	struct ocxl_afu *afu = vma->vm_private_data;
 71	unsigned long offset;
 72
 73	if (vmf->pgoff >= (afu->config.global_mmio_size >> PAGE_SHIFT))
 74		return VM_FAULT_SIGBUS;
 75
 76	offset = vmf->pgoff;
 77	offset += (afu->global_mmio_start >> PAGE_SHIFT);
 78	vm_insert_pfn(vma, vmf->address, offset);
 79	return VM_FAULT_NOPAGE;
 80}
 81
 82static const struct vm_operations_struct global_mmio_vmops = {
 83	.fault = global_mmio_fault,
 84};
 85
 86static int global_mmio_mmap(struct file *filp, struct kobject *kobj,
 87			struct bin_attribute *bin_attr,
 88			struct vm_area_struct *vma)
 89{
 90	struct ocxl_afu *afu = to_ocxl_afu(kobj_to_dev(kobj));
 91
 92	if ((vma_pages(vma) + vma->vm_pgoff) >
 93		(afu->config.global_mmio_size >> PAGE_SHIFT))
 94		return -EINVAL;
 95
 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;
100	return 0;
101}
102
103int ocxl_sysfs_add_afu(struct ocxl_afu *afu)
104{
105	int i, rc;
106
107	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
108		rc = device_create_file(&afu->dev, &afu_attrs[i]);
109		if (rc)
110			goto err;
111	}
112
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);
120	if (rc) {
121		dev_err(&afu->dev,
122			"Unable to create global mmio attr for afu: %d\n",
123			rc);
124		goto err;
125	}
126
127	return 0;
128
129err:
130	for (i--; i >= 0; i--)
131		device_remove_file(&afu->dev, &afu_attrs[i]);
132	return rc;
133}
134
135void ocxl_sysfs_remove_afu(struct ocxl_afu *afu)
136{
137	int i;
138
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);
142}