This commit registers a device on the aux bus after core NVKM init has finished, which will be used by a later commit to have the DRM driver probe() against an aux device instead of a PCI or platform device (in the case of Tegra). Signed-off-by: Ben Skeggs <bskeggs@xxxxxxxxxx> --- drivers/gpu/drm/nouveau/Kconfig | 1 + .../drm/nouveau/include/nvkm/core/device.h | 3 ++ drivers/gpu/drm/nouveau/nvkm/device/base.c | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 4c10b400658c..6d0d46a0e66f 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -7,6 +7,7 @@ config DRM_NOUVEAU depends on DRM_DISPLAY_HELPER depends on PCI depends on MMU + select AUXILIARY_BUS select IOMMU_API select FW_LOADER select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index d8596fe0adea..855d1b20820d 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -5,6 +5,8 @@ #include <core/intr.h> enum nvkm_subdev_type; +#include <linux/auxiliary_bus.h> + enum nvkm_device_type { NVKM_DEVICE_PCI, NVKM_DEVICE_AGP, @@ -78,6 +80,7 @@ struct nvkm_device { bool legacy_done; } intr; + struct auxiliary_device auxdev; const struct nvif_driver_func *driver; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/device/base.c b/drivers/gpu/drm/nouveau/nvkm/device/base.c index 4f8298bf71ee..fbb6e20bc1f2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/base.c @@ -3029,6 +3029,9 @@ nvkm_device_del(struct nvkm_device **pdevice) struct nvkm_device *device = *pdevice; struct nvkm_subdev *subdev, *subtmp; if (device) { + auxiliary_device_delete(&device->auxdev); + auxiliary_device_uninit(&device->auxdev); + nvkm_intr_dtor(device); list_for_each_entry_safe_reverse(subdev, subtmp, &device->subdev, head) @@ -3076,6 +3079,16 @@ nvkm_device_endianness(struct nvkm_device *device) return true; } +static DEFINE_IDA(nvkm_device_id); + +static void +nvkm_device_release(struct device *dev) +{ + struct nvkm_device *device = container_of(dev, typeof(*device), auxdev.dev); + + ida_free(&nvkm_device_id, device->auxdev.id); +} + int nvkm_device_ctor(const struct nvkm_device_func *func, const struct nvkm_device_quirk *quirk, @@ -3335,5 +3348,25 @@ nvkm_device_ctor(const struct nvkm_device_func *func, iounmap(device->pri); device->pri = NULL; } + + if (ret == 0) { + ret = ida_alloc(&nvkm_device_id, GFP_KERNEL); + if (ret < 0) + return ret; + + device->auxdev.dev.parent = device->dev; + device->auxdev.dev.release = nvkm_device_release; + device->auxdev.name = "device"; + device->auxdev.id = ret; + + ret = auxiliary_device_init(&device->auxdev); + if (ret) + return ret; + + ret = auxiliary_device_add(&device->auxdev); + if (ret) + auxiliary_device_uninit(&device->auxdev); + } + return ret; } -- 2.44.0