2 * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7 * A copy of the licence is included with the program, and can also be obtained from Free Software
8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 * @file mali_osk_irq.c
13 * Implementation of the OS abstraction layer for the kernel device driver
16 #include <linux/slab.h> /* For memory allocation */
19 #include "mali_kernel_common.h"
20 #include "linux/interrupt.h"
22 typedef struct _mali_osk_irq_t_struct
26 _mali_osk_irq_uhandler_t uhandler;
27 } mali_osk_irq_object_t;
29 typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *);
30 static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/
32 _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, void *int_data, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *probe_data, const char *description )
34 mali_osk_irq_object_t *irq_object;
36 irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL);
37 if (NULL == irq_object)
45 if ( (NULL != trigger_func) && (NULL != ack_func) )
47 unsigned long probe_count = 3;
48 _mali_osk_errcode_t err;
51 MALI_DEBUG_PRINT(2, ("Probing for irq\n"));
57 mask = probe_irq_on();
58 trigger_func(probe_data);
60 _mali_osk_time_ubusydelay(5);
62 irq = probe_irq_off(mask);
63 err = ack_func(probe_data);
65 while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--);
67 if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1;
70 else irqnum = -1; /* no probe functions, fault */
75 MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum));
79 MALI_DEBUG_PRINT(2, ("Probe for irq failed\n"));
83 irq_object->irqnum = irqnum;
84 irq_object->uhandler = uhandler;
85 irq_object->data = int_data;
89 MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description));
94 if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_SHARED, description, irq_object))
96 MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description));
104 void _mali_osk_irq_term( _mali_osk_irq_t *irq )
106 mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
107 free_irq(irq_object->irqnum, irq_object);
112 /** This function is called directly in interrupt context from the OS just after
113 * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel.
114 * It is registered one of these function for each mali core. When an interrupt
115 * arrives this function will be called equal times as registered mali cores.
116 * That means that we only check one mali core in one function call, and the
117 * core we check for each turn is given by the \a dev_id variable.
118 * If we detect an pending interrupt on the given core, we mask the interrupt
119 * out by settging the core's IRQ_MASK register to zero.
120 * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority
123 static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/
125 mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id;
127 if (irq_object->uhandler(irq_object->data) == _MALI_OSK_ERR_OK)