static int nokia_bluetooth_serdev_probe(struct serdev_device *serdev) { struct device *dev = &serdev->dev; struct nokia_bt_dev *btdev; struct clk *sysclk; int err = 0; btdev = devm_kzalloc(dev, sizeof(*btdev), GFP_KERNEL); if (!btdev) return -ENOMEM; btdev->hu.serdev = btdev->serdev = serdev; serdev_device_set_drvdata(serdev, btdev); btdev->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(btdev->reset)) { err = PTR_ERR(btdev->reset); dev_err(dev, "could not get reset gpio: %d", err); return err; } btdev->wakeup_host = devm_gpiod_get(dev, "host-wakeup", GPIOD_IN); if (IS_ERR(btdev->wakeup_host)) { err = PTR_ERR(btdev->wakeup_host); dev_err(dev, "could not get host wakeup gpio: %d", err); return err; } btdev->wake_irq = gpiod_to_irq(btdev->wakeup_host); err = devm_request_threaded_irq(dev, btdev->wake_irq, NULL, wakeup_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "wakeup", btdev); if (err) { dev_err(dev, "could request wakeup irq: %d", err); return err; } btdev->wakeup_bt = devm_gpiod_get(dev, "bluetooth-wakeup", GPIOD_OUT_LOW); if (IS_ERR(btdev->wakeup_bt)) { err = PTR_ERR(btdev->wakeup_bt); dev_err(dev, "could not get BT wakeup gpio: %d", err); return err; } sysclk = devm_clk_get(dev, "sysclk"); if (IS_ERR(sysclk)) { err = PTR_ERR(sysclk); dev_err(dev, "could not get sysclk: %d", err); return err; } clk_prepare_enable(sysclk); btdev->sysclk_speed = clk_get_rate(sysclk); clk_disable_unprepare(sysclk); skb_queue_head_init(&btdev->txq); btdev->hu.priv = btdev; btdev->hu.alignment = 2; /* Nokia H4+ is word aligned */ err = hci_uart_register_device(&btdev->hu, &nokia_proto); if (err) { dev_err(dev, "could not register bluetooth uart: %d", err); return err; } return 0; }
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; }
static int qca_serdev_probe(struct serdev_device *serdev) { struct qca_serdev *qcadev; const struct qca_vreg_data *data; int err; qcadev = devm_kzalloc(&serdev->dev, sizeof(*qcadev), GFP_KERNEL); if (!qcadev) return -ENOMEM; qcadev->serdev_hu.serdev = serdev; data = of_device_get_match_data(&serdev->dev); serdev_device_set_drvdata(serdev, qcadev); if (data && data->soc_type == QCA_WCN3990) { qcadev->btsoc_type = QCA_WCN3990; qcadev->bt_power = devm_kzalloc(&serdev->dev, sizeof(struct qca_power), GFP_KERNEL); if (!qcadev->bt_power) return -ENOMEM; qcadev->bt_power->dev = &serdev->dev; qcadev->bt_power->vreg_data = data; err = qca_init_regulators(qcadev->bt_power, data->vregs, data->num_vregs); if (err) { BT_ERR("Failed to init regulators:%d", err); goto out; } qcadev->bt_power->vregs_on = false; device_property_read_u32(&serdev->dev, "max-speed", &qcadev->oper_speed); if (!qcadev->oper_speed) BT_DBG("UART will pick default operating speed"); err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); if (err) { BT_ERR("wcn3990 serdev registration failed"); goto out; } } else { qcadev->btsoc_type = QCA_ROME; qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(qcadev->bt_en)) { dev_err(&serdev->dev, "failed to acquire enable gpio\n"); return PTR_ERR(qcadev->bt_en); } qcadev->susclk = devm_clk_get(&serdev->dev, NULL); if (IS_ERR(qcadev->susclk)) { dev_err(&serdev->dev, "failed to acquire clk\n"); return PTR_ERR(qcadev->susclk); } err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ); if (err) return err; err = clk_prepare_enable(qcadev->susclk); if (err) return err; err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); if (err) clk_disable_unprepare(qcadev->susclk); } out: return err; }