Example #1
0
_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;
}
Example #2
0
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;
}