All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: Sebastian Reichel <sre@kernel.org>
Cc: Phil Reid <preid@electromag.com.au>,
	Arnd Bergmann <arnd@arndb.de>, YH Huang <yh.huang@mediatek.com>,
	Joshua Clayton <stillcompiling@gmail.com>,
	linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] power: supply: sbs-battery: simplify DT parsing
Date: Tue,  6 Sep 2016 15:16:33 +0200	[thread overview]
Message-ID: <20160906131643.1930011-1-arnd@arndb.de> (raw)

After the change to use the gpio descriptor interface, we get a warning if
-Wmaybe-uninitialized is added back to the build flags (it is currently
disabled:

drivers/power/supply/sbs-battery.c: In function 'sbs_probe':
drivers/power/supply/sbs-battery.c:760:28: error: 'pdata' may be used uninitialized in this function [-Werror=maybe-uninitialized]

The problem is that if neither the DT properties nor a platform_data
pointer are provided, the chip->pdata pointer gets set to an uninitialized
value.

Looking at the code some more, I found that the sbs_of_populate_pdata
function is more complex than necessary and has confusing calling
conventions of possibly returning a valid pointer, a NULL pointer
or an ERR_PTR pointer (in addition to the uninitialized pointer).

To fix all of that, this gets rid of the chip->pdata pointer and
simply moves the two integers into the sbs_info structure. This
makes it much clearer from reading sbs_probe() what the precedence
of the three possible values are (pdata, DT, hardcoded defaults)
and completely avoids the #ifdef CONFIG_OF guards as
of_property_read_u32() gets replaced with a compile-time stub
when that is disabled, and returns an error if passed a NULL of_node
pointer.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Fixes: 3b5dd3a49496 ("power: supply: sbs-battery: Use gpio_desc and sleeping calls for battery detect")
---
 drivers/power/supply/sbs-battery.c | 98 ++++++++++++--------------------------
 1 file changed, 31 insertions(+), 67 deletions(-)

diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
index 8b4c6a8681b0..248a5dd75e22 100644
--- a/drivers/power/supply/sbs-battery.c
+++ b/drivers/power/supply/sbs-battery.c
@@ -169,6 +169,8 @@ struct sbs_info {
 	bool				enable_detection;
 	int				last_state;
 	int				poll_time;
+	int				i2c_retry_count;
+	int				poll_retry_count;
 	struct delayed_work		work;
 	int				ignore_changes;
 };
@@ -184,7 +186,7 @@ static int sbs_read_word_data(struct i2c_client *client, u8 address)
 	int retries = 1;
 
 	if (chip->pdata)
-		retries = max(chip->pdata->i2c_retry_count + 1, 1);
+		retries = max(chip->i2c_retry_count + 1, 1);
 
 	while (retries > 0) {
 		ret = i2c_smbus_read_word_data(client, address);
@@ -212,8 +214,8 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
 	u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
 
 	if (chip->pdata) {
-		retries_length = max(chip->pdata->i2c_retry_count + 1, 1);
-		retries_block = max(chip->pdata->i2c_retry_count + 1, 1);
+		retries_length = max(chip->i2c_retry_count + 1, 1);
+		retries_block = max(chip->i2c_retry_count + 1, 1);
 	}
 
 	/* Adapter needs to support these two functions */
@@ -279,7 +281,7 @@ static int sbs_write_word_data(struct i2c_client *client, u8 address,
 	int retries = 1;
 
 	if (chip->pdata)
-		retries = max(chip->pdata->i2c_retry_count + 1, 1);
+		retries = max(chip->i2c_retry_count + 1, 1);
 
 	while (retries > 0) {
 		ret = i2c_smbus_write_word_data(client, address,
@@ -741,61 +743,6 @@ static void sbs_delayed_work(struct work_struct *work)
 	}
 }
 
-#if defined(CONFIG_OF)
-
-#include <linux/of_device.h>
-#include <linux/of_gpio.h>
-
-static const struct of_device_id sbs_dt_ids[] = {
-	{ .compatible = "sbs,sbs-battery" },
-	{ .compatible = "ti,bq20z75" },
-	{ }
-};
-MODULE_DEVICE_TABLE(of, sbs_dt_ids);
-
-static struct sbs_platform_data *sbs_of_populate_pdata(struct sbs_info *chip)
-{
-	struct i2c_client *client = chip->client;
-	struct device_node *of_node = client->dev.of_node;
-	struct sbs_platform_data *pdata;
-	int rc;
-	u32 prop;
-
-	/* verify this driver matches this device */
-	if (!of_node)
-		return NULL;
-
-	/* first make sure at least one property is set, otherwise
-	 * it won't change behavior from running without pdata.
-	 */
-	if (!of_get_property(of_node, "sbs,i2c-retry-count", NULL) &&
-	    !of_get_property(of_node, "sbs,poll-retry-count", NULL))
-		goto of_out;
-
-	pdata = devm_kzalloc(&client->dev, sizeof(struct sbs_platform_data),
-				GFP_KERNEL);
-	if (!pdata)
-		return ERR_PTR(-ENOMEM);
-
-	rc = of_property_read_u32(of_node, "sbs,i2c-retry-count", &prop);
-	if (!rc)
-		pdata->i2c_retry_count = prop;
-
-	rc = of_property_read_u32(of_node, "sbs,poll-retry-count", &prop);
-	if (!rc)
-		pdata->poll_retry_count = prop;
-
-of_out:
-	return pdata;
-}
-#else
-static struct sbs_platform_data *sbs_of_populate_pdata(
-	struct sbs_info *client)
-{
-	return ERR_PTR(-ENOSYS);
-}
-#endif
-
 static const struct power_supply_desc sbs_default_desc = {
 	.type = POWER_SUPPLY_TYPE_BATTERY,
 	.properties = sbs_properties,
@@ -838,13 +785,23 @@ static int sbs_probe(struct i2c_client *client,
 	chip->ignore_changes = 1;
 	chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
 
-	if (!pdata)
-		pdata = sbs_of_populate_pdata(chip);
-
-	if (IS_ERR(pdata))
-		return PTR_ERR(pdata);
-
-	chip->pdata = pdata;
+	/* use pdata if available, fall back to DT properties,
+	 * or hardcoded defaults if not
+	 */
+	rc = of_property_read_u32(client->dev.of_node, "sbs,i2c-retry-count",
+				  &chip->i2c_retry_count);
+	if (rc)
+		chip->i2c_retry_count = 1;
+
+	rc = of_property_read_u32(client->dev.of_node, "sbs,poll-retry-count",
+				  &chip->poll_retry_count);
+	if (rc)
+		chip->poll_retry_count = 0;
+
+	if (pdata) {
+		chip->poll_retry_count = pdata->poll_retry_count;
+		chip->i2c_retry_count  = pdata->i2c_retry_count;
+	}
 
 	chip->gpio_detect = devm_gpiod_get_optional(&client->dev,
 			"sbs,battery-detect", GPIOD_IN);
@@ -953,13 +910,20 @@ static const struct i2c_device_id sbs_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, sbs_id);
 
+static const struct of_device_id sbs_dt_ids[] = {
+	{ .compatible = "sbs,sbs-battery" },
+	{ .compatible = "ti,bq20z75" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sbs_dt_ids);
+
 static struct i2c_driver sbs_battery_driver = {
 	.probe		= sbs_probe,
 	.remove		= sbs_remove,
 	.id_table	= sbs_id,
 	.driver = {
 		.name	= "sbs-battery",
-		.of_match_table = of_match_ptr(sbs_dt_ids),
+		.of_match_table = sbs_dt_ids,
 		.pm	= SBS_PM_OPS,
 	},
 };
-- 
2.9.0

             reply	other threads:[~2016-09-06 13:16 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-06 13:16 Arnd Bergmann [this message]
2016-09-06 23:55 ` [PATCH] power: supply: sbs-battery: simplify DT parsing Sebastian Reichel
2016-09-07  7:58   ` Arnd Bergmann
2016-09-07 13:17     ` Sebastian Reichel
2016-09-19  9:20 ` Phil Reid

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=20160906131643.1930011-1-arnd@arndb.de \
    --to=arnd@arndb.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=preid@electromag.com.au \
    --cc=sre@kernel.org \
    --cc=stillcompiling@gmail.com \
    --cc=yh.huang@mediatek.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.