All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH leds 0/7] leds: pca963x cleanup
@ 2020-09-20  0:24 Marek Behún
  2020-09-20  0:24 ` [PATCH leds 1/7] leds: pca963x: cosmetic: use helper variables, better indentation Marek Behún
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:24 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

Hi Pavel,

this is a cleanup of pca963x LED driver, in spirit of previous
patches I sent recently.

This series should apply on your for-next.

Marek

Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>

Marek Behún (7):
  leds: pca963x: cosmetic: use helper variables, better indentation
  leds: pca963x: use devres LED registering function
  leds: pca963x: cosmetic: rename variables
  leds: pca963x: cosmetic: rename variables
  leds: pca963x: use flexible array
  leds: pca963x: register LEDs immediately after parsing, get rid of
    platdata
  leds: pca963x: use struct led_init_data when registering

 drivers/leds/leds-pca963x.c                | 399 +++++++++------------
 include/linux/platform_data/leds-pca963x.h |  35 --
 2 files changed, 168 insertions(+), 266 deletions(-)
 delete mode 100644 include/linux/platform_data/leds-pca963x.h


base-commit: a0e550dc351ab5fabe8ea86e45b974494a0a6bf8
-- 
2.26.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH leds 1/7] leds: pca963x: cosmetic: use helper variables, better indentation
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
@ 2020-09-20  0:24 ` Marek Behún
  2020-09-20  0:24 ` [PATCH leds 2/7] leds: pca963x: use devres LED registering function Marek Behún
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:24 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

Use helper variables: instead of writing &client->dev at many places,
write only dev. The same with pca963x->chip->chipdef,
pca963x->chip->client).

Use helper variable u8 val for i2c_smbus_write_byte_data, for better
indentation.

Indent better on various places.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>
---
 drivers/leds/leds-pca963x.c | 139 ++++++++++++++++++------------------
 1 file changed, 71 insertions(+), 68 deletions(-)

diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index d288acbc99c7c..c03871f92fecc 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -116,35 +116,38 @@ struct pca963x_led {
 };
 
 static int pca963x_brightness(struct pca963x_led *pca963x,
-			       enum led_brightness brightness)
+			      enum led_brightness brightness)
 {
-	u8 ledout_addr = pca963x->chip->chipdef->ledout_base
-		+ (pca963x->led_num / 4);
-	u8 ledout;
-	int shift = 2 * (pca963x->led_num % 4);
-	u8 mask = 0x3 << shift;
+	struct i2c_client *client = pca963x->chip->client;
+	struct pca963x_chipdef *chipdef = pca963x->chip->chipdef;
+	u8 ledout_addr, ledout, mask, val;
+	int shift;
 	int ret;
 
-	ledout = i2c_smbus_read_byte_data(pca963x->chip->client, ledout_addr);
+	ledout_addr = chipdef->ledout_base + (pca963x->led_num / 4);
+	shift = 2 * (pca963x->led_num % 4);
+	mask = 0x3 << shift;
+	ledout = i2c_smbus_read_byte_data(client, ledout_addr);
+
 	switch (brightness) {
 	case LED_FULL:
-		ret = i2c_smbus_write_byte_data(pca963x->chip->client,
-			ledout_addr,
-			(ledout & ~mask) | (PCA963X_LED_ON << shift));
+		val = (ledout & ~mask) | (PCA963X_LED_ON << shift);
+		ret = i2c_smbus_write_byte_data(client, ledout_addr, val);
 		break;
 	case LED_OFF:
-		ret = i2c_smbus_write_byte_data(pca963x->chip->client,
-			ledout_addr, ledout & ~mask);
+		val = ledout & ~mask;
+		ret = i2c_smbus_write_byte_data(client, ledout_addr, val);
 		break;
 	default:
-		ret = i2c_smbus_write_byte_data(pca963x->chip->client,
-			PCA963X_PWM_BASE + pca963x->led_num,
-			brightness);
+		ret = i2c_smbus_write_byte_data(client,
+						PCA963X_PWM_BASE +
+						pca963x->led_num,
+						brightness);
 		if (ret < 0)
 			return ret;
-		ret = i2c_smbus_write_byte_data(pca963x->chip->client,
-			ledout_addr,
-			(ledout & ~mask) | (PCA963X_LED_PWM << shift));
+
+		val = (ledout & ~mask) | (PCA963X_LED_PWM << shift);
+		ret = i2c_smbus_write_byte_data(client, ledout_addr, val);
 		break;
 	}
 
@@ -153,36 +156,40 @@ static int pca963x_brightness(struct pca963x_led *pca963x,
 
 static void pca963x_blink(struct pca963x_led *pca963x)
 {
-	u8 ledout_addr = pca963x->chip->chipdef->ledout_base +
-		(pca963x->led_num / 4);
-	u8 ledout;
-	u8 mode2 = i2c_smbus_read_byte_data(pca963x->chip->client,
-							PCA963X_MODE2);
-	int shift = 2 * (pca963x->led_num % 4);
-	u8 mask = 0x3 << shift;
+	struct i2c_client *client = pca963x->chip->client;
+	struct pca963x_chipdef *chipdef = pca963x->chip->chipdef;
+	u8 ledout_addr, ledout, mask, val, mode2;
+	int shift;
+
+	ledout_addr = chipdef->ledout_base + (pca963x->led_num / 4);
+	shift = 2 * (pca963x->led_num % 4);
+	mask = 0x3 << shift;
+	mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);
 
-	i2c_smbus_write_byte_data(pca963x->chip->client,
-			pca963x->chip->chipdef->grppwm,	pca963x->gdc);
+	i2c_smbus_write_byte_data(client, chipdef->grppwm, pca963x->gdc);
 
-	i2c_smbus_write_byte_data(pca963x->chip->client,
-			pca963x->chip->chipdef->grpfreq, pca963x->gfrq);
+	i2c_smbus_write_byte_data(client, chipdef->grpfreq, pca963x->gfrq);
 
 	if (!(mode2 & PCA963X_MODE2_DMBLNK))
-		i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
-			mode2 | PCA963X_MODE2_DMBLNK);
+		i2c_smbus_write_byte_data(client, PCA963X_MODE2,
+					  mode2 | PCA963X_MODE2_DMBLNK);
 
 	mutex_lock(&pca963x->chip->mutex);
-	ledout = i2c_smbus_read_byte_data(pca963x->chip->client, ledout_addr);
-	if ((ledout & mask) != (PCA963X_LED_GRP_PWM << shift))
-		i2c_smbus_write_byte_data(pca963x->chip->client, ledout_addr,
-			(ledout & ~mask) | (PCA963X_LED_GRP_PWM << shift));
+
+	ledout = i2c_smbus_read_byte_data(client, ledout_addr);
+	if ((ledout & mask) != (PCA963X_LED_GRP_PWM << shift)) {
+		val = (ledout & ~mask) | (PCA963X_LED_GRP_PWM << shift);
+		i2c_smbus_write_byte_data(client, ledout_addr, val);
+	}
+
 	mutex_unlock(&pca963x->chip->mutex);
 }
 
 static int pca963x_power_state(struct pca963x_led *pca963x)
 {
+	struct i2c_client *client = pca963x->chip->client;
 	unsigned long *leds_on = &pca963x->chip->leds_on;
-	unsigned long cached_leds = pca963x->chip->leds_on;
+	unsigned long cached_leds = *leds_on;
 
 	if (pca963x->led_cdev.brightness)
 		set_bit(pca963x->led_num, leds_on);
@@ -190,14 +197,14 @@ static int pca963x_power_state(struct pca963x_led *pca963x)
 		clear_bit(pca963x->led_num, leds_on);
 
 	if (!(*leds_on) != !cached_leds)
-		return i2c_smbus_write_byte_data(pca963x->chip->client,
-			PCA963X_MODE1, *leds_on ? 0 : BIT(4));
+		return i2c_smbus_write_byte_data(client, PCA963X_MODE1,
+						 *leds_on ? 0 : BIT(4));
 
 	return 0;
 }
 
 static int pca963x_led_set(struct led_classdev *led_cdev,
-	enum led_brightness value)
+			   enum led_brightness value)
 {
 	struct pca963x_led *pca963x;
 	int ret;
@@ -217,7 +224,7 @@ static int pca963x_led_set(struct led_classdev *led_cdev,
 }
 
 static unsigned int pca963x_period_scale(struct pca963x_led *pca963x,
-	unsigned int val)
+					 unsigned int val)
 {
 	unsigned int scaling = pca963x->chip->chipdef->scaling;
 
@@ -225,7 +232,7 @@ static unsigned int pca963x_period_scale(struct pca963x_led *pca963x,
 }
 
 static int pca963x_blink_set(struct led_classdev *led_cdev,
-		unsigned long *delay_on, unsigned long *delay_off)
+			     unsigned long *delay_on, unsigned long *delay_off)
 {
 	struct pca963x_led *pca963x;
 	unsigned long time_on, time_off, period;
@@ -278,23 +285,23 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
 }
 
 static struct pca963x_platform_data *
-pca963x_get_pdata(struct i2c_client *client, struct pca963x_chipdef *chip)
+pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chip)
 {
 	struct pca963x_platform_data *pdata;
 	struct led_info *pca963x_leds;
 	struct fwnode_handle *child;
 	int count;
 
-	count = device_get_child_node_count(&client->dev);
+	count = device_get_child_node_count(dev);
 	if (!count || count > chip->n_leds)
 		return ERR_PTR(-ENODEV);
 
-	pca963x_leds = devm_kcalloc(&client->dev,
-			chip->n_leds, sizeof(struct led_info), GFP_KERNEL);
+	pca963x_leds = devm_kcalloc(dev, chip->n_leds, sizeof(struct led_info),
+				    GFP_KERNEL);
 	if (!pca963x_leds)
 		return ERR_PTR(-ENOMEM);
 
-	device_for_each_child_node(&client->dev, child) {
+	device_for_each_child_node(dev, child) {
 		struct led_info led = {};
 		u32 reg;
 		int res;
@@ -312,8 +319,8 @@ pca963x_get_pdata(struct i2c_client *client, struct pca963x_chipdef *chip)
 
 		pca963x_leds[reg] = led;
 	}
-	pdata = devm_kzalloc(&client->dev,
-			     sizeof(struct pca963x_platform_data), GFP_KERNEL);
+	pdata = devm_kzalloc(dev, sizeof(struct pca963x_platform_data),
+			     GFP_KERNEL);
 	if (!pdata)
 		return ERR_PTR(-ENOMEM);
 
@@ -321,23 +328,23 @@ pca963x_get_pdata(struct i2c_client *client, struct pca963x_chipdef *chip)
 	pdata->leds.num_leds = chip->n_leds;
 
 	/* default to open-drain unless totem pole (push-pull) is specified */
-	if (device_property_read_bool(&client->dev, "nxp,totem-pole"))
+	if (device_property_read_bool(dev, "nxp,totem-pole"))
 		pdata->outdrv = PCA963X_TOTEM_POLE;
 	else
 		pdata->outdrv = PCA963X_OPEN_DRAIN;
 
 	/* default to software blinking unless hardware blinking is specified */
-	if (device_property_read_bool(&client->dev, "nxp,hw-blink"))
+	if (device_property_read_bool(dev, "nxp,hw-blink"))
 		pdata->blink_type = PCA963X_HW_BLINK;
 	else
 		pdata->blink_type = PCA963X_SW_BLINK;
 
-	if (device_property_read_u32(&client->dev, "nxp,period-scale",
+	if (device_property_read_u32(dev, "nxp,period-scale",
 				     &chip->scaling))
 		chip->scaling = 1000;
 
 	/* default to non-inverted output, unless inverted is specified */
-	if (device_property_read_bool(&client->dev, "nxp,inverted-out"))
+	if (device_property_read_bool(dev, "nxp,inverted-out"))
 		pdata->dir = PCA963X_INVERTED;
 	else
 		pdata->dir = PCA963X_NORMAL;
@@ -355,8 +362,9 @@ static const struct of_device_id of_pca963x_match[] = {
 MODULE_DEVICE_TABLE(of, of_pca963x_match);
 
 static int pca963x_probe(struct i2c_client *client,
-					const struct i2c_device_id *id)
+			 const struct i2c_device_id *id)
 {
+	struct device *dev = &client->dev;
 	struct pca963x *pca963x_chip;
 	struct pca963x_led *pca963x;
 	struct pca963x_platform_data *pdata;
@@ -364,29 +372,26 @@ static int pca963x_probe(struct i2c_client *client,
 	int i, err;
 
 	chip = &pca963x_chipdefs[id->driver_data];
-	pdata = dev_get_platdata(&client->dev);
+	pdata = dev_get_platdata(dev);
 
 	if (!pdata) {
-		pdata = pca963x_get_pdata(client, chip);
+		pdata = pca963x_get_pdata(dev, chip);
 		if (IS_ERR(pdata)) {
-			dev_warn(&client->dev, "could not parse configuration\n");
+			dev_warn(dev, "could not parse configuration\n");
 			pdata = NULL;
 		}
 	}
 
 	if (pdata && (pdata->leds.num_leds < 1 ||
-				 pdata->leds.num_leds > chip->n_leds)) {
-		dev_err(&client->dev, "board info must claim 1-%d LEDs",
-								chip->n_leds);
+		      pdata->leds.num_leds > chip->n_leds)) {
+		dev_err(dev, "board info must claim 1-%d LEDs", chip->n_leds);
 		return -EINVAL;
 	}
 
-	pca963x_chip = devm_kzalloc(&client->dev, sizeof(*pca963x_chip),
-								GFP_KERNEL);
+	pca963x_chip = devm_kzalloc(dev, sizeof(*pca963x_chip), GFP_KERNEL);
 	if (!pca963x_chip)
 		return -ENOMEM;
-	pca963x = devm_kcalloc(&client->dev, chip->n_leds, sizeof(*pca963x),
-								GFP_KERNEL);
+	pca963x = devm_kcalloc(dev, chip->n_leds, sizeof(*pca963x), GFP_KERNEL);
 	if (!pca963x)
 		return -ENOMEM;
 
@@ -427,7 +432,7 @@ static int pca963x_probe(struct i2c_client *client,
 		if (pdata && pdata->blink_type == PCA963X_HW_BLINK)
 			pca963x[i].led_cdev.blink_set = pca963x_blink_set;
 
-		err = led_classdev_register(&client->dev, &pca963x[i].led_cdev);
+		err = led_classdev_register(dev, &pca963x[i].led_cdev);
 		if (err < 0)
 			goto exit;
 	}
@@ -436,8 +441,7 @@ static int pca963x_probe(struct i2c_client *client,
 	i2c_smbus_write_byte_data(client, PCA963X_MODE1, BIT(4));
 
 	if (pdata) {
-		u8 mode2 = i2c_smbus_read_byte_data(pca963x->chip->client,
-						    PCA963X_MODE2);
+		u8 mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);
 		/* Configure output: open-drain or totem pole (push-pull) */
 		if (pdata->outdrv == PCA963X_OPEN_DRAIN)
 			mode2 &= ~PCA963X_MODE2_OUTDRV;
@@ -446,8 +450,7 @@ static int pca963x_probe(struct i2c_client *client,
 		/* Configure direction: normal or inverted */
 		if (pdata->dir == PCA963X_INVERTED)
 			mode2 |= PCA963X_MODE2_INVRT;
-		i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
-					  mode2);
+		i2c_smbus_write_byte_data(client, PCA963X_MODE2, mode2);
 	}
 
 	return 0;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH leds 2/7] leds: pca963x: use devres LED registering function
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
  2020-09-20  0:24 ` [PATCH leds 1/7] leds: pca963x: cosmetic: use helper variables, better indentation Marek Behún
