OMAPDSS: implement display sysfs without dss bus

We aim to remove the custom omapdss bus totally, as it's quite a strange
construct and won't be compatible with common display framework. One
problem on the road is that we have sysfs files for each display, and
they depend on the omapdss bus.

This patch creates the display sysfs files independent of the omapdss
bus. This gives us backwards compatibility without using the omapdss bus
for the sysfs files.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
Tomi Valkeinen 2013-02-13 13:40:19 +02:00
Родитель a65c8bdab9
Коммит 94140f0d22
4 изменённых файлов: 80 добавлений и 96 удалений

Просмотреть файл

@ -1581,7 +1581,6 @@ static DEFINE_MUTEX(compat_init_lock);
int omapdss_compat_init(void)
{
struct platform_device *pdev = dss_get_core_pdev();
struct omap_dss_device *dssdev = NULL;
int i, r;
mutex_lock(&compat_init_lock);
@ -1627,12 +1626,9 @@ int omapdss_compat_init(void)
if (r)
goto err_mgr_ops;
for_each_dss_dev(dssdev) {
r = display_init_sysfs(pdev, dssdev);
/* XXX uninit sysfs files on error */
if (r)
goto err_disp_sysfs;
}
r = display_init_sysfs(pdev);
if (r)
goto err_disp_sysfs;
dispc_runtime_get();
@ -1649,6 +1645,7 @@ out:
err_init_irq:
dispc_runtime_put();
display_uninit_sysfs(pdev);
err_disp_sysfs:
dss_uninstall_mgr_ops();
@ -1668,7 +1665,6 @@ EXPORT_SYMBOL(omapdss_compat_init);
void omapdss_compat_uninit(void)
{
struct platform_device *pdev = dss_get_core_pdev();
struct omap_dss_device *dssdev = NULL;
mutex_lock(&compat_init_lock);
@ -1677,8 +1673,7 @@ void omapdss_compat_uninit(void)
dss_dispc_uninitialize_irq();
for_each_dss_dev(dssdev)
display_uninit_sysfs(pdev, dssdev);
display_uninit_sysfs(pdev);
dss_uninstall_mgr_ops();

Просмотреть файл

@ -292,37 +292,9 @@ static int dss_bus_match(struct device *dev, struct device_driver *driver)
return strcmp(dssdev->driver_name, driver->name) == 0;
}
static ssize_t device_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
return snprintf(buf, PAGE_SIZE, "%s\n",
dssdev->name ?
dssdev->name : "");
}
static struct device_attribute default_dev_attrs[] = {
__ATTR(name, S_IRUGO, device_name_show, NULL),
__ATTR_NULL,
};
static ssize_t driver_name_show(struct device_driver *drv, char *buf)
{
struct omap_dss_driver *dssdrv = to_dss_driver(drv);
return snprintf(buf, PAGE_SIZE, "%s\n",
dssdrv->driver.name ?
dssdrv->driver.name : "");
}
static struct driver_attribute default_drv_attrs[] = {
__ATTR(name, S_IRUGO, driver_name_show, NULL),
__ATTR_NULL,
};
static struct bus_type dss_bus_type = {
.name = "omapdss",
.match = dss_bus_match,
.dev_attrs = default_dev_attrs,
.drv_attrs = default_drv_attrs,
};
static void dss_bus_release(struct device *dev)

Просмотреть файл

