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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright 2003 José Fonseca.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2003 Leif Delgass.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Permission is hereby granted, free of charge, to any person obtaining a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * copy of this software and associated documentation files (the "Software"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * to deal in the Software without restriction, including without limitation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * and/or sell copies of the Software, and to permit persons to whom the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Software is furnished to do so, subject to the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * The above copyright notice and this permission notice (including the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * paragraph) shall be included in all copies or substantial portions of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <drm/drm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <drm/drm_agpsupport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <drm/drm_drv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include "drm_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include "drm_legacy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #ifdef CONFIG_DRM_LEGACY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * drm_pci_alloc - Allocate a PCI consistent memory block, for DMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * @size: size of block to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * @align: alignment of block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * FIXME: This is a needless abstraction of the Linux dma-api and should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * Return: A handle to the allocated memory block on success or NULL on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	drm_dma_handle_t *dmah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	/* pci_alloc_consistent only guarantees alignment to the smallest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	 * PAGE_SIZE order which is greater than or equal to the requested size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	 * Return NULL here for now to make sure nobody tries for larger alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (align > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (!dmah)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	dmah->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 					 &dmah->busaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 					 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (dmah->vaddr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		kfree(dmah);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	return dmah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) EXPORT_SYMBOL(drm_pci_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * drm_pci_free - Free a PCI consistent memory block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * @dmah: handle to memory block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * FIXME: This is a needless abstraction of the Linux dma-api and should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			  dmah->busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	kfree(dmah);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) EXPORT_SYMBOL(drm_pci_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static int drm_get_pci_domain(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #ifndef __alpha__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	/* For historical reasons, drm_get_pci_domain() is busticated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	 * on most archs and has to remain so for userspace interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	 * < 1.4, except on alpha which was right from the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (dev->if_version < 0x10004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #endif /* __alpha__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	return pci_domain_nr(dev->pdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	master->unique = kasprintf(GFP_KERNEL, "pci:%04x:%02x:%02x.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 					drm_get_pci_domain(dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 					dev->pdev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 					PCI_SLOT(dev->pdev->devfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 					PCI_FUNC(dev->pdev->devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if (!master->unique)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	master->unique_len = strlen(master->unique);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	    (p->busnum & 0xff) != dev->pdev->bus->number ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	    p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	p->irq = dev->pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		  p->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * drm_irq_by_busid - Get interrupt from bus ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * @data: IOCTL parameter pointing to a drm_irq_busid structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * @file_priv: DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * Finds the PCI device with the specified bus id and gets its IRQ number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * to that of the device that this DRM instance attached to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * Return: 0 on success or a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int drm_irq_by_busid(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		     struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct drm_irq_busid *p = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (!drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	/* UMS was only ever support on PCI devices. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (WARN_ON(!dev->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	return drm_pci_irq_by_busid(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) void drm_pci_agp_destroy(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	if (dev->agp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		arch_phys_wc_del(dev->agp->agp_mtrr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		drm_legacy_agp_clear(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		kfree(dev->agp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		dev->agp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #ifdef CONFIG_DRM_LEGACY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void drm_pci_agp_init(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			dev->agp = drm_agp_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		if (dev->agp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			dev->agp->agp_mtrr = arch_phys_wc_add(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				dev->agp->agp_info.aper_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 				dev->agp->agp_info.aper_size *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				1024 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int drm_get_pci_dev(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			   const struct pci_device_id *ent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			   struct drm_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	struct drm_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	DRM_DEBUG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	dev = drm_dev_alloc(driver, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (IS_ERR(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		return PTR_ERR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	ret = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	dev->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #ifdef __alpha__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	dev->hose = pdev->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (drm_core_check_feature(dev, DRIVER_MODESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		pci_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	drm_pci_agp_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	ret = drm_dev_register(dev, ent->driver_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		goto err_agp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	/* No locking needed since shadow-attach is single-threaded since it may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	 * only be called from the per-driver module init hook. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err_agp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	drm_pci_agp_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	drm_dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  * drm_legacy_pci_init - shadow-attach a legacy DRM PCI driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  * @driver: DRM device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  * @pdriver: PCI device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * This is only used by legacy dri1 drivers and deprecated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  * Return: 0 on success or a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	struct pci_dev *pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	const struct pci_device_id *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	DRM_DEBUG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (WARN_ON(!(driver->driver_features & DRIVER_LEGACY)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	/* If not using KMS, fall back to stealth mode manual scanning. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	INIT_LIST_HEAD(&driver->legacy_dev_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		pid = &pdriver->id_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		/* Loop around setting up a DRM device for each PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		 * matching our ID and device class.  If we had the internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		 * function that pci_get_subsys and pci_get_class used, we'd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		 * be able to just pass pid in instead of doing a two-stage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		 * thing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		while ((pdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				       pid->subdevice, pdev)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			if ((pdev->class & pid->class_mask) != pid->class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			/* stealth mode requires a manual probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			pci_dev_get(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			drm_get_pci_dev(pdev, pid, driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) EXPORT_SYMBOL(drm_legacy_pci_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  * drm_legacy_pci_exit - unregister shadow-attach legacy DRM driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  * @driver: DRM device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * @pdriver: PCI device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * Unregister a DRM driver shadow-attached through drm_legacy_pci_init(). This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * is deprecated and only used by dri1 drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	struct drm_device *dev, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	DRM_DEBUG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (!(driver->driver_features & DRIVER_LEGACY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 					 legacy_dev_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			list_del(&dev->legacy_dev_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 			drm_put_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	DRM_INFO("Module unloaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) EXPORT_SYMBOL(drm_legacy_pci_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #endif