Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 333570
b: refs/heads/master
c: 406f7b8
h: refs/heads/master
v: v3
  • Loading branch information
Tomi Valkeinen committed Sep 25, 2012
1 parent 983232b commit 286cc0d
Show file tree
Hide file tree
Showing 12 changed files with 478 additions and 201 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 995885897ff0ef3dad12fcfbfd0c26e185bf4ac0
refs/heads/master: 406f7b8baa8f92d88dac448a9dc0dbeb3e330874
91 changes: 47 additions & 44 deletions trunk/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 trunk/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 trunk/drivers/video/omap2/dss/dpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,27 +376,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 @@ -411,7 +447,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 286cc0d

Please sign in to comment.