diff options
author | Marek BehĂșn <kabel@kernel.org> | 2020-09-26 22:11:30 +0200 |
---|---|---|
committer | Pavel Machek <pavel@ucw.cz> | 2020-09-30 19:22:58 +0200 |
commit | 940cca1ab5d6c3bc1f8db0c804cf7c5e0caf1853 (patch) | |
tree | c25fb05943875a15dfbfbe722040deccc837962d | |
parent | 108f4664e3449828114780a05393eb8d2be7fdd0 (diff) |
leds: ns2: convert to fwnode API
Convert from OF api to fwnode API, so that it is possible to bind this
driver without device-tree.
The fwnode API does not expose a function to read a specific element of
an array. We therefore change the types of the ns2_led_modval structure
so that we can read the whole modval array with one fwnode call.
Signed-off-by: Marek BehĂșn <kabel@kernel.org>
Tested-by: Simon Guinot <simon.guinot@sequanux.org>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
-rw-r--r-- | drivers/leds/leds-ns2.c | 55 |
1 files changed, 26 insertions, 29 deletions
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index e1ec5cbed07e..dba6bdfa861b 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c @@ -24,11 +24,16 @@ enum ns2_led_modes { NS_V2_LED_SATA, }; +/* + * If the size of this structure or types of its members is changed, + * the filling of array modval in function ns2_led_register must be changed + * accordingly. + */ struct ns2_led_modval { - enum ns2_led_modes mode; - int cmd_level; - int slow_level; -}; + u32 mode; + u32 cmd_level; + u32 slow_level; +} __packed; /* * The Network Space v2 dual-GPIO LED is wired to a CPLD. Three different LED @@ -167,27 +172,28 @@ static struct attribute *ns2_led_attrs[] = { }; ATTRIBUTE_GROUPS(ns2_led); -static int ns2_led_register(struct device *dev, struct device_node *np, +static int ns2_led_register(struct device *dev, struct fwnode_handle *node, struct ns2_led *led) { struct led_init_data init_data = {}; struct ns2_led_modval *modval; enum ns2_led_modes mode; - int nmodes, ret, i; + int nmodes, ret; - led->cmd = devm_gpiod_get_from_of_node(dev, np, "cmd-gpio", 0, - GPIOD_ASIS, np->name); + led->cmd = devm_fwnode_gpiod_get_index(dev, node, "cmd", 0, GPIOD_ASIS, + fwnode_get_name(node)); if (IS_ERR(led->cmd)) return PTR_ERR(led->cmd); - led->slow = devm_gpiod_get_from_of_node(dev, np, "slow-gpio", 0, - GPIOD_ASIS, np->name); + led->slow = devm_fwnode_gpiod_get_index(dev, node, "slow", 0, + GPIOD_ASIS, + fwnode_get_name(node)); if (IS_ERR(led->slow)) return PTR_ERR(led->slow); - ret = of_property_count_u32_elems(np, "modes-map"); + ret = fwnode_property_count_u32(node, "modes-map"); if (ret < 0 || ret % 3) { - dev_err(dev, "Missing or malformed modes-map for %pOF\n", np); + dev_err(dev, "Missing or malformed modes-map for %pfw\n", node); return -EINVAL; } @@ -196,16 +202,8 @@ static int ns2_led_register(struct device *dev, struct device_node *np, if (!modval) return -ENOMEM; - for (i = 0; i < nmodes; i++) { - u32 val; - - of_property_read_u32_index(np, "modes-map", 3 * i, &val); - modval[i].mode = val; - of_property_read_u32_index(np, "modes-map", 3 * i + 1, &val); - modval[i].cmd_level = val; - of_property_read_u32_index(np, "modes-map", 3 * i + 2, &val); - modval[i].slow_level = val; - } + fwnode_property_read_u32_array(node, "modes-map", (void *)modval, + nmodes * 3); rwlock_init(&led->rw_lock); @@ -228,11 +226,11 @@ static int ns2_led_register(struct device *dev, struct device_node *np, led->sata = (mode == NS_V2_LED_SATA) ? 1 : 0; led->cdev.brightness = (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL; - init_data.fwnode = of_fwnode_handle(np); + init_data.fwnode = node; ret = devm_led_classdev_register_ext(dev, &led->cdev, &init_data); if (ret) - dev_err(dev, "Failed to register LED for node %pOF\n", np); + dev_err(dev, "Failed to register LED for node %pfw\n", node); return ret; } @@ -246,13 +244,12 @@ MODULE_DEVICE_TABLE(of, of_ns2_leds_match); static int ns2_led_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np, *child; + struct fwnode_handle *child; struct ns2_led *leds; int count; int ret; - np = dev_of_node(dev); - count = of_get_available_child_count(np); + count = device_get_child_node_count(dev); if (!count) return -ENODEV; @@ -260,10 +257,10 @@ static int ns2_led_probe(struct platform_device *pdev) if (!leds) return -ENOMEM; - for_each_available_child_of_node(np, child) { + device_for_each_child_node(dev, child) { ret = ns2_led_register(dev, child, leds++); if (ret) { - of_node_put(child); + fwnode_handle_put(child); return ret; } } |