Commit 2a257b4e22df120dd4a811012675158039a93c7d
authorMichel Pollet <buserror@gmail.com>
Thu, 2 Sep 2010 11:55:05 +0000 (12:55 +0100)
committerMichel Pollet <buserror@gmail.com>
Thu, 2 Sep 2010 11:55:05 +0000 (12:55 +0100)
Added a function to set the io module IRQ, and added a way
to deallocate them at teardown time.

Signed-off-by: Michel Pollet <buserror@gmail.com>
2 files changed:
simavr/sim/sim_io.c
simavr/sim/sim_io.h

index 63862e2be3f0cc54d9d83806b938fffcc833b34e..42e8c1be7d58ef9f418c65e51b054c91bdde3d03 100644 (file)
@@ -70,7 +70,6 @@ struct avr_irq_t * avr_io_getirq(avr_t * avr, uint32_t ctl, int index)
        
 }
 
-
 avr_irq_t * avr_iomem_getirq(avr_t * avr, avr_io_addr_t addr, int index)
 {
        avr_io_addr_t a = AVR_DATA_TO_IO(addr);
@@ -83,3 +82,33 @@ avr_irq_t * avr_iomem_getirq(avr_t * avr, avr_io_addr_t addr, int index)
        return index < 9 ? avr->io[a].irq + index : NULL;
 }
 
+struct avr_irq_t * avr_io_setirqs(avr_io_t * io, uint32_t ctl, int count, struct avr_irq_t * irqs)
+{
+       // allocate this module's IRQ
+       io->irq_count = count;
+       io->irq = irqs ? irqs : avr_alloc_irq(0, count);
+       io->irq_ioctl_get = ctl;
+       return io->irq;
+}
+
+static void avr_deallocate_io(avr_io_t * io)
+{
+       if (io->dealloc)
+               io->dealloc(io);
+       avr_free_irq(io->irq, io->irq_count);
+       io->irq_count = 0;
+       io->irq_ioctl_get = 0;
+       io->avr = NULL;
+       io->next = NULL;
+}
+
+void avr_deallocate_ios(avr_t * avr)
+{
+       avr_io_t * port = avr->io_port;
+       while (port) {
+               avr_io_t * next = port->next;
+               avr_deallocate_io(port);
+               port = next;
+       }
+       avr->io_port = NULL;
+}
index 8fa338d99346023f91c9a1c58edb0167971ac7ac..e1656786ddb1e49632c3c97cb935109bb3f40c36 100644 (file)
@@ -53,6 +53,9 @@ typedef struct avr_io_t {
        void (*reset)(struct avr_io_t *io);
        // called externally. allow access to io modules and so on
        int (*ioctl)(struct avr_io_t *io, uint32_t ctl, void *io_param);
+
+       // optional, a function to free up allocated system resources
+       void (*dealloc)(struct avr_io_t *io);
 } avr_io_t;
 
 /*
@@ -63,6 +66,10 @@ typedef struct avr_io_t {
 // this is called by the AVR core init functions, you /could/ register an external
 // one after instanciation, for whatever purpose...
 void avr_register_io(avr_t *avr, avr_io_t * io);
+// Sets an IO module "official" IRQs and the ioctl used to get to them. if 'irqs' is NULL,
+// 'count' will be allocated
+struct avr_irq_t * avr_io_setirqs(avr_io_t * io, uint32_t ctl, int count, struct avr_irq_t * irqs);
+
 // register a callback for when IO register "addr" is read
 void avr_register_io_read(avr_t *avr, avr_io_addr_t addr, avr_io_read_t read, void * param);
 // register a callback for when the IO register is written. callback has to set the memory itself
@@ -82,6 +89,9 @@ struct avr_irq_t * avr_io_getirq(avr_t * avr, uint32_t ctl, int index);
 #define AVR_IOMEM_IRQ_ALL 8
 struct avr_irq_t * avr_iomem_getirq(avr_t * avr, avr_io_addr_t addr, int index);
 
+// Terminates all IOs and remove from them from the io chain
+void avr_deallocate_ios(avr_t *avr);
+
 #ifdef __cplusplus
 };
 #endif