@ 2020-09-20  0:24 ` Marek Behún
  2020-09-20  0:24 ` [PATCH leds 3/7] leds: pca963x: cosmetic: rename variables Marek Behún
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:24 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

By using devres version of LED registering function we can remove the
.remove method from this driver. The probe method also gets simpler.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>
---
 drivers/leds/leds-pca963x.c | 22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)

diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index c03871f92fecc..cbb3bf6c044f2 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -432,9 +432,9 @@ static int pca963x_probe(struct i2c_client *client,
 		if (pdata && pdata->blink_type == PCA963X_HW_BLINK)
 			pca963x[i].led_cdev.blink_set = pca963x_blink_set;
 
-		err = led_classdev_register(dev, &pca963x[i].led_cdev);
+		err = devm_led_classdev_register(dev, &pca963x[i].led_cdev);
 		if (err < 0)
-			goto exit;
+			return err;
 	}
 
 	/* Disable LED all-call address, and power down initially */
@@ -454,23 +454,6 @@ static int pca963x_probe(struct i2c_client *client,
 	}
 
 	return 0;
-
-exit:
-	while (i--)
-		led_classdev_unregister(&pca963x[i].led_cdev);
-
-	return err;
-}
-
-static int pca963x_remove(struct i2c_client *client)
-{
-	struct pca963x *pca963x = i2c_get_clientdata(client);
-	int i;
-
-	for (i = 0; i < pca963x->chipdef->n_leds; i++)
-		led_classdev_unregister(&pca963x->leds[i].led_cdev);
-
-	return 0;
 }
 
 static struct i2c_driver pca963x_driver = {
@@ -479,7 +462,6 @@ static struct i2c_driver pca963x_driver = {
 		.of_match_table = of_pca963x_match,
 	},
 	.probe	= pca963x_probe,
-	.remove	= pca963x_remove,
 	.id_table = pca963x_id,
 };
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH leds 3/7] leds: pca963x: cosmetic: rename variables
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
  2020-09-20  0:24 ` [PATCH leds 1/7] leds: pca963x: cosmetic: use helper variables, better indentation Marek Behún
  2020-09-20  0:24 ` [PATCH leds 2/7] leds: pca963x: use devres LED registering function Marek Behún
