Date: Wed, 14 Aug 2019 09:36:26 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r351009 - head/sys/compat/linuxkpi/common/include/linux Message-ID: <201908140936.x7E9aQAc069612@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Wed Aug 14 09:36:25 2019 New Revision: 351009 URL: https://svnweb.freebsd.org/changeset/base/351009 Log: Implement pci_enable_msi() and pci_disable_msi() in the LinuxKPI. This patch makes the DRM graphics driver in ports usable on aarch64. Submitted by: Greg V <greg@unrelenting.technology> Differential Revision: https://reviews.freebsd.org/D21008 MFC after: 1 week Sponsored by: Mellanox Technologies Modified: head/sys/compat/linuxkpi/common/include/linux/device.h head/sys/compat/linuxkpi/common/include/linux/interrupt.h head/sys/compat/linuxkpi/common/include/linux/pci.h Modified: head/sys/compat/linuxkpi/common/include/linux/device.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/device.h Wed Aug 14 06:41:22 2019 (r351008) +++ head/sys/compat/linuxkpi/common/include/linux/device.h Wed Aug 14 09:36:25 2019 (r351009) @@ -110,8 +110,8 @@ struct device { void *driver_data; unsigned int irq; #define LINUX_IRQ_INVALID 65535 - unsigned int msix; - unsigned int msix_max; + unsigned int irq_start; + unsigned int irq_end; const struct attribute_group **groups; struct fwnode_handle *fwnode; Modified: head/sys/compat/linuxkpi/common/include/linux/interrupt.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/interrupt.h Wed Aug 14 06:41:22 2019 (r351008) +++ head/sys/compat/linuxkpi/common/include/linux/interrupt.h Wed Aug 14 09:36:25 2019 (r351009) @@ -55,9 +55,11 @@ struct irq_ent { static inline int linux_irq_rid(struct device *dev, unsigned int irq) { - if (irq == dev->irq) + /* check for MSI- or MSIX- interrupt */ + if (irq >= dev->irq_start && irq < dev->irq_end) + return (irq - dev->irq_start + 1); + else return (0); - return irq - dev->msix + 1; } extern void linux_irq_handler(void *); Modified: head/sys/compat/linuxkpi/common/include/linux/pci.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/pci.h Wed Aug 14 06:41:22 2019 (r351008) +++ head/sys/compat/linuxkpi/common/include/linux/pci.h Wed Aug 14 09:36:25 2019 (r351009) @@ -228,6 +228,7 @@ struct pci_dev { unsigned int devfn; uint32_t class; uint8_t revision; + bool msi_enabled; }; static inline struct resource_list_entry * @@ -262,7 +263,7 @@ linux_pci_find_irq_dev(unsigned int irq) spin_lock(&pci_lock); list_for_each_entry(pdev, &pci_devices, links) { if (irq == pdev->dev.irq || - (irq >= pdev->dev.msix && irq < pdev->dev.msix_max)) { + (irq >= pdev->dev.irq_start && irq < pdev->dev.irq_end)) { found = &pdev->dev; break; } @@ -424,10 +425,25 @@ pci_disable_msix(struct pci_dev *pdev) * linux_pci_find_irq_dev() does no longer see them by * resetting their references to zero: */ - pdev->dev.msix = 0; - pdev->dev.msix_max = 0; + pdev->dev.irq_start = 0; + pdev->dev.irq_end = 0; } +#define pci_disable_msi(pdev) \ + linux_pci_disable_msi(pdev) + +static inline void +linux_pci_disable_msi(struct pci_dev *pdev) +{ + + pci_release_msi(pdev->dev.bsddev); + + pdev->dev.irq_start = 0; + pdev->dev.irq_end = 0; + pdev->irq = pdev->dev.irq; + pdev->msi_enabled = false; +} + unsigned long pci_resource_start(struct pci_dev *pdev, int bar); unsigned long pci_resource_len(struct pci_dev *pdev, int bar); @@ -562,10 +578,10 @@ pci_enable_msix(struct pci_dev *pdev, struct msix_entr return avail; } rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1); - pdev->dev.msix = rle->start; - pdev->dev.msix_max = rle->start + avail; + pdev->dev.irq_start = rle->start; + pdev->dev.irq_end = rle->start + avail; for (i = 0; i < nreq; i++) - entries[i].vector = pdev->dev.msix + i; + entries[i].vector = pdev->dev.irq_start + i; return (0); } @@ -593,6 +609,32 @@ pci_enable_msix_range(struct pci_dev *dev, struct msix } } while (rc); return (nvec); +} + +#define pci_enable_msi(pdev) \ + linux_pci_enable_msi(pdev) + +static inline int +pci_enable_msi(struct pci_dev *pdev) +{ + struct resource_list_entry *rle; + int error; + int avail; + + avail = pci_msi_count(pdev->dev.bsddev); + if (avail < 1) + return -EINVAL; + + avail = 1; /* this function only enable one MSI IRQ */ + if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0) + return error; + + rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1); + pdev->dev.irq_start = rle->start; + pdev->dev.irq_end = rle->start + avail; + pdev->irq = rle->start; + pdev->msi_enabled = true; + return (0); } static inline int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908140936.x7E9aQAc069612>