static int sirf_probe(struct serdev_device *serdev) { struct device *dev = &serdev->dev; struct gnss_device *gdev; struct sirf_data *data; int ret; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; gdev = gnss_allocate_device(dev); if (!gdev) return -ENOMEM; gdev->type = GNSS_TYPE_SIRF; gdev->ops = &sirf_gnss_ops; gnss_set_drvdata(gdev, data); data->serdev = serdev; data->gdev = gdev; init_waitqueue_head(&data->power_wait); serdev_device_set_drvdata(serdev, data); serdev_device_set_client_ops(serdev, &sirf_serdev_ops); ret = sirf_parse_dt(serdev); if (ret) goto err_put_device; data->vcc = devm_regulator_get(dev, "vcc"); if (IS_ERR(data->vcc)) { ret = PTR_ERR(data->vcc); goto err_put_device; } data->on_off = devm_gpiod_get_optional(dev, "sirf,onoff", GPIOD_OUT_LOW); if (IS_ERR(data->on_off)) goto err_put_device; if (data->on_off) { data->wakeup = devm_gpiod_get_optional(dev, "sirf,wakeup", GPIOD_IN); if (IS_ERR(data->wakeup)) goto err_put_device; /* * Configurations where WAKEUP has been left not connected, * are currently not supported. */ if (!data->wakeup) { dev_err(dev, "no wakeup gpio specified\n"); ret = -ENODEV; goto err_put_device; } } if (data->wakeup) { ret = gpiod_to_irq(data->wakeup); if (ret < 0) goto err_put_device; data->irq = ret; ret = devm_request_threaded_irq(dev, data->irq, NULL, sirf_wakeup_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "wakeup", data); if (ret) goto err_put_device; } if (data->on_off) { ret = regulator_enable(data->vcc); if (ret) goto err_put_device; /* Wait for chip to boot into hibernate mode */ msleep(SIRF_BOOT_DELAY); } if (IS_ENABLED(CONFIG_PM)) { pm_runtime_set_suspended(dev); /* clear runtime_error flag */ pm_runtime_enable(dev); } else { ret = sirf_runtime_resume(dev); if (ret < 0) goto err_disable_vcc; } ret = gnss_register_device(gdev); if (ret) goto err_disable_rpm; return 0; err_disable_rpm: if (IS_ENABLED(CONFIG_PM)) pm_runtime_disable(dev); else sirf_runtime_suspend(dev); err_disable_vcc: if (data->on_off) regulator_disable(data->vcc); err_put_device: gnss_put_device(data->gdev); return ret; }
int hci_uart_register_device(struct hci_uart *hu, const struct hci_uart_proto *p) { int err; struct hci_dev *hdev; BT_DBG(""); serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops); err = p->open(hu); if (err) return err; hu->proto = p; set_bit(HCI_UART_PROTO_READY, &hu->flags); /* Initialize and register HCI device */ hdev = hci_alloc_dev(); if (!hdev) { BT_ERR("Can't allocate HCI device"); err = -ENOMEM; goto err_alloc; } hu->hdev = hdev; hdev->bus = HCI_UART; hci_set_drvdata(hdev, hu); INIT_WORK(&hu->write_work, hci_uart_write_work); /* Only when vendor specific setup callback is provided, consider * the manufacturer information valid. This avoids filling in the * value for Ericsson when nothing is specified. */ if (hu->proto->setup) hdev->manufacturer = hu->proto->manufacturer; hdev->open = hci_uart_open; hdev->close = hci_uart_close; hdev->flush = hci_uart_flush; hdev->send = hci_uart_send_frame; hdev->setup = hci_uart_setup; SET_HCIDEV_DEV(hdev, &hu->serdev->dev); if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags)) set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks); if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags)) set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) hdev->dev_type = HCI_AMP; else hdev->dev_type = HCI_PRIMARY; if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) return 0; if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); err = -ENODEV; goto err_register; } set_bit(HCI_UART_REGISTERED, &hu->flags); return 0; err_register: hci_free_dev(hdev); err_alloc: clear_bit(HCI_UART_PROTO_READY, &hu->flags); p->close(hu); return err; }