{"id":1941020,"url":"http://patchwork.ozlabs.org/api/patches/1941020/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/c139d3a42c61d978296aa2e513de073c643e4fbe.1716965617.git.ysato@users.sourceforge.jp/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<c139d3a42c61d978296aa2e513de073c643e4fbe.1716965617.git.ysato@users.sourceforge.jp>","list_archive_url":null,"date":"2024-05-29T08:01:09","name":"[DO,NOT,MERGE,v8,23/36] mfd: sm501: Convert platform_data to OF property","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"4b8b474b23ccc34ee1c1199cf916d46fcdbceaee","submitter":{"id":7114,"url":"http://patchwork.ozlabs.org/api/people/7114/?format=json","name":"Yoshinori Sato","email":"ysato@users.sourceforge.jp"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/c139d3a42c61d978296aa2e513de073c643e4fbe.1716965617.git.ysato@users.sourceforge.jp/mbox/","series":[{"id":408652,"url":"http://patchwork.ozlabs.org/api/series/408652/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=408652","date":"2024-05-29T08:00:51","name":"Device Tree support for SH7751 based board","version":8,"mbox":"http://patchwork.ozlabs.org/series/408652/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/1941020/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/1941020/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-pci+bounces-7977-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2604:1380:45e3:2400::1; helo=sv.mirrors.kernel.org;\n envelope-from=linux-pci+bounces-7977-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=153.127.30.23","smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=users.sourceforge.jp","smtp.subspace.kernel.org;\n spf=fail smtp.mailfrom=users.sourceforge.jp"],"Received":["from sv.mirrors.kernel.org (sv.mirrors.kernel.org\n [IPv6:2604:1380:45e3:2400::1])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature ECDSA (secp384r1))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4Vq27L1WxBz20Pr\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 May 2024 18:07:58 +1000 (AEST)","from smtp.subspace.kernel.org (wormhole.subspace.kernel.org\n [52.25.139.140])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby sv.mirrors.kernel.org (Postfix) with ESMTPS id CF80528BBE1\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 May 2024 08:07:56 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 1CCAF181302;\n\tWed, 29 May 2024 08:02:14 +0000 (UTC)","from sakura.ysato.name (ik1-413-38519.vs.sakura.ne.jp\n [153.127.30.23])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 2B937180A8A;\n\tWed, 29 May 2024 08:02:11 +0000 (UTC)","from SIOS1075.ysato.name (al128006.dynamic.ppp.asahi-net.or.jp\n [111.234.128.6])\n\tby sakura.ysato.name (Postfix) with ESMTPSA id 7DFDE1C0FD1;\n\tWed, 29 May 2024 17:02:09 +0900 (JST)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1716969734; cv=none;\n b=I6ee1/2Fjippu7I0X27csybvWL6zQ+wsj4pwHym65VJ98lEmTHI4L7DalCN96PCqNsOScawVf1gDrF6myb2X68YDclX72r+KGQT0Br6QYQMI555yPEthqQ9LOZnAT/cBACPbtCz95WLuxQtNShnRzBlYNZD2NvGAMN15g7HrUCU=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1716969734; c=relaxed/simple;\n\tbh=rXJ3FIMjhLIJCYj9qzJ/Vj+aCVUa/aALbLHc5PmBo14=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:\n\t MIME-Version;\n b=h/H+dQJ24UJc2l1Hp+hsrloOUUfJg/nLG+sNtjwWUC7APv1j0aS8MluKow3UXaPX6sA85wLYHAfn6k4P6sZZVoyGlF4RSzuPPzuz6lno4SXeawYgQvFYMf4//KYX9yOJk3xDkcmWkAH8gdv5DvKKprNWi88jkTU2L7UpI7GEfBM=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=users.sourceforge.jp;\n spf=fail smtp.mailfrom=users.sourceforge.jp;\n arc=none smtp.client-ip=153.127.30.23","From":"Yoshinori Sato <ysato@users.sourceforge.jp>","To":"linux-sh@vger.kernel.org","Cc":"Yoshinori Sato <ysato@users.sourceforge.jp>,\n Damien Le Moal <dlemoal@kernel.org>, Niklas Cassel <cassel@kernel.org>,\n Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,\n Conor Dooley <conor+dt@kernel.org>,\n Geert Uytterhoeven <geert+renesas@glider.be>,\n Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org>,\n David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,\n Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,\n Maxime Ripard <mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de>,\n Thomas Gleixner <tglx@linutronix.de>, Bjorn Helgaas <bhelgaas@google.com>,\n Lorenzo Pieralisi <lpieralisi@kernel.org>, =?utf-8?q?Krzysztof_Wilczy=C5=84?=\n\t=?utf-8?q?ski?= <kw@linux.com>,\n Greg Kroah-Hartman <gregkh@linuxfoundation.org>,\n Jiri Slaby <jirislaby@kernel.org>, Magnus Damm <magnus.damm@gmail.com>,\n Daniel Lezcano <daniel.lezcano@linaro.org>, Rich Felker <dalias@libc.org>,\n John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>,\n Lee Jones <lee@kernel.org>, Helge Deller <deller@gmx.de>,\n Heiko Stuebner <heiko.stuebner@cherry.de>,\n Neil Armstrong <neil.armstrong@linaro.org>,\n Chris Morgan <macromorgan@hotmail.com>, Sebastian Reichel <sre@kernel.org>,\n Linus Walleij <linus.walleij@linaro.org>, Arnd Bergmann <arnd@arndb.de>,\n Masahiro Yamada <masahiroy@kernel.org>, Baoquan He <bhe@redhat.com>,\n Andrew Morton <akpm@linux-foundation.org>,\n Guenter Roeck <linux@roeck-us.net>, Kefeng Wang <wangkefeng.wang@huawei.com>,\n Stephen Rothwell <sfr@canb.auug.org.au>,\n Azeem Shaikh <azeemshaikh38@gmail.com>, Guo Ren <guoren@kernel.org>,\n Max Filippov <jcmvbkbc@gmail.com>, Jernej Skrabec <jernej.skrabec@gmail.com>,\n Herve Codina <herve.codina@bootlin.com>,\n Andy Shevchenko <andriy.shevchenko@linux.intel.com>,\n Anup Patel <apatel@ventanamicro.com>, Jacky Huang <ychuang3@nuvoton.com>,\n Hugo Villeneuve <hvilleneuve@dimonoff.com>, Jonathan Corbet <corbet@lwn.net>,\n Wolfram Sang <wsa+renesas@sang-engineering.com>, =?utf-8?q?Uwe_Kleine-K?=\n\t=?utf-8?q?=C3=B6nig?= <u.kleine-koenig@pengutronix.de>,\n Christophe JAILLET <christophe.jaillet@wanadoo.fr>,\n Sam Ravnborg <sam@ravnborg.org>,\n Javier Martinez Canillas <javierm@redhat.com>,\n Sergey Shtylyov <s.shtylyov@omp.ru>,\n Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,\n linux-ide@vger.kernel.org, devicetree@vger.kernel.org,\n linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,\n linux-clk@vger.kernel.org, dri-devel@lists.freedesktop.org,\n linux-pci@vger.kernel.org, linux-serial@vger.kernel.org,\n linux-fbdev@vger.kernel.org","Subject":"[DO NOT MERGE v8 23/36] mfd: sm501: Convert platform_data to OF\n property","Date":"Wed, 29 May 2024 17:01:09 +0900","Message-Id":"\n <c139d3a42c61d978296aa2e513de073c643e4fbe.1716965617.git.ysato@users.sourceforge.jp>","X-Mailer":"git-send-email 2.39.2","In-Reply-To":"<cover.1716965617.git.ysato@users.sourceforge.jp>","References":"<cover.1716965617.git.ysato@users.sourceforge.jp>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit"},"content":"Various parameters of SM501 can be set using platform_data,\nso parameters cannot be passed in the DeviceTree target.\nExpands the parameters set in platform_data so that they can be\nspecified using DeviceTree properties.\n\nSigned-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>\n---\n drivers/mfd/sm501.c           | 238 ++++++++++++++++++++++++++++++++++\n drivers/video/fbdev/sm501fb.c |  87 +++++++++++++\n 2 files changed, 325 insertions(+)","diff":"diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c\nindex b3592982a83b..d373aded0c3b 100644\n--- a/drivers/mfd/sm501.c\n+++ b/drivers/mfd/sm501.c\n@@ -20,6 +20,7 @@\n #include <linux/gpio/driver.h>\n #include <linux/gpio/machine.h>\n #include <linux/slab.h>\n+#include <linux/clk.h>\n \n #include <linux/sm501.h>\n #include <linux/sm501-regs.h>\n@@ -82,6 +83,16 @@ struct sm501_devdata {\n \tunsigned int\t\t\t rev;\n };\n \n+struct sm501_config_props_uint {\n+\tchar *name;\n+\tu32 shift;\n+};\n+\n+struct sm501_config_props_flag {\n+\tchar *clr_name;\n+\tchar *set_name;\n+\tu32 bit;\n+};\n \n #define MHZ (1000 * 1000)\n \n@@ -1370,6 +1381,227 @@ static int sm501_init_dev(struct sm501_devdata *sm)\n \treturn 0;\n }\n \n+#define FIELD_WIDTH 4\n+struct dt_values {\n+\tchar *name;\n+\tunsigned int offset;\n+\tunsigned int width;\n+\tchar *val[(1 << FIELD_WIDTH) + 1];\n+};\n+\n+#define fld(_name, _offset, _width, ...)\t\\\n+\t{ \\\n+\t\t.name = _name, \\\n+\t\t.offset = _offset, \\\n+\t\t.width = _width,\t\\\n+\t\t.val = { __VA_ARGS__, NULL},\t\\\n+\t}\n+\n+static const struct dt_values misc_timing[] = {\n+\tfld(\"ex\", 28, 4,\n+\t    \"none\", \"16\", \"32\", \"48\", \"64\", \"80\", \"96\", \"112\",\n+\t    \"128\", \"144\", \"160\", \"176\", \"192\", \"208\", \"224\", \"240\"),\n+\tfld(\"xc\", 24, 2, \"internal-pll\", \"hclk\", \"gpio30\"),\n+\tfld(\"us\", 23, 1, \"disable\", \"enable\"),\n+\tfld(\"ssm1\", 20, 1, \"288\", \"divider\"),\n+\tfld(\"sm1\", 16, 4,\n+\t    \"1\", \"2\", \"4\", \"8\", \"16\", \"32\", \"64\", \"128\",\n+\t    \"3\", \"6\", \"12\", \"24\", \"48\", \"96\", \"192\", \"384\"),\n+\tfld(\"ssm0\", 12, 1, \"288\", \"divider\"),\n+\tfld(\"sm0\", 8, 4,\n+\t    \"1\", \"2\", \"4\", \"8\", \"16\", \"32\", \"64\", \"128\",\n+\t    \"3\", \"6\", \"12\", \"24\", \"48\", \"96\", \"192\", \"384\"),\n+\tfld(\"deb\", 7, 1, \"input-reference\", \"output\"),\n+\tfld(\"a\", 6, 1, \"no-acpi\", \"acpi\"),\n+\tfld(\"divider\", 4, 2, \"336\", \"288\", \"240\", \"192\"),\n+\tfld(\"u\", 3, 1, \"normal\", \"simulation\"),\n+\tfld(\"delay\", 0, 3, \"none\", \"0.5\", \"1.0\", \"1.5\", \"2.0\", \"2.5\"),\n+\t{ .name = NULL },\n+};\n+\n+static const struct dt_values misc_control[] = {\n+\tfld(\"pad\", 30, 2, \"24\", \"12\", \"8\"),\n+\tfld(\"usbclk\", 28, 2, \"xtal\", \"96\", \"48\"),\n+\tfld(\"ssp\", 27, 1, \"uart1\", \"ssp1\"),\n+\tfld(\"lat\", 26, 1, \"disable\", \"enable\"),\n+\tfld(\"fp\", 25, 1, \"18\", \"24\"),\n+\tfld(\"freq\", 24, 1, \"24\", \"12\"),\n+\tfld(\"refresh\", 21, 2, \"8\", \"16\", \"32\", \"64\"),\n+\tfld(\"hold\", 18, 3, \"fifo-empty\", \"8\", \"16\", \"24\", \"32\"),\n+\tfld(\"sh\", 17, 1, \"active-low\", \"active-high\"),\n+\tfld(\"ii\", 16, 1, \"normal\", \"inverted\"),\n+\tfld(\"pll\", 15, 1, \"disable\", \"enable\"),\n+\tfld(\"gap\", 13, 2, \"0\"),\n+\tfld(\"dac\", 12, 1, \"enable\", \"disable\"),\n+\tfld(\"mc\", 11, 1, \"cpu\", \"8051\"),\n+\tfld(\"bl\", 10, 8, \"1\"),\n+\tfld(\"usb\", 9, 1, \"master\", \"slave\"),\n+\tfld(\"vr\", 4, 1, \"0x1e00000\", \"0x3e00000\"),\n+\t{ .name = NULL },\n+};\n+\n+/* Read configuration values */\n+static void sm501_of_read_config(struct device *dev, struct device_node *np,\n+\t\t\t\t const char *prefix,\n+\t\t\t\t const struct dt_values *values,\n+\t\t\t\t struct sm501_reg_init *ret)\n+{\n+\tconst char *name;\n+\tconst char *val;\n+\tunsigned int i;\n+\tchar key[64];\n+\tu32 shift;\n+\tu32 width;\n+\tu32 mask;\n+\n+\tret->mask = ~0;\n+\tret->set = 0;\n+\n+\twhile (values->name) {\n+\t\tsnprintf(key, sizeof(key), \"%s-%s\", prefix, values->name);\n+\t\tname = values->name;\n+\t\tshift = values->offset;\n+\t\twidth = values->width;\n+\n+\t\tif (of_property_read_string(np, key, &val) == 0) {\n+\t\t\tmask = (1 << width) - 1;\n+\t\t\tmask = ~(mask << shift);\n+\t\t\tret->mask &= mask;\n+\t\t\ti = 0;\n+\t\t\twhile (values->val[i]) {\n+\t\t\t\tif (strcmp(val, values->val[i]) == 0) {\n+\t\t\t\t\tret->set |= i << shift;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\ti++;\n+\t\t\t}\n+\t\t}\n+\t\tvalues++;\n+\t}\n+}\n+\n+static void sm501_of_read_gpio(struct device *dev, struct device_node *np,\n+\t\t\t       struct sm501_reg_init *hi, struct sm501_reg_init *low)\n+{\n+\tstruct device_node *gpio_node;\n+\tstruct property *prop;\n+\tunsigned int pin_no;\n+\tconst char *s;\n+\tint mode;\n+\tu64 mask;\n+\tu64 set;\n+\n+\tmask = ~0;\n+\tset = 0;\n+\tgpio_node = of_get_child_by_name(np, \"gpio\");\n+\tif (gpio_node) {\n+\t\tfor (prop = gpio_node->properties; prop; prop = prop->next) {\n+\t\t\tmode = -1;\n+\t\t\tif (sscanf(prop->name, \"pin-%u\", &pin_no) == 1) {\n+\t\t\t\tof_property_read_string(gpio_node, prop->name, &s);\n+\t\t\t\tif (strcmp(s, \"ioport\")) {\n+\t\t\t\t\tmode = 0;\n+\t\t\t\t} else if (strcmp(s, \"function\")) {\n+\t\t\t\t\tmode = 1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (mode >= 0) {\n+\t\t\t\tmask &= ~(1 << pin_no);\n+\t\t\t\tset |= mode << pin_no;\n+\t\t\t}\n+\t\t}\n+\t}\n+\t/* Bit48 - 54 is reserved */\n+\tmask &= ~0x007f000000000000UL;\n+\tset &= ~0x007f000000000000UL;\n+\n+\thi->set = set >> 32;\n+\tlow->set = set & 0xffffffff;\n+\thi->mask = mask >> 32;\n+\tlow->mask = mask & 0xffffffff;\n+}\n+\n+/* Read device functions */\n+static u32 sm501_read_devices(struct device *dev, struct device_node *np)\n+{\n+\tstatic const char * const funcname[] = {\n+\t\t\"usb-host\", \"usb-slave\", \"ssp0\", \"ssp1\",\n+\t\t\"uart0\", \"uart1\", \"fbaccel\", \"ac97\",\n+\t\t\"i2s\",\n+\t};\n+\tstruct property *prop;\n+\tunsigned int i;\n+\tconst char *s;\n+\tu32 ret = 0;\n+\n+\tof_property_for_each_string(np, \"smi,devices\", prop, s) {\n+\t\tfor (i = 0; i < ARRAY_SIZE(funcname); i++) {\n+\t\t\tif (strcmp(s, funcname[i]) == 0) {\n+\t\t\t\tret |= 1 << i;\n+\t\t\t\tgoto next;\n+\t\t\t}\n+\t\t}\n+\t\tdev_warn(dev, \"Unknown device function '%s'\", s);\n+next:\n+\t}\n+\tif (!ret)\n+\t\tdev_warn(dev, \"devices not defined. disable all functions.\");\n+\treturn ret;\n+}\n+\n+/* Build platform_data from OF property */\n+struct plat_dt {\n+\tstruct sm501_platdata plat;\n+\tstruct sm501_initdata init;\n+};\n+\n+static int mclk_get(struct device_node *np, int index, unsigned long *out)\n+{\n+\tstruct clk *clk;\n+\n+\tclk = of_clk_get(np, 0);\n+\tif (IS_ERR(clk))\n+\t\treturn PTR_ERR(clk);\n+\t*out = clk_get_rate(clk);\n+\tclk_put(clk);\n+\treturn 0;\n+}\n+\n+static int sm501_parse_dt(struct sm501_devdata *sm, struct device_node *np)\n+{\n+\tstruct sm501_platdata *plat;\n+\tstruct plat_dt *dt_p;\n+\tint ret;\n+\n+\tdt_p = devm_kzalloc(sm->dev, sizeof(*dt_p), GFP_KERNEL);\n+\tif (!dt_p)\n+\t\treturn -ENOMEM;\n+\n+\tplat = &dt_p->plat;\n+\tplat->init = &dt_p->init;\n+\n+\tplat->init->devices = sm501_read_devices(sm->dev, np);\n+\n+\tret = mclk_get(np, 0, &plat->init->mclk);\n+\tif (ret && ret != -ENOENT)\n+\t\treturn ret;\n+\tret = mclk_get(np, 0, &plat->init->m1xclk);\n+\tif (ret && ret != -ENOENT)\n+\t\treturn ret;\n+\n+\tsm501_of_read_config(sm->dev, np, \"misc-timing\",\n+\t\t\t     misc_timing, &plat->init->misc_timing);\n+\tsm501_of_read_config(sm->dev, np, \"misc-control\",\n+\t\t\t     misc_control, &plat->init->misc_control);\n+\tif (IS_ENABLED(CONFIG_MFD_SM501_GPIO)) {\n+\t\tsm501_of_read_gpio(sm->dev, np,\n+\t\t\t\t   &plat->init->gpio_high,\n+\t\t\t\t   &plat->init->gpio_low);\n+\t}\n+\tsm->platdata = plat;\n+\treturn 0;\n+}\n+\n static int sm501_plat_probe(struct platform_device *dev)\n {\n \tstruct sm501_devdata *sm;\n@@ -1406,6 +1638,12 @@ static int sm501_plat_probe(struct platform_device *dev)\n \t\tgoto err_res;\n \t}\n \n+\tif (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {\n+\t\tret = sm501_parse_dt(sm, dev->dev.of_node);\n+\t\tif (ret)\n+\t\t\tgoto err_res;\n+\t}\n+\n \tplatform_set_drvdata(dev, sm);\n \n \tsm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));\ndiff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c\nindex d6fdc1737cd2..4162e1322dd4 100644\n--- a/drivers/video/fbdev/sm501fb.c\n+++ b/drivers/video/fbdev/sm501fb.c\n@@ -1932,6 +1932,87 @@ static int sm501fb_start_one(struct sm501fb_info *info,\n \treturn 0;\n }\n \n+#if defined(CONFIG_OF)\n+static u32 read_display_flags(struct device_node *np)\n+{\n+\tstatic const char * const name[] = {\n+\t\t\"use-init-done\", \"disable-at-exit\", \"use-hwcursor\", \"use-hwaccel\",\n+\t\t\"panel-no-fpen\", \"panel-no-vbiasen\", \"panel-inv-fpen\", \"panel-inv-vbiasen\",\n+\t};\n+\n+\tstruct property *prop;\n+\tunsigned int i;\n+\tconst char *s;\n+\tu32 ret = 0;\n+\n+\tof_property_for_each_string(np, \"smi,flags\", prop, s) {\n+\t\tfor (i = 0; i < ARRAY_SIZE(name); i++) {\n+\t\t\tif (strcmp(s, name[i]) == 0) {\n+\t\t\t\tret |= 1 << i;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn ret;\n+}\n+\n+/* parse CRT / panel configuration */\n+static struct sm501_platdata_fbsub *dt_fbsub(struct device *dev,\n+\t\t\t\t\t     struct device_node *np,\n+\t\t\t\t\t     const char *name)\n+{\n+\tstruct sm501_platdata_fbsub *fbsub = NULL;\n+\tstruct device_node *child;\n+\tu32 flags = 0;\n+\tu32 bpp = 0;\n+\tint len;\n+\n+\tchild = of_get_child_by_name(np, name);\n+\tif (child == NULL)\n+\t\treturn NULL;\n+\n+\tof_property_read_u32(child, \"bpp\", &bpp);\n+\n+\t/* If flags property is obtained, fbsub is returned. */\n+\tflags = read_display_flags(child);\n+\tif (flags) {\n+\t\tfbsub = devm_kzalloc(dev, sizeof(*fbsub), GFP_KERNEL);\n+\t\tif (fbsub) {\n+\t\t\tfbsub->def_bpp = bpp;\n+\t\t\tfbsub->flags = flags;\n+\t\t}\n+\t}\n+\treturn fbsub;\n+}\n+\n+/* Build platform_data from OF property */\n+static struct sm501_platdata_fb *pdata_from_dt(struct device *dev, struct device_node *np)\n+{\n+\tenum sm501_fb_routing fb_route = SM501_FB_OWN;\n+\tstruct sm501_platdata_fb *pdata = NULL;\n+\tstruct sm501_platdata_fbsub *fb_crt;\n+\tstruct sm501_platdata_fbsub *fb_pnl;\n+\tunsigned int flags = 0;\n+\n+\tif (of_property_read_bool(np, \"route-crt-panel\"))\n+\t\tfb_route = SM501_FB_CRT_PANEL;\n+\tif (of_property_read_bool(np, \"swap-fb-endian\"))\n+\t\tflags = SM501_FBPD_SWAP_FB_ENDIAN;\n+\tfb_crt = dt_fbsub(dev, np, \"crt\");\n+\tfb_pnl = dt_fbsub(dev, np, \"panel\");\n+\tif (fb_crt || fb_pnl) {\n+\t\tpdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);\n+\t\tif (pdata) {\n+\t\t\tpdata->fb_route = fb_route;\n+\t\t\tpdata->flags = flags;\n+\t\t\tpdata->fb_crt = fb_crt;\n+\t\t\tpdata->fb_pnl = fb_pnl;\n+\t\t}\n+\t}\n+\treturn pdata;\n+}\n+#endif\n+\n static int sm501fb_probe(struct platform_device *pdev)\n {\n \tstruct sm501fb_info *info;\n@@ -1974,6 +2055,12 @@ static int sm501fb_probe(struct platform_device *pdev)\n \t\t\t\tif (info->edid_data)\n \t\t\t\t\tfound = 1;\n \t\t\t}\n+\t\t\t/* Get platform data compatible configuration */\n+\t\t\tif (!found) {\n+\t\t\t\tinfo->pdata = pdata_from_dt(dev, np);\n+\t\t\t\tif (info->pdata)\n+\t\t\t\t\tfound = 1;\n+\t\t\t}\n \t\t}\n #endif\n \t\tif (!found) {\n","prefixes":["DO","NOT","MERGE","v8","23/36"]}