Skip to content

Commit

Permalink
serial: sh-sci: Fix probe error paths
Browse files Browse the repository at this point in the history
When probing fails, the driver must not try to cleanup resources that
have not been initialized. Fix this.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Laurent Pinchart authored and Greg Kroah-Hartman committed Jun 12, 2012
1 parent 95f4d5f commit 9800ee6
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions drivers/tty/serial/sh-sci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,16 @@ static int __devinit sci_init_single(struct platform_device *dev,
return 0;
}

static void sci_cleanup_single(struct sci_port *port)
{
sci_free_gpios(port);

clk_put(port->iclk);
clk_put(port->fclk);

pm_runtime_disable(port->port.dev);
}

#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
static void serial_console_putchar(struct uart_port *port, int ch)
{
Expand Down Expand Up @@ -2360,14 +2370,10 @@ static int sci_remove(struct platform_device *dev)
cpufreq_unregister_notifier(&port->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);

sci_free_gpios(port);

uart_remove_one_port(&sci_uart_driver, &port->port);

clk_put(port->iclk);
clk_put(port->fclk);
sci_cleanup_single(port);

pm_runtime_disable(&dev->dev);
return 0;
}

Expand All @@ -2392,7 +2398,13 @@ static int __devinit sci_probe_single(struct platform_device *dev,
if (ret)
return ret;

return uart_add_one_port(&sci_uart_driver, &sciport->port);
ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
if (ret) {
sci_cleanup_single(sciport);
return ret;
}

return 0;
}

static int __devinit sci_probe(struct platform_device *dev)
Expand All @@ -2413,24 +2425,22 @@ static int __devinit sci_probe(struct platform_device *dev)

ret = sci_probe_single(dev, dev->id, p, sp);
if (ret)
goto err_unreg;
return ret;

sp->freq_transition.notifier_call = sci_notifier;

ret = cpufreq_register_notifier(&sp->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
if (unlikely(ret < 0))
goto err_unreg;
if (unlikely(ret < 0)) {
sci_cleanup_single(sp);
return ret;
}

#ifdef CONFIG_SH_STANDARD_BIOS
sh_bios_gdb_detach();
#endif

return 0;

err_unreg:
sci_remove(dev);
return ret;
}

static int sci_suspend(struct device *dev)
Expand Down

0 comments on commit 9800ee6

Please sign in to comment.