@ 2020-09-20  0:24 ` Marek Behún
  2020-09-20  0:24 ` [PATCH leds 4/7] " Marek Behún
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:24 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

Rename variables chip and pca963x_chip to chipdef and chip,
respectively, so that their names correspond to the names of their
types.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>
---
 drivers/leds/leds-pca963x.c | 55 +++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 27 deletions(-)

diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index cbb3bf6c044f2..bdb014c76a078 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -285,7 +285,7 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
 }
 
 static struct pca963x_platform_data *
-pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chip)
+pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chipdef)
 {
 	struct pca963x_platform_data *pdata;
 	struct led_info *pca963x_leds;
@@ -293,11 +293,11 @@ pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chip)
 	int count;
 
 	count = device_get_child_node_count(dev);
-	if (!count || count > chip->n_leds)
+	if (!count || count > chipdef->n_leds)
 		return ERR_PTR(-ENODEV);
 
-	pca963x_leds = devm_kcalloc(dev, chip->n_leds, sizeof(struct led_info),
-				    GFP_KERNEL);
+	pca963x_leds = devm_kcalloc(dev, chipdef->n_leds,
+				    sizeof(struct led_info), GFP_KERNEL);
 	if (!pca963x_leds)
 		return ERR_PTR(-ENOMEM);
 
@@ -307,7 +307,7 @@ pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chip)
 		int res;
 
 		res = fwnode_property_read_u32(child, "reg", &reg);
-		if ((res != 0) || (reg >= chip->n_leds))
+		if ((res != 0) || (reg >= chipdef->n_leds))
 			continue;
 
 		res = fwnode_property_read_string(child, "label", &led.name);
@@ -325,7 +325,7 @@ pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chip)
 		return ERR_PTR(-ENOMEM);
 
 	pdata->leds.leds = pca963x_leds;
-	pdata->leds.num_leds = chip->n_leds;
+	pdata->leds.num_leds = chipdef->n_leds;
 
 	/* default to open-drain unless totem pole (push-pull) is specified */
 	if (device_property_read_bool(dev, "nxp,totem-pole"))
@@ -340,8 +340,8 @@ pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chip)
 		pdata->blink_type = PCA963X_SW_BLINK;
 
 	if (device_property_read_u32(dev, "nxp,period-scale",
-				     &chip->scaling))
-		chip->scaling = 1000;
+				     &chipdef->scaling))
+		chipdef->scaling = 1000;
 
 	/* default to non-inverted output, unless inverted is specified */
 	if (device_property_read_bool(dev, "nxp,inverted-out"))
@@ -365,17 +365,17 @@ static int pca963x_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
 	struct device *dev = &client->dev;
-	struct pca963x *pca963x_chip;
-	struct pca963x_led *pca963x;
+	struct pca963x_chipdef *chipdef;
 	struct pca963x_platform_data *pdata;
-	struct pca963x_chipdef *chip;
+	struct pca963x_led *pca963x;
+	struct pca963x *chip;
 	int i, err;
 
