Skip to content

Commit

Permalink
Merge omapdss single-dssdev series
Browse files Browse the repository at this point in the history
This series contains patches that change how omapdss's panel devices
(omap_dss_device) are initialized and registered. There are two patches that
change behaviour, the rest are just cleanups:

The patch "omap_dss_register_device() doesn't take display index" affects the
number for the "displayX" sysfs files. This hopefully doesn't affect the
userspace, as the number has never been a clear indication of what the
particular display is.

The patch "register only one display device per output" affects how panel
devices are created. Currently we support multiple panels per output, i.e. you
could have DVI and an LCD displays using the same DPI output, as long as the
DVI and LCD are not used at the same time.

This patch changes the omapdss driver to only register one display device per
output. If there are multiple displays for the output, either the first one is
picked or, if def_display has been defined in kernel parameters and the
def_display is one of the displays for this output, the def_display is picked.
See the patch for more information.

  OMAPDSS: alloc dssdevs dynamically
  OMAPDSS: cleanup dss_recheck_connections further
  OMAPDSS: cleanup dss_recheck_connections
  OMAPDSS: handle errors in dss_init_device
  OMAPDSS: explicitely initialize dssdev->channel for new displays
  OMAPDSS: register only one display device per output
  OMAPDSS: Add dss_get_default_display_name()
  OMAPDSS: omap_dss_register_device() doesn't take display index
  • Loading branch information
Tomi Valkeinen committed Sep 25, 2012
2 parents 524d9f4 + 5274484 commit c0ca7c3
Show file tree
Hide file tree
Showing 10 changed files with 428 additions and 198 deletions.
91 changes: 47 additions & 44 deletions drivers/video/omap2/dss/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <linux/device.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
#include <linux/slab.h>

#include <video/omapdss.h>

Expand All @@ -57,6 +58,11 @@ bool dss_debug;
module_param_named(debug, dss_debug, bool, 0644);
#endif

const char *dss_get_default_display_name(void)
{
return core.default_display_name;
}

/* REGULATORS */

struct regulator *dss_get_vdds_dsi(void)
Expand Down Expand Up @@ -347,17 +353,14 @@ static int dss_driver_probe(struct device *dev)
int r;
struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
struct omap_dss_device *dssdev = to_dss_device(dev);
bool force;

DSSDBG("driver_probe: dev %s/%s, drv %s\n",
dev_name(dev), dssdev->driver_name,
dssdrv->driver.name);

dss_init_device(core.pdev, dssdev);

force = core.default_display_name &&
strcmp(core.default_display_name, dssdev->name) == 0;
dss_recheck_connections(dssdev, force);
r = dss_init_device(core.pdev, dssdev);
if (r)
return r;

r = dssdrv->probe(dssdev);

Expand Down Expand Up @@ -416,70 +419,70 @@ void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
EXPORT_SYMBOL(omap_dss_unregister_driver);

/* DEVICE */
static void reset_device(struct device *dev, int check)
{
u8 *dev_p = (u8 *)dev;
u8 *dev_end = dev_p + sizeof(*dev);
void *saved_pdata;

saved_pdata = dev->platform_data;
if (check) {
/*
* Check if there is any other setting than platform_data
* in struct device; warn that these will be reset by our
* init.
*/
dev->platform_data = NULL;
while (dev_p < dev_end) {
if (*dev_p) {
WARN("%s: struct device fields will be "
"discarded\n",
__func__);
break;
}
dev_p++;
}
}
memset(dev, 0, sizeof(*dev));
dev->platform_data = saved_pdata;
}


static void omap_dss_dev_release(struct device *dev)
{
reset_device(dev, 0);
struct omap_dss_device *dssdev = to_dss_device(dev);
kfree(dssdev);
}

int omap_dss_register_device(struct omap_dss_device *dssdev,
struct device *parent, int disp_num)
static int disp_num_counter;

struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
{
WARN_ON(!dssdev->driver_name);
struct omap_dss_device *dssdev;

dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL);
if (!dssdev)
return NULL;

reset_device(&dssdev->dev, 1);
dssdev->dev.bus = &dss_bus_type;
dssdev->dev.parent = parent;
dssdev->dev.release = omap_dss_dev_release;
dev_set_name(&dssdev->dev, "display%d", disp_num);
return device_register(&dssdev->dev);
dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);

device_initialize(&dssdev->dev);

return dssdev;
}

int dss_add_device(struct omap_dss_device *dssdev)
{
return device_add(&dssdev->dev);
}

void dss_put_device(struct omap_dss_device *dssdev)
{
put_device(&dssdev->dev);
}

void omap_dss_unregister_device(struct omap_dss_device *dssdev)
void dss_unregister_device(struct omap_dss_device *dssdev)
{
device_unregister(&dssdev->dev);
}

static int dss_unregister_dss_dev(struct device *dev, void *data)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
omap_dss_unregister_device(dssdev);
dss_unregister_device(dssdev);
return 0;
}

