From: Balakrishna Godavarthi <bgodavar@codeaurora.org>
To: Matthias Kaehlcke <mka@chromium.org>
Cc: marcel@holtmann.org, johan.hedberg@gmail.com,
linux-bluetooth@vger.kernel.org, rtatiya@codeaurora.org,
hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org
Subject: Re: [PATCH v5 3/3] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth chip wcn3990.
Date: Wed, 23 May 2018 17:47:00 +0530 [thread overview]
Message-ID: <8b8cc08dbef6cbbc2b5522330e4d9690@codeaurora.org> (raw)
In-Reply-To: <20180511212520.GM19594@google.com>
Hi Matthias,
please find my comment inline.
On 2018-05-12 02:55, Matthias Kaehlcke wrote:
> Hi Bala,
>
> On Fri, May 11, 2018 at 05:51:03PM +0530, Balakrishna Godavarthi wrote:
>> Add support to set voltage/current of various regulators
>> to power up/down Bluetooth chip wcn3990.
>> Add support to read baudrate from dts.
>>
>> Signed-off-by: Balakrishna Godavarthi <bgodavar@codeaurora.org>
>> ---
>
> Please include a change log also in the individual patches, not just
> in the cover letter. In a revision after many comments it may be
> sufficient to say "addressed <reviewers> comments", if the number if
> changes is limited it is preferable to briefly list the individual
> changes.
>
[Bala]: will add from next patch set.
>> drivers/bluetooth/btqca.h | 6 +
>> drivers/bluetooth/hci_qca.c | 547
>> ++++++++++++++++++++++++++++++++++++++------
>> 2 files changed, 480 insertions(+), 73 deletions(-)
>>
>> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
>> index 2a7366b..8e2142a 100644
>> --- a/drivers/bluetooth/btqca.h
>> +++ b/drivers/bluetooth/btqca.h
>> @@ -37,6 +37,9 @@
>> #define EDL_TAG_ID_HCI (17)
>> #define EDL_TAG_ID_DEEP_SLEEP (27)
>>
>> +#define CHEROKEE_POWERON_PULSE (0xFC)
>> +#define CHEROKEE_POWEROFF_PULSE (0xC0)
>
> The parentheses are not needed around a literal. That they are used
> for the other values is IMO no good reason to introduce more of them.
> You might want to squeeze in a clean up patch that removes them for
> the other defines.
>
>> +int btqca_power_setup(bool on);
>> +int qca_btsoc_cleanup(struct hci_dev *hdev);
>
> nit: inconsistent naming.
>
> If maintainers and authors have no objections you might want to
> squeeze in a patch that renames everything to btqca. Just a suggestion
> though.
>
[bala]: changed the name of function to qca_power_setup
>> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
>> index f05382b..71f9591 100644
>> --- a/drivers/bluetooth/hci_qca.c
>> +++ b/drivers/bluetooth/hci_qca.c
>> @@ -5,7 +5,7 @@
>> * protocol extension to H4.
>> *
>> * Copyright (C) 2007 Texas Instruments, Inc.
>> - * Copyright (c) 2010, 2012 The Linux Foundation. All rights
>> reserved.
>> + * Copyright (c) 2010, 2012, 2018 The Linux Foundation. All rights
>> reserved.
>> *
>> * Acknowledgements:
>> * This file is based on hci_ll.c, which was...
>> @@ -35,6 +35,11 @@
>> #include <linux/mod_devicetable.h>
>> #include <linux/module.h>
>> #include <linux/serdev.h>
>> +#include <linux/delay.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/of_device.h>
>> +#include <linux/device.h>
>
> As I mentioned on v4, the includes should be in alphabetical order.
>
[Bala]: some thing like this?
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/serdev.h>
>> +enum btqca_soc_t {
>
> nit: Again, inconsistent naming, some functions/structs are called
> qca_... other btqca_... Personally I prefer btqca_ to avoid clashes.
>
[Bala]: will append qca_.* for the function and structure which are
newly added. to aling with already existing functions and strcutures
so btqca_soc_t will be qca_soc_type.
let me know your comments on this.
>> +/*
>> + * voltage regulator information required for configuring the
>> + * QCA bluetooth chipset
>
> nit: Voltage, Bluetooth
>
[Bala]: will update
>> + */
>> +struct btqca_vreg {
>> + const char *name;
>> + unsigned int min_v;
>> + unsigned int max_v;
>> + unsigned int load_ua;
>> +};
>
> nit: consider min_uV, max_uV, load_uA (as in the regulator framework).
>
[Bala]: will update
>> +
>> +struct btqca_vreg_data {
>> + enum btqca_soc_t soc_type;
>> + struct btqca_vreg *vregs;
>> + size_t num_vregs;
>> +};
>> +
>> +/*
>> + * Platform data for the QCA bluetooth power driver.
>
> nit: Bluetooth
>
[Bala]: will update
>> +static int qca_send_vendor_cmd(struct hci_dev *hdev, u8 cmd)
>> +{
>> + struct hci_uart *hu = hci_get_drvdata(hdev);
>> + struct qca_data *qca = hu->priv;
>> + struct sk_buff *skb;
>> +
>> + BT_DBG("%s:sending command %02x to SoC", hdev->name, cmd);
>
> bt_dev_dbg()
>
[Bala]: will update
>> +
>> + skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
>> + if (!skb) {
>> + BT_ERR("Failed to allocate memory for skb packet");
>
> bt_dev_err()
>
[Bala]: will update
>> + /* Wait for 100 us for soc to settle down */
>
> nit: uS, SoC
>
[Bala]: will update
>> +static int qca_serdev_open(struct hci_uart *hu)
>> +{
>> + int ret = 0;
>> +
>> + if (hu->serdev) {
>> + serdev_device_open(hu->serdev);
>> + } else {
>> + bt_dev_err(hu->hdev, "open operation not supported");
>> + ret = 1;
>> + }
>> +
>> + return ret;
>> +}
>
> From v4:
>
>> > Check return value.
>> [Bala]: as we are not checking in qca_open, the return in this
>> function is to know the serdev function availability.
>
> Sorry, your comment didn't really clarify things for me. The function
> is called from qca_setup() apparently with the intention to open the
> serial port, not to check if the function is available. If the serial
> port can't be opened for whatever reason the function should return an
> error (typically a negative value).
>
> Also the error message is misleading, the underlying problem is not
> that the open operations is not supported, but that no serdev device
> is associated with the hci_uart. Actually it seems this could never
> happen:
>
> In qca_serdev_probe():
>
> qcadev->serdev_hu.serdev = serdev;
>
> And qca_serdev_open() is only called from qca_setup(). Basically the
> first thing qca_setup() does is:
>
> qcadev = serdev_device_get_drvdata(hu->serdev);
>
> Thus if hu->serdev is NULL qca_setup() will crash shortly after:
>
> switch (qcadev->btsoc_type) {
>
> I think we can get rid of qca_serdev_open/close() and just call
> directly serdev_device_open().
>
[Bala]: yes your correct. will call the serdev_.* close and open from
qca_setup()
Do we really need to check hu->serdev == NULL in qca_setup?
>> +int qca_btsoc_cleanup(struct hci_dev *hdev)
>> +{
>> + struct hci_uart *hu = hci_get_drvdata(hdev);
>> +
>> + /* change host baud rate before sending power off command */
>> + host_set_baudrate(hu, 2400);
>> + /* send 0xC0 command to btsoc before turning off regulators */
>> + qca_send_vendor_cmd(hdev, CHEROKEE_POWEROFF_PULSE);
>
> The comment doesn't provide any useful information. From the code it's
> evident that a CHEROKEE_POWEROFF_PULSE is sent, if anybody is
> interested in the hex code they can look up the definition of
> CHEROKEE_POWEROFF_PULSE.
>
[Bala]: will remove the comment.
>> + /* turn off btsoc */
>> + return btqca_power_setup(false);
>
> This comment laso doesn't provide any value.
>
[Bala]: will remove
>> +static int qca_serdev_close(struct hci_uart *hu)
>> +{
>> + int ret = 0;
>> +
>> + if (hu->serdev) {
>> + serdev_device_close(hu->serdev);
>> + } else {
>> + bt_dev_err(hu->hdev, "close operation not supported");
>> + ret = 1;
>> + }
>> +
>> + return ret;
>> +}
>
> Same commants as for open().
>
> Preferably keep open() and close() together, without squeezing the
> cleanup function in between.
>
[Bala]: will remove these functions and directly call them from serdev_*
close or open from qca_setup()
>> static int qca_setup(struct hci_uart *hu)
>> {
>> struct hci_dev *hdev = hu->hdev;
>> struct qca_data *qca = hu->priv;
>> + struct qca_serdev *qcadev;
>> unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200;
>> int ret;
>> + int soc_ver;
>> +
>> + qcadev = serdev_device_get_drvdata(hu->serdev);
>> +
>> + switch (qcadev->btsoc_type) {
>> + case BTQCA_CHEROKEE:
>
> I still thinks this is has a lot of common code with the default/Rome
> case, but let's first clarify and possibly improve a few things.
>
[Bala]: actually i haven't edited any part of code for ROME i.e. default
case expect the indentation.
Yes we have little common code, but if i do any changes to ROME
code i.e. default case,i don't have ROME Chip to test.
i am little bit worried if some thing in ROME got broken with my
change. that will create problem.
>> + bt_dev_info(hdev, "setting up wcn3990");
>> + /* Patch downloading has to be done without IBS mode */
>> + clear_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags);
>> + /* Setup initial baudrate */
>> + speed = 0;
>> + if (hu->init_speed)
>> + speed = hu->init_speed;
>> + else if (hu->proto->init_speed)
>> + speed = hu->proto->init_speed;
>
> This pattern is repeated a several times for initial and operating
> speeds. Helper functions like btqca_get_init_speed() and
> btqca_get_oper_speed() would make the code more readable and compact.
[Bala]: will create a new functions.
>
>> +
>> + if (speed) {
>> + host_set_baudrate(hu, speed);
>> + } else {
>> + bt_dev_err(hdev, "initial speed %u", speed);
>> + return -1;
>> + }
>
> Note: Up to here Rome and Cherokee do exactly the same.
>
>> + /* disable flow control, as chip is still not turned on */
>> + hci_uart_set_flow_control(hu, true);
>> + /* send 0xFC command to btsoc */
>> + ret = qca_send_vendor_cmd(hdev, CHEROKEE_POWERON_PULSE);
>
> Delete useless comment.
>
[Bala]: will update.
>> + if (ret) {
>> + bt_dev_err(hdev, "Failed to send power on command");
>> + return ret;
>> + }
>> +
>> + /* close serial port */
>> + ret = qca_serdev_close(hu);
>> + if (ret)
>> + return ret;
>> + /* open serial port */
>> + ret = qca_serdev_open(hu);
>> + if (ret)
>> + return ret;
>
> The comments are pointless, it is evident from the code that the
> serial port is opened/closed. Much more interesting would be to
> explain why it is necessary to close and re-open the port.
>
[Bala]: will update.
>> - bt_dev_info(hdev, "ROME setup");
>> + /* Setup initial baudrate */
>> + speed = 0;
>> + if (hu->init_speed)
>> + speed = hu->init_speed;
>> + else if (hu->proto->init_speed)
>> + speed = hu->proto->init_speed;
>> + if (speed) {
>> + host_set_baudrate(hu, speed);
>> + } else {
>> + BT_ERR("%s:initial speed %u", hdev->name, speed);
>
> bt_dev_err()
>
>> + return -1;
>> + }
>
> The initial baudrate has already been set above, is it necessary to
> configure it again because the port was closed?
>
[Bala]: for safer side we setting init speed again after close and open.
> This baudrate code is extremely noisy. Besides introducing the helper
> functions mentioned above you could log the error message in
> host_set_baudrate() or even have an addtional wrapper that determines
> and sets the baudrate. The latter would reduce the above to:
>
> if (xyz_set_baudrate(hu, INIT_RATE))
> return -1;
>
> And that multiple times.
>
[Bala]: will create wrapper to handle baudrate setting.
>> + /* clear flow control */
>> + hci_uart_set_flow_control(hu, true);
>> + /* set operating speed */
>
> Note: Starting from here the code for Cherokee and Rome is essentially
> the same, except for enabling flow control.
>
> If you prefer keep the somewhat redundant code paths in the next
> revision, but please consider the improvements I suggested. With less
> noisy code it will be easier to determine if it is reasonable to join
> the two code paths.
>
[Bala]: will try to use common code.
>> +static int btqca_enable_regulators(int i, struct btqca_vreg *vregs)
>
> The common convention is to pass first the structure a function acts
> on, then other parameters. Use a more expressive name for the
> number of regulators, like 'num_regs' or 'nregs'.
>
>
[Bala]:will update.
>> +{
>> + int ret = 0;
>
> Initialization is not necessary, ret is assigned in the next line.
>
[Bala]:will remove.
>> +static void btqca_disable_regulators(int reg_nu, struct btqca_vreg
>> *vregs)
>> +{
>
> Same as for the enable function. Please use the same name for the
> argument with the number of regulators on both functions, personally I
> don't think 'reg_nu' is a great choice, but that's just my opinion ;-)
>
[Bala]: in btqca_enable_regulator() we are enabling one regulator. i.e.
this is called by btqc_power_setup() function.
in btqca_disable_regulator() we are disabling all the
regulators.
i think it require a checkup. will update both in the same way.
>> +int btqca_power_setup(bool on)
>> +{
>> + int ret = 0;
>> + int i;
>> + struct btqca_vreg *vregs;
>> +
>> + if (!qca || !qca->vreg_data || !qca->vreg_bulk)
>> + return -EINVAL;
>> + vregs = qca->vreg_data->vregs;
>> +
>> + BT_DBG("on: %d", on);
>> + /* turn on if regualtors are off */
>
> regulators
>
> Consider dropping the comment, IMO the code speaks for itself.
>
[Bala]: will remove
>> + if (on == true && qca->vregs_on == false) {
>
> if (on && !qca->vreg_on) {
>
>> + qca->vregs_on = true;
>
> Typically you'd change the variable after having performed the
> operation with success.
>
[Bala]: will update.
>> + for (i = 0; i < qca->vreg_data->num_vregs; i++) {
>> + ret = btqca_enable_regulators(i, vregs);
>> + if (ret)
>> + break;
>> + }
>> + } else if (on == false && qca->vregs_on == true) {
>
> if (!on && qca->vreg_on) {
>
>> + qca->vregs_on = false;
>
> Better done after having disabled the regulators.
[Bala]: will update.
>
>> + /* turn off regulator in reverse order */
>> + btqca_disable_regulators(qca->vreg_data->num_vregs, vregs);
>> + }
>> +
>> + /* regulators failed */
>> + if (ret) {
>> + qca->vregs_on = false;
>> + BT_ERR("failed to enable regulator:%s", vregs[i].name);
>> + /* turn off regulators which are enabled */
>> + btqca_disable_regulators(i, vregs);
>> + }
>
> Why not do this directly when the problem is detected? The code also
> relies on 'ret' only being set in the 'on' path. Which isn't intuitive
> for the reader and *might* change in the future.
>
[Bala]: will copy the same in on block.
>> +
>> + return ret;
>> +}
>> +
>> +static int init_regulators(struct btqca_power *qca,
>
> Preferably keep use the same prefix (btqca_) consistently, unless
> names become awfully long or otherwise unreadable.
>
[Bala]: will rename as qca_init_regulators() and also changes functions
starting with btqca_.* to qca_.*
>> static int qca_serdev_probe(struct serdev_device *serdev)
>> {
>> struct qca_serdev *qcadev;
>> const struct btqca_vreg_data *data;
>> int err = 0;
>
> unnecessary initialization
[Bala]: will remove.
>
>> /* set voltage regulator status as false */
>> qca->vregs_on = false;
>
> delete pointless comment
[Bala]: will remove
>
>> /* get operating speed */
>> device_property_read_u32(&serdev->dev, "oper-speed",
>
> comment doesn't add much value
>
[Bala]: will remove
>> + err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
>> + if (err) {
>> + BT_ERR("wcn3990 serdev registration failed");
>> + kfree(qca);
>> + goto out;
>
> disable regulators
[Bala]: we didn't enable regulators yet. we just get the regulators
address. explicitly disabling the regulators is not safe.
>
> Thanks
>
> Matthias
--
Regards
Balakrishna.
prev parent reply other threads:[~2018-05-23 12:17 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-11 12:21 [PATCH v5 0/3] Enable Bluetooth functionality for WCN3990 Balakrishna Godavarthi
2018-05-11 12:21 ` [PATCH v5 1/3] dt-bindings: net: bluetooth: Add device tree bindings for QTI chip wcn3990 Balakrishna Godavarthi
2018-05-11 18:28 ` Marcel Holtmann
2018-05-18 14:36 ` Balakrishna Godavarthi
2018-05-11 12:21 ` [PATCH v5 2/3] Bluetooth: btqca: Add wcn3990 firmware download support Balakrishna Godavarthi
2018-05-11 17:40 ` Matthias Kaehlcke
2018-05-18 14:34 ` Balakrishna Godavarthi
2018-05-25 23:54 ` Matthias Kaehlcke
2018-05-11 12:21 ` [PATCH v5 3/3] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth chip wcn3990 Balakrishna Godavarthi
2018-05-11 20:10 ` Marcel Holtmann
2018-05-18 14:42 ` Balakrishna Godavarthi
2018-05-11 21:25 ` Matthias Kaehlcke
2018-05-23 12:17 ` Balakrishna Godavarthi [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8b8cc08dbef6cbbc2b5522330e4d9690@codeaurora.org \
--to=bgodavar@codeaurora.org \
--cc=hemantg@codeaurora.org \
--cc=johan.hedberg@gmail.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-bluetooth@vger.kernel.org \
--cc=marcel@holtmann.org \
--cc=mka@chromium.org \
--cc=rtatiya@codeaurora.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).