_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 handler for core '%s' failed\n", 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; }
void trigger(void *cvoid, zctx_t * context, void * control) { triggerconfig_t * c = (triggerconfig_t*) cvoid; //set up msgpack stuff zclock_log("watch_port started!"); msgpack_zone mempool; msgpack_zone_init(&mempool, 2048); // TODO char * user_id = "17"; // TODO get broker in somehow char * broker = "tcp://au.ninjablocks.com:5773"; mdcli_t * client = mdcli_new(broker, 1); //VERBOSE triggermemory_t trigger_memory; msgpack_object * addins_obj = parse_msgpack(&mempool, c->addins); if(!parse_addins(addins_obj, &trigger_memory)) { //bad message zclock_log("bad trigger definition"); msgpack_object_print(stdout, *addins_obj); send_sync("bad trigger", control); return; } zclock_log("Creating trigger: target %s, rule_id %s, name %s", c->target_worker, c->rule_id, c->trigger_name); dump_trigger(&trigger_memory); triggerfunction trigger_func; if(!(trigger_func = find_trigger(c->channel, c->trigger_name))) { zclock_log("no trigger found for channel %s, trigger %s", c->channel, c->trigger_name); send_sync("no such trigger", control); return; } void * line = zsocket_new(context, ZMQ_SUB); // what line are we on? // this comes in the addins. char * linesocket = to_linesocket(trigger_memory.line_id); zclock_log("trigger is connecting to listen on %s", linesocket); zsocket_connect(line, linesocket); zsockopt_set_unsubscribe(line, ""); zsockopt_set_subscribe(line, "VALUE"); recv_sync("ping", control); send_sync("pong", control); zmq_pollitem_t items [] = { { line, 0, ZMQ_POLLIN, 0 }, { control, 0, ZMQ_POLLIN, 0 } }; while(1) { // listen on control and line zmq_poll (items, 2, -1); if (items[1].revents & ZMQ_POLLIN) { zclock_log("rule %s received message on control pipe", c->rule_id); // control message // really only expecting DESTROY zmsg_t * msg = zmsg_recv(control); char * str = zmsg_popstr(msg); zmsg_destroy(&msg); if (strcmp("Destroy", str) == 0) { zclock_log("rule %s will quit on request", c->rule_id); free(str); send_sync("ok", control); zclock_log("rule %s quitting on request", c->rule_id); break; } else { zclock_log("unexpected command %s for rule %s", str, c->rule_id); free(str); send_sync("ok", control); } } if (items[0].revents & ZMQ_POLLIN) { // serial update zmsg_t * msg = zmsg_recv(line); zframe_t * cmd = zmsg_pop(msg); if(zframe_streq(cmd, "CHANNEL_CHANGE")) { // TODO // must have been dormant to have gotten this char * new_channel = zmsg_popstr(msg); if(strcmp(c->channel, new_channel) == 0) { // oh, happy day! We're relevant again. // reactivate and start looking at reset levels. zclock_log("line %d: changed channel from %s to %s: trigger coming back to life", trigger_memory.line_id, c->channel, new_channel); zsockopt_set_subscribe(line, "VALUE"); zsockopt_set_unsubscribe(line, "CHANNEL_CHANGE"); } free(new_channel); } else if (zframe_streq(cmd, "VALUE")) { zframe_t * vframe = zmsg_pop(msg); int value; memcpy(&value, zframe_data(vframe), sizeof(int)); char * update_channel = zmsg_popstr(msg); if(strcmp(c->channel, update_channel) != 0) { // channel changed, go dormant // this is legit according to my tests at // https://gist.github.com/2042350 zclock_log("line %d: changed channel from %s to %s: trigger going dormant", trigger_memory.line_id, c->channel, update_channel); zsockopt_set_subscribe(line, "CHANNEL_CHANGE"); zsockopt_set_unsubscribe(line, "VALUE"); } else if(trigger_func(&trigger_memory, value)) { send_trigger(client, c->target_worker, c->rule_id, value, user_id); } free(update_channel); } else { // shouldn't ever happen. zclock_log("shouldn't have received command %s\n", zframe_strdup(cmd)); } zmsg_destroy(&msg); zframe_destroy(&cmd); } } msgpack_zone_destroy(&mempool); }
_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; /* 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_irq_wq == NULL) { mali_irq_wq = create_singlethread_workqueue("mali-pmm-wq"); } 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; 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; }