summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/pvr/Makefile1
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb-sysfs.c130
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb.h12
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c7
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_linux.c75
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);