mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 05:04:00 +08:00
OMAPDSS: DISPC: lock access to DISPC_CONTROL & DISPC_CONFIG
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>
This commit is contained in:
parent
4e1d3ca083
commit
d49cd15550
@ -123,6 +123,9 @@ static struct {
|
|||||||
|
|
||||||
struct regmap *syscon_pol;
|
struct regmap *syscon_pol;
|
||||||
u32 syscon_pol_offset;
|
u32 syscon_pol_offset;
|
||||||
|
|
||||||
|
/* DISPC_CONTROL & DISPC_CONFIG lock*/
|
||||||
|
spinlock_t control_lock;
|
||||||
} dispc;
|
} dispc;
|
||||||
|
|
||||||
enum omap_color_component {
|
enum omap_color_component {
|
||||||
@ -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,
|
static void mgr_fld_write(enum omap_channel channel,
|
||||||
enum mgr_reg_fields regfld, int val) {
|
enum mgr_reg_fields regfld, int val) {
|
||||||
const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
|
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);
|
REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
|
||||||
|
|
||||||
|
if (need_lock)
|
||||||
|
spin_unlock_irqrestore(&dispc.control_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SR(reg) \
|
#define SR(reg) \
|
||||||
@ -3804,6 +3816,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
dispc.pdev = pdev;
|
dispc.pdev = pdev;
|
||||||
|
|
||||||
|
spin_lock_init(&dispc.control_lock);
|
||||||
|
|
||||||
r = dispc_init_features(dispc.pdev);
|
r = dispc_init_features(dispc.pdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
Loading…
Reference in New Issue
Block a user