Update Linux to v5.4.2

Change-Id: Idf6911045d9d382da2cfe01b1edff026404ac8fd
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
index 2030a6b..2d8e819 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -1,11 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
 * Simple driver for Texas Instruments LM3630A Backlight driver chip
 * Copyright (C) 2012 Texas Instruments
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
 */
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -35,6 +31,14 @@
 #define REG_MAX		0x50
 
 #define INT_DEBOUNCE_MSEC	10
+
+#define LM3630A_BANK_0		0
+#define LM3630A_BANK_1		1
+
+#define LM3630A_NUM_SINKS	2
+#define LM3630A_SINK_0		0
+#define LM3630A_SINK_1		1
+
 struct lm3630a_chip {
 	struct device *dev;
 	struct delayed_work work;
@@ -201,7 +205,7 @@
 				      LM3630A_LEDA_ENABLE, LM3630A_LEDA_ENABLE);
 	if (ret < 0)
 		goto out_i2c_err;
-	return bl->props.brightness;
+	return 0;
 
 out_i2c_err:
 	dev_err(pchip->dev, "i2c failed to access\n");
@@ -278,7 +282,7 @@
 				      LM3630A_LEDB_ENABLE, LM3630A_LEDB_ENABLE);
 	if (ret < 0)
 		goto out_i2c_err;
-	return bl->props.brightness;
+	return 0;
 
 out_i2c_err:
 	dev_err(pchip->dev, "i2c failed to access REG_CTRL\n");
