diff options
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_sysfs.c | 6 | ||||
-rw-r--r-- | include/drm/drmP.h | 6 |
4 files changed, 94 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 14c7a23dc15..30546a72d75 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -251,6 +251,7 @@ int drm_lastclose(struct drm_device * dev) */ int drm_init(struct drm_driver *driver) { +#ifdef CONFIG_PCI struct pci_dev *pdev = NULL; struct pci_device_id *pid; int i; @@ -280,12 +281,40 @@ int drm_init(struct drm_driver *driver) drm_get_dev(pdev, pid, driver); } } +#endif return 0; } EXPORT_SYMBOL(drm_init); /** + * + * Call this to associate a drm_driver with a platform_device. + * + * \return zero on success or a negative number on failure. + * + * This is a replacement for drm_init(), but for platform drivers. + * In this case, the caller must provide the matching platform_device + * + * since there is no physical bus to scan through. + * + * \sa drm_init + * + */ + +int drm_platform_init(struct drm_driver *driver, struct platform_device *pdev) +{ + DRM_DEBUG("\n"); + + INIT_LIST_HEAD(&driver->device_list); + + return drm_get_platform_dev(pdev, driver); +} + +EXPORT_SYMBOL(drm_platform_init); + + +/** * Called via cleanup_module() at module unload time. * * Cleans up all DRM device, calling drm_lastclose(). diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 46bb923b097..e8aa423bd9b 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -213,12 +213,13 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, idr_init(&dev->drw_idr); dev->pdev = pdev; - dev->pci_device = pdev->device; - dev->pci_vendor = pdev->vendor; - + if (pdev) { + dev->pci_device = pdev->device; + dev->pci_vendor = pdev->vendor; #ifdef __alpha__ dev->hose = pdev->sysdata; #endif + } if (drm_ht_create(&dev->map_hash, 12)) { return -ENOMEM; @@ -418,6 +419,56 @@ err_g1: return ret; } + /** + * + * Register a platform device as a DRM device + * + * \param pdev - platform device structure + * \param driver - the matching drm_driver structure + * \return zero on success or a negative number on failure. + * + * Attempt to gets inter module "drm" information. If we are first + * then register the character device and inter module information. + * Try and register, if we fail to register, backout previous work. + * + * \sa drm_get_dev + */ +int drm_get_platform_dev(struct platform_device *pdev, + struct drm_driver *driver) +{ + struct drm_device *dev; + int ret; +#if 0 + int len; +#endif + DRM_DEBUG("\n"); + + dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB); + if (!dev) + return -ENOMEM; + + if ((ret = drm_fill_in_dev(dev, NULL, NULL, driver))) { + printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); + goto err_g1; + } + + dev->platform_dev = pdev; + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) + goto err_g1; + + list_add_tail(&dev->driver_item, &driver->device_list); + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", + driver->name, driver->major, driver->minor, driver->patchlevel, + driver->date, dev->primary->index); + + return 0; + +err_g1: + drm_free(dev, sizeof(*dev), DRM_MEM_STUB); + return ret; +} + /** * Put a device minor number. * diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 5aa6780652a..44f7f16ebd6 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -477,7 +477,11 @@ int drm_sysfs_device_add(struct drm_minor *minor) int i, j; char *minor_str; - minor->kdev.parent = &minor->dev->pdev->dev; + if (minor->dev->pdev) { + minor->kdev.parent = &minor->dev->pdev->dev; + } else { + minor->kdev.parent = &minor->dev->platform_dev->dev; + } minor->kdev.class = drm_class; minor->kdev.release = drm_sysfs_device_release; minor->kdev.devt = minor->device; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 8190b9bcc2d..ca7034ac11b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -58,6 +58,7 @@ #include <linux/mm.h> #include <linux/cdev.h> #include <linux/mutex.h> +#include <linux/platform_device.h> #if defined(__alpha__) || defined(__powerpc__) #include <asm/pgtable.h> /* For pte_wrprotect */ #endif @@ -106,6 +107,7 @@ struct drm_device; #define DRIVER_IRQ_VBL2 0x800 #define DRIVER_GEM 0x1000 #define DRIVER_MODESET 0x2000 +#define DRIVER_IS_PLATFORM 0x4000 /***********************************************************************/ /** \name Begin the DRM... */ @@ -916,6 +918,7 @@ struct drm_device { wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */ struct drm_agp_head *agp; /**< AGP data */ + struct platform_device *platform_dev; /**< platform device structure */ struct pci_dev *pdev; /**< PCI device structure */ int pci_vendor; /**< PCI vendor id */ @@ -1032,6 +1035,7 @@ static inline int drm_mtrr_del(int handle, unsigned long offset, /* Driver support (drm_drv.h) */ extern int drm_init(struct drm_driver *driver); +extern int drm_platform_init(struct drm_driver *driver, struct platform_device *pdev); extern void drm_exit(struct drm_driver *driver); extern int drm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -1252,6 +1256,8 @@ extern struct drm_master *drm_master_get(struct drm_master *master); extern void drm_master_put(struct drm_master **master); extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); +extern int drm_get_platform_dev(struct platform_device *pdev, + struct drm_driver *driver); extern int drm_put_dev(struct drm_device *dev); extern int drm_put_minor(struct drm_minor **minor); extern unsigned int drm_debug; |