Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 988f7b57 authored by venkatesh.pallipadi@intel.com's avatar venkatesh.pallipadi@intel.com Committed by Ingo Molnar
Browse files

x86: PAT export resource_wc in pci sysfs



For the ranges with IORESOURCE_PREFETCH, export a new resource_wc interface in
pci /sysfs along with resource (which is uncached).

Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Acked-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 492c2e47
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ files, each with their own function.
       local_cpus	   nearby CPU mask (cpumask, ro)
       local_cpus	   nearby CPU mask (cpumask, ro)
       resource		   PCI resource host addresses (ascii, ro)
       resource		   PCI resource host addresses (ascii, ro)
       resource0..N	   PCI resource N, if present (binary, mmap)
       resource0..N	   PCI resource N, if present (binary, mmap)
       resource0_wc..N_wc  PCI WC map resource N, if prefetchable (binary, mmap)
       rom		   PCI ROM resource, if present (binary, ro)
       rom		   PCI ROM resource, if present (binary, ro)
       subsystem_device	   PCI subsystem device (ascii, ro)
       subsystem_device	   PCI subsystem device (ascii, ro)
       subsystem_vendor	   PCI subsystem vendor (ascii, ro)
       subsystem_vendor	   PCI subsystem vendor (ascii, ro)
+62 −22
Original line number Original line Diff line number Diff line
@@ -489,13 +489,14 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
 * @kobj: kobject for mapping
 * @kobj: kobject for mapping
 * @attr: struct bin_attribute for the file being mapped
 * @attr: struct bin_attribute for the file being mapped
 * @vma: struct vm_area_struct passed into the mmap
 * @vma: struct vm_area_struct passed into the mmap
 * @write_combine: 1 for write_combine mapping
 *
 *
 * Use the regular PCI mapping routines to map a PCI resource into userspace.
 * Use the regular PCI mapping routines to map a PCI resource into userspace.
 * FIXME: write combining?  maybe automatic for prefetchable regions?
 * FIXME: write combining?  maybe automatic for prefetchable regions?
 */
 */
static int
static int
pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
		  struct vm_area_struct *vma)
		  struct vm_area_struct *vma, int write_combine)
{
{
	struct pci_dev *pdev = to_pci_dev(container_of(kobj,
	struct pci_dev *pdev = to_pci_dev(container_of(kobj,
						       struct device, kobj));
						       struct device, kobj));
@@ -518,7 +519,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
	vma->vm_pgoff += start >> PAGE_SHIFT;
	vma->vm_pgoff += start >> PAGE_SHIFT;
	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;


	return pci_mmap_page_range(pdev, vma, mmap_type, 0);
	return pci_mmap_page_range(pdev, vma, mmap_type, write_combine);
}

static int
pci_mmap_resource_uc(struct kobject *kobj, struct bin_attribute *attr,
		     struct vm_area_struct *vma)
{
	return pci_mmap_resource(kobj, attr, vma, 0);
}

static int
pci_mmap_resource_wc(struct kobject *kobj, struct bin_attribute *attr,
		     struct vm_area_struct *vma)
{
	return pci_mmap_resource(kobj, attr, vma, 1);
}
}


/**
/**
@@ -541,9 +556,46 @@ pci_remove_resource_files(struct pci_dev *pdev)
			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
			kfree(res_attr);
			kfree(res_attr);
		}
		}

		res_attr = pdev->res_attr_wc[i];
		if (res_attr) {
			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
			kfree(res_attr);
		}
	}
	}
}
}


static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
{
	/* allocate attribute structure, piggyback attribute name */
	int name_len = write_combine ? 13 : 10;
	struct bin_attribute *res_attr;
	int retval;

	res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
	if (res_attr) {
		char *res_attr_name = (char *)(res_attr + 1);

		if (write_combine) {
			pdev->res_attr_wc[num] = res_attr;
			sprintf(res_attr_name, "resource%d_wc", num);
			res_attr->mmap = pci_mmap_resource_wc;
		} else {
			pdev->res_attr[num] = res_attr;
			sprintf(res_attr_name, "resource%d", num);
			res_attr->mmap = pci_mmap_resource_uc;
		}
		res_attr->attr.name = res_attr_name;
		res_attr->attr.mode = S_IRUSR | S_IWUSR;
		res_attr->size = pci_resource_len(pdev, num);
		res_attr->private = &pdev->resource[num];
		retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
	} else
		retval = -ENOMEM;

	return retval;
}

/**
/**
 * pci_create_resource_files - create resource files in sysfs for @dev
 * pci_create_resource_files - create resource files in sysfs for @dev
 * @dev: dev in question
 * @dev: dev in question
@@ -557,32 +609,20 @@ static int pci_create_resource_files(struct pci_dev *pdev)


	/* Expose the PCI resources from this device as files */
	/* Expose the PCI resources from this device as files */
	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
		struct bin_attribute *res_attr;


		/* skip empty resources */
		/* skip empty resources */
		if (!pci_resource_len(pdev, i))
		if (!pci_resource_len(pdev, i))
			continue;
			continue;


		/* allocate attribute structure, piggyback attribute name */
		retval = pci_create_attr(pdev, i, 0);
		res_attr = kzalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
		/* for prefetchable resources, create a WC mappable file */
		if (res_attr) {
		if (!retval && pdev->resource[i].flags & IORESOURCE_PREFETCH)
			char *res_attr_name = (char *)(res_attr + 1);
			retval = pci_create_attr(pdev, i, 1);


			pdev->res_attr[i] = res_attr;
			sprintf(res_attr_name, "resource%d", i);
			res_attr->attr.name = res_attr_name;
			res_attr->attr.mode = S_IRUSR | S_IWUSR;
			res_attr->size = pci_resource_len(pdev, i);
			res_attr->mmap = pci_mmap_resource;
			res_attr->private = &pdev->resource[i];
			retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
		if (retval) {
		if (retval) {
			pci_remove_resource_files(pdev);
			pci_remove_resource_files(pdev);
			return retval;
			return retval;
		}
		}
		} else {
			return -ENOMEM;
		}
	}
	}
	return 0;
	return 0;
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -206,6 +206,7 @@ struct pci_dev {
	struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
	struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
	int rom_attr_enabled;		/* has display of the rom attribute been enabled? */
	int rom_attr_enabled;		/* has display of the rom attribute been enabled? */
	struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
	struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
	struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_PCI_MSI
#ifdef CONFIG_PCI_MSI
	struct list_head msi_list;
	struct list_head msi_list;
#endif
#endif