Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9174fc8f authored by Paul Mundt's avatar Paul Mundt
Browse files

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: default avatarPaul Mundt <lethal@linux-sh.org>
parent 23241d43
Loading
Loading
Loading
Loading
+85 −33
Original line number Diff line number Diff line
@@ -71,6 +71,8 @@ struct sci_port {
	/* Function clock */
	struct clk		*fclk;

	char			*irqstr[SCIx_NR_IRQS];

	struct dma_chan			*chan_tx;
	struct dma_chan			*chan_rx;

@@ -954,53 +956,102 @@ static int sci_notifier(struct notifier_block *self,
	return NOTIFY_OK;
}

static struct sci_irq_desc {
	const char	*desc;
	irq_handler_t	handler;
} sci_irq_desc[] = {
	/*
	 * Split out handlers, the default case.
	 */
	[SCIx_ERI_IRQ] = {
		.desc = "rx err",
		.handler = sci_er_interrupt,
	},

	[SCIx_RXI_IRQ] = {
		.desc = "rx full",
		.handler = sci_rx_interrupt,
	},

	[SCIx_TXI_IRQ] = {
		.desc = "tx empty",
		.handler = sci_tx_interrupt,
	},

	[SCIx_BRI_IRQ] = {
		.desc = "break",
		.handler = sci_br_interrupt,
	},

	/*
	 * Special muxed handler.
	 */
	[SCIx_MUX_IRQ] = {
		.desc = "mux",
		.handler = sci_mpxed_interrupt,
	},
};

static int sci_request_irq(struct sci_port *port)
{
	int i;
	irqreturn_t (*handlers[4])(int irq, void *ptr) = {
		sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
		sci_br_interrupt,
	};
	const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full",
			       "SCI Transmit Data Empty", "SCI Break" };
	struct uart_port *up = &port->port;
	int i, j, ret = 0;

	if (port->cfg->irqs[0] == port->cfg->irqs[1]) {
		if (unlikely(!port->cfg->irqs[0]))
			return -ENODEV;
	for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) {
		struct sci_irq_desc *desc;
		unsigned int irq;

		if (request_irq(port->cfg->irqs[0], sci_mpxed_interrupt,
				IRQF_DISABLED, "sci", port)) {
			dev_err(port->port.dev, "Can't allocate IRQ\n");
			return -ENODEV;
		}
	} else {
		for (i = 0; i < ARRAY_SIZE(handlers); i++) {
			if (unlikely(!port->cfg->irqs[i]))
				continue;
		if (SCIx_IRQ_IS_MUXED(port)) {
			i = SCIx_MUX_IRQ;
			irq = up->irq;
		} else
			irq = port->cfg->irqs[i];

			if (request_irq(port->cfg->irqs[i], handlers[i],
					IRQF_DISABLED, desc[i], port)) {
				dev_err(port->port.dev, "Can't allocate IRQ\n");
				return -ENODEV;
		desc = sci_irq_desc + i;
		port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s",
					    dev_name(up->dev), desc->desc);
		if (!port->irqstr[j]) {
			dev_err(up->dev, "Failed to allocate %s IRQ string\n",
				desc->desc);
			goto out_nomem;
		}

		ret = request_irq(irq, desc->handler, up->irqflags,
				  port->irqstr[j], port);
		if (unlikely(ret)) {
			dev_err(up->dev, "Can't allocate %s IRQ\n", desc->desc);
			goto out_noirq;
		}
	}

	return 0;

out_noirq:
	while (--i >= 0)
		free_irq(port->cfg->irqs[i], port);

out_nomem:
	while (--j >= 0)
		kfree(port->irqstr[j]);

	return ret;
}

static void sci_free_irq(struct sci_port *port)
{
	int i;

	if (port->cfg->irqs[0] == port->cfg->irqs[1])
		free_irq(port->cfg->irqs[0], port);
	else {
		for (i = 0; i < ARRAY_SIZE(port->cfg->irqs); i++) {
			if (!port->cfg->irqs[i])
				continue;

	/*
	 * Intentionally in reverse order so we iterate over the muxed
	 * IRQ first.
	 */
	for (i = 0; i < SCIx_NR_IRQS; i++) {
		free_irq(port->cfg->irqs[i], port);
		kfree(port->irqstr[i]);

		if (SCIx_IRQ_IS_MUXED(port)) {
			/* If there's only one IRQ, we're done. */
			return;
		}
	}
}
@@ -1910,6 +1961,7 @@ static int __devinit sci_init_single(struct platform_device *dev,
	 * For the muxed case there's nothing more to do.
	 */
	port->irq		= p->irqs[SCIx_RXI_IRQ];
	port->irqflags		= IRQF_DISABLED;

	port->serial_in		= sci_serial_in;
	port->serial_out	= sci_serial_out;
+7 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ enum {
	SCIx_TXI_IRQ,
	SCIx_BRI_IRQ,
	SCIx_NR_IRQS,

	SCIx_MUX_IRQ = SCIx_NR_IRQS,	/* special case */
};

enum {
@@ -82,6 +84,11 @@ enum {
	[SCIx_BRI_IRQ]	= (irq),	\
}

#define SCIx_IRQ_IS_MUXED(port)			\
	((port)->cfg->irqs[SCIx_ERI_IRQ] ==	\
	 (port)->cfg->irqs[SCIx_RXI_IRQ]) ||	\
	((port)->cfg->irqs[SCIx_ERI_IRQ] &&	\
	 !(port)->cfg->irqs[SCIx_RXI_IRQ])
/*
 * SCI register subset common for all port types.
 * Not all registers will exist on all parts.