@ -22,17 +22,40 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <linux/sysfs.h>
#include <video/omapdss.h>
#include "dss.h"
#include "dss_features.h"
static struct omap_dss_device *to_dss_device_sysfs(struct device *dev)
{
struct omap_dss_device *dssdev = NULL;
for_each_dss_dev(dssdev) {
if (&dssdev->dev == dev) {
omap_dss_put_device(dssdev);
return dssdev;
}
}
return NULL;
}
static ssize_t display_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
return snprintf(buf, PAGE_SIZE, "%s\n",
dssdev->name ?
dssdev->name : "");
}
static ssize_t display_enabled_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
return snprintf(buf, PAGE_SIZE, "%d\n",
omapdss_device_is_enabled(dssdev));
@ -42,7 +65,7 @@ static ssize_t display_enabled_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r;
bool enable;
@ -70,7 +93,7 @@ static ssize_t display_enabled_store(struct device *dev,
static ssize_t display_tear_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
return snprintf(buf, PAGE_SIZE, "%d\n",
dssdev->driver->get_te ?
dssdev->driver->get_te(dssdev) : 0);
@ -79,7 +102,7 @@ static ssize_t display_tear_show(struct device *dev,
static ssize_t display_tear_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r;
bool te;
@ -100,7 +123,7 @@ static ssize_t display_tear_store(struct device *dev,
static ssize_t display_timings_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
struct omap_video_timings t;
if (!dssdev->driver->get_timings)
@ -117,7 +140,7 @@ static ssize_t display_timings_show(struct device *dev,
static ssize_t display_timings_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
struct omap_video_timings t = dssdev->panel.timings;
int r, found;
@ -156,7 +179,7 @@ static ssize_t display_timings_store(struct device *dev,
static ssize_t display_rotate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int rotate;
if (!dssdev->driver->get_rotate)
return -ENOENT;
@ -167,7 +190,7 @@ static ssize_t display_rotate_show(struct device *dev,
static ssize_t display_rotate_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int rot, r;
if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
@ -187,7 +210,7 @@ static ssize_t display_rotate_store(struct device *dev,
static ssize_t display_mirror_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int mirror;
if (!dssdev->driver->get_mirror)
return -ENOENT;
@ -198,7 +221,7 @@ static ssize_t display_mirror_show(struct device *dev,
static ssize_t display_mirror_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r;
bool mirror;
@ -219,7 +242,7 @@ static ssize_t display_mirror_store(struct device *dev,
static ssize_t display_wss_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
unsigned int wss;
if (!dssdev->driver->get_wss)
@ -233,7 +256,7 @@ static ssize_t display_wss_show(struct device *dev,
static ssize_t display_wss_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
u32 wss;
int r;
@ -254,6 +277,7 @@ static ssize_t display_wss_store(struct device *dev,
return size;
}
static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL);
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
display_enabled_show, display_enabled_store);
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
@ -267,59 +291,54 @@ static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
display_wss_show, display_wss_store);
static struct device_attribute *display_sysfs_attrs[] = {
&dev_attr_enabled,
&dev_attr_tear_elim,
&dev_attr_timings,
&dev_attr_rotate,
&dev_attr_mirror,
&dev_attr_wss,
static const struct attribute *display_sysfs_attrs[] = {
&dev_attr_name.attr,
&dev_attr_enabled.attr,
&dev_attr_tear_elim.attr,
&dev_attr_timings.attr,
&dev_attr_rotate.attr,
&dev_attr_mirror.attr,
&dev_attr_wss.attr,
NULL
};
int display_init_sysfs(struct platform_device *pdev,
struct omap_dss_device *dssdev)
int display_init_sysfs(struct platform_device *pdev)
{
struct device_attribute *attr;
int i, r;
struct omap_dss_device *dssdev = NULL;
int r;
/* create device sysfs files */
i = 0;
while ((attr = display_sysfs_attrs[i++]) != NULL) {
r = device_create_file(&dssdev->dev, attr);
for_each_dss_dev(dssdev) {
struct kobject *kobj = &dssdev->dev.kobj;
r = sysfs_create_files(kobj, display_sysfs_attrs);
if (r) {
for (i = i - 2; i >= 0; i--) {
attr = display_sysfs_attrs[i];
device_remove_file(&dssdev->dev, attr);
}
DSSERR("failed to create sysfs files\n");
goto err;
}
DSSERR("failed to create sysfs file\n");
return r;
r = sysfs_create_link(&pdev->dev.kobj, kobj, dssdev->alias);
if (r) {
sysfs_remove_files(kobj, display_sysfs_attrs);
DSSERR("failed to create sysfs display link\n");
goto err;
}
}
/* create display? sysfs links */
r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
dev_name(&dssdev->dev));
if (r) {
while ((attr = display_sysfs_attrs[i++]) != NULL)
device_remove_file(&dssdev->dev, attr);
DSSERR("failed to create sysfs display link\n");
return r;
}
return 0;
err:
display_uninit_sysfs(pdev);
return r;
}
void display_uninit_sysfs(struct platform_device *pdev,
struct omap_dss_device *dssdev)
void display_uninit_sysfs(struct platform_device *pdev)
{
struct device_attribute *attr;
int i = 0;
struct omap_dss_device *dssdev = NULL;
sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
while ((attr = display_sysfs_attrs[i++]) != NULL)
device_remove_file(&dssdev->dev, attr);
for_each_dss_dev(dssdev) {
sysfs_remove_link(&pdev->dev.kobj, dssdev->alias);
sysfs_remove_files(&dssdev->dev.kobj, display_sysfs_attrs);
}
}

Просмотреть файл

@ -188,10 +188,8 @@ int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
void dss_disable_all_devices(void);
int display_init_sysfs(struct platform_device *pdev,
struct omap_dss_device *dssdev);
void display_uninit_sysfs(struct platform_device *pdev,
struct omap_dss_device *dssdev);
int display_init_sysfs(struct platform_device *pdev);
void display_uninit_sysfs(struct platform_device *pdev);
/* manager */
int dss_init_overlay_managers(void);