diff options
author | Ryan Bradetich <rbrad@j6000.bradetich.net> | 2006-11-03 06:34:16 +0000 |
---|---|---|
committer | Kyle McMartin <kyle@ubuntu.com> | 2006-12-08 00:34:14 -0500 |
commit | 9c6416ce6a9829ede1594403d19b22d23cf54e2e (patch) | |
tree | 19c0002be37dcf21f9d75f694eef137481137d90 /drivers/serial/mux.c | |
parent | 3de7b6482b4e9a34f91604ee0fb7a3ace250f3bb (diff) | |
download | lwn-9c6416ce6a9829ede1594403d19b22d23cf54e2e.tar.gz lwn-9c6416ce6a9829ede1594403d19b22d23cf54e2e.zip |
[PARISC] [MUX] Claim resources for the Mux driver
This patch claims the iomem resources
for the Mux driver.
Signed-off-by: Ryan Bradetich <rbrad@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'drivers/serial/mux.c')
-rw-r--r-- | drivers/serial/mux.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 6408b9b1561a..f21faf163955 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -66,6 +66,13 @@ static struct uart_driver mux_driver = { .nr = MUX_NR, }; +struct mux_card { + int port_count; + struct parisc_device *dev; + struct mux_card *next; +}; + +static struct mux_card *mux_card_head; static struct timer_list mux_timer; #define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET) @@ -434,6 +441,37 @@ static struct uart_ops mux_pops = { }; /** + * get_new_mux_card - Allocate and return a new mux card. + * + * This function is used to allocate and return a new mux card. + */ +static struct mux_card * __init get_new_mux_card(void) +{ + struct mux_card *card = mux_card_head; + + if(card == NULL) { + mux_card_head = kzalloc(sizeof(struct mux_card), GFP_KERNEL); + if(!mux_card_head) { + printk(KERN_ERR "MUX: Unable to allocate memory.\n"); + return NULL; + } + return mux_card_head; + } + + while(card->next) { + card = card->next; + } + + card->next = kzalloc(sizeof(struct mux_card), GFP_KERNEL); + if(!card->next) { + printk(KERN_ERR "MUX: Unable to allocate memory.\n"); + return NULL; + } + + return card->next; +} + +/** * mux_probe - Determine if the Serial Mux should claim this device. * @dev: The parisc device. * @@ -446,6 +484,7 @@ static int __init mux_probe(struct parisc_device *dev) u8 iodc_data[32]; unsigned long bytecnt; struct uart_port *port; + struct mux_card *card; status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32); if(status != PDC_OK) { @@ -454,7 +493,16 @@ static int __init mux_probe(struct parisc_device *dev) } ports = GET_MUX_PORTS(iodc_data); - printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.3\n", ports); + printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.4\n", ports); + + card = get_new_mux_card(); + if(card == NULL) + return 1; + + card->dev = dev; + card->port_count = ports; + request_mem_region(card->dev->hpa.start + MUX_OFFSET, + card->port_count * MUX_LINE_OFFSET, "Mux"); if(!port_cnt) { mux_driver.cons = MUX_CONSOLE; @@ -534,6 +582,8 @@ static int __init mux_init(void) static void __exit mux_exit(void) { int i; + struct mux_card *next; + struct mux_card *card = mux_card_head; for (i = 0; i < port_cnt; i++) { uart_remove_one_port(&mux_driver, &mux_ports[i].port); @@ -541,6 +591,15 @@ static void __exit mux_exit(void) iounmap(mux_ports[i].port.membase); } + while(card != NULL) { + release_mem_region(card->dev->hpa.start + MUX_OFFSET, + card->port_count * MUX_LINE_OFFSET); + + next = card->next; + kfree(card); + card = next; + } + uart_unregister_driver(&mux_driver); } |