From: Dave Airlie <[email protected]>
This patch adds the GPU layer support to the drm library.
It doesn't touch any drivers just adds the gpu layer to the drm code.
Signed-off-by: Dave Airlie <[email protected]>
---
drivers/char/drm/Makefile | 2 +
drivers/char/drm/drmP.h | 16 ++++++++++
drivers/char/drm/drm_drv.c | 10 +++++--
drivers/char/drm/drm_gpu.c | 63 +++++++++++++++++++++++++++++++++++++++++
drivers/char/drm/drm_ioctl.c | 8 +++--
drivers/char/drm/drm_memory.c | 1 +
drivers/char/drm/drm_stub.c | 31 ++++++++++----------
drivers/char/drm/drm_sysfs.c | 8 +++++
8 files changed, 114 insertions(+), 25 deletions(-)
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 3ad0f64..7438e29 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -6,7 +6,7 @@ drm-objs := drm_auth.o drm_bufs.o drm
drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
- drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
+ drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o drm_gpu.o
tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 6dcdceb..7fb9ec9 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -52,6 +52,7 @@ #include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/file.h>
#include <linux/pci.h>
+#include <linux/gpu_layer.h>
#include <linux/jiffies.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
#include <linux/mm.h>
@@ -544,6 +545,10 @@ typedef struct drm_mm {
* a family of cards. There will one drm_device for each card present
* in this family
*/
+
+#define DRM_DRV_PCI 1
+#define DRM_DRV_GPU 2
+
struct drm_device;
struct drm_driver {
@@ -604,6 +609,9 @@ struct drm_driver {
drm_ioctl_desc_t *ioctls;
int num_ioctls;
struct file_operations fops;
+ int drv_type;
+
+ struct gpu_driver gpu_driver;
struct pci_driver pci_driver;
};
@@ -728,6 +736,8 @@ typedef struct drm_device {
drm_agp_head_t *agp; /**< AGP data */
+ /* a pointer to the GPU device */
+ struct gpu_device *gdev;
struct pci_dev *pdev; /**< PCI device structure */
int pci_vendor; /**< PCI vendor id */
int pci_device; /**< PCI device id */
@@ -817,9 +827,12 @@ #endif
/******************************************************************/
/** \name Internal function definitions */
/*@{*/
+extern void drm_gpu_cleanup(struct gpu_device *gdev);
+extern int drm_gpu_get_dev(struct gpu_device *gdev, struct drm_driver *driver, void *driver_id, struct pci_dev *pdev);
/* Driver support (drm_drv.h) */
extern int drm_init(struct drm_driver *driver);
+extern void drm_cleanup(drm_device_t * dev);
extern void drm_exit(struct drm_driver *driver);
extern int drm_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
@@ -1003,9 +1016,12 @@ extern int drm_agp_bind_memory(DRM_AGP_M
extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
/* Stub support (drm_stub.h) */
+extern int drm_fill_in_dev(drm_device_t * dev, unsigned long driver_data,
+ struct drm_driver *driver);
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
struct drm_driver *driver);
extern int drm_put_dev(drm_device_t * dev);
+extern int drm_get_head(drm_device_t * dev, drm_head_t * head);
extern int drm_put_head(drm_head_t * head);
extern unsigned int drm_debug;
extern unsigned int drm_cards_limit;
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index a70af0d..2c94231 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -275,6 +275,8 @@ int drm_init(struct drm_driver *driver)
drm_mem_init();
+ driver->drv_type = DRM_DRV_PCI;
+
for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
@@ -300,7 +302,7 @@ EXPORT_SYMBOL(drm_init);
*
* \sa drm_init
*/
-static void drm_cleanup(drm_device_t * dev)
+void drm_cleanup(drm_device_t * dev)
{
DRM_DEBUG("\n");
@@ -360,8 +362,10 @@ void drm_exit(struct drm_driver *driver)
dev = head->dev;
if (dev) {
/* release the pci driver */
- if (dev->pdev)
- pci_dev_put(dev->pdev);
+ if (dev->pdev && (dev->driver->drv_type == DRM_DRV_PCI)) {
+ if (dev->pdev)
+ pci_dev_put(dev->pdev);
+ }
drm_cleanup(dev);
}
}
diff --git a/drivers/char/drm/drm_gpu.c b/drivers/char/drm/drm_gpu.c
new file mode 100644
index 0000000..4c34d6d
--- /dev/null
+++ b/drivers/char/drm/drm_gpu.c
@@ -0,0 +1,63 @@
+/*
+ * drivers/char/drm/drm_gpu.c
+ *
+ * Copyright (C) Dave Airlie <[email protected]>
+ *
+ * Unlike the rest of the DRM this is actually GPL licensed
+ * as it doesn't make much sense for it to be MIT.
+ */
+#include "drmP.h"
+
+/* DRM GPU Interface layer */
+
+int drm_gpu_get_dev(struct gpu_device *gdev, struct drm_driver *driver, void *driver_id, struct pci_dev *pdev)
+{
+ drm_device_t *dev;
+ int ret;
+ struct pci_device_id *id = (struct pci_device_id *)driver_id;
+ unsigned long driver_data = id->driver_data;
+
+ DRM_DEBUG("gdev is %p, driver is %p, void is %p, pdev is %p\n", gdev, driver, driver_id, pdev);
+
+ dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->gdev = gdev;
+ dev->pdev = pdev;
+#ifdef __alpha__
+ dev->hose = pdev->sysdata;
+#endif
+ dev->irq = pdev->irq;
+
+ if ((ret = drm_fill_in_dev(dev, driver_data, driver))) {
+ printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+ goto err_g1;
+ }
+
+ if ((ret = drm_get_head(dev, &dev->primary)))
+ goto err_g1;
+
+ gpu_set_drvdata(gdev, dev);
+
+ DRM_INFO("Initialized GPU %s %d.%d.%d %s on minor %d\n",
+ driver->name, driver->major, driver->minor, driver->patchlevel,
+ driver->date, dev->primary.minor);
+ return 0;
+
+err_g1:
+ drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+ return 0;
+}
+EXPORT_SYMBOL(drm_gpu_get_dev);
+
+void drm_gpu_cleanup(struct gpu_device *gdev)
+{
+ drm_device_t *dev = gpu_get_drvdata(gdev);
+
+ gpu_set_drvdata(gdev, NULL);
+ if (dev)
+ drm_cleanup(dev);
+}
+EXPORT_SYMBOL(drm_gpu_cleanup);
+
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 5658955..a34f9c4 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -110,12 +110,12 @@ int drm_setunique(struct inode *inode, s
dev->unique[dev->unique_len] = '\0';
dev->devname =
- drm_alloc(strlen(dev->driver->pci_driver.name) +
+ drm_alloc(strlen(dev->driver->name) +
strlen(dev->unique) + 2, DRM_MEM_DRIVER);
if (!dev->devname)
return -ENOMEM;
- sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
+ sprintf(dev->devname, "%s@%s", dev->driver->name,
dev->unique);
/* Return error if the busid submitted doesn't match the device's actual
@@ -157,12 +157,12 @@ static int drm_set_busid(drm_device_t *
DRM_ERROR("Unique buffer overflowed\n");
dev->devname =
- drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
+ drm_alloc(strlen(dev->driver->name) + dev->unique_len +
2, DRM_MEM_DRIVER);
if (dev->devname == NULL)
return -ENOMEM;
- sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
+ sprintf(dev->devname, "%s@%s", dev->driver->name,
dev->unique);
return 0;
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index 5681cae..96d962d 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -44,6 +44,7 @@ #else
void drm_mem_init(void)
{
}
+EXPORT_SYMBOL(drm_mem_init);
/**
* Called when "/proc/dri/%dev%/mem" is read.
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 120d102..6b0fef4 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -53,9 +53,8 @@ drm_head_t **drm_heads;
struct class *drm_class;
struct proc_dir_entry *drm_proc_root;
-static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
- const struct pci_device_id *ent,
- struct drm_driver *driver)
+int drm_fill_in_dev(drm_device_t * dev, unsigned long driver_data,
+ struct drm_driver *driver)
{
int retcode;
@@ -66,15 +65,6 @@ static int drm_fill_in_dev(drm_device_t
mutex_init(&dev->struct_mutex);
mutex_init(&dev->ctxlist_mutex);
- dev->pdev = pdev;
- dev->pci_device = pdev->device;
- dev->pci_vendor = pdev->vendor;
-
-#ifdef __alpha__
- dev->hose = pdev->sysdata;
-#endif
- dev->irq = pdev->irq;
-
dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
if (dev->maplist == NULL)
return -ENOMEM;
@@ -96,7 +86,7 @@ #endif
dev->driver = driver;
if (dev->driver->load)
- if ((retcode = dev->driver->load(dev, ent->driver_data)))
+ if ((retcode = dev->driver->load(dev, driver_data)))
goto error_out_unreg;
if (drm_core_has_AGP(dev)) {
@@ -142,7 +132,7 @@ #endif
* create the proc init entry via proc_init(). This routines assigns
* minor numbers to secondary heads of multi-headed cards
*/
-static int drm_get_head(drm_device_t * dev, drm_head_t * head)
+int drm_get_head(drm_device_t * dev, drm_head_t * head)
{
drm_head_t **heads = drm_heads;
int ret;
@@ -215,14 +205,23 @@ int drm_get_dev(struct pci_dev *pdev, co
if (ret)
goto err_g1;
- if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
+ dev->pdev = pdev;
+ dev->pci_device = pdev->device;
+ dev->pci_vendor = pdev->vendor;
+
+#ifdef __alpha__
+ dev->hose = pdev->sysdata;
+#endif
+ dev->irq = pdev->irq;
+
+ if ((ret = drm_fill_in_dev(dev, ent->driver_data, driver))) {
printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
goto err_g2;
}
if ((ret = drm_get_head(dev, &dev->primary)))
goto err_g2;
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ DRM_INFO("Initialized PCI %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
driver->date, dev->primary.minor);
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index cc8e2eb..fd25766 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -108,10 +108,16 @@ struct class_device *drm_sysfs_device_ad
{
struct class_device *class_dev;
int i, j, err;
+ struct device *dev;
+
+ if (head->dev->driver->drv_type == DRM_DRV_PCI)
+ dev = &(head->dev->pdev)->dev;
+ else
+ dev = &(head->dev->gdev)->dev;
class_dev = class_device_create(cs, NULL,
MKDEV(DRM_MAJOR, head->minor),
- &(head->dev->pdev)->dev,
+ dev,
"card%d", head->minor);
if (IS_ERR(class_dev)) {
err = PTR_ERR(class_dev);
--
1.4.1.ga3e6
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]