Skip to content

Commit

Permalink
serial: sh-sci: Support resources passed through platform resources
Browse files Browse the repository at this point in the history
Memory and IRQ resources are currently passed to the driver through
platform data. Support passing them through the standard platform
resources mechanism instead. This deprecates platform data resources.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
  • Loading branch information
Laurent Pinchart authored and Simon Horman committed Dec 24, 2013
1 parent bc14e00 commit 1fcc91a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 20 deletions.
65 changes: 49 additions & 16 deletions drivers/tty/serial/sh-sci.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct sci_port {
/* Function clock */
struct clk *fclk;

int irqs[SCIx_NR_IRQS];
char *irqstr[SCIx_NR_IRQS];
char *gpiostr[SCIx_NR_FNS];

Expand Down Expand Up @@ -1079,19 +1080,19 @@ static int sci_request_irq(struct sci_port *port)

for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) {
struct sci_irq_desc *desc;
unsigned int irq;
int irq;

if (SCIx_IRQ_IS_MUXED(port)) {
i = SCIx_MUX_IRQ;
irq = up->irq;
} else {
irq = port->cfg->irqs[i];
irq = port->irqs[i];

/*
* Certain port types won't support all of the
* available interrupt sources.
*/
if (unlikely(!irq))
if (unlikely(irq < 0))
continue;
}

Expand All @@ -1116,7 +1117,7 @@ static int sci_request_irq(struct sci_port *port)

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

out_nomem:
while (--j >= 0)
Expand All @@ -1134,16 +1135,16 @@ static void sci_free_irq(struct sci_port *port)
* IRQ first.
*/
for (i = 0; i < SCIx_NR_IRQS; i++) {
unsigned int irq = port->cfg->irqs[i];
int irq = port->irqs[i];

/*
* Certain port types won't support all of the available
* interrupt sources.
*/
if (unlikely(!irq))
if (unlikely(irq < 0))
continue;

free_irq(port->cfg->irqs[i], port);
free_irq(port->irqs[i], port);
kfree(port->irqstr[i]);

if (SCIx_IRQ_IS_MUXED(port)) {
Expand Down Expand Up @@ -1659,7 +1660,7 @@ static void rx_timer_fn(unsigned long arg)

if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
scr &= ~0x4000;
enable_irq(s->cfg->irqs[1]);
enable_irq(s->irqs[SCIx_RXI_IRQ]);
}
serial_port_out(port, SCSCR, scr | SCSCR_RIE);
dev_dbg(port->dev, "DMA Rx timed out\n");
Expand Down Expand Up @@ -2150,11 +2151,12 @@ static struct uart_ops sci_uart_ops = {
};

static int sci_init_single(struct platform_device *dev,
struct sci_port *sci_port,
unsigned int index,
struct plat_sci_port *p)
struct sci_port *sci_port, unsigned int index,
struct plat_sci_port *p, bool early)
{
struct uart_port *port = &sci_port->port;
const struct resource *res;
unsigned int i;
int ret;

sci_port->cfg = p;
Expand All @@ -2163,6 +2165,38 @@ static int sci_init_single(struct platform_device *dev,
port->iotype = UPIO_MEM;
port->line = index;

if (dev->num_resources) {
/* Device has resources, use them. */
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (res == NULL)
return -ENOMEM;

port->mapbase = res->start;

for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i)
sci_port->irqs[i] = platform_get_irq(dev, i);

/* The SCI generates several interrupts. They can be muxed
* together or connected to different interrupt lines. In the
* muxed case only one interrupt resource is specified. In the
* non-muxed case three or four interrupt resources are
* specified, as the BRI interrupt is optional.
*/
if (sci_port->irqs[0] < 0)
return -ENXIO;

if (sci_port->irqs[1] < 0) {
sci_port->irqs[1] = sci_port->irqs[0];
sci_port->irqs[2] = sci_port->irqs[0];
sci_port->irqs[3] = sci_port->irqs[0];
}
} else {
/* No resources, use old-style platform data. */
port->mapbase = p->mapbase;
for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i)
sci_port->irqs[i] = p->irqs[i] ? p->irqs[i] : -ENXIO;
}

switch (p->type) {
case PORT_SCIFB:
port->fifosize = 256;
Expand All @@ -2187,7 +2221,7 @@ static int sci_init_single(struct platform_device *dev,
return ret;
}

if (dev) {
if (!early) {
sci_port->iclk = clk_get(&dev->dev, "sci_ick");
if (IS_ERR(sci_port->iclk)) {
sci_port->iclk = clk_get(&dev->dev, "peripheral_clk");
Expand Down Expand Up @@ -2242,7 +2276,6 @@ static int sci_init_single(struct platform_device *dev,
p->error_mask |= (1 << p->overrun_bit);
}

port->mapbase = p->mapbase;
port->type = p->type;
port->flags = UPF_FIXED_PORT | p->flags;
port->regshift = p->regshift;
Expand All @@ -2254,7 +2287,7 @@ static int 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->irq = sci_port->irqs[SCIx_RXI_IRQ];
port->irqflags = 0;

port->serial_in = sci_serial_in;
Expand Down Expand Up @@ -2386,7 +2419,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev)

early_serial_console.index = pdev->id;

sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg);
sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true);

serial_console_setup(&early_serial_console, early_serial_buf);

Expand Down Expand Up @@ -2453,7 +2486,7 @@ static int sci_probe_single(struct platform_device *dev,
return -EINVAL;
}

ret = sci_init_single(dev, sciport, index, p);
ret = sci_init_single(dev, sciport, index, p, false);
if (ret)
return ret;

Expand Down
8 changes: 4 additions & 4 deletions include/linux/serial_sci.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ enum {
}

#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])
((port)->irqs[SCIx_ERI_IRQ] == \
(port)->irqs[SCIx_RXI_IRQ]) || \
((port)->irqs[SCIx_ERI_IRQ] && \
((port)->irqs[SCIx_RXI_IRQ] < 0))
/*
* SCI register subset common for all port types.
* Not all registers will exist on all parts.
Expand Down

0 comments on commit 1fcc91a

Please sign in to comment.