Revision 43d91709

b/hw/mst_fpga.c
46 46
}mst_irq_state;
47 47

  
48 48
static void
49
mst_fpga_update_gpio(mst_irq_state *s)
50
{
51
	uint32_t level, diff;
52
	int bit;
53
	level = s->prev_level ^ s->intsetclr;
54

  
55
	for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
56
		bit = ffs(diff) - 1;
57
		qemu_set_irq(s->pins[bit], (level >> bit) & 1 );
58
	}
59
	s->prev_level = level;
60
}
61

  
62
static void
63 49
mst_fpga_set_irq(void *opaque, int irq, int level)
64 50
{
65 51
	mst_irq_state *s = (mst_irq_state *)opaque;
52
	uint32_t oldint = s->intsetclr;
66 53

  
67 54
	if (level)
68 55
		s->prev_level |= 1u << irq;
69 56
	else
70 57
		s->prev_level &= ~(1u << irq);
71 58

  
72
	if(s->intmskena & (1u << irq)) {
73
		s->intsetclr = 1u << irq;
74
		qemu_set_irq(s->parent, level);
75
	}
59
	if ((s->intmskena & (1u << irq)) && level)
60
		s->intsetclr |= 1u << irq;
61

  
62
	if (oldint != (s->intsetclr & s->intmskena))
63
		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
76 64
}
77 65

  
78 66

  
......
146 134
		break;
147 135
	case MST_INTMSKENA:	/* Mask interupt */
148 136
		s->intmskena = (value & 0xFEEFF);
149
		mst_fpga_update_gpio(s);
137
		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
150 138
		break;
151 139
	case MST_INTSETCLR:	/* clear or set interrupt */
152 140
		s->intsetclr = (value & 0xFEEFF);
141
		qemu_set_irq(s->parent, s->intsetclr);
153 142
		break;
154 143
	case MST_PCMCIA0:
155 144
		s->pcmcia0 = value;
......
212 201
	qemu_get_be32s(f, &s->intsetclr);
213 202
	qemu_get_be32s(f, &s->pcmcia0);
214 203
	qemu_get_be32s(f, &s->pcmcia1);
204

  
205
	qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
215 206
	return 0;
216 207
}
217 208

  

Also available in: Unified diff