_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 ) { mali_osk_irq_object_t *irq_object; irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL); if (NULL == irq_object) { return NULL; } if (-1 == irqnum) { /* Probe for IRQ */ if ( (NULL != trigger_func) && (NULL != ack_func) ) { unsigned long probe_count = 3; _mali_osk_errcode_t err; int irq; MALI_DEBUG_PRINT(2, ("Probing for irq\n")); do { unsigned long mask; mask = probe_irq_on(); trigger_func(probe_data); _mali_osk_time_ubusydelay(5); irq = probe_irq_off(mask); err = ack_func(probe_data); } while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--); if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1; else irqnum = irq; } else irqnum = -1; /* no probe functions, fault */ if (-1 != irqnum) { /* found an irq */ MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum)); } else { MALI_DEBUG_PRINT(2, ("Probe for irq failed\n")); } } irq_object->irqnum = irqnum; irq_object->uhandler = uhandler; irq_object->data = int_data; if (-1 == irqnum) { MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description)); kfree(irq_object); return NULL; } if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_TRIGGER_LOW, description, irq_object)) { MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description)); kfree(irq_object); return NULL; } return irq_object; }
_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core) { int i; const int request_loop_count = 20; MALI_DEBUG_ASSERT_POINTER(core); MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description)); MALI_ASSERT_GROUP_LOCKED(core->group); mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */ #if defined(USING_MALI200) /* On Mali-200, stop the bus, then do a hard reset of the core */ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS); for (i = 0; i < request_loop_count; i++) { if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) { break; } _mali_osk_time_ubusydelay(10); } if (request_loop_count == i) { MALI_PRINT_ERROR(("Mali PP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description)); return _MALI_OSK_ERR_FAULT ; } /* the bus was stopped OK, do the hard reset */ mali_pp_hard_reset(core); #elif defined(USING_MALI400) /* Mali-300 and Mali-400 have a safe reset command which we use */ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED); mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET); for (i = 0; i < request_loop_count; i++) { if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) { break; } _mali_osk_time_ubusydelay(10); } if (request_loop_count == i) { MALI_DEBUG_PRINT(2, ("Mali PP: Failed to reset core %s, Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); return _MALI_OSK_ERR_FAULT; } #else #error "no supported mali core defined" #endif /* Re-enable interrupts */ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); return _MALI_OSK_ERR_OK; }
_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description ) { mali_osk_irq_object_t *irq_object; irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL); if (NULL == irq_object) return NULL; #if MALI_LICENSE_IS_GPL if (NULL == mali_wq) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0); #else mali_wq = create_workqueue("mali"); #endif if(NULL == mali_wq) { MALI_PRINT_ERROR(("Unable to create Mali workqueue\n")); kfree( irq_object ); return NULL; } } #endif /* workqueue API changed in 2.6.20, support both versions: */ #if defined(INIT_DELAYED_WORK) /* New syntax: INIT_WORK( struct work_struct *work, void (*function)(struct work_struct *)) */ INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half); #else /* Old syntax: INIT_WORK( struct work_struct *work, void (*function)(void *), void *data) */ INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half, irq_object); #endif /* defined(INIT_DELAYED_WORK) */ if (-1 == irqnum) { /* Probe for IRQ */ if ( (NULL != trigger_func) && (NULL != ack_func) ) { unsigned long probe_count = 3; _mali_osk_errcode_t err; int irq; MALI_DEBUG_PRINT(2, ("Probing for irq\n")); do { unsigned long mask; mask = probe_irq_on(); trigger_func(data); _mali_osk_time_ubusydelay(5); irq = probe_irq_off(mask); err = ack_func(data); } while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--); if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1; else irqnum = irq; } else irqnum = -1; /* no probe functions, fault */ if (-1 != irqnum) { /* found an irq */ MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum)); } else { MALI_DEBUG_PRINT(2, ("Probe for irq failed\n")); } } irq_object->irqnum = irqnum; irq_object->uhandler = uhandler; irq_object->bhandler = bhandler; irq_object->data = data; /* Is this a real IRQ handler we need? */ if (!mali_benchmark && irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM) { if (-1 == irqnum) { MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description)); kfree(irq_object); return NULL; } if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_SHARED, description, irq_object)) { MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description)); kfree(irq_object); return NULL; } } #if MALI_LICENSE_IS_GPL if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum ) { pmm_wq = create_singlethread_workqueue("mali-pmm-wq"); } #endif return irq_object; }
_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) { mali_osk_irq_object_t *irq_object; unsigned long irq_flags = 0; #if defined(CONFIG_MALI_SHARED_INTERRUPTS) irq_flags |= IRQF_SHARED; #endif /* defined(CONFIG_MALI_SHARED_INTERRUPTS) */ irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL); if (NULL == irq_object) { return NULL; } if (-1 == irqnum) { /* Probe for IRQ */ if ((NULL != trigger_func) && (NULL != ack_func)) { unsigned long probe_count = 3; _mali_osk_errcode_t err; int irq; MALI_DEBUG_PRINT(2, ("Probing for irq\n")); do { unsigned long mask; mask = probe_irq_on(); trigger_func(probe_data); _mali_osk_time_ubusydelay(5); irq = probe_irq_off(mask); err = ack_func(probe_data); } while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--); if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1; else irqnum = irq; } else irqnum = -1; /* no probe functions, fault */ if (-1 != irqnum) { /* found an irq */ MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum)); } else { MALI_DEBUG_PRINT(2, ("Probe for irq failed\n")); } } irq_object->irqnum = irqnum; irq_object->uhandler = uhandler; irq_object->data = int_data; if (-1 == irqnum) { MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description)); kfree(irq_object); return NULL; } #if defined(DEBUG) /* Verify that the configured interrupt settings are working */ if (_MALI_OSK_ERR_OK != test_interrupt(irqnum, trigger_func, ack_func, probe_data, description)) { MALI_DEBUG_PRINT(2, ("Test of IRQ(%d) handler for core '%s' failed\n", irqnum, description)); kfree(irq_object); return NULL; } #endif if (0 != request_irq(irqnum, irq_handler_upper_half, irq_flags, description, irq_object)) { MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description)); kfree(irq_object); return NULL; } return irq_object; }