@@ -329,15 +333,17 @@
 
 static int lm3630a_backlight_register(struct lm3630a_chip *pchip)
 {
-	struct backlight_properties props;
 	struct lm3630a_platform_data *pdata = pchip->pdata;
+	struct backlight_properties props;
+	const char *label;
 
 	props.type = BACKLIGHT_RAW;
 	if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) {
 		props.brightness = pdata->leda_init_brt;
 		props.max_brightness = pdata->leda_max_brt;
+		label = pdata->leda_label ? pdata->leda_label : "lm3630a_leda";
 		pchip->bleda =
-		    devm_backlight_device_register(pchip->dev, "lm3630a_leda",
+		    devm_backlight_device_register(pchip->dev, label,
 						   pchip->dev, pchip,
 						   &lm3630a_bank_a_ops, &props);
 		if (IS_ERR(pchip->bleda))
@@ -348,8 +354,9 @@
 	    (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) {
 		props.brightness = pdata->ledb_init_brt;
 		props.max_brightness = pdata->ledb_max_brt;
+		label = pdata->ledb_label ? pdata->ledb_label : "lm3630a_ledb";
 		pchip->bledb =
-		    devm_backlight_device_register(pchip->dev, "lm3630a_ledb",
+		    devm_backlight_device_register(pchip->dev, label,
 						   pchip->dev, pchip,
 						   &lm3630a_bank_b_ops, &props);
 		if (IS_ERR(pchip->bledb))
@@ -364,6 +371,122 @@
 	.max_register = REG_MAX,
 };
 
+static int lm3630a_parse_led_sources(struct fwnode_handle *node,
+				     int default_led_sources)
+{
+	u32 sources[LM3630A_NUM_SINKS];
+	int ret, num_sources, i;
+
+	num_sources = fwnode_property_count_u32(node, "led-sources");
+	if (num_sources < 0)
+		return default_led_sources;
+	else if (num_sources > ARRAY_SIZE(sources))
+		return -EINVAL;
+
+	ret = fwnode_property_read_u32_array(node, "led-sources", sources,
+					     num_sources);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < num_sources; i++) {
+		if (sources[i] < LM3630A_SINK_0 || sources[i] > LM3630A_SINK_1)
+			return -EINVAL;
+
+		ret |= BIT(sources[i]);
+	}
+
+	return ret;
+}
+
+static int lm3630a_parse_bank(struct lm3630a_platform_data *pdata,
+			      struct fwnode_handle *node, int *seen_led_sources)
+{
+	int led_sources, ret;
+	const char *label;
+	u32 bank, val;
+	bool linear;
+
+	ret = fwnode_property_read_u32(node, "reg", &bank);
+	if (ret)
+		return ret;
+
+	if (bank < LM3630A_BANK_0 || bank > LM3630A_BANK_1)
+		return -EINVAL;
+
+	led_sources = lm3630a_parse_led_sources(node, BIT(bank));
+	if (led_sources < 0)
+		return led_sources;
+
+	if (*seen_led_sources & led_sources)
+		return -EINVAL;
+
+	*seen_led_sources |= led_sources;
+
+	linear = fwnode_property_read_bool(node,
+					   "ti,linear-mapping-mode");
+	if (bank) {
+		if (led_sources & BIT(LM3630A_SINK_0) ||
+		    !(led_sources & BIT(LM3630A_SINK_1)))
+			return -EINVAL;
+
+		pdata->ledb_ctrl = linear ?
+			LM3630A_LEDB_ENABLE_LINEAR :
+			LM3630A_LEDB_ENABLE;
+	} else {
+		if (!(led_sources & BIT(LM3630A_SINK_0)))
+			return -EINVAL;
+
+		pdata->leda_ctrl = linear ?
+			LM3630A_LEDA_ENABLE_LINEAR :
+			LM3630A_LEDA_ENABLE;
+
+		if (led_sources & BIT(LM3630A_SINK_1))
+			pdata->ledb_ctrl = LM3630A_LEDB_ON_A;
+	}
+
+	ret = fwnode_property_read_string(node, "label", &label);
+	if (!ret) {
+		if (bank)
+			pdata->ledb_label = label;
+		else
+			pdata->leda_label = label;
+	}
+
+	ret = fwnode_property_read_u32(node, "default-brightness",
+				       &val);
+	if (!ret) {
+		if (bank)
+			pdata->ledb_init_brt = val;
+		else
+			pdata->leda_init_brt = val;
+	}
+
+	ret = fwnode_property_read_u32(node, "max-brightness", &val);
+	if (!ret) {
+		if (bank)
+			pdata->ledb_max_brt = val;
+		else
+			pdata->leda_max_brt = val;
+	}
+
+	return 0;
+}
+
+static int lm3630a_parse_node(struct lm3630a_chip *pchip,
+			      struct lm3630a_platform_data *pdata)
+{
+	int ret = -ENODEV, seen_led_sources = 0;
+	struct fwnode_handle *node;
+
+	device_for_each_child_node(pchip->dev, node) {
+		ret = lm3630a_parse_bank(pdata, node, &seen_led_sources);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
 static int lm3630a_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -396,13 +519,18 @@
 				     GFP_KERNEL);
 		if (pdata == NULL)
 			return -ENOMEM;
+
 		/* default values */
-		pdata->leda_ctrl = LM3630A_LEDA_ENABLE;
-		pdata->ledb_ctrl = LM3630A_LEDB_ENABLE;
 		pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS;
 		pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS;
 		pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS;
 		pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS;
+
+		rval = lm3630a_parse_node(pchip, pdata);
+		if (rval) {
+			dev_err(&client->dev, "fail : parse node\n");
+			return rval;
+		}
 	}
 	pchip->pdata = pdata;
 
@@ -470,11 +598,17 @@
 	{}
 };
 
+static const struct of_device_id lm3630a_match_table[] = {
+	{ .compatible = "ti,lm3630a", },
+	{ },
+};
+
 MODULE_DEVICE_TABLE(i2c, lm3630a_id);
 
 static struct i2c_driver lm3630a_i2c_driver = {
 	.driver = {
 		   .name = LM3630A_NAME,
+		   .of_match_table = lm3630a_match_table,
 		   },
 	.probe = lm3630a_probe,
 	.remove = lm3630a_remove,