-	chip = &pca963x_chipdefs[id->driver_data];
+	chipdef = &pca963x_chipdefs[id->driver_data];
 	pdata = dev_get_platdata(dev);
 
 	if (!pdata) {
-		pdata = pca963x_get_pdata(dev, chip);
+		pdata = pca963x_get_pdata(dev, chipdef);
 		if (IS_ERR(pdata)) {
 			dev_warn(dev, "could not parse configuration\n");
 			pdata = NULL;
@@ -383,32 +383,33 @@ static int pca963x_probe(struct i2c_client *client,
 	}
 
 	if (pdata && (pdata->leds.num_leds < 1 ||
-		      pdata->leds.num_leds > chip->n_leds)) {
-		dev_err(dev, "board info must claim 1-%d LEDs", chip->n_leds);
+		      pdata->leds.num_leds > chipdef->n_leds)) {
+		dev_err(dev, "board info must claim 1-%d LEDs",
+			chipdef->n_leds);
 		return -EINVAL;
 	}
 
-	pca963x_chip = devm_kzalloc(dev, sizeof(*pca963x_chip), GFP_KERNEL);
-	if (!pca963x_chip)
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
 		return -ENOMEM;
-	pca963x = devm_kcalloc(dev, chip->n_leds, sizeof(*pca963x), GFP_KERNEL);
+	pca963x = devm_kcalloc(dev, chipdef->n_leds, sizeof(*pca963x), GFP_KERNEL);
 	if (!pca963x)
 		return -ENOMEM;
 
-	i2c_set_clientdata(client, pca963x_chip);
+	i2c_set_clientdata(client, chip);
 
-	mutex_init(&pca963x_chip->mutex);
-	pca963x_chip->chipdef = chip;
-	pca963x_chip->client = client;
-	pca963x_chip->leds = pca963x;
+	mutex_init(&chip->mutex);
+	chip->chipdef = chipdef;
+	chip->client = client;
+	chip->leds = pca963x;
 
 	/* Turn off LEDs by default*/
-	for (i = 0; i < chip->n_leds / 4; i++)
-		i2c_smbus_write_byte_data(client, chip->ledout_base + i, 0x00);
+	for (i = 0; i < chipdef->n_leds / 4; i++)
+		i2c_smbus_write_byte_data(client, chipdef->ledout_base + i, 0x00);
 
-	for (i = 0; i < chip->n_leds; i++) {
+	for (i = 0; i < chipdef->n_leds; i++) {
 		pca963x[i].led_num = i;
-		pca963x[i].chip = pca963x_chip;
+		pca963x[i].chip = chip;
 
 		/* Platform data can specify LED names and default triggers */
 		if (pdata && i < pdata->leds.num_leds) {
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH leds 4/7] leds: pca963x: cosmetic: rename variables
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
                   ` (2 preceding siblings ...)
  2020-09-20  0:24 ` [PATCH leds 3/7] leds: pca963x: cosmetic: rename variables Marek Behún
@ 2020-09-20  0:24 ` Marek Behún
  2020-09-20  0:24 ` [PATCH leds 5/7] leds: pca963x: use flexible array Marek Behún
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:24 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

Rename variable of type struct pca963x_led from pca963x to simple led.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>
---
 drivers/leds/leds-pca963x.c | 104 ++++++++++++++++++------------------
 1 file changed, 53 insertions(+), 51 deletions(-)

diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index bdb014c76a078..a4096694925f5 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -115,17 +115,17 @@ struct pca963x_led {
 	u8 gfrq;
 };
 
-static int pca963x_brightness(struct pca963x_led *pca963x,
+static int pca963x_brightness(struct pca963x_led *led,
 			      enum led_brightness brightness)
 {
-	struct i2c_client *client = pca963x->chip->client;
-	struct pca963x_chipdef *chipdef = pca963x->chip->chipdef;
+	struct i2c_client *client = led->chip->client;
+	struct pca963x_chipdef *chipdef = led->chip->chipdef;
 	u8 ledout_addr, ledout, mask, val;
 	int shift;
 	int ret;
 
-	ledout_addr = chipdef->ledout_base + (pca963x->led_num / 4);
-	shift = 2 * (pca963x->led_num % 4);
+	ledout_addr = chipdef->ledout_base + (led->led_num / 4);
+	shift = 2 * (led->led_num % 4);
 	mask = 0x3 << shift;
 	ledout = i2c_smbus_read_byte_data(client, ledout_addr);
 
@@ -141,7 +141,7 @@ static int pca963x_brightness(struct pca963x_led *pca963x,
 	default:
 		ret = i2c_smbus_write_byte_data(client,
 						PCA963X_PWM_BASE +
-						pca963x->led_num,
+						led->led_num,
 						brightness);
 		if (ret < 0)
 			return ret;
@@ -154,27 +154,27 @@ static int pca963x_brightness(struct pca963x_led *pca963x,
 	return ret;
 }
 
-static void pca963x_blink(struct pca963x_led *pca963x)
+static void pca963x_blink(struct pca963x_led *led)
 {
-	struct i2c_client *client = pca963x->chip->client;
-	struct pca963x_chipdef *chipdef = pca963x->chip->chipdef;
+	struct i2c_client *client = led->chip->client;
+	struct pca963x_chipdef *chipdef = led->chip->chipdef;
 	u8 ledout_addr, ledout, mask, val, mode2;
 	int shift;
 
-	ledout_addr = chipdef->ledout_base + (pca963x->led_num / 4);
-	shift = 2 * (pca963x->led_num % 4);
+	ledout_addr = chipdef->ledout_base + (led->led_num / 4);
+	shift = 2 * (led->led_num % 4);
 	mask = 0x3 << shift;
 	mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);
 
-	i2c_smbus_write_byte_data(client, chipdef->grppwm, pca963x->gdc);
+	i2c_smbus_write_byte_data(client, chipdef->grppwm, led->gdc);
 
-	i2c_smbus_write_byte_data(client, chipdef->grpfreq, pca963x->gfrq);
+	i2c_smbus_write_byte_data(client, chipdef->grpfreq, led->gfrq);
 
 	if (!(mode2 & PCA963X_MODE2_DMBLNK))
 		i2c_smbus_write_byte_data(client, PCA963X_MODE2,
 					  mode2 | PCA963X_MODE2_DMBLNK);
 
-	mutex_lock(&pca963x->chip->mutex);
+	mutex_lock(&led->chip->mutex);
 
 	ledout = i2c_smbus_read_byte_data(client, ledout_addr);
 	if ((ledout & mask) != (PCA963X_LED_GRP_PWM << shift)) {
@@ -182,19 +182,19 @@ static void pca963x_blink(struct pca963x_led *pca963x)
 		i2c_smbus_write_byte_data(client, ledout_addr, val);
 	}
 
-	mutex_unlock(&pca963x->chip->mutex);
+	mutex_unlock(&led->chip->mutex);
 }
 
-static int pca963x_power_state(struct pca963x_led *pca963x)
+static int pca963x_power_state(struct pca963x_led *led)
 {
-	struct i2c_client *client = pca963x->chip->client;
-	unsigned long *leds_on = &pca963x->chip->leds_on;
+	struct i2c_client *client = led->chip->client;
+	unsigned long *leds_on = &led->chip->leds_on;
 	unsigned long cached_leds = *leds_on;
 
-	if (pca963x->led_cdev.brightness)
-		set_bit(pca963x->led_num, leds_on);
+	if (led->led_cdev.brightness)
+		set_bit(led->led_num, leds_on);
 	else
-		clear_bit(pca963x->led_num, leds_on);
+		clear_bit(led->led_num, leds_on);
 
 	if (!(*leds_on) != !cached_leds)
 		return i2c_smbus_write_byte_data(client, PCA963X_MODE1,
@@ -206,27 +206,27 @@ static int pca963x_power_state(struct pca963x_led *pca963x)
 static int pca963x_led_set(struct led_classdev *led_cdev,
 			   enum led_brightness value)
 {
-	struct pca963x_led *pca963x;
+	struct pca963x_led *led;
 	int ret;
 
-	pca963x = container_of(led_cdev, struct pca963x_led, led_cdev);
+	led = container_of(led_cdev, struct pca963x_led, led_cdev);
 
-	mutex_lock(&pca963x->chip->mutex);
+	mutex_lock(&led->chip->mutex);
 
-	ret = pca963x_brightness(pca963x, value);
+	ret = pca963x_brightness(led, value);
 	if (ret < 0)
 		goto unlock;
-	ret = pca963x_power_state(pca963x);
+	ret = pca963x_power_state(led);
 
 unlock:
-	mutex_unlock(&pca963x->chip->mutex);
+	mutex_unlock(&led->chip->mutex);
 	return ret;
 }
 
-static unsigned int pca963x_period_scale(struct pca963x_led *pca963x,
+static unsigned int pca963x_period_scale(struct pca963x_led *led,
 					 unsigned int val)
 {
-	unsigned int scaling = pca963x->chip->chipdef->scaling;
+	unsigned int scaling = led->chip->chipdef->scaling;
 
 	return scaling ? DIV_ROUND_CLOSEST(val * scaling, 1000) : val;
 }
@@ -234,11 +234,11 @@ static unsigned int pca963x_period_scale(struct pca963x_led *pca963x,
 static int pca963x_blink_set(struct led_classdev *led_cdev,
 			     unsigned long *delay_on, unsigned long *delay_off)
 {
-	struct pca963x_led *pca963x;
 	unsigned long time_on, time_off, period;
+	struct pca963x_led *led;
 	u8 gdc, gfrq;
 
-	pca963x = container_of(led_cdev, struct pca963x_led, led_cdev);
+	led = container_of(led_cdev, struct pca963x_led, led_cdev);
 
 	time_on = *delay_on;
 	time_off = *delay_off;
@@ -249,14 +249,14 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
 		time_off = 500;
 	}
 
-	period = pca963x_period_scale(pca963x, time_on + time_off);
+	period = pca963x_period_scale(led, time_on + time_off);
 
 	/* If period not supported by hardware, default to someting sane. */
 	if ((period < PCA963X_BLINK_PERIOD_MIN) ||
 	    (period > PCA963X_BLINK_PERIOD_MAX)) {
 		time_on = 500;
 		time_off = 500;
-		period = pca963x_period_scale(pca963x, 1000);
+		period = pca963x_period_scale(led, 1000);
 	}
 
 	/*
@@ -264,7 +264,7 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
 	 *	(time_on / period) = (GDC / 256) ->
 	 *		GDC = ((time_on * 256) / period)
 	 */
-	gdc = (pca963x_period_scale(pca963x, time_on) * 256) / period;
+	gdc = (pca963x_period_scale(led, time_on) * 256) / period;
 
 	/*
 	 * From manual: period = ((GFRQ + 1) / 24) in seconds.
@@ -273,10 +273,10 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
 	 */
 	gfrq = (period * 24 / 1000) - 1;
 
-	pca963x->gdc = gdc;
-	pca963x->gfrq = gfrq;
+	led->gdc = gdc;
+	led->gfrq = gfrq;
 
-	pca963x_blink(pca963x);
+	pca963x_blink(led);
 
 	*delay_on = time_on;
 	*delay_off = time_off;
@@ -367,7 +367,7 @@ static int pca963x_probe(struct i2c_client *client,
 	struct device *dev = &client->dev;
 	struct pca963x_chipdef *chipdef;
 	struct pca963x_platform_data *pdata;
-	struct pca963x_led *pca963x;
+	struct pca963x_led *leds;
 	struct pca963x *chip;
 	int i, err;
 
@@ -392,8 +392,8 @@ static int pca963x_probe(struct i2c_client *client,
 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
-	pca963x = devm_kcalloc(dev, chipdef->n_leds, sizeof(*pca963x), GFP_KERNEL);
-	if (!pca963x)
+	leds = devm_kcalloc(dev, chipdef->n_leds, sizeof(*leds), GFP_KERNEL);
+	if (!leds)
 		return -ENOMEM;
 
 	i2c_set_clientdata(client, chip);
@@ -401,39 +401,41 @@ static int pca963x_probe(struct i2c_client *client,
 	mutex_init(&chip->mutex);
 	chip->chipdef = chipdef;
 	chip->client = client;
-	chip->leds = pca963x;
+	chip->leds = leds;
 
 	/* Turn off LEDs by default*/
 	for (i = 0; i < chipdef->n_leds / 4; i++)
 		i2c_smbus_write_byte_data(client, chipdef->ledout_base + i, 0x00);
 
 	for (i = 0; i < chipdef->n_leds; i++) {
-		pca963x[i].led_num = i;
-		pca963x[i].chip = chip;
+		struct pca963x_led *led = &leds[i];
+
+		led->led_num = i;
+		led->chip = chip;
 
 		/* Platform data can specify LED names and default triggers */
 		if (pdata && i < pdata->leds.num_leds) {
 			if (pdata->leds.leds[i].name)
-				snprintf(pca963x[i].name,
-					 sizeof(pca963x[i].name), "pca963x:%s",
+				snprintf(led->name,
+					 sizeof(led->name), "pca963x:%s",
 					 pdata->leds.leds[i].name);
 			if (pdata->leds.leds[i].default_trigger)
-				pca963x[i].led_cdev.default_trigger =
+				led->led_cdev.default_trigger =
 					pdata->leds.leds[i].default_trigger;
 		}
 		if (!pdata || i >= pdata->leds.num_leds ||
 						!pdata->leds.leds[i].name)
-			snprintf(pca963x[i].name, sizeof(pca963x[i].name),
+			snprintf(led->name, sizeof(led->name),
 				 "pca963x:%d:%.2x:%d", client->adapter->nr,
 				 client->addr, i);
 
-		pca963x[i].led_cdev.name = pca963x[i].name;
-		pca963x[i].led_cdev.brightness_set_blocking = pca963x_led_set;
+		led->led_cdev.name = led->name;
+		led->led_cdev.brightness_set_blocking = pca963x_led_set;
 
 		if (pdata && pdata->blink_type == PCA963X_HW_BLINK)
-			pca963x[i].led_cdev.blink_set = pca963x_blink_set;
+			led->led_cdev.blink_set = pca963x_blink_set;
 
-		err = devm_led_classdev_register(dev, &pca963x[i].led_cdev);
+		err = devm_led_classdev_register(dev, &led->led_cdev);
 		if (err < 0)
 			return err;
 	}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH leds 5/7] leds: pca963x: use flexible array
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
                   ` (3 preceding siblings ...)
  2020-09-20  0:24 ` [PATCH leds 4/7] " Marek Behún
@ 2020-09-20  0:24 ` Marek Behún
  2020-09-24 12:16   ` Pavel Machek
  2020-09-20  0:24 ` [PATCH leds 6/7] leds: pca963x: register LEDs immediately after parsing, get rid of platdata Marek Behún
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:24 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

Instead of doing two allocations, allocate only once, by utilizing
flexible array members.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>
---
 drivers/leds/leds-pca963x.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index a4096694925f5..73dc00787beed 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -96,15 +96,7 @@ static const struct i2c_device_id pca963x_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, pca963x_id);
 
-struct pca963x_led;
-
-struct pca963x {
-	struct pca963x_chipdef *chipdef;
-	struct mutex mutex;
-	struct i2c_client *client;
-	struct pca963x_led *leds;
-	unsigned long leds_on;
-};
+struct pca963x;
 
 struct pca963x_led {
 	struct pca963x *chip;
@@ -115,6 +107,14 @@ struct pca963x_led {
 	u8 gfrq;
 };
 
+struct pca963x {
+	struct pca963x_chipdef *chipdef;
+	struct mutex mutex;
+	struct i2c_client *client;
+	unsigned long leds_on;
+	struct pca963x_led leds[];
+};
+
 static int pca963x_brightness(struct pca963x_led *led,
 			      enum led_brightness brightness)
 {
@@ -367,7 +367,6 @@ static int pca963x_probe(struct i2c_client *client,
 	struct device *dev = &client->dev;
 	struct pca963x_chipdef *chipdef;
 	struct pca963x_platform_data *pdata;
-	struct pca963x_led *leds;
 	struct pca963x *chip;
 	int i, err;
 
@@ -389,26 +388,23 @@ static int pca963x_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
-	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	chip = devm_kzalloc(dev, struct_size(chip, leds, chipdef->n_leds),
+			    GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
-	leds = devm_kcalloc(dev, chipdef->n_leds, sizeof(*leds), GFP_KERNEL);
-	if (!leds)
-		return -ENOMEM;
 
 	i2c_set_clientdata(client, chip);
 
 	mutex_init(&chip->mutex);
 	chip->chipdef = chipdef;
 	chip->client = client;
-	chip->leds = leds;
 
 	/* Turn off LEDs by default*/
 	for (i = 0; i < chipdef->n_leds / 4; i++)
 		i2c_smbus_write_byte_data(client, chipdef->ledout_base + i, 0x00);
 
 	for (i = 0; i < chipdef->n_leds; i++) {
-		struct pca963x_led *led = &leds[i];
+		struct pca963x_led *led = &chip->leds[i];
 
 		led->led_num = i;
 		led->chip = chip;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH leds 6/7] leds: pca963x: register LEDs immediately after parsing, get rid of platdata
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
                   ` (4 preceding siblings ...)
  2020-09-20  0:24 ` [PATCH leds 5/7] leds: pca963x: use flexible array Marek Behún
@ 2020-09-20  0:24 ` Marek Behún
  2020-09-20  0:25 ` [PATCH leds 7/7] leds: pca963x: use struct led_init_data when registering Marek Behún
  2020-09-22 17:12 ` [PATCH leds 0/7] leds: pca963x cleanup Pavel Machek
  7 siblings, 0 replies; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:24 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

Register LEDs immediately after parsing their properties.
This allows us to get rid of platdata, and since no one in tree uses
header linux/platform_data/leds-pca963x.h, remove it.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>
---
 drivers/leds/leds-pca963x.c                | 188 ++++++++-------------
 include/linux/platform_data/leds-pca963x.h |  35 ----
 2 files changed, 71 insertions(+), 152 deletions(-)
 delete mode 100644 include/linux/platform_data/leds-pca963x.h

diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index 73dc00787beed..5083ccce1a519 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -32,7 +32,6 @@
 #include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/of.h>
-#include <linux/platform_data/leds-pca963x.h>
 
 /* LED select registers determine the source that drives LED outputs */
 #define PCA963X_LED_OFF		0x0	/* LED driver off */
@@ -102,7 +101,6 @@ struct pca963x_led {
 	struct pca963x *chip;
 	struct led_classdev led_cdev;
 	int led_num; /* 0 .. 15 potentially */
-	char name[32];
 	u8 gdc;
 	u8 gfrq;
 };
@@ -284,72 +282,85 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
 	return 0;
 }
 
-static struct pca963x_platform_data *
-pca963x_get_pdata(struct device *dev, struct pca963x_chipdef *chipdef)
+static int pca963x_register_leds(struct i2c_client *client,
+				 struct pca963x *chip)
 {
-	struct pca963x_platform_data *pdata;
-	struct led_info *pca963x_leds;
+	struct pca963x_chipdef *chipdef = chip->chipdef;
+	struct pca963x_led *led = chip->leds;
+	struct device *dev = &client->dev;
 	struct fwnode_handle *child;
-	int count;
+	const char *name;
+	char label[64];
+	bool hw_blink;
+	s32 mode2;
+	u32 reg;
+	int ret;
 
-	count = device_get_child_node_count(dev);
-	if (!count || count > chipdef->n_leds)
-		return ERR_PTR(-ENODEV);
+	if (device_property_read_u32(dev, "nxp,period-scale",
+				     &chipdef->scaling))
+		chipdef->scaling = 1000;
 
-	pca963x_leds = devm_kcalloc(dev, chipdef->n_leds,
-				    sizeof(struct led_info), GFP_KERNEL);
-	if (!pca963x_leds)
-		return ERR_PTR(-ENOMEM);
+	hw_blink = device_property_read_bool(dev, "nxp,hw-blink");
 
-	device_for_each_child_node(dev, child) {
-		struct led_info led = {};
-		u32 reg;
-		int res;
+	mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);
+	if (mode2 < 0)
+		return mode2;
 
-		res = fwnode_property_read_u32(child, "reg", &reg);
-		if ((res != 0) || (reg >= chipdef->n_leds))
-			continue;
+	/* default to open-drain unless totem pole (push-pull) is specified */
+	if (device_property_read_bool(dev, "nxp,totem-pole"))
+		mode2 |= PCA963X_MODE2_OUTDRV;
+	else
+		mode2 &= ~PCA963X_MODE2_OUTDRV;
 
-		res = fwnode_property_read_string(child, "label", &led.name);
-		if ((res != 0) && is_of_node(child))
-			led.name = to_of_node(child)->name;
+	/* default to non-inverted output, unless inverted is specified */
+	if (device_property_read_bool(dev, "nxp,inverted-out"))
+		mode2 |= PCA963X_MODE2_INVRT;
+	else
+		mode2 &= ~PCA963X_MODE2_INVRT;
 
-		fwnode_property_read_string(child, "linux,default-trigger",
-					    &led.default_trigger);
+	ret = i2c_smbus_write_byte_data(client, PCA963X_MODE2, mode2);
+	if (ret < 0)
+		return ret;
 
-		pca963x_leds[reg] = led;
-	}
-	pdata = devm_kzalloc(dev, sizeof(struct pca963x_platform_data),
-			     GFP_KERNEL);
-	if (!pdata)
-		return ERR_PTR(-ENOMEM);
+	device_for_each_child_node(dev, child) {
+		ret = fwnode_property_read_u32(child, "reg", &reg);
+		if (ret || reg >= chipdef->n_leds) {
+			dev_err(dev, "Invalid 'reg' property for node %pfw\n",
+				child);
+			ret = -EINVAL;
+			goto err;
+		}
 
-	pdata->leds.leds = pca963x_leds;
-	pdata->leds.num_leds = chipdef->n_leds;
+		ret = fwnode_property_read_string(child, "label", &name);
+		if (!fwnode_property_read_string(child, "label", &name))
+			snprintf(label, sizeof(label), "pca963x:%s", name);
+		else
+			snprintf(label, sizeof(label), "pca963x::");
 
-	/* default to open-drain unless totem pole (push-pull) is specified */
-	if (device_property_read_bool(dev, "nxp,totem-pole"))
-		pdata->outdrv = PCA963X_TOTEM_POLE;
-	else
-		pdata->outdrv = PCA963X_OPEN_DRAIN;
+		fwnode_property_read_string(child, "linux,default-trigger",
+					    &led->led_cdev.default_trigger);
 
-	/* default to software blinking unless hardware blinking is specified */
-	if (device_property_read_bool(dev, "nxp,hw-blink"))
-		pdata->blink_type = PCA963X_HW_BLINK;
-	else
-		pdata->blink_type = PCA963X_SW_BLINK;
+		led->led_num = reg;
+		led->chip = chip;
+		led->led_cdev.name = label;
+		led->led_cdev.brightness_set_blocking = pca963x_led_set;
+		if (hw_blink)
+			led->led_cdev.blink_set = pca963x_blink_set;
 
-	if (device_property_read_u32(dev, "nxp,period-scale",
-				     &chipdef->scaling))
-		chipdef->scaling = 1000;
+		ret = devm_led_classdev_register(dev, &led->led_cdev);
+		if (ret) {
+			dev_err(dev, "Failed to register LED for node %pfw\n",
+				child);
+			goto err;
+		}
 
-	/* default to non-inverted output, unless inverted is specified */
-	if (device_property_read_bool(dev, "nxp,inverted-out"))
-		pdata->dir = PCA963X_INVERTED;
-	else
-		pdata->dir = PCA963X_NORMAL;
+		++led;
+	}
 
-	return pdata;
+	return 0;
+err:
+	fwnode_handle_put(child);
+	return ret;
 }
 
 static const struct of_device_id of_pca963x_match[] = {
@@ -366,30 +377,19 @@ static int pca963x_probe(struct i2c_client *client,
 {
 	struct device *dev = &client->dev;
 	struct pca963x_chipdef *chipdef;
-	struct pca963x_platform_data *pdata;
 	struct pca963x *chip;
-	int i, err;
+	int i, count;
 
 	chipdef = &pca963x_chipdefs[id->driver_data];
-	pdata = dev_get_platdata(dev);
 
-	if (!pdata) {
-		pdata = pca963x_get_pdata(dev, chipdef);
-		if (IS_ERR(pdata)) {
-			dev_warn(dev, "could not parse configuration\n");
-			pdata = NULL;
-		}
-	}
-
-	if (pdata && (pdata->leds.num_leds < 1 ||
-		      pdata->leds.num_leds > chipdef->n_leds)) {
-		dev_err(dev, "board info must claim 1-%d LEDs",
-			chipdef->n_leds);
+	count = device_get_child_node_count(dev);
+	if (!count || count > chipdef->n_leds) {
+		dev_err(dev, "Node %pfw must define between 1 and %d LEDs\n",
+			dev_fwnode(dev), chipdef->n_leds);
 		return -EINVAL;
 	}
 
-	chip = devm_kzalloc(dev, struct_size(chip, leds, chipdef->n_leds),
-			    GFP_KERNEL);
+	chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 
@@ -403,56 +403,10 @@ static int pca963x_probe(struct i2c_client *client,
 	for (i = 0; i < chipdef->n_leds / 4; i++)
 		i2c_smbus_write_byte_data(client, chipdef->ledout_base + i, 0x00);
 
-	for (i = 0; i < chipdef->n_leds; i++) {
-		struct pca963x_led *led = &chip->leds[i];
-
-		led->led_num = i;
-		led->chip = chip;
-
-		/* Platform data can specify LED names and default triggers */
-		if (pdata && i < pdata->leds.num_leds) {
-			if (pdata->leds.leds[i].name)
-				snprintf(led->name,
-					 sizeof(led->name), "pca963x:%s",
-					 pdata->leds.leds[i].name);
-			if (pdata->leds.leds[i].default_trigger)
-				led->led_cdev.default_trigger =
-					pdata->leds.leds[i].default_trigger;
-		}
-		if (!pdata || i >= pdata->leds.num_leds ||
-						!pdata->leds.leds[i].name)
-			snprintf(led->name, sizeof(led->name),
-				 "pca963x:%d:%.2x:%d", client->adapter->nr,
-				 client->addr, i);
-
-		led->led_cdev.name = led->name;
-		led->led_cdev.brightness_set_blocking = pca963x_led_set;
-
-		if (pdata && pdata->blink_type == PCA963X_HW_BLINK)
-			led->led_cdev.blink_set = pca963x_blink_set;
-
-		err = devm_led_classdev_register(dev, &led->led_cdev);
-		if (err < 0)
-			return err;
-	}
-
 	/* Disable LED all-call address, and power down initially */
 	i2c_smbus_write_byte_data(client, PCA963X_MODE1, BIT(4));
 
-	if (pdata) {
-		u8 mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);
-		/* Configure output: open-drain or totem pole (push-pull) */
-		if (pdata->outdrv == PCA963X_OPEN_DRAIN)
-			mode2 &= ~PCA963X_MODE2_OUTDRV;
-		else
-			mode2 |= PCA963X_MODE2_OUTDRV;
-		/* Configure direction: normal or inverted */
-		if (pdata->dir == PCA963X_INVERTED)
-			mode2 |= PCA963X_MODE2_INVRT;
-		i2c_smbus_write_byte_data(client, PCA963X_MODE2, mode2);
-	}
-
-	return 0;
+	return pca963x_register_leds(client, chip);
 }
 
 static struct i2c_driver pca963x_driver = {
diff --git a/include/linux/platform_data/leds-pca963x.h b/include/linux/platform_data/leds-pca963x.h
deleted file mode 100644
index 6091337ce4bfb..0000000000000
--- a/include/linux/platform_data/leds-pca963x.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * PCA963X LED chip driver.
- *
- * Copyright 2012 bct electronic GmbH
- * Copyright 2013 Qtechnology A/S
- */
-
-#ifndef __LINUX_PCA963X_H
-#define __LINUX_PCA963X_H
-#include <linux/leds.h>
-
-enum pca963x_outdrv {
-	PCA963X_OPEN_DRAIN,
-	PCA963X_TOTEM_POLE, /* aka push-pull */
-};
-
-enum pca963x_blink_type {
-	PCA963X_SW_BLINK,
-	PCA963X_HW_BLINK,
-};
-
-enum pca963x_direction {
-	PCA963X_NORMAL,
-	PCA963X_INVERTED,
-};
-
-struct pca963x_platform_data {
-	struct led_platform_data leds;
-	enum pca963x_outdrv outdrv;
-	enum pca963x_blink_type blink_type;
-	enum pca963x_direction dir;
-};
-
-#endif /* __LINUX_PCA963X_H*/
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH leds 7/7] leds: pca963x: use struct led_init_data when registering
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
                   ` (5 preceding siblings ...)
  2020-09-20  0:24 ` [PATCH leds 6/7] leds: pca963x: register LEDs immediately after parsing, get rid of platdata Marek Behún
@ 2020-09-20  0:25 ` Marek Behún
  2020-09-30 17:04   ` Pavel Machek
  2020-09-22 17:12 ` [PATCH leds 0/7] leds: pca963x cleanup Pavel Machek
  7 siblings, 1 reply; 11+ messages in thread
From: Marek Behún @ 2020-09-20  0:25 UTC (permalink / raw)
  To: linux-leds
  Cc: Pavel Machek, Dan Murphy, Marek Behún, Peter Meerwald,
	Ricardo Ribalda, Zahari Petkov

By using struct led_init_data when registering we do not need to parse
`label` DT property. Moreover `label` is deprecated and if it is not
present but `color` and `function` are, LED core will compose a name
from these properties instead.

Previously if the `label` DT property was not present, the code composed
name for the LED in the form
  "pca963x:%d:%.2x:%u"
For backwards compatibility we therefore set init_data->default_label
to this value so that the LED will not get a different name if `label`
property is not present, nor are `color` and `function`.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Peter Meerwald <p.meerwald@bct-electronic.com>
Cc: Ricardo Ribalda <ribalda@kernel.org>
Cc: Zahari Petkov <zahari@balena.io>
---
 drivers/leds/leds-pca963x.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index 5083ccce1a519..00aecd67e3483 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -289,8 +289,6 @@ static int pca963x_register_leds(struct i2c_client *client,
 	struct pca963x_led *led = chip->leds;
 	struct device *dev = &client->dev;
 	struct fwnode_handle *child;
-	const char *name;
-	char label[64];
 	bool hw_blink;
 	s32 mode2;
 	u32 reg;
@@ -323,6 +321,9 @@ static int pca963x_register_leds(struct i2c_client *client,
 		return ret;
 
 	device_for_each_child_node(dev, child) {
+		struct led_init_data init_data = {};
+		char default_label[32];
+
 		ret = fwnode_property_read_u32(child, "reg", &reg);
 		if (ret || reg >= chipdef->n_leds) {
 			dev_err(dev, "Invalid 'reg' property for node %pfw\n",
@@ -331,23 +332,21 @@ static int pca963x_register_leds(struct i2c_client *client,
 			goto err;
 		}
 
-		ret = fwnode_property_read_string(child, "label", &name);
-		if (!fwnode_property_read_string(child, "label", &name))
-			snprintf(label, sizeof(label), "pca963x:%s", name);
-		else
-			snprintf(label, sizeof(label), "pca963x::");
-
-		fwnode_property_read_string(child, "linux,default-trigger",
-					    &led->led_cdev.default_trigger);
-
 		led->led_num = reg;
 		led->chip = chip;
-		led->led_cdev.name = label;
 		led->led_cdev.brightness_set_blocking = pca963x_led_set;
 		if (hw_blink)
 			led->led_cdev.blink_set = pca963x_blink_set;
 
-		ret = devm_led_classdev_register(dev, &led->led_cdev);
+		init_data.fwnode = child;
+		/* for backwards compatibility */
+		init_data.devicename = "pca963x";
+		snprintf(default_label, sizeof(default_label), "%d:%.2x:%u",
+			 client->adapter->nr, client->addr, reg);
+		init_data.default_label = default_label;
+
+		ret = devm_led_classdev_register_ext(dev, &led->led_cdev,
+						     &init_data);
 		if (ret) {
 			dev_err(dev, "Failed to register LED for node %pfw\n",
 				child);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH leds 0/7] leds: pca963x cleanup
  2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
                   ` (6 preceding siblings ...)
  2020-09-20  0:25 ` [PATCH leds 7/7] leds: pca963x: use struct led_init_data when registering Marek Behún
@ 2020-09-22 17:12 ` Pavel Machek
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2020-09-22 17:12 UTC (permalink / raw)
  To: Marek Behún
  Cc: linux-leds, Dan Murphy, Peter Meerwald, Ricardo Ribalda, Zahari Petkov

[-- Attachment #1: Type: text/plain, Size: 418 bytes --]

Hi!

> this is a cleanup of pca963x LED driver, in spirit of previous
> patches I sent recently.
> 
> This series should apply on your for-next.

I like the series. Looks good on quick review. Someone testing it
would be very welcome...

Best regards,
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH leds 5/7] leds: pca963x: use flexible array
  2020-09-20  0:24 ` [PATCH leds 5/7] leds: pca963x: use flexible array Marek Behún
@ 2020-09-24 12:16   ` Pavel Machek
  0 siblings, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2020-09-24 12:16 UTC (permalink / raw)
  To: Marek Behún
  Cc: linux-leds, Dan Murphy, Peter Meerwald, Ricardo Ribalda, Zahari Petkov

[-- Attachment #1: Type: text/plain, Size: 364 bytes --]

Hi!

> Instead of doing two allocations, allocate only once, by utilizing
> flexible array members.

Thanks, I have applied 1-5 of the series. I would not mind getting
some testing here.

Best regards,
							Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH leds 7/7] leds: pca963x: use struct led_init_data when registering
  2020-09-20  0:25 ` [PATCH leds 7/7] leds: pca963x: use struct led_init_data when registering Marek Behún
@ 2020-09-30 17:04   ` Pavel Machek
  0 siblings, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2020-09-30 17:04 UTC (permalink / raw)
  To: Marek Behún
  Cc: linux-leds, Dan Murphy, Peter Meerwald, Ricardo Ribalda, Zahari Petkov

[-- Attachment #1: Type: text/plain, Size: 813 bytes --]

Hi!

> By using struct led_init_data when registering we do not need to parse
> `label` DT property. Moreover `label` is deprecated and if it is not
> present but `color` and `function` are, LED core will compose a name
> from these properties instead.
> 
> Previously if the `label` DT property was not present, the code composed
> name for the LED in the form
>   "pca963x:%d:%.2x:%u"
> For backwards compatibility we therefore set init_data->default_label
> to this value so that the LED will not get a different name if `label`
> property is not present, nor are `color` and `function`.

I took patches 6 and 7 of the series.

Thanks,
									Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-09-30 17:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-20  0:24 [PATCH leds 0/7] leds: pca963x cleanup Marek Behún
2020-09-20  0:24 ` [PATCH leds 1/7] leds: pca963x: cosmetic: use helper variables, better indentation Marek Behún
2020-09-20  0:24 ` [PATCH leds 2/7] leds: pca963x: use devres LED registering function Marek Behún
2020-09-20  0:24 ` [PATCH leds 3/7] leds: pca963x: cosmetic: rename variables Marek Behún
2020-09-20  0:24 ` [PATCH leds 4/7] " Marek Behún
2020-09-20  0:24 ` [PATCH leds 5/7] leds: pca963x: use flexible array Marek Behún
2020-09-24 12:16   ` Pavel Machek
2020-09-20  0:24 ` [PATCH leds 6/7] leds: pca963x: register LEDs immediately after parsing, get rid of platdata Marek Behún
2020-09-20  0:25 ` [PATCH leds 7/7] leds: pca963x: use struct led_init_data when registering Marek Behún
2020-09-30 17:04   ` Pavel Machek
2020-09-22 17:12 ` [PATCH leds 0/7] leds: pca963x cleanup Pavel Machek

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.