diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/pvr/Makefile | 1 | ||||
| -rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c | 130 | ||||
| -rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb.h | 12 | ||||
| -rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb_linux.c | 75 |
5 files changed, 201 insertions, 24 deletions
diff --git a/drivers/gpu/pvr/Makefile b/drivers/gpu/pvr/Makefile index 05b3bf6745f..0dc058d364d 100644 --- a/drivers/gpu/pvr/Makefile +++ b/drivers/gpu/pvr/Makefile @@ -141,6 +141,7 @@ sgx_displayclass-y := \ omaplfb-y := \ omaplfb/omaplfb_displayclass.o \ + omaplfb/omaplfb-sysfs.o \ omaplfb/omaplfb_linux.o dbgdrv-$(CONFIG_SGX_PDUMP) := \ diff --git a/drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c b/drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c new file mode 100644 index 00000000000..2e0458387ae --- /dev/null +++ b/drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c @@ -0,0 +1,130 @@ +/* + * omaplfb-sysfs.c + * + * Copyright (C) 2011 Texas Instruments. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + * Author: Gustavo Diaz (gusdp@ti.com) + * + */ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/sysfs.h> +#include <linux/platform_device.h> +#include <linux/device.h> +#include <linux/uaccess.h> + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" + +static ssize_t show_ignore_sync(OMAPLFB_DEVINFO *display_info, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", display_info->ignore_sync); +} + +static ssize_t store_ignore_sync(OMAPLFB_DEVINFO *display_info, + const char *buf, size_t count) +{ + unsigned long new_value; + + if (strict_strtoul(buf, 10, &new_value)) + return -EINVAL; + + if (new_value == 0 || new_value == 1) { + display_info->ignore_sync = new_value; + return count; + } + + return -EINVAL; +} + +struct omaplfb_attribute { + struct attribute attr; + ssize_t (*show)(OMAPLFB_DEVINFO *, char *); + ssize_t (*store)(OMAPLFB_DEVINFO *, const char *, size_t); +}; + +static ssize_t omaplfb_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + OMAPLFB_DEVINFO *display_info; + struct omaplfb_attribute *omaplfb_attr; + + display_info = container_of(kobj, OMAPLFB_DEVINFO, kobj); + omaplfb_attr = container_of(attr, struct omaplfb_attribute, attr); + + if (!omaplfb_attr->show) + return -ENOENT; + + return omaplfb_attr->show(display_info, buf); +} + +static ssize_t omaplfb_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t size) +{ + OMAPLFB_DEVINFO *display_info; + struct omaplfb_attribute *omaplfb_attr; + + display_info = container_of(kobj, OMAPLFB_DEVINFO, kobj); + omaplfb_attr = container_of(attr, struct omaplfb_attribute, attr); + + if (!omaplfb_attr->store) + return -ENOENT; + + return omaplfb_attr->store(display_info, buf, size); +} + +#define OMAPLFB_ATTR(_name, _mode, _show, _store) \ + struct omaplfb_attribute omaplfb_attr_##_name = \ + __ATTR(_name, _mode, _show, _store) + +static OMAPLFB_ATTR(ignore_sync, S_IRUGO|S_IWUSR, show_ignore_sync, + store_ignore_sync); + +#undef OMAPLFB_ATTR + +static struct attribute *omaplfb_sysfs_attrs[] = { + &omaplfb_attr_ignore_sync.attr, + NULL +}; + +static const struct sysfs_ops omaplfb_sysfs_ops = { + .show = omaplfb_attr_show, + .store = omaplfb_attr_store, +}; + +static struct kobj_type omaplfb_ktype = { + .sysfs_ops = &omaplfb_sysfs_ops, + .default_attrs = omaplfb_sysfs_attrs, +}; + +void omaplfb_create_sysfs(struct omaplfb_device *odev) +{ + int i, r; + + /* Create a sysfs entry for every display */ + for (i = 0; i < odev->display_count; i++) { + OMAPLFB_DEVINFO *display_info = &odev->display_info_list[i]; + r = kobject_init_and_add(&display_info->kobj, &omaplfb_ktype, + &odev->dev->kobj, "display%d", + display_info->uDeviceID); + if (r) + ERROR_PRINTK("failed to create sysfs file\n"); + } +} + +void omaplfb_remove_sysfs(struct omaplfb_device *odev) +{ + int i; + for (i = 0; i < odev->display_count; i++) { + OMAPLFB_DEVINFO *display_info = &odev->display_info_list[i]; + kobject_del(&display_info->kobj); + kobject_put(&display_info->kobj); + } +} diff --git a/drivers/gpu/pvr/omaplfb/omaplfb.h b/drivers/gpu/pvr/omaplfb/omaplfb.h index 7e46c9063ab..57620ab0add 100644 --- a/drivers/gpu/pvr/omaplfb/omaplfb.h +++ b/drivers/gpu/pvr/omaplfb/omaplfb.h @@ -107,6 +107,8 @@ typedef struct OMAPLFB_DEVINFO_TAG DISPLAY_DIMS sDisplayDim; struct workqueue_struct* sync_display_wq; struct work_struct sync_display_work; + struct kobject kobj; + OMAP_BOOL ignore_sync; } OMAPLFB_DEVINFO; @@ -124,6 +126,12 @@ typedef enum _OMAP_ERROR_ } OMAP_ERROR; +struct omaplfb_device { + struct device *dev; + OMAPLFB_DEVINFO *display_info_list; + int display_count; +}; + #define OMAPLFB_PAGE_SIZE 4096 #define OMAPLFB_PAGE_MASK (OMAPLFB_PAGE_SIZE - 1) #define OMAPLFB_PAGE_TRUNC (~OMAPLFB_PAGE_MASK) @@ -149,7 +157,7 @@ typedef enum _OMAP_ERROR_ #define ERROR_PRINTK(format, ...) printk("ERROR " DRIVER_PREFIX \ " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__) -OMAP_ERROR OMAPLFBInit(void); +OMAP_ERROR OMAPLFBInit(struct omaplfb_device *omaplfb_dev); OMAP_ERROR OMAPLFBDeinit(void); void *OMAPLFBAllocKernelMem(unsigned long ulSize); void OMAPLFBFreeKernelMem(void *pvMem); @@ -158,6 +166,8 @@ void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo, OMAP_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr); +void omaplfb_create_sysfs(struct omaplfb_device *odev); +void omaplfb_remove_sysfs(struct omaplfb_device *odev); #ifdef LDM_PLATFORM void OMAPLFBDriverSuspend(void); void OMAPLFBDriverResume(void); diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c index cc078249b21..425059c29a4 100644 --- a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c +++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c @@ -1135,6 +1135,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, #if defined(SYS_USING_INTERRUPTS) if( psFlipCmd->ui32SwapInterval == 0 || + psDevInfo->ignore_sync || psSwapChain->bFlushCommands == OMAP_TRUE) { #endif @@ -1533,7 +1534,7 @@ static OMAP_ERROR InitDev(OMAPLFB_DEVINFO *psDevInfo, int fb_idx) /* * Initialization routine for the 3rd party display driver */ -OMAP_ERROR OMAPLFBInit(void) +OMAP_ERROR OMAPLFBInit(struct omaplfb_device *omaplfb_dev) { OMAPLFB_DEVINFO *psDevInfo; PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; @@ -1573,12 +1574,13 @@ OMAP_ERROR OMAPLFBInit(void) sizeof(OMAPLFB_DEVINFO) * FRAMEBUFFER_COUNT); if(!pDisplayDevices) { - pDisplayDevices = NULL; ERROR_PRINTK("Out of memory"); return OMAP_ERROR_OUT_OF_MEMORY; } memset(pDisplayDevices, 0, sizeof(OMAPLFB_DEVINFO) * FRAMEBUFFER_COUNT); + omaplfb_dev->display_info_list = pDisplayDevices; + omaplfb_dev->display_count = FRAMEBUFFER_COUNT; /* * Initialize each display device @@ -1617,6 +1619,7 @@ OMAP_ERROR OMAPLFBInit(void) psDevInfo->psSwapChain = 0; psDevInfo->bFlushCommands = OMAP_FALSE; psDevInfo->bDeviceSuspended = OMAP_FALSE; + psDevInfo->ignore_sync = OMAP_FALSE; if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 1) { diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c index 10805d64158..7629c6f3c9c 100644 --- a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c +++ b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c @@ -296,6 +296,44 @@ void OMAPLFBPresentSync(OMAPLFB_DEVINFO *psDevInfo, static volatile OMAP_BOOL bDeviceSuspended; +static int omaplfb_probe(struct platform_device *pdev) +{ + struct omaplfb_device *odev; + + odev = kzalloc(sizeof(*odev), GFP_KERNEL); + + if (!odev) + return -ENOMEM; + + if (OMAPLFBInit(odev) != OMAP_OK) { + dev_err(&pdev->dev, "failed to setup omaplfb\n"); + kfree(odev); + return -ENODEV; + } + + odev->dev = &pdev->dev; + platform_set_drvdata(pdev, odev); + omaplfb_create_sysfs(odev); + + return 0; +} + +static int omaplfb_remove(struct platform_device *pdev) +{ + struct omaplfb_device *odev; + + odev = platform_get_drvdata(pdev); + + omaplfb_remove_sysfs(odev); + + if (OMAPLFBDeinit() != OMAP_OK) + WARNING_PRINTK("Driver cleanup failed"); + + kfree(odev); + + return 0; +} + /* * Common suspend driver function * in: psSwapChain, aPhyAddr @@ -334,8 +372,6 @@ static struct platform_device omaplfb_device = { #if defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND) -static struct early_suspend omaplfb_early_suspend; - /* * Android specific, driver is requested to be suspended * in: ea_event @@ -360,7 +396,16 @@ static void OMAPLFBDriverResume_Entry(struct early_suspend *ea_event) static struct platform_driver omaplfb_driver = { .driver = { .name = DRVNAME, - } + .owner = THIS_MODULE, + }, + .probe = omaplfb_probe, + .remove = omaplfb_remove, +}; + +static struct early_suspend omaplfb_early_suspend = { + .suspend = OMAPLFBDriverSuspend_Entry, + .resume = OMAPLFBDriverResume_Entry, + .level = EARLY_SUSPEND_LEVEL_DISABLE_FB, }; #else /* defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND) */ @@ -403,7 +448,10 @@ static IMG_VOID OMAPLFBDriverShutdown_Entry( static struct platform_driver omaplfb_driver = { .driver = { .name = DRVNAME, + .owner = THIS_MODULE, }, + .probe = omaplfb_probe, + .remove = omaplfb_remove, .suspend = OMAPLFBDriverSuspend_Entry, .resume = OMAPLFBDriverResume_Entry, .shutdown = OMAPLFBDriverShutdown_Entry, @@ -418,21 +466,10 @@ static struct platform_driver omaplfb_driver = { */ static int __init OMAPLFB_Init(void) { - if(OMAPLFBInit() != OMAP_OK) - { - WARNING_PRINTK("Driver init failed"); - return -ENODEV; - } - #if defined(LDM_PLATFORM) DEBUG_PRINTK("Registering platform driver"); if (platform_driver_register(&omaplfb_driver)) - { - WARNING_PRINTK("Unable to register platform driver"); - if(OMAPLFBDeinit() != OMAP_OK) - WARNING_PRINTK("Driver cleanup failed\n"); return -ENODEV; - } #if 0 DEBUG_PRINTK("Registering device driver"); if (platform_device_register(&omaplfb_device)) @@ -446,10 +483,7 @@ static int __init OMAPLFB_Init(void) #endif #if defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND) - omaplfb_early_suspend.suspend = OMAPLFBDriverSuspend_Entry; - omaplfb_early_suspend.resume = OMAPLFBDriverResume_Entry; - omaplfb_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - register_early_suspend(&omaplfb_early_suspend); + register_early_suspend(&omaplfb_early_suspend); DEBUG_PRINTK("Registered early suspend support"); #endif @@ -470,11 +504,10 @@ static IMG_VOID __exit OMAPLFB_Cleanup(IMG_VOID) DEBUG_PRINTK("Removing platform driver"); platform_driver_unregister(&omaplfb_driver); #if defined(SGX_EARLYSUSPEND) && defined(CONFIG_HAS_EARLYSUSPEND) - unregister_early_suspend(&omaplfb_early_suspend); + DEBUG_PRINTK("Removed early suspend support"); + unregister_early_suspend(&omaplfb_early_suspend); #endif #endif - if(OMAPLFBDeinit() != OMAP_OK) - WARNING_PRINTK("Driver cleanup failed"); } late_initcall(OMAPLFB_Init); |
