Hi Pavel, Here are some cleanup suggestions for probe, removal & module initialization functions. On Fri, Jan 03, 2014 at 01:17:54AM +0100, Pavel Machek wrote: > +static int hci_h4p_probe(struct platform_device *pdev) > +{ > + struct hci_h4p_platform_data *bt_plat_data; > + struct hci_h4p_info *info; > + int err; > + > + dev_info(&pdev->dev, "Registering HCI H4P device\n"); > + info = kzalloc(sizeof(struct hci_h4p_info), GFP_KERNEL); info = devm_kzalloc(&pdev->dev, sizeof(struct hci_h4p_info), GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + info->dev = &pdev->dev; > + info->tx_enabled = 1; > + info->rx_enabled = 1; > + spin_lock_init(&info->lock); > + spin_lock_init(&info->clocks_lock); > + skb_queue_head_init(&info->txq); > + > + if (pdev->dev.platform_data == NULL) { > + dev_err(&pdev->dev, "Could not get Bluetooth config data\n"); > + kfree(info); > + return -ENODATA; > + } > + > + bt_plat_data = pdev->dev.platform_data; > + info->chip_type = bt_plat_data->chip_type; > + info->bt_wakeup_gpio = bt_plat_data->bt_wakeup_gpio; > + info->host_wakeup_gpio = bt_plat_data->host_wakeup_gpio; > + info->reset_gpio = bt_plat_data->reset_gpio; > + info->reset_gpio_shared = bt_plat_data->reset_gpio_shared; > + info->bt_sysclk = bt_plat_data->bt_sysclk; > + > + BT_DBG("RESET gpio: %d\n", info->reset_gpio); > + BT_DBG("BTWU gpio: %d\n", info->bt_wakeup_gpio); > + BT_DBG("HOSTWU gpio: %d\n", info->host_wakeup_gpio); > + BT_DBG("sysclk: %d\n", info->bt_sysclk); > + > + init_completion(&info->test_completion); > + complete_all(&info->test_completion); > + > + if (!info->reset_gpio_shared) { > + err = gpio_request(info->reset_gpio, "bt_reset"); err = devm_gpio_request_one(&pdev->dev, info->reset_gpio, GPIOF_OUT_INIT_LOW, "bt_reset"); > + if (err < 0) { > + dev_err(&pdev->dev, "Cannot get GPIO line %d\n", > + info->reset_gpio); > + goto cleanup_setup; > + } > + } > + > + err = gpio_request(info->bt_wakeup_gpio, "bt_wakeup"); err = devm_gpio_request_one(&pdev->dev, info->bt_wakeup_gpio, GPIOF_OUT_INIT_LOW, "bt_wakeup"); > + if (err < 0) { > + dev_err(info->dev, "Cannot get GPIO line 0x%d", > + info->bt_wakeup_gpio); > + if (!info->reset_gpio_shared) > + gpio_free(info->reset_gpio); > + goto cleanup_setup; > + } > + > + err = gpio_request(info->host_wakeup_gpio, "host_wakeup"); err = devm_gpio_request_one(&pdev->dev, info->host_wakeup_gpio, GPIOF_DIR_IN, "host_wakeup"); > + if (err < 0) { > + dev_err(info->dev, "Cannot get GPIO line %d", > + info->host_wakeup_gpio); > + if (!info->reset_gpio_shared) > + gpio_free(info->reset_gpio); > + gpio_free(info->bt_wakeup_gpio); > + goto cleanup_setup; > + } > + > + gpio_direction_output(info->reset_gpio, 0); > + gpio_direction_output(info->bt_wakeup_gpio, 0); > + gpio_direction_input(info->host_wakeup_gpio); You can remove these when you use the _request_one gpio_request methods. > + info->irq = bt_plat_data->uart_irq; > + info->uart_base = ioremap(bt_plat_data->uart_base, SZ_2K); info->uart_base = devm_ioremap(&pdev->dev, bt_plat_data->uart_base, SZ_2K); > + info->uart_iclk = clk_get(NULL, bt_plat_data->uart_iclk); > + info->uart_fclk = clk_get(NULL, bt_plat_data->uart_fclk); devm_clk_get(...) > + err = request_irq(info->irq, hci_h4p_interrupt, IRQF_DISABLED, "hci_h4p", > + info); devm_request_irq(...) > + if (err < 0) { > + dev_err(info->dev, "hci_h4p: unable to get IRQ %d\n", info->irq); > + goto cleanup; > + } > + > + err = request_irq(gpio_to_irq(info->host_wakeup_gpio), > + hci_h4p_wakeup_interrupt, IRQF_TRIGGER_FALLING | > + IRQF_TRIGGER_RISING | IRQF_DISABLED, > + "hci_h4p_wkup", info); devm_request_irq(...) > + if (err < 0) { > + dev_err(info->dev, "hci_h4p: unable to get wakeup IRQ %d\n", > + gpio_to_irq(info->host_wakeup_gpio)); > + free_irq(info->irq, info); > + goto cleanup; > + } > + > + err = irq_set_irq_wake(gpio_to_irq(info->host_wakeup_gpio), 1); > + if (err < 0) { > + dev_err(info->dev, "hci_h4p: unable to set wakeup for IRQ %d\n", > + gpio_to_irq(info->host_wakeup_gpio)); > + free_irq(info->irq, info); > + free_irq(gpio_to_irq(info->host_wakeup_gpio), info); > + goto cleanup; > + } > + > + init_timer_deferrable(&info->lazy_release); > + info->lazy_release.function = hci_h4p_lazy_clock_release; > + info->lazy_release.data = (unsigned long)info; > + hci_h4p_set_clk(info, &info->tx_clocks_en, 1); > + err = hci_h4p_reset_uart(info); > + if (err < 0) > + goto cleanup_irq; > + gpio_set_value(info->reset_gpio, 0); > + hci_h4p_set_clk(info, &info->tx_clocks_en, 0); > + > + platform_set_drvdata(pdev, info); > + > + if (hci_h4p_register_hdev(info) < 0) { > + dev_err(info->dev, "failed to register hci_h4p hci device\n"); > + goto cleanup_irq; > + } > + > + return 0; > + > +cleanup_irq: > + free_irq(info->irq, (void *)info); > + free_irq(gpio_to_irq(info->host_wakeup_gpio), info); > +cleanup: > + gpio_set_value(info->reset_gpio, 0); > + if (!info->reset_gpio_shared) > + gpio_free(info->reset_gpio); > + gpio_free(info->bt_wakeup_gpio); > + gpio_free(info->host_wakeup_gpio); > +cleanup_setup: > + kfree(info); > + return err; > +} This can be removed after the conversion to devm_ methods. > [...] > > +static int __init hci_h4p_init(void) > +{ > + int err = 0; > + > + /* Register the driver with LDM */ > + err = platform_driver_register(&hci_h4p_driver); > + if (err < 0) > + printk(KERN_WARNING "failed to register hci_h4p driver\n"); > + > + return err; > +} > + > +static void __exit hci_h4p_exit(void) > +{ > + platform_driver_unregister(&hci_h4p_driver); > +} > > +module_init(hci_h4p_init); > +module_exit(hci_h4p_exit); module_platform_driver(hci_h4p_driver); -- Sebastian
Attachment:
signature.asc
Description: Digital signature