void omap_dss_unregister_child_devices(struct device *parent)
void dss_unregister_child_devices(struct device *parent)
{
device_for_each_child(parent, NULL, dss_unregister_dss_dev);
}

void dss_copy_device_pdata(struct omap_dss_device *dst,
const struct omap_dss_device *src)
{
u8 *d = (u8 *)dst;
u8 *s = (u8 *)src;
size_t dsize = sizeof(struct device);

memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize);
}

/* BUS */
static int __init omap_dss_bus_register(void)
{
Expand Down
85 changes: 78 additions & 7 deletions drivers/video/omap2/dss/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,26 +320,98 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_default_get_timings);

void dss_init_device(struct platform_device *pdev,
/*
* Connect dssdev to a manager if the manager is free or if force is specified.
* Connect all overlays to that manager if they are free or if force is
* specified.
*/
static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
{
struct omap_overlay_manager *mgr;
int i, r;

WARN_ON(dssdev->manager);

mgr = omap_dss_get_overlay_manager(dssdev->channel);

if (mgr->device && !force)
return 0;

if (mgr->device)
mgr->unset_device(mgr);

r = mgr->set_device(mgr, dssdev);
if (r) {
DSSERR("failed to set initial manager\n");
return r;
}

for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
struct omap_overlay *ovl = omap_dss_get_overlay(i);

if (!ovl->manager || force) {
if (ovl->manager)
ovl->unset_manager(ovl);

r = ovl->set_manager(ovl, mgr);
if (r) {
DSSERR("failed to set initial overlay\n");
return r;
}
}
}

return 0;
}

static void dss_uninit_connections(struct omap_dss_device *dssdev)
{
if (dssdev->manager)
dssdev->manager->unset_device(dssdev->manager);
}

int dss_init_device(struct platform_device *pdev,
struct omap_dss_device *dssdev)
{
struct device_attribute *attr;
int i;
int r;
int i, r;
const char *def_disp_name = dss_get_default_display_name();
bool force;

force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
dss_init_connections(dssdev, force);

/* create device sysfs files */
i = 0;
while ((attr = display_sysfs_attrs[i++]) != NULL) {
r = device_create_file(&dssdev->dev, attr);
if (r)
if (r) {
for (i = i - 2; i >= 0; i--) {
attr = display_sysfs_attrs[i];
device_remove_file(&dssdev->dev, attr);
}

dss_uninit_connections(dssdev);

DSSERR("failed to create sysfs file\n");
return r;
}
}

/* create display? sysfs links */
r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
dev_name(&dssdev->dev));
if (r)
if (r) {
while ((attr = display_sysfs_attrs[i++]) != NULL)
device_remove_file(&dssdev->dev, attr);

dss_uninit_connections(dssdev);

DSSERR("failed to create sysfs display link\n");
return r;
}

return 0;
}

void dss_uninit_device(struct platform_device *pdev,
Expand All @@ -353,8 +425,7 @@ void dss_uninit_device(struct platform_device *pdev,
while ((attr = display_sysfs_attrs[i++]) != NULL)
device_remove_file(&dssdev->dev, attr);

if (dssdev->manager)
dssdev->manager->unset_device(dssdev->manager);
dss_uninit_connections(dssdev);
}

static int dss_suspend_device(struct device *dev, void *data)
Expand Down
58 changes: 47 additions & 11 deletions drivers/video/omap2/dss/dpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,27 +371,63 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
return 0;
}

static void __init dpi_probe_pdata(struct platform_device *pdev)
static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
int i, r;
const char *def_disp_name = dss_get_default_display_name();
struct omap_dss_device *def_dssdev;
int i;

def_dssdev = NULL;

for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];

if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
continue;

r = dpi_init_display(dssdev);
if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r);
continue;
if (def_dssdev == NULL)
def_dssdev = dssdev;

if (def_disp_name != NULL &&
strcmp(dssdev->name, def_disp_name) == 0) {
def_dssdev = dssdev;
break;
}
}

r = omap_dss_register_device(dssdev, &pdev->dev, i);
if (r)
DSSERR("device %s register failed: %d\n",
dssdev->name, r);
return def_dssdev;
}

static void __init dpi_probe_pdata(struct platform_device *dpidev)
{
struct omap_dss_device *plat_dssdev;
struct omap_dss_device *dssdev;
int r;

plat_dssdev = dpi_find_dssdev(dpidev);

if (!plat_dssdev)
return;

dssdev = dss_alloc_and_init_device(&dpidev->dev);
if (!dssdev)
return;

dss_copy_device_pdata(dssdev, plat_dssdev);

r = dpi_init_display(dssdev);
if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r);
dss_put_device(dssdev);
return;
}

r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
dss_put_device(dssdev);
return;
}
}

Expand All @@ -406,7 +442,7 @@ static int __init omap_dpi_probe(struct platform_device *pdev)

static int __exit omap_dpi_remove(struct platform_device *pdev)
{
omap_dss_unregister_child_devices(&pdev->dev);
dss_unregister_child_devices(&pdev->dev);

return 0;
}
Expand Down
Loading

0 comments on commit c0ca7c3

Please sign in to comment.