aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dispc.c
diff options
context:
space:
mode:
authorarchit taneja <archit@ti.com>2011-02-23 03:41:03 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-03-11 08:46:24 -0500
commitaffe360d13e54b415cde2f11cee02369b4ed54bd (patch)
tree5c3b0382ac358351c86e73bb16004cc90aa930ab /drivers/video/omap2/dss/dispc.c
parent371e2081447ce2bc6a25c20b513b9ba33cf5769e (diff)
OMAP: DSS2: Have separate irq handlers for DISPC and DSI
Currently, the core DSS platform device requests for an irq line for OMAP2 and OMAP3. Make DISPC and DSI platform devices request for a shared IRQ line. On OMAP3, the logical OR of DSI and DISPC interrupt lines goes to the MPU. There is a register DSS_IRQSTATUS which tells if the interrupt came from DISPC or DSI. On OMAP2, there is no DSI, only DISPC interrupts goto the MPU. There is no DSS_IRQSTATUS register. Hence, it makes more sense to have separate irq handlers corresponding to the DSS sub modules instead of having a common handler. Since on OMAP3 the logical OR of the lines goes to MPU, the irq line is shared among the IRQ handlers. The hwmod irq info has been removed for DSS to DISPC and DSI for OMAP2 and OMAP3 hwmod databases. The Probes of DISPC and DSI now request for irq handlers. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r--drivers/video/omap2/dss/dispc.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index dc4518c4b0e4..43f7091c71cb 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/interrupt.h>
35 36
36#include <plat/sram.h> 37#include <plat/sram.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -178,6 +179,7 @@ struct dispc_irq_stats {
178static struct { 179static struct {
179 struct platform_device *pdev; 180 struct platform_device *pdev;
180 void __iomem *base; 181 void __iomem *base;
182 int irq;
181 183
182 u32 fifo_size[3]; 184 u32 fifo_size[3];
183 185
@@ -2865,10 +2867,10 @@ static void print_irq_status(u32 status)
2865 * but we presume they are on because we got an IRQ. However, 2867 * but we presume they are on because we got an IRQ. However,
2866 * an irq handler may turn the clocks off, so we may not have 2868 * an irq handler may turn the clocks off, so we may not have
2867 * clock later in the function. */ 2869 * clock later in the function. */
2868void dispc_irq_handler(void) 2870static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
2869{ 2871{
2870 int i; 2872 int i;
2871 u32 irqstatus; 2873 u32 irqstatus, irqenable;
2872 u32 handledirqs = 0; 2874 u32 handledirqs = 0;
2873 u32 unhandled_errors; 2875 u32 unhandled_errors;
2874 struct omap_dispc_isr_data *isr_data; 2876 struct omap_dispc_isr_data *isr_data;
@@ -2877,6 +2879,13 @@ void dispc_irq_handler(void)
2877 spin_lock(&dispc.irq_lock); 2879 spin_lock(&dispc.irq_lock);
2878 2880
2879 irqstatus = dispc_read_reg(DISPC_IRQSTATUS); 2881 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
2882 irqenable = dispc_read_reg(DISPC_IRQENABLE);
2883
2884 /* IRQ is not for us */
2885 if (!(irqstatus & irqenable)) {
2886 spin_unlock(&dispc.irq_lock);
2887 return IRQ_NONE;
2888 }
2880 2889
2881#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 2890#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2882 spin_lock(&dispc.irq_stats_lock); 2891 spin_lock(&dispc.irq_stats_lock);
@@ -2928,6 +2937,8 @@ void dispc_irq_handler(void)
2928 } 2937 }
2929 2938
2930 spin_unlock(&dispc.irq_lock); 2939 spin_unlock(&dispc.irq_lock);
2940
2941 return IRQ_HANDLED;
2931} 2942}
2932 2943
2933static void dispc_error_worker(struct work_struct *work) 2944static void dispc_error_worker(struct work_struct *work)
@@ -3322,6 +3333,7 @@ int dispc_setup_plane(enum omap_plane plane,
3322static int omap_dispchw_probe(struct platform_device *pdev) 3333static int omap_dispchw_probe(struct platform_device *pdev)
3323{ 3334{
3324 u32 rev; 3335 u32 rev;
3336 int r = 0;
3325 struct resource *dispc_mem; 3337 struct resource *dispc_mem;
3326 3338
3327 dispc.pdev = pdev; 3339 dispc.pdev = pdev;
@@ -3338,12 +3350,27 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3338 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); 3350 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3339 if (!dispc_mem) { 3351 if (!dispc_mem) {
3340 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3352 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3341 return -EINVAL; 3353 r = -EINVAL;
3354 goto fail0;
3342 } 3355 }
3343 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); 3356 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3344 if (!dispc.base) { 3357 if (!dispc.base) {
3345 DSSERR("can't ioremap DISPC\n"); 3358 DSSERR("can't ioremap DISPC\n");
3346 return -ENOMEM; 3359 r = -ENOMEM;
3360 goto fail0;
3361 }
3362 dispc.irq = platform_get_irq(dispc.pdev, 0);
3363 if (dispc.irq < 0) {
3364 DSSERR("platform_get_irq failed\n");
3365 r = -ENODEV;
3366 goto fail1;
3367 }
3368
3369 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3370 "OMAP DISPC", dispc.pdev);
3371 if (r < 0) {
3372 DSSERR("request_irq failed\n");
3373 goto fail1;
3347 } 3374 }
3348 3375
3349 enable_clocks(1); 3376 enable_clocks(1);
@@ -3361,10 +3388,15 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3361 enable_clocks(0); 3388 enable_clocks(0);
3362 3389
3363 return 0; 3390 return 0;
3391fail1:
3392 iounmap(dispc.base);
3393fail0:
3394 return r;
3364} 3395}
3365 3396
3366static int omap_dispchw_remove(struct platform_device *pdev) 3397static int omap_dispchw_remove(struct platform_device *pdev)
3367{ 3398{
3399 free_irq(dispc.irq, dispc.pdev);
3368 iounmap(dispc.base); 3400 iounmap(dispc.base);
3369 return 0; 3401 return 0;
3370} 3402}