[oe-commits] Koen Kooi : linux-omap 2.6.29: add more DSS2 patches

git version control git at git.openembedded.org
Wed May 27 20:38:51 UTC 2009


Module: openembedded.git
Branch: org.openembedded.dev
Commit: e47846def85976da24a74838c55fafcb7751d3dd
URL:    http://gitweb.openembedded.net/?p=openembedded.git&a=commit;h=e47846def85976da24a74838c55fafcb7751d3dd

Author: Koen Kooi <koen at openembedded.org>
Date:   Wed May 27 22:36:51 2009 +0200

linux-omap 2.6.29: add more DSS2 patches

---

 .../linux-omap-2.6.29/dss2/0070-DSS2-fix-irq1.diff |  221 ++++++++++++++++++++
 .../linux-omap-2.6.29/dss2/0071-DSS2-fix-irq2.diff |   35 +++
 recipes/linux/linux-omap_2.6.29.bb                 |    2 +
 3 files changed, 258 insertions(+), 0 deletions(-)

diff --git a/recipes/linux/linux-omap-2.6.29/dss2/0070-DSS2-fix-irq1.diff b/recipes/linux/linux-omap-2.6.29/dss2/0070-DSS2-fix-irq1.diff
new file mode 100644
index 0000000..8f384df
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.29/dss2/0070-DSS2-fix-irq1.diff
@@ -0,0 +1,221 @@
+From 093988f36ffcb0201927f8b452e546e1141aa0fa Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen at nokia.com>
+Date: Sat, 23 May 2009 15:00:21 +0000
+Subject: DSS2: DISPC: fix irq handling locking
+
+---
+diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
+index b0e4960..b3685b2 100644
+--- a/drivers/video/omap2/dss/dispc.c
++++ b/drivers/video/omap2/dss/dispc.c
+@@ -154,23 +154,20 @@ static struct {
+ 
+ 	struct clk	*dpll4_m4_ck;
+ 
+-	spinlock_t	irq_lock;
+-
+ 	unsigned long	cache_req_pck;
+ 	unsigned long	cache_prate;
+ 	struct dispc_clock_info cache_cinfo;
+ 
+-	u32		irq_error_mask;
++	spinlock_t irq_lock;
++	u32 irq_error_mask;
+ 	struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
+-
+-	spinlock_t error_lock;
+ 	u32 error_irqs;
+ 	struct work_struct error_work;
+ 
+ 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
+ } dispc;
+ 
+-static void omap_dispc_set_irqs(void);
++static void _omap_dispc_set_irqs(void);
+ 
+ static inline void dispc_write_reg(const struct dispc_reg idx, u32 val)
+ {
+@@ -1691,10 +1688,13 @@ void dispc_enable_digit_out(bool enable)
+ 	}
+ 
+ 	if (enable) {
++		unsigned long flags;
+ 		/* When we enable digit output, we'll get an extra digit
+ 		 * sync lost interrupt, that we need to ignore */
++		spin_lock_irqsave(&dispc.irq_lock, flags);
+ 		dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
+-		omap_dispc_set_irqs();
++		_omap_dispc_set_irqs();
++		spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ 	}
+ 
+ 	/* When we disable digit output, we need to wait until fields are done.
+@@ -1728,9 +1728,12 @@ void dispc_enable_digit_out(bool enable)
+ 		DSSERR("failed to unregister EVSYNC isr\n");
+ 
+ 	if (enable) {
++		unsigned long flags;
++		spin_lock_irqsave(&dispc.irq_lock, flags);
+ 		dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
+ 		dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
+-		omap_dispc_set_irqs();
++		_omap_dispc_set_irqs();
++		spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ 	}
+ 
+ 	enable_clocks(0);
+@@ -2508,14 +2511,14 @@ int dispc_get_clock_div(struct dispc_clock_info *cinfo)
+ 	return 0;
+ }
+ 
+-static void omap_dispc_set_irqs(void)
++/* dispc.irq_lock has to be locked by the caller */
++static void _omap_dispc_set_irqs(void)
+ {
+-	unsigned long flags;
+-	u32 mask = dispc.irq_error_mask;
++	u32 mask;
+ 	int i;
+ 	struct omap_dispc_isr_data *isr_data;
+ 
+-	spin_lock_irqsave(&dispc.irq_lock, flags);
++	mask = dispc.irq_error_mask;
+ 
+ 	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+ 		isr_data = &dispc.registered_isr[i];
+@@ -2528,9 +2531,8 @@ static void omap_dispc_set_irqs(void)
+ 
+ 	enable_clocks(1);
+ 	dispc_write_reg(DISPC_IRQENABLE, mask);
+-	enable_clocks(0);
+ 
+-	spin_unlock_irqrestore(&dispc.irq_lock, flags);
++	enable_clocks(0);
+ }
+ 
+ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+@@ -2571,11 +2573,14 @@ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+ 
+ 		break;
+ 	}
+-err:
++
++	_omap_dispc_set_irqs();
++
+ 	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ 
+-	if (ret == 0)
+-		omap_dispc_set_irqs();
++	return 0;
++err:
++	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ 
+ 	return ret;
+ }
+@@ -2606,10 +2611,10 @@ int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+ 		break;
+ 	}
+ 
+-	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+-
+ 	if (ret == 0)
+-		omap_dispc_set_irqs();
++		_omap_dispc_set_irqs();
++
++	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ 
+ 	return ret;
+ }
+@@ -2645,11 +2650,15 @@ static void print_irq_status(u32 status)
+ void dispc_irq_handler(void)
+ {
+ 	int i;
+-	u32 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
++	u32 irqstatus;
+ 	u32 handledirqs = 0;
+ 	u32 unhandled_errors;
+ 	struct omap_dispc_isr_data *isr_data;
+ 
++	spin_lock(&dispc.irq_lock);
++
++	irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
++
+ #ifdef DEBUG
+ 	if (dss_debug)
+ 		print_irq_status(irqstatus);
+@@ -2673,15 +2682,15 @@ void dispc_irq_handler(void)
+ 	unhandled_errors = irqstatus & ~handledirqs & dispc.irq_error_mask;
+ 
+ 	if (unhandled_errors) {
+-		spin_lock(&dispc.error_lock);
+ 		dispc.error_irqs |= unhandled_errors;
+-		spin_unlock(&dispc.error_lock);
+ 
+ 		dispc.irq_error_mask &= ~unhandled_errors;
+-		omap_dispc_set_irqs();
++		_omap_dispc_set_irqs();
+ 
+ 		schedule_work(&dispc.error_work);
+ 	}
++
++	spin_unlock(&dispc.irq_lock);
+ }
+ 
+ static void dispc_error_worker(struct work_struct *work)
+@@ -2690,10 +2699,10 @@ static void dispc_error_worker(struct work_struct *work)
+ 	u32 errors;
+ 	unsigned long flags;
+ 
+-	spin_lock_irqsave(&dispc.error_lock, flags);
++	spin_lock_irqsave(&dispc.irq_lock, flags);
+ 	errors = dispc.error_irqs;
+ 	dispc.error_irqs = 0;
+-	spin_unlock_irqrestore(&dispc.error_lock, flags);
++	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ 
+ 	if (errors & DISPC_IRQ_GFX_FIFO_UNDERFLOW) {
+ 		DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n");
+@@ -2836,8 +2845,10 @@ static void dispc_error_worker(struct work_struct *work)
+ 		}
+ 	}
+ 
++	spin_lock_irqsave(&dispc.irq_lock, flags);
+ 	dispc.irq_error_mask |= errors;
+-	omap_dispc_set_irqs();
++	_omap_dispc_set_irqs();
++	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ }
+ 
+ int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
+@@ -2921,6 +2932,10 @@ void dispc_fake_vsync_irq(void)
+ 
+ static void _omap_dispc_initialize_irq(void)
+ {
++	unsigned long flags;
++
++	spin_lock_irqsave(&dispc.irq_lock, flags);
++
+ 	memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
+ 
+ 	dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
+@@ -2929,7 +2944,9 @@ static void _omap_dispc_initialize_irq(void)
+ 	 * so clear it */
+ 	dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS));
+ 
+-	omap_dispc_set_irqs();
++	_omap_dispc_set_irqs();
++
++	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+ }
+ 
+ void dispc_enable_sidle(void)
+@@ -2970,7 +2987,6 @@ int dispc_init(void)
+ 	u32 rev;
+ 
+ 	spin_lock_init(&dispc.irq_lock);
+-	spin_lock_init(&dispc.error_lock);
+ 
+ 	INIT_WORK(&dispc.error_work, dispc_error_worker);
+ 
+--
+cgit v0.8.2.1-10-g45e7
diff --git a/recipes/linux/linux-omap-2.6.29/dss2/0071-DSS2-fix-irq2.diff b/recipes/linux/linux-omap-2.6.29/dss2/0071-DSS2-fix-irq2.diff
new file mode 100644
index 0000000..cb8aaf1
--- /dev/null
+++ b/recipes/linux/linux-omap-2.6.29/dss2/0071-DSS2-fix-irq2.diff
@@ -0,0 +1,35 @@
+From 8af2f6550d6971875e4c5d3f93982f86f4bcf216 Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen at nokia.com>
+Date: Sat, 23 May 2009 15:00:00 +0000
+Subject: DSS2: DISPC: clear irqstatus for newly enabled irqs
+
+This fixes the problem that when requesting a new irq
+we could get the isr called too early in case irqstatus
+already had that irq flag on.
+---
+diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
+index b3685b2..2471cfe 100644
+--- a/drivers/video/omap2/dss/dispc.c
++++ b/drivers/video/omap2/dss/dispc.c
+@@ -2515,6 +2515,7 @@ int dispc_get_clock_div(struct dispc_clock_info *cinfo)
+ static void _omap_dispc_set_irqs(void)
+ {
+ 	u32 mask;
++	u32 old_mask;
+ 	int i;
+ 	struct omap_dispc_isr_data *isr_data;
+ 
+@@ -2530,6 +2531,11 @@ static void _omap_dispc_set_irqs(void)
+ 	}
+ 
+ 	enable_clocks(1);
++
++	old_mask = dispc_read_reg(DISPC_IRQENABLE);
++	/* clear the irqstatus for newly enabled irqs */
++	dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask);
++
+ 	dispc_write_reg(DISPC_IRQENABLE, mask);
+ 
+ 	enable_clocks(0);
+--
+cgit v0.8.2.1-10-g45e7
diff --git a/recipes/linux/linux-omap_2.6.29.bb b/recipes/linux/linux-omap_2.6.29.bb
index 5be04d2..67a4803 100644
--- a/recipes/linux/linux-omap_2.6.29.bb
+++ b/recipes/linux/linux-omap_2.6.29.bb
@@ -91,6 +91,8 @@ SRC_URI_append = " \
            file://dss2/0067-DSS2-VRFB-don-t-WARN-when-releasing-inactive-ctx.patch;patch=1 \
            file://dss2/0068-DSS2-Swap-field-offset-values-w-VRFB-rotation.patch;patch=1 \
            file://dss2/0069-DSS2-OMAP3EVM-Added-DSI-powerup-and-powerdown-func.patch;patch=1 \
+           file://dss2/0070-DSS2-fix-irq1.diff;patch=1 \
+           file://dss2/0071-DSS2-fix-irq2.diff;patch=1 \
            file://0001-board-ldp-add-regulator-info-to-get-the-microSD-slo.patch;patch=1 \
            file://fix-unaligned-access.diff;patch=1 \
            file://make-alignment-visible.diff;patch=1 \





More information about the Openembedded-commits mailing list