Hi Dmitry, I already replied against patch6 about the exception handling of tegra_devfreq_probe(). This patchset split out the patch related to error handling for probe(). I think that you can squash the patches regarding of exception handling for probe() to one patch instead of split out the multiple patches. On 19. 4. 15. 오후 11:54, Dmitry Osipenko wrote: > Reset hardware, disable ACTMON clock, release OPP's and free IRQ before > removing devfreq device since there is no guarantee that interrupt > handling won't run after masking interrupt in hardware. > > Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx> > --- > drivers/devfreq/tegra-devfreq.c | 53 ++++++++++++++++----------------- > 1 file changed, 26 insertions(+), 27 deletions(-) > > diff --git a/drivers/devfreq/tegra-devfreq.c b/drivers/devfreq/tegra-devfreq.c > index 69b557df5084..a668e4fbc874 100644 > --- a/drivers/devfreq/tegra-devfreq.c > +++ b/drivers/devfreq/tegra-devfreq.c > @@ -663,28 +663,28 @@ static int tegra_devfreq_probe(struct platform_device *pdev) > > irq = platform_get_irq(pdev, 0); > if (irq < 0) { > - dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq); > - return irq; > + err = irq; > + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", err); > + goto remove_opps; > } > > platform_set_drvdata(pdev, tegra); > > tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock); > - tegra->devfreq = devm_devfreq_add_device(&pdev->dev, > - &tegra_devfreq_profile, > - "tegra_actmon", > - NULL); > + tegra->devfreq = devfreq_add_device(&pdev->dev, > + &tegra_devfreq_profile, > + "tegra_actmon", > + NULL); > if (IS_ERR(tegra->devfreq)) { > err = PTR_ERR(tegra->devfreq); > - return err; > + goto remove_opps; > } > > - err = devm_request_threaded_irq(&pdev->dev, irq, NULL, > - actmon_thread_isr, IRQF_ONESHOT, > - "tegra-devfreq", tegra); > + err = request_threaded_irq(irq, NULL, actmon_thread_isr, IRQF_ONESHOT, > + "tegra-devfreq", tegra); > if (err) { > dev_err(&pdev->dev, "Interrupt request failed\n"); > - goto remove_opps; > + goto remove_devfreq; > } > > tegra->rate_change_nb.notifier_call = tegra_actmon_rate_notify_cb; > @@ -692,14 +692,23 @@ static int tegra_devfreq_probe(struct platform_device *pdev) > if (err) { > dev_err(&pdev->dev, > "Failed to register rate change notifier\n"); > - goto remove_opps; > + goto disable_interrupt; > } > > return 0; > > +disable_interrupt: > + free_irq(irq, tegra); > + > +remove_devfreq: > + devfreq_remove_device(tegra->devfreq); > + > remove_opps: > dev_pm_opp_remove_all_dynamic(&pdev->dev); > > + reset_control_reset(tegra->reset); > + clk_disable_unprepare(tegra->clock); > + > return err; > } > > @@ -707,24 +716,14 @@ static int tegra_devfreq_remove(struct platform_device *pdev) > { > struct tegra_devfreq *tegra = platform_get_drvdata(pdev); > int irq = platform_get_irq(pdev, 0); > - u32 val; > - unsigned int i; > - > - devm_devfreq_remove_device(&pdev->dev, tegra->devfreq); > - dev_pm_opp_remove_all_dynamic(&pdev->dev); > - > - for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) { > - val = device_readl(&tegra->devices[i], ACTMON_DEV_CTRL); > - val &= ~ACTMON_DEV_CTRL_ENB; > - device_writel(&tegra->devices[i], val, ACTMON_DEV_CTRL); > - } > - > - actmon_write_barrier(tegra); > - > - devm_free_irq(&pdev->dev, irq, tegra); > > clk_notifier_unregister(tegra->emc_clock, &tegra->rate_change_nb); > + free_irq(irq, tegra); > + > + devfreq_remove_device(tegra->devfreq); > + dev_pm_opp_remove_all_dynamic(&pdev->dev); > > + reset_control_reset(tegra->reset); > clk_disable_unprepare(tegra->clock); > > return 0; > -- Best Regards, Chanwoo Choi Samsung Electronics