mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
PCI/VGA: pass a data pointer to be used in the decode callback (v2)
This changes the vgaarb client API so that the user can pass a private data pointer into the register that will get used in the decode callback. This allows a bunch of pdev conversions in the drivers, and lets some future vfio cleanups be nicer. I'd like to merge this via the drm next tree but also fine with it going via pci. Signed-off-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Acked-by: Alex Williamson <alex@shazbot.org> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://lore.kernel.org/dri-devel/20260922071807.2533884-1-airlied@gmail.com/
This commit is contained in:
parent
93f51579e7
commit
93d41424ca
|
|
@ -1429,16 +1429,15 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_device_vga_set_decode - enable/disable vga decode
|
||||
*
|
||||
* @pdev: PCI device pointer
|
||||
* @data: driver private data (adev)
|
||||
* @state: enable/disable vga decode
|
||||
*
|
||||
* Enable/disable vga decode (all asics).
|
||||
* Returns VGA resource flags.
|
||||
*/
|
||||
static unsigned int amdgpu_device_vga_set_decode(struct pci_dev *pdev,
|
||||
bool state)
|
||||
static unsigned int amdgpu_device_vga_set_decode(void *data, bool state)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(pci_get_drvdata(pdev));
|
||||
struct amdgpu_device *adev = data;
|
||||
|
||||
amdgpu_asic_set_vga_state(adev, state);
|
||||
if (state)
|
||||
|
|
@ -4199,7 +4198,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
* ignore it
|
||||
*/
|
||||
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
|
||||
vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
|
||||
vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, adev);
|
||||
|
||||
px = amdgpu_device_supports_px(adev);
|
||||
|
||||
|
|
|
|||
|
|
@ -283,9 +283,10 @@ void intel_vga_disable(struct intel_display *display)
|
|||
intel_de_posting_read(display, vga_reg);
|
||||
}
|
||||
|
||||
static unsigned int intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
|
||||
static unsigned int intel_vga_set_decode(void *data, bool enable_decode)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(pdev);
|
||||
struct intel_display *display = data;
|
||||
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
|
||||
unsigned int decodes = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
|
||||
|
||||
drm_dbg_kms(display->drm, "%s VGA decode due to VGA arbitration\n",
|
||||
|
|
@ -331,7 +332,7 @@ void intel_vga_register(struct intel_display *display)
|
|||
* then we do not take part in VGA arbitration and the
|
||||
* vga_client_register() fails with -ENODEV.
|
||||
*/
|
||||
ret = vga_client_register(pdev, intel_vga_set_decode);
|
||||
ret = vga_client_register(pdev, intel_vga_set_decode, display);
|
||||
drm_WARN_ON(display->drm, ret && ret != -ENODEV);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ lsdc_create_device(struct pci_dev *pdev,
|
|||
|
||||
/* For multiple GPU driver instance co-exixt in the system */
|
||||
|
||||
static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state)
|
||||
static unsigned int lsdc_vga_set_decode(void *data, bool state)
|
||||
{
|
||||
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
|
||||
}
|
||||
|
|
@ -291,7 +291,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
pci_set_drvdata(pdev, ddev);
|
||||
|
||||
vga_client_register(pdev, lsdc_vga_set_decode);
|
||||
vga_client_register(pdev, lsdc_vga_set_decode, NULL);
|
||||
|
||||
drmm_kms_helper_poll_init(ddev);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
#include "nouveau_vga.h"
|
||||
|
||||
static unsigned int
|
||||
nouveau_vga_set_decode(struct pci_dev *pdev, bool state)
|
||||
nouveau_vga_set_decode(void *data, bool state)
|
||||
{
|
||||
struct nouveau_drm *drm = pci_get_drvdata(pdev);
|
||||
struct nouveau_drm *drm = data;
|
||||
struct nvif_object *device = &drm->client.device.object;
|
||||
|
||||
if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE &&
|
||||
|
|
@ -95,7 +95,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
|
|||
return;
|
||||
pdev = to_pci_dev(dev->dev);
|
||||
|
||||
vga_client_register(pdev, nouveau_vga_set_decode);
|
||||
vga_client_register(pdev, nouveau_vga_set_decode, drm);
|
||||
|
||||
/* don't register Thunderbolt eGPU with vga_switcheroo */
|
||||
if (pci_is_thunderbolt_attached(pdev))
|
||||
|
|
|
|||
|
|
@ -1070,16 +1070,15 @@ void radeon_combios_fini(struct radeon_device *rdev)
|
|||
/**
|
||||
* radeon_vga_set_decode - enable/disable vga decode
|
||||
*
|
||||
* @pdev: PCI device
|
||||
* @data: driver private data (rdev)
|
||||
* @state: enable/disable vga decode
|
||||
*
|
||||
* Enable/disable vga decode (all asics).
|
||||
* Returns VGA resource flags.
|
||||
*/
|
||||
static unsigned int radeon_vga_set_decode(struct pci_dev *pdev, bool state)
|
||||
static unsigned int radeon_vga_set_decode(void *data, bool state)
|
||||
{
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_device *rdev = data;
|
||||
radeon_vga_set_state(rdev, state);
|
||||
if (state)
|
||||
return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
|
||||
|
|
@ -1424,7 +1423,7 @@ int radeon_device_init(struct radeon_device *rdev,
|
|||
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
|
||||
/* this will fail for cards that aren't VGA class devices, just
|
||||
* ignore it */
|
||||
vga_client_register(rdev->pdev, radeon_vga_set_decode);
|
||||
vga_client_register(rdev->pdev, radeon_vga_set_decode, rdev);
|
||||
|
||||
if (rdev->flags & RADEON_IS_PX)
|
||||
runtime = true;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ struct vga_device {
|
|||
unsigned int mem_norm_cnt; /* normal MEM count */
|
||||
bool bridge_has_one_vga;
|
||||
bool is_firmware_default; /* device selected by firmware */
|
||||
unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
|
||||
unsigned int (*set_decode)(void *data, bool decode);
|
||||
void *set_decode_data;
|
||||
};
|
||||
|
||||
static LIST_HEAD(vga_list);
|
||||
|
|
@ -935,6 +936,7 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
|
|||
* vga_client_register - register or unregister a VGA arbitration client
|
||||
* @pdev: PCI device of the VGA client
|
||||
* @set_decode: VGA decode change callback
|
||||
* @data: private data to pass to callback
|
||||
*
|
||||
* Clients have two callback mechanisms they can use.
|
||||
*
|
||||
|
|
@ -956,15 +958,18 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
|
|||
* Returns: 0 on success, -ENODEV on failure
|
||||
*/
|
||||
int vga_client_register(struct pci_dev *pdev,
|
||||
unsigned int (*set_decode)(struct pci_dev *pdev, bool decode))
|
||||
unsigned int (*set_decode)(void *data, bool decode),
|
||||
void *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct vga_device *vgadev;
|
||||
|
||||
spin_lock_irqsave(&vga_lock, flags);
|
||||
vgadev = vgadev_find(pdev);
|
||||
if (vgadev)
|
||||
if (vgadev) {
|
||||
vgadev->set_decode = set_decode;
|
||||
vgadev->set_decode_data = data;
|
||||
}
|
||||
spin_unlock_irqrestore(&vga_lock, flags);
|
||||
if (!vgadev)
|
||||
return -ENODEV;
|
||||
|
|
@ -1464,7 +1469,7 @@ static void vga_arbiter_notify_clients(void)
|
|||
spin_lock_irqsave(&vga_lock, flags);
|
||||
list_for_each_entry(vgadev, &vga_list, list) {
|
||||
if (vgadev->set_decode) {
|
||||
new_decodes = vgadev->set_decode(vgadev->pdev,
|
||||
new_decodes = vgadev->set_decode(vgadev->set_decode_data,
|
||||
new_state);
|
||||
vga_update_device_decodes(vgadev, new_decodes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,9 +162,10 @@ static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
|
|||
* has no way to get to it and routing can be disabled externally at the
|
||||
* bridge.
|
||||
*/
|
||||
static unsigned int vfio_pci_set_decode(struct pci_dev *pdev, bool single_vga)
|
||||
static unsigned int vfio_pci_set_decode(void *data, bool single_vga)
|
||||
{
|
||||
struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev);
|
||||
struct vfio_pci_core_device *vdev = data;
|
||||
struct pci_dev *pdev = vdev->pdev;
|
||||
struct pci_dev *tmp = NULL;
|
||||
unsigned char max_busnr;
|
||||
unsigned int decodes;
|
||||
|
|
@ -2159,10 +2160,10 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = vga_client_register(pdev, vfio_pci_set_decode);
|
||||
ret = vga_client_register(pdev, vfio_pci_set_decode, vdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
vga_set_legacy_decoding(pdev, vfio_pci_set_decode(pdev, false));
|
||||
vga_set_legacy_decoding(pdev, vfio_pci_set_decode(vdev, false));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
|
|||
void vga_set_default_device(struct pci_dev *pdev);
|
||||
int vga_remove_vgacon(struct pci_dev *pdev);
|
||||
int vga_client_register(struct pci_dev *pdev,
|
||||
unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
|
||||
unsigned int (*set_decode)(void *data, bool state),
|
||||
void *data);
|
||||
#else /* CONFIG_VGA_ARB */
|
||||
static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
|
||||
unsigned int decodes)
|
||||
|
|
@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
|
|||
return 0;
|
||||
}
|
||||
static inline int vga_client_register(struct pci_dev *pdev,
|
||||
unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
|
||||
unsigned int (*set_decode)(void *data, bool state),
|
||||
void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
|
|||
|
||||
static inline void vga_client_unregister(struct pci_dev *pdev)
|
||||
{
|
||||
vga_client_register(pdev, NULL);
|
||||
vga_client_register(pdev, NULL, NULL);
|
||||
}
|
||||
|
||||
#endif /* LINUX_VGA_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user