Skip to content

Commit

Permalink
OMAPDSS: DISPC: lock access to DISPC_CONTROL & DISPC_CONFIG
Browse files Browse the repository at this point in the history
Dispc driver presumes that the callers handle locking for all normal
functions. However, omapdrm doesn't handle this, and presumes that all
overlay manager registers are private to that overlay manager, and thus
presumes that configurations for overlay managers can be written via
different threads freely.

For many registers the above is true. The exceptions are DISPC_CONTROL
and DISPC_CONFIG registers, which contain bits for both LCD and TV
overlay managers.

Fixing this properly in omapdrm means a big omapdrm rewrite. So, for
now, add locking to dispc for the problematic registers.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reported-by: Somnath Mukherjee <somnath@ti.com>
  • Loading branch information
Tomi Valkeinen committed Feb 26, 2015
1 parent 4e1d3ca commit d49cd15
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions drivers/video/fbdev/omap2/dss/dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ static struct {

struct regmap *syscon_pol;
u32 syscon_pol_offset;

/* DISPC_CONTROL & DISPC_CONFIG lock*/
spinlock_t control_lock;
} dispc;

enum omap_color_component {
Expand Down Expand Up @@ -261,7 +264,16 @@ static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
static void mgr_fld_write(enum omap_channel channel,
enum mgr_reg_fields regfld, int val) {
const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
const bool need_lock = rfld.reg == DISPC_CONTROL || rfld.reg == DISPC_CONFIG;
unsigned long flags;

if (need_lock)
spin_lock_irqsave(&dispc.control_lock, flags);

REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);

if (need_lock)
spin_unlock_irqrestore(&dispc.control_lock, flags);
}

#define SR(reg) \
Expand Down Expand Up @@ -3804,6 +3816,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)

dispc.pdev = pdev;

spin_lock_init(&dispc.control_lock);

r = dispc_init_features(dispc.pdev);
if (r)
return r;
Expand Down

0 comments on commit d49cd15

Please sign in to comment.