linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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.

      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).