diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-06-28 02:25:36 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-06-28 02:25:36 -0400 |
commit | 9174fc8f111982e024a00512c521ad8f1056fccb (patch) | |
tree | e8cd3f0bea432af9d970152b451eb96448000157 /drivers/tty/serial | |
parent | 23241d43eac88f63a7f0bf4d5c12bbc496651585 (diff) |
serial: sh-sci: Fix up pretty name printing for port IRQs.
Presently these were all using the same static string with no regard to
dev_name() and the like. This implements a bit of rework to name the IRQ
dynamically, as it should have been doing all along anyways.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 118 |
1 files changed, 85 insertions, 33 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 9c8624d9c803..d0a56235c50e 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -71,6 +71,8 @@ struct sci_port { | |||
71 | /* Function clock */ | 71 | /* Function clock */ |
72 | struct clk *fclk; | 72 | struct clk *fclk; |
73 | 73 | ||
74 | char *irqstr[SCIx_NR_IRQS]; | ||
75 | |||
74 | struct dma_chan *chan_tx; | 76 | struct dma_chan *chan_tx; |
75 | struct dma_chan *chan_rx; | 77 | struct dma_chan *chan_rx; |
76 | 78 | ||
@@ -954,53 +956,102 @@ static int sci_notifier(struct notifier_block *self, | |||
954 | return NOTIFY_OK; | 956 | return NOTIFY_OK; |
955 | } | 957 | } |
956 | 958 | ||
959 | static struct sci_irq_desc { | ||
960 | const char *desc; | ||
961 | irq_handler_t handler; | ||
962 | } sci_irq_desc[] = { | ||
963 | /* | ||
964 | * Split out handlers, the default case. | ||
965 | */ | ||
966 | [SCIx_ERI_IRQ] = { | ||
967 | .desc = "rx err", | ||
968 | .handler = sci_er_interrupt, | ||
969 | }, | ||
970 | |||
971 | [SCIx_RXI_IRQ] = { | ||
972 | .desc = "rx full", | ||
973 | .handler = sci_rx_interrupt, | ||
974 | }, | ||
975 | |||
976 | [SCIx_TXI_IRQ] = { | ||
977 | .desc = "tx empty", | ||
978 | .handler = sci_tx_interrupt, | ||
979 | }, | ||
980 | |||
981 | [SCIx_BRI_IRQ] = { | ||
982 | .desc = "break", | ||
983 | .handler = sci_br_interrupt, | ||
984 | }, | ||
985 | |||
986 | /* | ||
987 | * Special muxed handler. | ||
988 | */ | ||
989 | [SCIx_MUX_IRQ] = { | ||
990 | .desc = "mux", | ||
991 | .handler = sci_mpxed_interrupt, | ||
992 | }, | ||
993 | }; | ||
994 | |||
957 | static int sci_request_irq(struct sci_port *port) | 995 | static int sci_request_irq(struct sci_port *port) |
958 | { | 996 | { |
959 | int i; | 997 | struct uart_port *up = &port->port; |
960 | irqreturn_t (*handlers[4])(int irq, void *ptr) = { | 998 | int i, j, ret = 0; |
961 | sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt, | 999 | |
962 | sci_br_interrupt, | 1000 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { |
963 | }; | 1001 | struct sci_irq_desc *desc; |
964 | const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", | 1002 | unsigned int irq; |
965 | "SCI Transmit Data Empty", "SCI Break" }; | 1003 | |
966 | 1004 | if (SCIx_IRQ_IS_MUXED(port)) { | |
967 | if (port->cfg->irqs[0] == port->cfg->irqs[1]) { | 1005 | i = SCIx_MUX_IRQ; |
968 | if (unlikely(!port->cfg->irqs[0])) | 1006 | irq = up->irq; |
969 | return -ENODEV; | 1007 | } else |
970 | 1008 | irq = port->cfg->irqs[i]; | |
971 | if (request_irq(port->cfg->irqs[0], sci_mpxed_interrupt, | 1009 | |
972 | IRQF_DISABLED, "sci", port)) { | 1010 | desc = sci_irq_desc + i; |
973 | dev_err(port->port.dev, "Can't allocate IRQ\n"); | 1011 | port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", |
974 | return -ENODEV; | 1012 | dev_name(up->dev), desc->desc); |
1013 | if (!port->irqstr[j]) { | ||
1014 | dev_err(up->dev, "Failed to allocate %s IRQ string\n", | ||
1015 | desc->desc); | ||
1016 | goto out_nomem; | ||
975 | } | 1017 | } |
976 | } else { | 1018 | |
977 | for (i = 0; i < ARRAY_SIZE(handlers); i++) { | 1019 | ret = request_irq(irq, desc->handler, up->irqflags, |
978 | if (unlikely(!port->cfg->irqs[i])) | 1020 | port->irqstr[j], port); |
979 | continue; | 1021 | if (unlikely(ret)) { |
980 | 1022 | dev_err(up->dev, "Can't allocate %s IRQ\n", desc->desc); | |
981 | if (request_irq(port->cfg->irqs[i], handlers[i], | 1023 | goto out_noirq; |
982 | IRQF_DISABLED, desc[i], port)) { | ||
983 | dev_err(port->port.dev, "Can't allocate IRQ\n"); | ||
984 | return -ENODEV; | ||
985 | } | ||
986 | } | 1024 | } |
987 | } | 1025 | } |
988 | 1026 | ||
989 | return 0; | 1027 | return 0; |
1028 | |||
1029 | out_noirq: | ||
1030 | while (--i >= 0) | ||
1031 | free_irq(port->cfg->irqs[i], port); | ||
1032 | |||
1033 | out_nomem: | ||
1034 | while (--j >= 0) | ||
1035 | kfree(port->irqstr[j]); | ||
1036 | |||
1037 | return ret; | ||
990 | } | 1038 | } |
991 | 1039 | ||
992 | static void sci_free_irq(struct sci_port *port) | 1040 | static void sci_free_irq(struct sci_port *port) |
993 | { | 1041 | { |
994 | int i; | 1042 | int i; |
995 | 1043 | ||
996 | if (port->cfg->irqs[0] == port->cfg->irqs[1]) | 1044 | /* |
997 | free_irq(port->cfg->irqs[0], port); | 1045 | * Intentionally in reverse order so we iterate over the muxed |
998 | else { | 1046 | * IRQ first. |
999 | for (i = 0; i < ARRAY_SIZE(port->cfg->irqs); i++) { | 1047 | */ |
1000 | if (!port->cfg->irqs[i]) | 1048 | for (i = 0; i < SCIx_NR_IRQS; i++) { |
1001 | continue; | 1049 | free_irq(port->cfg->irqs[i], port); |
1050 | kfree(port->irqstr[i]); | ||
1002 | 1051 | ||
1003 | free_irq(port->cfg->irqs[i], port); | 1052 | if (SCIx_IRQ_IS_MUXED(port)) { |
1053 | /* If there's only one IRQ, we're done. */ | ||
1054 | return; | ||
1004 | } | 1055 | } |
1005 | } | 1056 | } |
1006 | } | 1057 | } |
@@ -1910,6 +1961,7 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
1910 | * For the muxed case there's nothing more to do. | 1961 | * For the muxed case there's nothing more to do. |
1911 | */ | 1962 | */ |
1912 | port->irq = p->irqs[SCIx_RXI_IRQ]; | 1963 | port->irq = p->irqs[SCIx_RXI_IRQ]; |
1964 | port->irqflags = IRQF_DISABLED; | ||
1913 | 1965 | ||
1914 | port->serial_in = sci_serial_in; | 1966 | port->serial_in = sci_serial_in; |
1915 | port->serial_out = sci_serial_out; | 1967 | port->serial_out = sci_serial_out; |