Skip to content

Commit

Permalink
atmel_serial: fix bugs in probe() error path and remove()
Browse files Browse the repository at this point in the history
When an error happens in probe(), the clocks should be disabled, but
only if the port isn't already used as a console.

In remove(), the port struct shouldn't be freed because it's defined
statically.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: Andrew Victor <linux@maxim.org.za>
Tested-by: Marc Pignat <marc.pignat@hevs.ch>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Haavard Skinnemoen authored and Linus Torvalds committed Feb 8, 2008
1 parent 1c0fd82 commit dfa7f34
Showing 1 changed file with 29 additions and 10 deletions.
39 changes: 29 additions & 10 deletions drivers/serial/atmel_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,8 +934,18 @@ static int __init atmel_late_console_init(void)

core_initcall(atmel_late_console_init);

static inline bool atmel_is_console_port(struct uart_port *port)
{
return port->cons && port->cons->index == port->line;
}

#else
#define ATMEL_CONSOLE_DEVICE NULL

static inline bool atmel_is_console_port(struct uart_port *port)
{
return false;
}
#endif

static struct uart_driver atmel_uart = {
Expand Down Expand Up @@ -993,9 +1003,19 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
atmel_init_port(port, pdev);

ret = uart_add_one_port(&atmel_uart, &port->uart);
if (!ret) {
device_init_wakeup(&pdev->dev, 1);
platform_set_drvdata(pdev, port);
if (ret)
goto err_add_port;

device_init_wakeup(&pdev->dev, 1);
platform_set_drvdata(pdev, port);

return 0;

err_add_port:
if (!atmel_is_console_port(&port->uart)) {
clk_disable(port->clk);
clk_put(port->clk);
port->clk = NULL;
}

return ret;
Expand All @@ -1007,16 +1027,15 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
struct atmel_uart_port *atmel_port = (struct atmel_uart_port *)port;
int ret = 0;

clk_disable(atmel_port->clk);
clk_put(atmel_port->clk);

device_init_wakeup(&pdev->dev, 0);
platform_set_drvdata(pdev, NULL);

if (port) {
ret = uart_remove_one_port(&atmel_uart, port);
kfree(port);
}
ret = uart_remove_one_port(&atmel_uart, port);

/* "port" is allocated statically, so we shouldn't free it */

clk_disable(atmel_port->clk);
clk_put(atmel_port->clk);

return ret;
}
Expand Down

0 comments on commit dfa7f34

Please sign in to comment.