Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* uio_pci_generic - generic UIO driver for PCI 2.3 devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2009 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Author: Michael S. Tsirkin <mst@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Since the driver does not declare any device ids, you must allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * id and bind the device to the driver yourself.  For example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * # echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * # ls -l /sys/bus/pci/devices/0000:00:19.0/driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Driver won't bind to devices which do not support the Interrupt Disable Bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * in the command register. All devices compliant to PCI 2.3 (circa 2002) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * all compliant PCI Express devices should support this bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/uio_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DRIVER_VERSION	"0.01.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define DRIVER_AUTHOR	"Michael S. Tsirkin <mst@redhat.com>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define DRIVER_DESC	"Generic UIO driver for PCI 2.3 devices"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) struct uio_pci_generic_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct uio_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static inline struct uio_pci_generic_dev *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) to_uio_pci_generic_dev(struct uio_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	return container_of(info, struct uio_pci_generic_dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static int release(struct uio_info *info, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	 * This driver is insecure when used with devices doing DMA, but some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	 * people (mis)use it with such devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 * Let's at least make sure DMA isn't left enabled after the userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	 * driver closes the fd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	 * Note that there's a non-zero chance doing this will wedge the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	 * at least until reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	pci_clear_master(gdev->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /* Interrupt handler. Read/modify/write the command register to disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * the interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static irqreturn_t irqhandler(int irq, struct uio_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (!pci_check_and_mask_intx(gdev->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	/* UIO core will signal the user process. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) static int probe(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			   const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct uio_pci_generic_dev *gdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			__func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (pdev->irq && !pci_intx_mask_supported(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		goto err_verify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (!gdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	gdev->info.name = "uio_pci_generic";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	gdev->info.version = DRIVER_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	gdev->info.release = release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	gdev->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (pdev->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		gdev->info.irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		gdev->info.irq_flags = IRQF_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		gdev->info.handler = irqhandler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		dev_warn(&pdev->dev, "No IRQ assigned to device: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			 "no support for interrupts?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	err = uio_register_device(&pdev->dev, &gdev->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		goto err_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	pci_set_drvdata(pdev, gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) err_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	kfree(gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) err_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) err_verify:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	uio_unregister_device(&gdev->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	kfree(gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static struct pci_driver uio_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	.name = "uio_pci_generic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	.id_table = NULL, /* only dynamic id's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	.probe = probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	.remove = remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) module_pci_driver(uio_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) MODULE_VERSION(DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) MODULE_DESCRIPTION(DRIVER_DESC);