Use struct option_iter to walk over the individual options in the driver's option string. Replaces the hand-written strsep() loop with a clean interface. The helpers for struct option_iter handle empty option strings and empty options transparently. The struct's _init and _release functions duplicate and release the option string's memory buffer as needed. Done in preparation of constifying the option string. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/staging/sm750fb/sm750.c | 43 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index effc7fcc3703..2eb223f0631e 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/aperture.h> +#include <linux/cmdline.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/errno.h> @@ -867,9 +868,10 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index) } /* chip specific g_option configuration routine */ -static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src) +static void sm750fb_setup(struct sm750_dev *sm750_dev, const char *src) { - char *opt; + struct option_iter iter; + const char *opt; int swap; swap = 0; @@ -889,9 +891,12 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src) goto NO_PARAM; } - while ((opt = strsep(&src, ":")) != NULL && *opt != 0) { + dev_info(&sm750_dev->pdev->dev, "src=%s\n", src); + + option_iter_init(&iter, src); + + while (option_iter_next(&iter, opt)) { dev_info(&sm750_dev->pdev->dev, "opt=%s\n", opt); - dev_info(&sm750_dev->pdev->dev, "src=%s\n", src); if (!strncmp(opt, "swap", strlen("swap"))) { swap = 1; @@ -924,6 +929,8 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src) } } + option_iter_release(&iter); + NO_PARAM: if (sm750_dev->revid != SM750LE_REVISION_ID) { if (sm750_dev->fb_count > 1) { @@ -1096,10 +1103,12 @@ static void lynxfb_pci_remove(struct pci_dev *pdev) kfree(g_settings); } -static int __init lynxfb_setup(char *options) +static int __init lynxfb_setup(const char *options) { + struct option_iter iter; + const char *opt; int len; - char *opt, *tmp; + char *tmp; if (!options || !*options) { pr_warn("no options.\n"); @@ -1112,19 +1121,11 @@ static int __init lynxfb_setup(char *options) g_settings = kzalloc(len, GFP_KERNEL); if (!g_settings) return -ENOMEM; - tmp = g_settings; - /* - * Notes: - * char * strsep(char **s,const char * ct); - * @s: the string to be searched - * @ct :the characters to search for - * - * strsep() updates @options to pointer after the first found token - * it also returns the pointer ahead the token. - */ - while ((opt = strsep(&options, ":")) != NULL) { + option_iter_init(&iter, options); + + while (option_iter_next(&iter, opt)) { /* options that mean for any lynx chips are configured here */ if (!strncmp(opt, "noaccel", strlen("noaccel"))) { g_noaccel = 1; @@ -1133,15 +1134,15 @@ static int __init lynxfb_setup(char *options) } else if (!strncmp(opt, "dual", strlen("dual"))) { g_dualview = 1; } else { + if (tmp != g_settings) + *tmp++ = ':'; // add separator strcat(tmp, opt); tmp += strlen(opt); - if (options) - *tmp++ = ':'; - else - *tmp++ = 0; } } + option_iter_release(&iter); + /* misc g_settings are transport to chip specific routines */ pr_info("parameter left for chip specific analysis:%s\n", g_settings); return 0; -- 2.39.2