lkml.org 
[lkml]   [2008]   [Aug]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 21/33] serial: change remove NR_IRQS in 8250.c v2
    Date
    use small array with index to handle irq locking for serial port
    hope 32 slot is enough

    v2: according to Eric, move irq_no into irq_info, and not clean irq_no

    Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
    Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
    ---
    drivers/serial/8250.c | 45 +++++++++++++++++++++++++++++++++++++++++----
    1 files changed, 41 insertions(+), 4 deletions(-)
    diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
    index 3920324..595b956 100644
    --- a/drivers/serial/8250.c
    +++ b/drivers/serial/8250.c
    @@ -147,9 +147,39 @@ struct uart_8250_port {
    struct irq_info {
    spinlock_t lock;
    struct list_head *head;
    + int irq_no;
    };

    -static struct irq_info irq_lists[NR_IRQS];
    +#define NR_IRQ_INFO 32
    +
    +static struct irq_info irq_lists[NR_IRQ_INFO] = {
    + [0 ... NR_IRQ_INFO-1] = {
    + .irq_no = -1,
    + }
    +};
    +
    +static struct irq_info *get_irq_info(int irq, int with_free)
    +{
    + int i, first_free = -1;
    +
    + for (i = 0; i < NR_IRQ_INFO; i++) {
    + if (irq_lists[i].irq_no == irq)
    + return &irq_lists[i];
    + if (irq_lists[i].irq_no == -1 && first_free == -1)
    + first_free = i;
    + }
    + if (!with_free)
    + return NULL;
    +
    + if (first_free != -1) {
    + irq_lists[first_free].irq_no = irq;
    + return &irq_lists[first_free];
    + }
    +
    + WARN_ON("NR_IRQ_INFO too small");
    +
    + return NULL;
    +}

    /*
    * Here we define the default xmit fifo size used for each type of UART.
    @@ -1554,9 +1584,12 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)

    static int serial_link_irq_chain(struct uart_8250_port *up)
    {
    - struct irq_info *i = irq_lists + up->port.irq;
    + struct irq_info *i = get_irq_info(up->port.irq, 1);
    int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;

    + if (!i)
    + return -1;
    +
    spin_lock_irq(&i->lock);

    if (i->head) {
    @@ -1580,7 +1613,11 @@ static int serial_link_irq_chain(struct uart_8250_port *up)

    static void serial_unlink_irq_chain(struct uart_8250_port *up)
    {
    - struct irq_info *i = irq_lists + up->port.irq;
    + int irq_no = up->port.irq;
    + struct irq_info *i = get_irq_info(irq_no, 0);
    +
    + if (!i)
    + return;

    BUG_ON(i->head == NULL);

    @@ -2964,7 +3001,7 @@ static int __init serial8250_init(void)
    "%d ports, IRQ sharing %sabled\n", nr_uarts,
    share_irqs ? "en" : "dis");

    - for (i = 0; i < nr_irqs; i++)
    + for (i = 0; i < NR_IRQ_INFO; i++)
    spin_lock_init(&irq_lists[i].lock);

    ret = uart_register_driver(&serial8250_reg);
    --
    1.5.4.5


    \
     
     \ /
      Last update: 2008-08-06 10:55    [from the cache]
    ©2003-2014 Jasper Spaans. Advertise on this site